1 /* |
|
2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 #include <QDebug> |
|
18 #include <QPixmap> |
|
19 #include <QTimer> |
|
20 #include <QFileInfo> |
|
21 #include <QApplication> |
|
22 #include <QGraphicsRectItem> |
|
23 #include <QBrush> |
|
24 #include <QDir> |
|
25 #include <QProcess> |
|
26 |
|
27 #include <hblabel.h> |
|
28 #include <hbmainwindow.h> |
|
29 #include <hbtoolbar.h> |
|
30 #include <hbaction.h> |
|
31 #include <hbmessagebox.h> |
|
32 #include <hbactivitymanager.h> |
|
33 |
|
34 #include <xqaiwdecl.h> |
|
35 #include <shareui.h> |
|
36 #include <thumbnailmanager_qt.h> |
|
37 |
|
38 #include "cxeviewfindercontrol.h" |
|
39 #include "cxuienums.h" |
|
40 #include "cxuipostcaptureview.h" |
|
41 #include "cxeengine.h" |
|
42 #include "cxecameradevicecontrol.h" |
|
43 #include "cxestillcapturecontrol.h" |
|
44 #include "cxevideocapturecontrol.h" |
|
45 #include "cxestillimage.h" |
|
46 #include "cxutils.h" |
|
47 #include "cxefeaturemanager.h" |
|
48 #include "cxuidocumentloader.h" |
|
49 #include "cxesettings.h" |
|
50 #include "cxenamespace.h" |
|
51 #include "cxuiserviceprovider.h" |
|
52 |
|
53 #ifdef Q_OS_SYMBIAN |
|
54 #include "OstTraceDefinitions.h" |
|
55 #ifdef OST_TRACE_COMPILER_IN_USE |
|
56 #include "cxuipostcaptureviewTraces.h" |
|
57 #endif |
|
58 #endif //Q_OS_SYMBIAN |
|
59 |
|
60 |
|
61 using namespace CxUiLayout; |
|
62 using namespace Cxe; |
|
63 |
|
64 |
|
65 namespace { |
|
66 const QString FILENAME_KEY = "filename"; |
|
67 const int CXUI_STOP_VIEWFINDER_TIMEOUT = 5000; // 5 seconds |
|
68 const int CXUI_RELEASE_CAMERA_TIMEOUT = 60000; // 60 seconds |
|
69 } |
|
70 |
|
71 |
|
72 /*! |
|
73 * Constructor. |
|
74 */ |
|
75 CxuiPostcaptureView::CxuiPostcaptureView(QGraphicsItem *parent) : |
|
76 CxuiView(parent), |
|
77 mStillToolbar(NULL), |
|
78 mVideoToolbar(NULL), |
|
79 mEmbeddedToolbar(NULL), |
|
80 mBackgroundItem(NULL), |
|
81 mImageLabel(NULL), |
|
82 mShareUi(NULL), |
|
83 mStopViewfinderTimer(this), |
|
84 mReleaseCameraTimer(this), |
|
85 mPostcaptureTimer(this), |
|
86 mTimersStarted(false), |
|
87 mDeleteNoteOpen(false), |
|
88 mFilename(QString::null), |
|
89 mThumbnailManager(NULL) |
|
90 { |
|
91 CX_DEBUG_IN_FUNCTION(); |
|
92 |
|
93 CX_DEBUG_EXIT_FUNCTION(); |
|
94 } |
|
95 |
|
96 /*! |
|
97 * Destructor. |
|
98 */ |
|
99 CxuiPostcaptureView::~CxuiPostcaptureView() |
|
100 { |
|
101 CX_DEBUG_ENTER_FUNCTION(); |
|
102 QCoreApplication::instance()->removeEventFilter(this); |
|
103 stopTimers(); |
|
104 delete mThumbnailManager; |
|
105 delete mShareUi; |
|
106 CX_DEBUG_EXIT_FUNCTION(); |
|
107 } |
|
108 |
|
109 /*! |
|
110 * Second phase construction. |
|
111 */ |
|
112 void CxuiPostcaptureView::construct(HbMainWindow *mainwindow, CxeEngine *engine, |
|
113 CxuiDocumentLoader *documentLoader, |
|
114 CxuiCaptureKeyHandler *keyHandler, |
|
115 HbActivityManager *activityManager) |
|
116 { |
|
117 Q_UNUSED(keyHandler); |
|
118 CX_DEBUG_ENTER_FUNCTION(); |
|
119 |
|
120 CxuiView::construct(mainwindow, engine, documentLoader, NULL, activityManager); |
|
121 |
|
122 // set back action to go back to pre-capture |
|
123 HbAction *backAction = new HbAction(Hb::BackNaviAction, this); |
|
124 connect(backAction, SIGNAL(triggered()), this, SLOT(goToPrecaptureView())); |
|
125 setNavigationAction(backAction); |
|
126 |
|
127 // creates black background item |
|
128 createBackground(); |
|
129 |
|
130 CX_DEBUG_ASSERT(mDocumentLoader); |
|
131 QGraphicsWidget *widget = 0; |
|
132 widget = mDocumentLoader->findWidget(POST_CAPTURE_SNAPSHOT_LABEL); |
|
133 mImageLabel = qobject_cast<HbLabel *>(widget); |
|
134 CX_DEBUG_ASSERT(mImageLabel); |
|
135 |
|
136 mShareUi = new ShareUi(); |
|
137 |
|
138 // get toolbar pointers from the documentloader |
|
139 widget = mDocumentLoader->findWidget(STILL_POST_CAPTURE_TOOLBAR); |
|
140 // This resize is a workaround to get toolbar shown correctly. |
|
141 widget->resize(60, 300); |
|
142 mStillToolbar = qobject_cast<HbToolBar *> (widget); |
|
143 CX_DEBUG_ASSERT(mStillToolbar); |
|
144 |
|
145 widget = mDocumentLoader->findWidget(VIDEO_POST_CAPTURE_TOOLBAR); |
|
146 // This resize is a workaround to get toolbar shown correctly. |
|
147 widget->resize(60, 300); |
|
148 mVideoToolbar = qobject_cast<HbToolBar *> (widget); |
|
149 CX_DEBUG_ASSERT(mVideoToolbar); |
|
150 |
|
151 widget = mDocumentLoader->findWidget(EMBEDDED_POST_CAPTURE_TOOLBAR); |
|
152 // This resize is a workaround to get toolbar shown correctly. |
|
153 widget->resize(60, 300); |
|
154 mEmbeddedToolbar = qobject_cast<HbToolBar *> (widget); |
|
155 CX_DEBUG_ASSERT(mEmbeddedToolbar); |
|
156 |
|
157 mStopViewfinderTimer.setSingleShot(true); |
|
158 connect(&mStopViewfinderTimer, SIGNAL(timeout()), |
|
159 this, SLOT(stopViewfinder())); |
|
160 |
|
161 mReleaseCameraTimer.setSingleShot(true); |
|
162 connect(&mReleaseCameraTimer, SIGNAL(timeout()), |
|
163 this, SLOT(releaseCamera())); |
|
164 |
|
165 mHideControlsTimeout.setSingleShot(true); |
|
166 connect(&mHideControlsTimeout, SIGNAL(timeout()), |
|
167 this, SLOT(hideControls())); |
|
168 |
|
169 mPostcaptureTimer.setSingleShot(true); |
|
170 connect(&mPostcaptureTimer, SIGNAL(timeout()), |
|
171 this, SLOT(goToPrecaptureView())); |
|
172 |
|
173 // set focus flags |
|
174 setFlag(QGraphicsItem::ItemIsFocusable); |
|
175 setFocusPolicy(Qt::StrongFocus); |
|
176 |
|
177 QCoreApplication::instance()->installEventFilter(this); |
|
178 CX_DEBUG_EXIT_FUNCTION(); |
|
179 } |
|
180 |
|
181 /*! |
|
182 * Handle pressing capture key. |
|
183 */ |
|
184 void CxuiPostcaptureView::handleCaptureKeyPressed() |
|
185 { |
|
186 CX_DEBUG_ENTER_FUNCTION(); |
|
187 |
|
188 if (!mDeleteNoteOpen) { |
|
189 goToPrecaptureView(); |
|
190 } |
|
191 |
|
192 CX_DEBUG_EXIT_FUNCTION(); |
|
193 } |
|
194 |
|
195 /*! |
|
196 * Handle pressing auto focus key. |
|
197 */ |
|
198 void CxuiPostcaptureView::handleAutofocusKeyPressed() |
|
199 { |
|
200 CX_DEBUG_ENTER_FUNCTION(); |
|
201 |
|
202 if (!mDeleteNoteOpen) { |
|
203 goToPrecaptureView(); |
|
204 } |
|
205 |
|
206 CX_DEBUG_EXIT_FUNCTION(); |
|
207 } |
|
208 |
|
209 /*! |
|
210 Slot for starting video playing. |
|
211 */ |
|
212 void CxuiPostcaptureView::playVideo() |
|
213 { |
|
214 CX_DEBUG_ENTER_FUNCTION(); |
|
215 |
|
216 stopTimers(); |
|
217 releaseCamera(); |
|
218 |
|
219 QString videoFile(getCurrentFilename()); |
|
220 |
|
221 XQAiwRequest *videoRequest = mAppManager.create(XQI_VIDEO_PLAY, XQOP_VIDEO_PLAY, true); |
|
222 |
|
223 if (videoRequest) { |
|
224 QVariantList fileList; |
|
225 fileList.append(QVariant(videoFile)); |
|
226 videoRequest->setArguments(fileList); |
|
227 |
|
228 CX_DEBUG(("CxuiPostcaptureView: sending request")); |
|
229 QVariant result; |
|
230 bool res = videoRequest->send(result); |
|
231 if (res) { |
|
232 CX_DEBUG(("CxuiPostcaptureView: request sent, received \"%s\"", |
|
233 qPrintable(result.toString()))); |
|
234 } else { |
|
235 CX_DEBUG(("CxuiPostcaptureView: request sending failed, error=%d", |
|
236 videoRequest->lastError())); |
|
237 } |
|
238 delete videoRequest; |
|
239 videoRequest = NULL; |
|
240 } |
|
241 |
|
242 CX_DEBUG_EXIT_FUNCTION(); |
|
243 |
|
244 } |
|
245 |
|
246 /*! |
|
247 * Show delete query. |
|
248 */ |
|
249 void CxuiPostcaptureView::showDeleteNote() |
|
250 { |
|
251 CX_DEBUG_ENTER_FUNCTION(); |
|
252 |
|
253 hideControls(); |
|
254 |
|
255 QString text(mEngine->mode() == Cxe::VideoMode |
|
256 ? hbTrId("txt_cam_other_delete_video_clip") |
|
257 : hbTrId("txt_cam_other_delete_image")); |
|
258 |
|
259 HbMessageBox::question(text, |
|
260 this, |
|
261 SLOT(handleDeleteDialogClosed(int)), |
|
262 HbMessageBox::Yes | HbMessageBox::No); |
|
263 |
|
264 mDeleteNoteOpen = true; |
|
265 CX_DEBUG_EXIT_FUNCTION(); |
|
266 } |
|
267 |
|
268 /*! |
|
269 * Handle closing delete query dialog. |
|
270 * @param action HbMessageBox::Yes if user accepted the delete query, HbMessageBox::No if not. |
|
271 */ |
|
272 void CxuiPostcaptureView::handleDeleteDialogClosed(int action) |
|
273 { |
|
274 CX_DEBUG_ENTER_FUNCTION(); |
|
275 |
|
276 hideControls(); |
|
277 mDeleteNoteOpen = false; |
|
278 |
|
279 // Check that user confirmed delete |
|
280 if (action == HbMessageBox::Yes) { |
|
281 QFileInfo fileInfo(getCurrentFilename()); |
|
282 if (fileInfo.exists()) { |
|
283 //! @todo |
|
284 // We can retry deletion if file deletion does'nt succeed, |
|
285 // but this is left out for the time being since the user |
|
286 // can't delete it so early that it's not saved yet or |
|
287 // is being harvested by MdS etc. |
|
288 QDir dir = fileInfo.absolutePath(); |
|
289 bool ok = dir.remove(fileInfo.fileName()); |
|
290 CX_DEBUG(("Delete file [%s], status %d", qPrintable(fileInfo.fileName()), ok)); |
|
291 |
|
292 // Go back to precapture view |
|
293 goToPrecaptureView(); |
|
294 } |
|
295 } |
|
296 |
|
297 CX_DEBUG_EXIT_FUNCTION(); |
|
298 } |
|
299 |
|
300 |
|
301 /*! |
|
302 Slot for handling image/video sharing. |
|
303 */ |
|
304 void CxuiPostcaptureView::launchShare() |
|
305 { |
|
306 CX_DEBUG_ENTER_FUNCTION(); |
|
307 |
|
308 stopTimers(); |
|
309 releaseCamera(); |
|
310 hideControls(); |
|
311 QString filename = getCurrentFilename(); |
|
312 QStringList filelist; |
|
313 filelist.append(filename); |
|
314 |
|
315 mShareUi->send(filelist, true); |
|
316 |
|
317 CX_DEBUG_EXIT_FUNCTION(); |
|
318 } |
|
319 |
|
320 /*! |
|
321 * Go to pre-capture view. |
|
322 */ |
|
323 void CxuiPostcaptureView::goToPrecaptureView() |
|
324 { |
|
325 CX_DEBUG_ENTER_FUNCTION(); |
|
326 |
|
327 // Cannot return to pre-capture while stopping in video mode |
|
328 if (mEngine->mode() != Cxe::VideoMode || |
|
329 mEngine->videoCaptureControl().state() != CxeVideoCaptureControl::Stopping) { |
|
330 stopTimers(); |
|
331 // Re-enabling starting timers the next time we enter post capture view. |
|
332 mTimersStarted = false; |
|
333 |
|
334 // reset saved filename |
|
335 mFilename = QString::null; |
|
336 |
|
337 // Switch to pre-capture view |
|
338 emit changeToPrecaptureView(); |
|
339 } |
|
340 |
|
341 CX_DEBUG_EXIT_FUNCTION(); |
|
342 } |
|
343 |
|
344 /*! |
|
345 * Stop viewfinder. |
|
346 */ |
|
347 void CxuiPostcaptureView::stopViewfinder() |
|
348 { |
|
349 CX_DEBUG_ENTER_FUNCTION(); |
|
350 |
|
351 if (mMainWindow->currentView() == this) { |
|
352 mEngine->viewfinderControl().stop(); |
|
353 } |
|
354 mStopViewfinderTimer.stop(); |
|
355 |
|
356 CX_DEBUG_EXIT_FUNCTION(); |
|
357 } |
|
358 |
|
359 /*! |
|
360 * Hides toolbar. |
|
361 */ |
|
362 void CxuiPostcaptureView::hideToolbar() |
|
363 { |
|
364 CX_DEBUG_ENTER_FUNCTION(); |
|
365 if (mStillToolbar) { |
|
366 mStillToolbar->hide(); |
|
367 } |
|
368 if (mVideoToolbar) { |
|
369 mVideoToolbar->hide(); |
|
370 } |
|
371 if (mEmbeddedToolbar) { |
|
372 mEmbeddedToolbar->hide(); |
|
373 } |
|
374 CX_DEBUG_EXIT_FUNCTION(); |
|
375 } |
|
376 |
|
377 /*! |
|
378 * Handle events. |
|
379 * Needed for restarting timers. |
|
380 */ |
|
381 bool CxuiPostcaptureView::eventFilter(QObject *object, QEvent *event) |
|
382 { |
|
383 Q_UNUSED(object) |
|
384 bool eventWasConsumed = false; |
|
385 |
|
386 switch (event->type()) |
|
387 { |
|
388 case QEvent::GraphicsSceneMouseRelease: |
|
389 mHideControlsTimeout.start(); |
|
390 break; |
|
391 case QEvent::GraphicsSceneMousePress: |
|
392 mHideControlsTimeout.stop(); |
|
393 // stop the postcapture timer |
|
394 mPostcaptureTimer.stop(); |
|
395 break; |
|
396 default: |
|
397 break; |
|
398 } |
|
399 |
|
400 return eventWasConsumed; |
|
401 } |
|
402 |
|
403 /*! |
|
404 * Paint method. |
|
405 * Used for performance tracing purposes. |
|
406 */ |
|
407 void CxuiPostcaptureView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
408 { |
|
409 // Performance trace for checking shot to snapshot time. |
|
410 // Guard that we actually have the snapshot set before outputting the trace. |
|
411 if (mImageLabel && !mImageLabel->icon().isNull()) { |
|
412 OstTrace0(camerax_performance, CXUIPOSTCAPTUREVIEW_SNAPSHOT_DRAW, "msg: e_CX_SHOT_TO_SNAPSHOT 0"); |
|
413 } |
|
414 |
|
415 QGraphicsWidget::paint(painter, option, widget); |
|
416 } |
|
417 |
|
418 /*! |
|
419 * Restore view state from activity. |
|
420 * @param activityId Activity id |
|
421 * @param data Activity data |
|
422 */ |
|
423 void CxuiPostcaptureView::restoreActivity(const QString &activityId, const QVariant &data) |
|
424 { |
|
425 Q_UNUSED(activityId); |
|
426 CX_DEBUG_ENTER_FUNCTION(); |
|
427 |
|
428 // get filename. if filename is not found (toString() returns empty string) |
|
429 // we will go back to pre-capture in updateSnapshotImage() |
|
430 mFilename = data.toMap()[FILENAME_KEY].toString(); |
|
431 CX_DEBUG(("Got filename [%s] from activity", qPrintable(mFilename))); |
|
432 |
|
433 CX_DEBUG_EXIT_FUNCTION(); |
|
434 } |
|
435 |
|
436 /*! |
|
437 * Save view state to activity. |
|
438 */ |
|
439 void CxuiPostcaptureView::saveActivity() |
|
440 { |
|
441 CX_DEBUG_ENTER_FUNCTION(); |
|
442 QVariantMap data; |
|
443 QVariantHash params; |
|
444 |
|
445 QString filename = getCurrentFilename(); |
|
446 CX_DEBUG(("Saving filename [%s]", qPrintable(filename))); |
|
447 data.insert(FILENAME_KEY, filename); |
|
448 |
|
449 QImage img(mMainWindow->rect().size(), QImage::Format_ARGB32_Premultiplied); |
|
450 QPainter p(&img); |
|
451 mMainWindow->render(&p, mMainWindow->rect(), mMainWindow->rect()); |
|
452 |
|
453 QPixmap screenshot = QPixmap::fromImage(img); |
|
454 |
|
455 params.insert("screenshot", screenshot); |
|
456 if (mEngine->mode() == Cxe::ImageMode) { |
|
457 mActivityManager->removeActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY); |
|
458 mActivityManager->addActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY, data, params); |
|
459 } else { |
|
460 mActivityManager->removeActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY); |
|
461 mActivityManager->addActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY, data, params); |
|
462 } |
|
463 CX_DEBUG_EXIT_FUNCTION(); |
|
464 } |
|
465 |
|
466 /*! |
|
467 * Clear activity from activity manager. |
|
468 */ |
|
469 void CxuiPostcaptureView::clearActivity() |
|
470 { |
|
471 CX_DEBUG_ENTER_FUNCTION(); |
|
472 mActivityManager->removeActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY); |
|
473 mActivityManager->removeActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY); |
|
474 CX_DEBUG_EXIT_FUNCTION(); |
|
475 } |
|
476 |
|
477 /*! |
|
478 * Show event for this view. |
|
479 * Update snapshot and start timers. |
|
480 */ |
|
481 void CxuiPostcaptureView::showEvent(QShowEvent *event) |
|
482 { |
|
483 CX_DEBUG_ENTER_FUNCTION(); |
|
484 |
|
485 QGraphicsWidget::showEvent(event); |
|
486 |
|
487 if (event->type() == QEvent::Show) { |
|
488 QCoreApplication::instance()->installEventFilter(this); |
|
489 |
|
490 // Update snapshot for current file. |
|
491 // If the current file does not exist anymore, return to pre-capture view. |
|
492 updateSnapshotImage(); |
|
493 |
|
494 // If the image / video has been deleted, control returned to pre-capture view. |
|
495 // No point to start timers or show controls then. |
|
496 if (mMainWindow->currentView() == this) { |
|
497 showControls(); |
|
498 startTimers(); |
|
499 } |
|
500 |
|
501 event->accept(); |
|
502 } |
|
503 |
|
504 CX_DEBUG_EXIT_FUNCTION(); |
|
505 } |
|
506 |
|
507 /*! |
|
508 * Hide event. |
|
509 * Release snapshot and stop timers. |
|
510 */ |
|
511 void CxuiPostcaptureView::hideEvent(QHideEvent *event) |
|
512 { |
|
513 CX_DEBUG_ENTER_FUNCTION(); |
|
514 |
|
515 QGraphicsWidget::hideEvent(event); |
|
516 |
|
517 if (event->type() == QEvent::Hide) { |
|
518 // remove event filter to disable unnecessary actions |
|
519 QCoreApplication::instance()->removeEventFilter(this); |
|
520 |
|
521 // Clear the snapshot. |
|
522 mImageLabel->setIcon(HbIcon()); |
|
523 |
|
524 stopTimers(); |
|
525 // Hide controls to make sure title bar reacts to show() |
|
526 // when this view is reactivated. |
|
527 hideControls(); |
|
528 event->accept(); |
|
529 } |
|
530 |
|
531 CX_DEBUG_EXIT_FUNCTION(); |
|
532 } |
|
533 |
|
534 /*! Shows toolbar. |
|
535 Toolbar that is shown is selected based on current mode. |
|
536 */ |
|
537 void CxuiPostcaptureView::showToolbar(){ |
|
538 |
|
539 CX_DEBUG_ENTER_FUNCTION(); |
|
540 |
|
541 if (CxuiServiceProvider::isCameraEmbedded()) { |
|
542 mEmbeddedToolbar->setVisible(true); |
|
543 mStillToolbar->setVisible(false); |
|
544 mVideoToolbar->setVisible(false); |
|
545 } else { |
|
546 mEmbeddedToolbar->setVisible(false); |
|
547 if (mEngine->mode() == ImageMode) { |
|
548 mVideoToolbar->setVisible(false); |
|
549 mStillToolbar->setVisible(true); |
|
550 mStillToolbar->show(); |
|
551 } else { |
|
552 mStillToolbar->setVisible(false); |
|
553 mVideoToolbar->setVisible(true); |
|
554 mVideoToolbar->show(); |
|
555 } |
|
556 } |
|
557 |
|
558 CX_DEBUG_EXIT_FUNCTION(); |
|
559 } |
|
560 |
|
561 /*! |
|
562 Creates black background item. If snapshot smaller than the screen size, |
|
563 background is visible. |
|
564 */ |
|
565 void CxuiPostcaptureView::createBackground() |
|
566 { |
|
567 CX_DEBUG_ENTER_FUNCTION(); |
|
568 |
|
569 if (!mBackgroundItem) { |
|
570 mBackgroundItem = new QGraphicsRectItem(this); |
|
571 QBrush blackBrush = QBrush(Qt::black); |
|
572 mBackgroundItem->setBrush(blackBrush); |
|
573 mBackgroundItem->setRect(mMainWindow->sceneRect()); |
|
574 } |
|
575 |
|
576 CX_DEBUG_EXIT_FUNCTION(); |
|
577 } |
|
578 |
|
579 /*! |
|
580 * Updates snapshot image. In normal case snapshot is retrieved from engine |
|
581 * but if we are restoring camera to post-capture through activity, then |
|
582 * we get snapshot from thumbnail manager. |
|
583 */ |
|
584 void CxuiPostcaptureView::updateSnapshotImage() |
|
585 { |
|
586 CX_DEBUG_ENTER_FUNCTION(); |
|
587 |
|
588 if (isFileDeleted()) { |
|
589 // File deleted, go to pre-capture view. |
|
590 CX_DEBUG(("File has been deleted, going back to pre-capture")); |
|
591 goToPrecaptureView(); |
|
592 |
|
593 } else if (!mFilename.isNull()) { |
|
594 // filename set, we are restoring activity |
|
595 if (!mThumbnailManager) { |
|
596 mThumbnailManager = new ThumbnailManager(); |
|
597 connect(mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void *, int, int)), |
|
598 this, SLOT(handleThumbnailReady(QPixmap))); |
|
599 mThumbnailManager->setThumbnailSize(ThumbnailManager::ThumbnailLarge); |
|
600 } |
|
601 mThumbnailManager->getThumbnail(mFilename); |
|
602 CX_DEBUG(("Thumbnail requested")); |
|
603 |
|
604 } else { |
|
605 // Normal use of post-capture view |
|
606 QPixmap snapshot; |
|
607 if (mEngine->mode() == ImageMode) { |
|
608 |
|
609 if (mEngine->stillCaptureControl().imageCount() > 0) { |
|
610 snapshot = mEngine->stillCaptureControl()[0].snapshot(); |
|
611 } |
|
612 } else { |
|
613 snapshot = mEngine->videoCaptureControl().snapshot(); |
|
614 } |
|
615 |
|
616 // Update the snapshot image |
|
617 handleThumbnailReady(snapshot); |
|
618 } |
|
619 |
|
620 CX_DEBUG_EXIT_FUNCTION(); |
|
621 } |
|
622 |
|
623 /*! |
|
624 * Check if the file we show this post-capture view for is deleted. |
|
625 * This can happen e.g. if we send camera to background and delete |
|
626 * the file in other application. When used as activity, we may also |
|
627 * get the name of already deleted file as activity parameter. |
|
628 * @return True if the current file is deleted, false if not. |
|
629 */ |
|
630 bool CxuiPostcaptureView::isFileDeleted() |
|
631 { |
|
632 CX_DEBUG_ENTER_FUNCTION(); |
|
633 |
|
634 bool deleted(false); |
|
635 |
|
636 // Check how we entered this view. |
|
637 if (mFilename.isNull()) { |
|
638 CX_DEBUG(("Checking engine filename")); |
|
639 // Normally entered post-capture view. |
|
640 if (mEngine->mode() == ImageMode) { |
|
641 // Check that the image have been saved already. |
|
642 // If not, it cannot have been deleted in that case. |
|
643 CxeStillImage &image(mEngine->stillCaptureControl()[0]); |
|
644 CX_DEBUG(("Image filename [%s]", qPrintable(image.filename()))); |
|
645 CX_DEBUG(("Image file saved: %d exists: %d", image.saved(), QFile::exists(image.filename()))); |
|
646 deleted = image.saved() && !QFile::exists(image.filename()); |
|
647 } else { |
|
648 // Check that video has been stopped fully. |
|
649 // If it's still stopping, QFile may not work. |
|
650 CX_DEBUG(("Video filename [%s]", qPrintable(mEngine->videoCaptureControl().filename()))); |
|
651 deleted = mEngine->videoCaptureControl().state() != CxeVideoCaptureControl::Stopping |
|
652 && !QFile::exists(mEngine->videoCaptureControl().filename()); |
|
653 } |
|
654 } else { |
|
655 // Started as activity, check the filename given when restoring activity. |
|
656 CX_DEBUG(("Checking filename saved in activity")); |
|
657 deleted = !QFile::exists(mFilename); |
|
658 } |
|
659 |
|
660 CX_DEBUG_EXIT_FUNCTION(); |
|
661 return deleted; |
|
662 } |
|
663 |
|
664 /* ! |
|
665 * gets the filename of the current file |
|
666 */ |
|
667 QString CxuiPostcaptureView::getCurrentFilename() |
|
668 { |
|
669 CX_DEBUG_ENTER_FUNCTION(); |
|
670 QString filename; |
|
671 |
|
672 if (!mFilename.isNull()) { |
|
673 // post-capture started by activity, engine doesn't contain correct |
|
674 // filename anymore so use the stored one |
|
675 CX_DEBUG(("Using filename saved in activity")); |
|
676 filename = mFilename; |
|
677 } else { |
|
678 CX_DEBUG(("Getting filename from engine")); |
|
679 if (mEngine->mode() == Cxe::VideoMode) { |
|
680 filename = mEngine->videoCaptureControl().filename(); |
|
681 } else { |
|
682 //!@todo Currently only gets index 0 from the still capture control. |
|
683 CxeStillCaptureControl& stillCaptureControl = mEngine->stillCaptureControl(); |
|
684 if (stillCaptureControl.imageCount() > 0) { |
|
685 filename = stillCaptureControl[0].filename(); |
|
686 } |
|
687 } |
|
688 } |
|
689 |
|
690 CX_DEBUG(("Got filename [%s]", qPrintable(filename))); |
|
691 CX_DEBUG_EXIT_FUNCTION(); |
|
692 |
|
693 return filename; |
|
694 } |
|
695 |
|
696 /*! |
|
697 Sends current capture to client app and closes camera |
|
698 */ |
|
699 void CxuiPostcaptureView::select() |
|
700 { |
|
701 CxuiServiceProvider *serviceProvider = CxuiServiceProvider::instance(); |
|
702 if (!serviceProvider) { |
|
703 return; |
|
704 } |
|
705 |
|
706 QString filename = getCurrentFilename(); |
|
707 serviceProvider->sendFilenameToClientAndExit(filename); |
|
708 } |
|
709 |
|
710 /*! |
|
711 * Handle exiting standby. |
|
712 */ |
|
713 void CxuiPostcaptureView::exitStandby() |
|
714 { |
|
715 CX_DEBUG_ENTER_FUNCTION(); |
|
716 |
|
717 // Common functionality first. |
|
718 CxuiView::exitStandby(); |
|
719 |
|
720 // Update snapshot and check the current file is not deleted. |
|
721 updateSnapshotImage(); |
|
722 |
|
723 if (mMainWindow->currentView() == this) { |
|
724 showControls(); |
|
725 } |
|
726 |
|
727 CX_DEBUG_EXIT_FUNCTION(); |
|
728 } |
|
729 |
|
730 /*! |
|
731 * Handle entering standby. |
|
732 */ |
|
733 void CxuiPostcaptureView::enterStandby() |
|
734 { |
|
735 CX_DEBUG_ENTER_FUNCTION(); |
|
736 |
|
737 // Common functionality (release camera). |
|
738 CxuiView::enterStandby(); |
|
739 |
|
740 stopTimers(); |
|
741 hideControls(); |
|
742 |
|
743 CX_DEBUG_EXIT_FUNCTION(); |
|
744 } |
|
745 |
|
746 /*! |
|
747 * Handle thumbnail received from ThumbnailManager. |
|
748 * |
|
749 * @param thumbnail Thumbnail as QPixmap |
|
750 */ |
|
751 void CxuiPostcaptureView::handleThumbnailReady(QPixmap thumbnail) |
|
752 { |
|
753 CX_DEBUG_ENTER_FUNCTION(); |
|
754 |
|
755 if (thumbnail.isNull()) { |
|
756 CX_DEBUG(("[WARNING] Received null thumbnail from TNM, going to pre-capture.")); |
|
757 // null thumbnail, go to precapture |
|
758 goToPrecaptureView(); |
|
759 } else if (mImageLabel) { |
|
760 mImageLabel->setIcon(HbIcon(QIcon(thumbnail))); |
|
761 } |
|
762 |
|
763 CX_DEBUG_EXIT_FUNCTION(); |
|
764 } |
|
765 |
|
766 /*! |
|
767 Start the timers |
|
768 */ |
|
769 void CxuiPostcaptureView::startTimers() |
|
770 { |
|
771 CX_DEBUG_ENTER_FUNCTION(); |
|
772 |
|
773 // we start timers only once in a given postcapture view session |
|
774 if(!mTimersStarted) { |
|
775 startPostcaptureTimer(); |
|
776 startReleaseTimers(); |
|
777 mTimersStarted = true; |
|
778 } |
|
779 |
|
780 CX_DEBUG_EXIT_FUNCTION(); |
|
781 } |
|
782 |
|
783 /*! |
|
784 Start the timer to return to pre-capture view |
|
785 */ |
|
786 void CxuiPostcaptureView::startPostcaptureTimer() |
|
787 { |
|
788 CX_DEBUG_ENTER_FUNCTION(); |
|
789 |
|
790 if (!mFilename.isNull()) { |
|
791 // restored from activity, don't do post-capture timeout |
|
792 CX_DEBUG_EXIT_FUNCTION(); |
|
793 return; |
|
794 } |
|
795 |
|
796 int postCaptureTimeout = 0; |
|
797 QString settingId; |
|
798 |
|
799 if (mEngine->mode() == ImageMode) { |
|
800 settingId = CxeSettingIds::STILL_SHOWCAPTURED; |
|
801 } else { |
|
802 settingId = CxeSettingIds::VIDEO_SHOWCAPTURED; |
|
803 } |
|
804 |
|
805 if (!CxuiServiceProvider::isCameraEmbedded()) { |
|
806 postCaptureTimeout = mEngine->settings().get<int>(settingId, 0); |
|
807 |
|
808 if (postCaptureTimeout > 0) { |
|
809 mPostcaptureTimer.start(postCaptureTimeout); |
|
810 } else { |
|
811 // do nothing |
|
812 } |
|
813 } |
|
814 |
|
815 CX_DEBUG_EXIT_FUNCTION(); |
|
816 } |
|
817 |
|
818 /*! |
|
819 Start the timers to stop viewfinder and release the camera |
|
820 */ |
|
821 void CxuiPostcaptureView::startReleaseTimers() |
|
822 { |
|
823 CX_DEBUG_ENTER_FUNCTION(); |
|
824 |
|
825 // Release camera and stop viewfinder if user stays in postcapture long enough. |
|
826 // Battery could otherwise drain fast. |
|
827 mReleaseCameraTimer.start(CXUI_RELEASE_CAMERA_TIMEOUT); |
|
828 mStopViewfinderTimer.start(CXUI_STOP_VIEWFINDER_TIMEOUT); |
|
829 |
|
830 CX_DEBUG_EXIT_FUNCTION(); |
|
831 } |
|
832 |
|
833 void CxuiPostcaptureView::stopTimers() |
|
834 { |
|
835 CX_DEBUG_ENTER_FUNCTION(); |
|
836 |
|
837 // stop all the timers |
|
838 mHideControlsTimeout.stop(); |
|
839 mReleaseCameraTimer.stop(); |
|
840 mPostcaptureTimer.stop(); |
|
841 mStopViewfinderTimer.stop(); |
|
842 |
|
843 //!@note mTimersStarted is intentionally not reset here. |
|
844 // Once the timers are stopped, they are not to be started again until |
|
845 // we come from precapture view again. |
|
846 // E.g. returning from background could otherwise restart the timers and |
|
847 // if post-capture timer would be on, user could be confused: camera |
|
848 // shows up with post-capture view, after couple seconds it disappears |
|
849 // and we return to pre-capture view. That's not what we want. |
|
850 |
|
851 CX_DEBUG_EXIT_FUNCTION(); |
|
852 } |
|
853 |
|
854 // end of file |
|