Reworked postcapture model
[harmattan/cameraplus] / declarative / mode.cpp
1 /*!
2  * This file is part of CameraPlus.
3  *
4  * Copyright (C) 2012-2013 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 "mode.h"
22 #include "qtcammode.h"
23 #include "camera.h"
24 #include "qtcamdevice.h"
25 #include "previewprovider.h"
26
27 Mode::Mode(QObject *parent) :
28   QObject(parent),
29   m_cam(0),
30   m_mode(0),
31   m_seq(0) {
32
33 }
34
35 Mode::~Mode() {
36   m_cam = 0;
37   m_mode = 0;
38 }
39
40 Camera *Mode::camera() {
41   return m_cam;
42 }
43
44 void Mode::setCamera(Camera *camera) {
45   if (camera == m_cam) {
46     return;
47   }
48
49   if (m_cam) {
50     QObject::disconnect(m_cam, SIGNAL(prepareForDeviceChange()), this, SLOT(prepareForDeviceChange()));
51     QObject::disconnect(m_cam, SIGNAL(deviceChanged()), this, SLOT(deviceChanged()));
52     QObject::disconnect(m_cam, SIGNAL(deviceChanged()), this, SIGNAL(isReadyChanged()));
53   }
54
55   m_cam = camera;
56
57   if (m_cam) {
58     QObject::connect(m_cam, SIGNAL(prepareForDeviceChange()), this, SLOT(prepareForDeviceChange()));
59     QObject::connect(m_cam, SIGNAL(deviceChanged()), this, SLOT(deviceChanged()));
60     QObject::connect(m_cam, SIGNAL(deviceChanged()), this, SIGNAL(isReadyChanged()));
61   }
62
63   emit cameraChanged();
64
65   deviceChanged();
66
67   emit isReadyChanged();
68 }
69
70 bool Mode::isActive() {
71   return m_mode ? m_mode->isActive() : false;
72 }
73
74 bool Mode::canCapture() {
75   return m_mode ? m_mode->canCapture() : false;
76 }
77
78 void Mode::deviceChanged() {
79   if (!m_cam || !m_cam->device()) {
80     return;
81   }
82
83   changeMode();
84
85   if (m_mode) {
86     QObject::connect(m_mode, SIGNAL(canCaptureChanged()), this, SIGNAL(canCaptureChanged()));
87     QObject::connect(m_mode, SIGNAL(saved(const QString&)), this, SIGNAL(saved(const QString&)));
88     QObject::connect(m_mode, SIGNAL(previewAvailable(const QImage&, const QString&)),
89                      this, SLOT(gotPreview(const QImage&, const QString&)));
90     QObject::connect(m_mode, SIGNAL(activeChanged()), this, SIGNAL(activeChanged()));
91     QObject::connect(m_mode, SIGNAL(activeChanged()), this, SIGNAL(canCaptureChanged()));
92     QObject::connect(m_cam->device(), SIGNAL(idleStateChanged(bool)),
93                      this, SIGNAL(canCaptureChanged()));
94     QObject::connect(m_cam->device(), SIGNAL(runningStateChanged(bool)),
95                      this, SIGNAL(canCaptureChanged()));
96
97     postChangeMode();
98   }
99
100   emit canCaptureChanged();
101   emit activeChanged();
102 }
103
104 void Mode::gotPreview(const QImage& image, const QString& fileName) {
105   PreviewProvider::instance()->setPreview(image);
106
107   // HACK: QML insists on caching the images.
108   QString url = QString("image://preview/%1").arg(m_seq);
109   ++m_seq;
110
111   emit previewAvailable(url, fileName);
112 }
113
114 bool Mode::isReady() const {
115   return m_mode;
116 }
117
118 void Mode::prepareForDeviceChange() {
119   if (m_mode) {
120     QObject::disconnect(m_mode, SIGNAL(canCaptureChanged()), this, SIGNAL(canCaptureChanged()));
121     QObject::disconnect(m_mode, SIGNAL(saved(const QString&)),
122                         this, SIGNAL(saved(const QString&)));
123     QObject::disconnect(m_mode, SIGNAL(previewAvailable(const QImage&, const QString&)),
124                         this, SLOT(gotPreview(const QImage&, const QString&)));
125     QObject::disconnect(m_mode, SIGNAL(activeChanged()), this, SIGNAL(activeChanged()));
126     QObject::disconnect(m_mode, SIGNAL(activeChanged()), this, SIGNAL(canCaptureChanged()));
127     QObject::disconnect(m_cam->device(), SIGNAL(idleStateChanged(bool)),
128                         this, SIGNAL(canCaptureChanged()));
129     QObject::disconnect(m_cam->device(), SIGNAL(runningStateChanged(bool)),
130                         this, SIGNAL(canCaptureChanged()));
131
132     preChangeMode();
133   }
134 }