833b58029b0f1d5c837ac944143587f25ec1ba25
[harmattan/cameraplus] / imports / camera.cpp
1 /*!
2  * This file is part of CameraPlus.
3  *
4  * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "camera.h"
22 #include "qtcamera.h"
23 #include "qtcamdevice.h"
24 #include "qtcammode.h"
25 #include "qtcamimagemode.h"
26 #include "qtcamvideomode.h"
27 #include "qtcamgraphicsviewfinder.h"
28 #include "qtcamconfig.h"
29 #include "notifications.h"
30 #include "notificationscontainer.h"
31 #include "sounds.h"
32 #include <QDeclarativeInfo>
33
34 #include "zoom.h"
35 #include "flash.h"
36 #include "scene.h"
37 #include "evcomp.h"
38 #include "whitebalance.h"
39 #include "colortone.h"
40 #include "iso.h"
41 #include "exposure.h"
42 #include "aperture.h"
43 #include "noisereduction.h"
44 #include "flickerreduction.h"
45 #include "focus.h"
46 #include "autofocus.h"
47
48 #include "videomute.h"
49 #include "videotorch.h"
50
51 // TODO: a viewfinder class that inherits QDeclarativeItem
52
53 Camera::Camera(QDeclarativeItem *parent) :
54   QDeclarativeItem(parent),
55   m_cam(new QtCamera(this)),
56   m_dev(0),
57   m_vf(new QtCamGraphicsViewfinder(m_cam->config(), this)),
58   m_mode(Camera::UnknownMode),
59   m_notifications(new NotificationsContainer(this)),
60   m_zoom(0),
61   m_flash(0),
62   m_scene(0),
63   m_evComp(0),
64   m_whiteBalance(0),
65   m_colorTone(0),
66   m_iso(0),
67   m_exposure(0),
68   m_aperture(0),
69   m_noiseReduction(0),
70   m_flickerReduction(0),
71   m_focus(0),
72   m_autoFocus(0),
73   m_videoMute(0),
74   m_videoTorch(0) {
75
76   // TODO:
77 }
78
79 Camera::~Camera() {
80   if (m_dev) {
81     m_dev->stop(true);
82     m_dev->deleteLater();
83     m_dev = 0;
84   }
85
86   delete m_zoom;
87   delete m_flash;
88   delete m_scene;
89   delete m_evComp;
90   delete m_whiteBalance;
91   delete m_colorTone;
92   delete m_iso;
93   delete m_exposure;
94   delete m_aperture;
95   delete m_noiseReduction;
96   delete m_flickerReduction;
97   delete m_focus;
98   delete m_autoFocus;
99   delete m_videoMute;
100   delete m_videoTorch;
101   // TODO: cleanup
102 }
103
104 void Camera::componentComplete() {
105   QDeclarativeItem::componentComplete();
106
107   emit deviceCountChanged();
108 }
109
110 int Camera::deviceCount() const {
111   return m_cam ? m_cam->devices().size() : 0;
112 }
113
114 QString Camera::deviceName(int index) const {
115   return m_cam->devices().at(index).first;
116 }
117
118 QVariant Camera::deviceId(int index) const {
119   return m_cam->devices().at(index).second;
120 }
121
122 bool Camera::reset(const QVariant& deviceId, const CameraMode& mode) {
123   if (mode == Camera::UnknownMode) {
124     qmlInfo(this) << "Cannot set mode to unknown";
125     return false;
126   }
127
128   if (!isComponentComplete()) {
129     qmlInfo(this) << "Component is still not ready";
130     return false;
131   }
132
133   QVariant oldId = m_id;
134   Camera::CameraMode oldMode = m_mode;
135
136   if (setDeviceId(deviceId) && setMode(mode)) {
137     if (oldId != m_id) {
138       emit deviceIdChanged();
139       emit deviceChanged();
140
141       resetCapabilities();
142     }
143
144     if (oldMode != m_mode) {
145       emit modeChanged();
146     }
147
148     return true;
149   }
150
151   return false;
152 }
153
154 bool Camera::setDeviceId(const QVariant& deviceId) {
155   if (deviceId == m_id) {
156     return true;
157   }
158
159   if (m_dev && m_dev->stop(false)) {
160     delete m_dev;
161   }
162   else if (m_dev) {
163     qmlInfo(this) << "Failed to stop device";
164     return false;
165   }
166
167   m_dev = m_cam->device(deviceId, this);
168
169   m_id = deviceId;
170
171   m_vf->setDevice(m_dev);
172
173   QObject::connect(m_dev, SIGNAL(runningStateChanged(bool)),
174                       this, SIGNAL(runningStateChanged()));
175   QObject::connect(m_dev, SIGNAL(idleStateChanged(bool)), this, SIGNAL(idleStateChanged()));
176   QObject::connect(m_dev, SIGNAL(error(const QString&, int, const QString&)),
177                    this, SIGNAL(error(const QString&, int, const QString&)));
178
179   m_notifications->setDevice(m_dev);
180
181   return true;
182 }
183
184 QVariant Camera::deviceId() const {
185   return m_id;
186 }
187
188 void Camera::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) {
189   QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
190
191   m_vf->setGeometry(newGeometry);
192 }
193
194 QtCamDevice *Camera::device() const {
195   return m_dev;
196 }
197
198 bool Camera::setMode(const Camera::CameraMode& mode) {
199   if (m_mode == mode) {
200     return true;
201   }
202
203   if (!m_dev) {
204     return false;
205   }
206
207   m_mode = mode;
208
209   if (m_dev->isRunning()) {
210     applyMode();
211   }
212
213   return true;
214 }
215
216 Camera::CameraMode Camera::mode() {
217   return m_mode;
218 }
219
220 bool Camera::start() {
221   if (!m_dev) {
222     return false;
223   }
224
225   if (!applyMode()) {
226     return false;
227   }
228
229   return m_dev->start();
230 }
231
232 bool Camera::stop(bool force) {
233   if (m_dev) {
234     return m_dev->stop(force);
235   }
236
237   return true;
238 }
239
240 bool Camera::isIdle() {
241   return m_dev ? m_dev->isIdle() : true;
242 }
243
244 bool Camera::isRunning() {
245   return m_dev ? m_dev->isRunning() : false;
246 }
247
248 bool Camera::applyMode() {
249   if (m_mode == Camera::UnknownMode) {
250     return false;
251   }
252
253   if (m_mode == Camera::VideoMode && m_dev->activeMode() != m_dev->videoMode()) {
254     m_dev->videoMode()->activate();
255   }
256   else if (m_mode == Camera::ImageMode && m_dev->activeMode() != m_dev->imageMode()) {
257     m_dev->imageMode()->activate();
258   }
259
260   return true;
261 }
262
263 QString Camera::imageSuffix() const {
264   return m_cam->config()->imageSuffix();
265 }
266
267 QString Camera::videoSuffix() const {
268   return m_cam->config()->videoSuffix();
269 }
270
271 Notifications *Camera::notifications() const {
272   return m_notifications->notifications();
273 }
274
275 void Camera::setNotifications(Notifications *notifications) {
276   if (m_notifications->setNotifications(notifications)) {
277
278     if (Sounds *s = dynamic_cast<Sounds *>(notifications)) {
279       s->setConfig(m_cam->config());
280       s->reload();
281     }
282
283     emit notificationsChanged();
284   }
285 }
286
287 void Camera::resetCapabilities() {
288   QtCamDevice *dev = device();
289
290   delete m_zoom;
291   m_zoom = new Zoom(dev, this);
292   emit zoomChanged();
293
294   delete m_flash;
295   m_flash = new Flash(dev, this);
296   emit flashChanged();
297
298   delete m_scene;
299   m_scene = new Scene(dev, this);
300   emit sceneChanged();
301
302   delete m_evComp;
303   m_evComp = new EvComp(dev, this);
304   emit evCompChanged();
305
306   delete m_whiteBalance;
307   m_whiteBalance = new WhiteBalance(dev, this);
308   emit whiteBalanceChanged();
309
310   delete m_colorTone;
311   m_colorTone = new ColorTone(dev, this);
312   emit colorToneChanged();
313
314   delete m_iso;
315   m_iso = new Iso(dev, this);
316   emit isoChanged();
317
318   delete m_exposure;
319   m_exposure = new Exposure(dev, this);
320   emit exposureChanged();
321
322   delete m_aperture;
323   m_aperture = new Aperture(dev, this);
324   emit apertureChanged();
325
326   delete m_noiseReduction;
327   m_noiseReduction = new NoiseReduction(dev, this);
328   emit noiseReductionChanged();
329
330   delete m_flickerReduction;
331   m_flickerReduction = new FlickerReduction(dev, this);
332   emit flickerReductionChanged();
333
334   delete m_focus;
335   m_focus = new Focus(dev, this);
336   emit focusChanged();
337
338   delete m_autoFocus;
339   m_autoFocus = new AutoFocus(dev, this);
340   emit autoFocusChanged();
341
342   delete m_videoMute;
343   m_videoMute = new VideoMute(dev, this);
344   emit videoMuteChanged();
345
346   delete m_videoTorch;
347   m_videoTorch = new VideoTorch(dev, this);
348   emit videoTorchChanged();
349 }
350
351 Zoom *Camera::zoom() const {
352   return m_zoom;
353 }
354
355 Flash *Camera::flash() const {
356   return m_flash;
357 }
358
359 Scene *Camera::scene() const {
360   return m_scene;
361 }
362
363 EvComp *Camera::evComp() const {
364   return m_evComp;
365 }
366
367 WhiteBalance *Camera::whiteBalance() const {
368   return m_whiteBalance;
369 }
370
371 ColorTone *Camera::colorTone() const {
372   return m_colorTone;
373 }
374
375 Iso *Camera::iso() const {
376   return m_iso;
377 }
378
379 Exposure *Camera::exposure() const {
380   return m_exposure;
381 }
382
383 Aperture *Camera::aperture() const {
384   return m_aperture;
385 }
386
387 NoiseReduction *Camera::noiseReduction() const {
388   return m_noiseReduction;
389 }
390
391 FlickerReduction *Camera::flickerReduction() const {
392   return m_flickerReduction;
393 }
394
395 Focus *Camera::focus() const {
396   return m_focus;
397 }
398
399 AutoFocus *Camera::autoFocus() const {
400   return m_autoFocus;
401 }
402
403 VideoMute *Camera::videoMute() const {
404   return m_videoMute;
405 }
406
407 VideoTorch *Camera::videoTorch() const {
408 return m_videoTorch;
409 }