1 /*
2 * Kaidan - A user-friendly XMPP client for every device!
3 *
4 * Copyright (C) 2016-2021 Kaidan developers and contributors
5 * (see the LICENSE file for a full list of copyright authors)
6 *
7 * Kaidan is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * In addition, as a special exception, the author of Kaidan gives
13 * permission to link the code of its release with the OpenSSL
14 * project's "OpenSSL" library (or with modified versions of it that
15 * use the same license as the "OpenSSL" library), and distribute the
16 * linked executables. You must obey the GNU General Public License in
17 * all respects for all of the code used other than "OpenSSL". If you
18 * modify this file, you may extend this exception to your version of
19 * the file, but you are not obligated to do so. If you do not wish to
20 * do so, delete this exception statement from your version.
21 *
22 * Kaidan is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include "CameraModel.h"
32
CameraInfo(const QString & deviceName)33 CameraInfo::CameraInfo(const QString &deviceName)
34 : QCameraInfo(deviceName.toLocal8Bit())
35 {
36 }
37
CameraInfo(const QCameraInfo & other)38 CameraInfo::CameraInfo(const QCameraInfo &other)
39 : QCameraInfo(other)
40 {
41 }
42
CameraModel(QObject * parent)43 CameraModel::CameraModel(QObject *parent)
44 : QAbstractListModel(parent)
45 {
46 refresh();
47 }
48
rowCount(const QModelIndex & parent) const49 int CameraModel::rowCount(const QModelIndex &parent) const
50 {
51 return parent == QModelIndex() ? m_cameras.count() : 0;
52 }
53
data(const QModelIndex & index,int role) const54 QVariant CameraModel::data(const QModelIndex &index, int role) const
55 {
56 if (hasIndex(index.row(), index.column(), index.parent())) {
57 const auto &cameraInfo(m_cameras[index.row()]);
58
59 switch (role) {
60 case CameraModel::CustomRoles::IsNullRole:
61 return cameraInfo.isNull();
62 case CameraModel::CustomRoles::DeviceNameRole:
63 return cameraInfo.deviceName();
64 case CameraModel::CustomRoles::DescriptionRole:
65 return cameraInfo.description();
66 case CameraModel::CustomRoles::PositionRole:
67 return cameraInfo.position();
68 case CameraModel::CustomRoles::OrientationRole:
69 return cameraInfo.orientation();
70 case CameraModel::CustomRoles::CameraInfoRole:
71 return QVariant::fromValue(CameraInfo(cameraInfo));
72 }
73 }
74
75 return QVariant();
76 }
77
roleNames() const78 QHash<int, QByteArray> CameraModel::roleNames() const
79 {
80 static const QHash<int, QByteArray> roles {
81 { IsNullRole, QByteArrayLiteral("isNull") },
82 { DeviceNameRole, QByteArrayLiteral("deviceName") },
83 { DescriptionRole, QByteArrayLiteral("description") },
84 { PositionRole, QByteArrayLiteral("position") },
85 { OrientationRole, QByteArrayLiteral("orientation") },
86 { CameraInfoRole, QByteArrayLiteral("cameraInfo") }
87 };
88
89 return roles;
90 }
91
cameras() const92 QList<QCameraInfo> CameraModel::cameras() const
93 {
94 return m_cameras;
95 }
96
defaultCamera()97 CameraInfo CameraModel::defaultCamera()
98 {
99 return CameraInfo(QCameraInfo::defaultCamera());
100 }
101
currentIndex() const102 int CameraModel::currentIndex() const
103 {
104 return m_currentIndex;
105 }
106
setCurrentIndex(int currentIndex)107 void CameraModel::setCurrentIndex(int currentIndex)
108 {
109 if (currentIndex < 0 || currentIndex >= m_cameras.count()
110 || m_currentIndex == currentIndex) {
111 return;
112 }
113
114 m_currentIndex = currentIndex;
115 emit currentIndexChanged();
116 }
117
currentCamera() const118 CameraInfo CameraModel::currentCamera() const
119 {
120 return m_currentIndex >= 0 && m_currentIndex < m_cameras.count()
121 ? CameraInfo(m_cameras[m_currentIndex])
122 : CameraInfo();
123 }
124
setCurrentCamera(const CameraInfo & currentCamera)125 void CameraModel::setCurrentCamera(const CameraInfo ¤tCamera)
126 {
127 setCurrentIndex(m_cameras.indexOf(currentCamera));
128 }
129
camera(int row) const130 CameraInfo CameraModel::camera(int row) const
131 {
132 return hasIndex(row, 0)
133 ? CameraInfo(m_cameras[row])
134 : CameraInfo();
135 }
136
indexOf(const QString & deviceName) const137 int CameraModel::indexOf(const QString &deviceName) const
138 {
139 for (int i = 0; i < m_cameras.count(); ++i) {
140 const auto &camera(m_cameras[i]);
141
142 if (camera.deviceName() == deviceName) {
143 return i;
144 }
145 }
146
147 return -1;
148 }
149
camera(const QString & deviceName)150 CameraInfo CameraModel::camera(const QString &deviceName)
151 {
152 return CameraInfo(deviceName);
153 }
154
camera(QCamera::Position position)155 CameraInfo CameraModel::camera(QCamera::Position position)
156 {
157 const auto cameras = QCameraInfo::availableCameras(position);
158 return cameras.isEmpty() ? CameraInfo() : CameraInfo(cameras.first());
159 }
160
refresh()161 void CameraModel::refresh()
162 {
163 const auto cameras = QCameraInfo::availableCameras();
164
165 if (m_cameras == cameras) {
166 return;
167 }
168
169 beginResetModel();
170 const QString currentDeviceName = currentCamera().deviceName();
171 const auto it = std::find_if(m_cameras.constBegin(), m_cameras.constEnd(),
172 [¤tDeviceName](const QCameraInfo &deviceInfo) {
173 return deviceInfo.deviceName() == currentDeviceName;
174 });
175
176 m_cameras = cameras;
177 m_currentIndex = it == m_cameras.constEnd() ? -1 : it - m_cameras.constBegin();
178 endResetModel();
179
180 emit camerasChanged();
181 emit currentIndexChanged();
182 }
183