Added touch focus
[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 Camera::Camera(QDeclarativeItem *parent) :
52   QDeclarativeItem(parent),
53   m_cam(new QtCamera(this)),
54   m_dev(0),
55   m_vf(new QtCamGraphicsViewfinder(m_cam->config(), this)),
56   m_mode(Camera::UnknownMode),
57   m_notifications(new NotificationsContainer(this)),
58   m_zoom(0),
59   m_flash(0),
60   m_scene(0),
61   m_evComp(0),
62   m_whiteBalance(0),
63   m_colorTone(0),
64   m_iso(0),
65   m_exposure(0),
66   m_aperture(0),
67   m_noiseReduction(0),
68   m_flickerReduction(0),
69   m_focus(0),
70   m_autoFocus(0),
71   m_videoMute(0),
72   m_videoTorch(0) {
73
74   QObject::connect(m_vf, SIGNAL(renderAreaChanged()), this, SIGNAL(renderAreaChanged()));
75   QObject::connect(m_vf, SIGNAL(videoResolutionChanged()), this, SIGNAL(videoResolutionChanged()));
76 }
77
78 Camera::~Camera() {
79   if (m_dev) {
80     m_dev->stop(true);
81     m_dev->deleteLater();
82     m_dev = 0;
83   }
84
85   delete m_zoom;
86   delete m_flash;
87   delete m_scene;
88   delete m_evComp;
89   delete m_whiteBalance;
90   delete m_colorTone;
91   delete m_iso;
92   delete m_exposure;
93   delete m_aperture;
94   delete m_noiseReduction;
95   delete m_flickerReduction;
96   delete m_focus;
97   delete m_autoFocus;
98   delete m_videoMute;
99   delete m_videoTorch;
100   // TODO: cleanup
101 }
102
103 void Camera::componentComplete() {
104   QDeclarativeItem::componentComplete();
105
106   emit deviceCountChanged();
107 }
108
109 int Camera::deviceCount() const {
110   return m_cam ? m_cam->devices().size() : 0;
111 }
112
113 QString Camera::deviceName(int index) const {
114   return m_cam->devices().at(index).first;
115 }
116
117 QVariant Camera::deviceId(int index) const {
118   return m_cam->devices().at(index).second;
119 }
120
121 bool Camera::reset(const QVariant& deviceId, const CameraMode& mode) {
122   if (mode == Camera::UnknownMode) {
123     qmlInfo(this) << "Cannot set mode to unknown";
124     return false;
125   }
126
127   if (!isComponentComplete()) {
128     qmlInfo(this) << "Component is still not ready";
129     return false;
130   }
131
132   QVariant oldId = m_id;
133   Camera::CameraMode oldMode = m_mode;
134
135   if (setDeviceId(deviceId) && setMode(mode)) {
136     if (oldId != m_id) {
137       emit deviceIdChanged();
138       emit deviceChanged();
139
140       resetCapabilities();
141     }
142
143     if (oldMode != m_mode) {
144       emit modeChanged();
145     }
146
147     return true;
148   }
149
150   return false;
151 }
152
153 bool Camera::setDeviceId(const QVariant& deviceId) {
154   if (deviceId == m_id) {
155     return true;
156   }
157
158   if (m_dev && m_dev->stop(false)) {
159     delete m_dev;
160   }
161   else if (m_dev) {
162     qmlInfo(this) << "Failed to stop device";
163     return false;
164   }
165
166   m_dev = m_cam->device(deviceId, this);
167
168   m_id = deviceId;
169
170   m_vf->setDevice(m_dev);
171
172   QObject::connect(m_dev, SIGNAL(runningStateChanged(bool)),
173                       this, SIGNAL(runningStateChanged()));
174   QObject::connect(m_dev, SIGNAL(idleStateChanged(bool)), this, SIGNAL(idleStateChanged()));
175   QObject::connect(m_dev, SIGNAL(error(const QString&, int, const QString&)),
176                    this, SIGNAL(error(const QString&, int, const QString&)));
177
178   m_notifications->setDevice(m_dev);
179
180   return true;
181 }
182
183 QVariant Camera::deviceId() const {
184   return m_id;
185 }
186
187 void Camera::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) {
188   QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
189
190   m_vf->setGeometry(newGeometry);
191 }
192
193 QtCamDevice *Camera::device() const {
194   return m_dev;
195 }
196
197 bool Camera::setMode(const Camera::CameraMode& mode) {
198   if (m_mode == mode) {
199     return true;
200   }
201
202   if (!m_dev) {
203     return false;
204   }
205
206   m_mode = mode;
207
208   if (m_dev->isRunning()) {
209     applyMode();
210   }
211
212   return true;
213 }
214
215 Camera::CameraMode Camera::mode() {
216   return m_mode;
217 }
218
219 bool Camera::start() {
220   if (!m_dev) {
221     return false;
222   }
223
224   if (!applyMode()) {
225     return false;
226   }
227
228   return m_dev->start();
229 }
230
231 bool Camera::stop(bool force) {
232   if (m_dev) {
233     return m_dev->stop(force);
234   }
235
236   return true;
237 }
238
239 bool Camera::isIdle() {
240   return m_dev ? m_dev->isIdle() : true;
241 }
242
243 bool Camera::isRunning() {
244   return m_dev ? m_dev->isRunning() : false;
245 }
246
247 bool Camera::applyMode() {
248   if (m_mode == Camera::UnknownMode) {
249     return false;
250   }
251
252   if (m_mode == Camera::VideoMode && m_dev->activeMode() != m_dev->videoMode()) {
253     m_dev->videoMode()->activate();
254   }
255   else if (m_mode == Camera::ImageMode && m_dev->activeMode() != m_dev->imageMode()) {
256     m_dev->imageMode()->activate();
257   }
258
259   return true;
260 }
261
262 QString Camera::imageSuffix() const {
263   return m_cam->config()->imageSuffix();
264 }
265
266 QString Camera::videoSuffix() const {
267   return m_cam->config()->videoSuffix();
268 }
269
270 Notifications *Camera::notifications() const {
271   return m_notifications->notifications();
272 }
273
274 void Camera::setNotifications(Notifications *notifications) {
275   if (m_notifications->setNotifications(notifications)) {
276
277     if (Sounds *s = dynamic_cast<Sounds *>(notifications)) {
278       s->setConfig(m_cam->config());
279       s->reload();
280     }
281
282     emit notificationsChanged();
283   }
284 }
285
286 QRectF Camera::renderArea() const {
287   return m_vf->renderArea();
288 }
289
290 QSizeF Camera::videoResolution() const {
291   return m_vf->videoResolution();
292 }
293
294 void Camera::resetCapabilities() {
295   QtCamDevice *dev = device();
296
297   delete m_zoom;
298   m_zoom = new Zoom(dev, this);
299   emit zoomChanged();
300
301   delete m_flash;
302   m_flash = new Flash(dev, this);
303   emit flashChanged();
304
305   delete m_scene;
306   m_scene = new Scene(dev, this);
307   emit sceneChanged();
308
309   delete m_evComp;
310   m_evComp = new EvComp(dev, this);
311   emit evCompChanged();
312
313   delete m_whiteBalance;
314   m_whiteBalance = new WhiteBalance(dev, this);
315   emit whiteBalanceChanged();
316
317   delete m_colorTone;
318   m_colorTone = new ColorTone(dev, this);
319   emit colorToneChanged();
320
321   delete m_iso;
322   m_iso = new Iso(dev, this);
323   emit isoChanged();
324
325   delete m_exposure;
326   m_exposure = new Exposure(dev, this);
327   emit exposureChanged();
328
329   delete m_aperture;
330   m_aperture = new Aperture(dev, this);
331   emit apertureChanged();
332
333   delete m_noiseReduction;
334   m_noiseReduction = new NoiseReduction(dev, this);
335   emit noiseReductionChanged();
336
337   delete m_flickerReduction;
338   m_flickerReduction = new FlickerReduction(dev, this);
339   emit flickerReductionChanged();
340
341   delete m_focus;
342   m_focus = new Focus(dev, this);
343   emit focusChanged();
344
345   delete m_autoFocus;
346   m_autoFocus = new AutoFocus(dev, this);
347   emit autoFocusChanged();
348
349   delete m_videoMute;
350   m_videoMute = new VideoMute(dev, this);
351   emit videoMuteChanged();
352
353   delete m_videoTorch;
354   m_videoTorch = new VideoTorch(dev, this);
355   emit videoTorchChanged();
356 }
357
358 Zoom *Camera::zoom() const {
359   return m_zoom;
360 }
361
362 Flash *Camera::flash() const {
363   return m_flash;
364 }
365
366 Scene *Camera::scene() const {
367   return m_scene;
368 }
369
370 EvComp *Camera::evComp() const {
371   return m_evComp;
372 }
373
374 WhiteBalance *Camera::whiteBalance() const {
375   return m_whiteBalance;
376 }
377
378 ColorTone *Camera::colorTone() const {
379   return m_colorTone;
380 }
381
382 Iso *Camera::iso() const {
383   return m_iso;
384 }
385
386 Exposure *Camera::exposure() const {
387   return m_exposure;
388 }
389
390 Aperture *Camera::aperture() const {
391   return m_aperture;
392 }
393
394 NoiseReduction *Camera::noiseReduction() const {
395   return m_noiseReduction;
396 }
397
398 FlickerReduction *Camera::flickerReduction() const {
399   return m_flickerReduction;
400 }
401
402 Focus *Camera::focus() const {
403   return m_focus;
404 }
405
406 AutoFocus *Camera::autoFocus() const {
407   return m_autoFocus;
408 }
409
410 VideoMute *Camera::videoMute() const {
411   return m_videoMute;
412 }
413
414 VideoTorch *Camera::videoTorch() const {
415 return m_videoTorch;
416 }