28 #include <hbmainwindow.h> |
28 #include <hbmainwindow.h> |
29 #include <hbtoolbar.h> |
29 #include <hbtoolbar.h> |
30 #include <hbaction.h> |
30 #include <hbaction.h> |
31 #include <hbmessagebox.h> |
31 #include <hbmessagebox.h> |
32 #include <hbnotificationdialog.h> |
32 #include <hbnotificationdialog.h> |
|
33 #include <hbactivitymanager.h> |
33 |
34 |
34 #include <shareui.h> |
35 #include <shareui.h> |
|
36 #include <thumbnailmanager_qt.h> |
35 |
37 |
36 #include "cxeviewfindercontrol.h" |
38 #include "cxeviewfindercontrol.h" |
37 #include "cxuienums.h" |
39 #include "cxuienums.h" |
38 #include "cxuipostcaptureview.h" |
40 #include "cxuipostcaptureview.h" |
39 #include "cxeengine.h" |
41 #include "cxeengine.h" |
40 #include "cxecameradevicecontrol.h" |
42 #include "cxecameradevicecontrol.h" |
41 #include "cxestillcapturecontrol.h" |
43 #include "cxestillcapturecontrol.h" |
42 #include "cxeviewfindercontrol.h" |
|
43 #include "cxevideocapturecontrol.h" |
44 #include "cxevideocapturecontrol.h" |
44 #include "cxestillimage.h" |
45 #include "cxestillimage.h" |
45 #include "cxutils.h" |
46 #include "cxutils.h" |
46 #include "cxefeaturemanager.h" |
47 #include "cxefeaturemanager.h" |
47 #include "cxuidocumentloader.h" |
48 #include "cxuidocumentloader.h" |
57 |
58 |
58 using namespace CxUiLayout; |
59 using namespace CxUiLayout; |
59 using namespace Cxe; |
60 using namespace Cxe; |
60 |
61 |
61 |
62 |
62 //!@todo Temporarily disabled. |
63 namespace { |
63 //const int CXUI_STOP_VIEWFINDER_TIMEOUT = 5000; // 5 seconds |
64 const QString FILENAME_KEY = "filename"; |
64 //const int CXUI_RELEASE_CAMERA_TIMEOUT = 10000; // 10 seconds |
65 const int CXUI_STOP_VIEWFINDER_TIMEOUT = 5000; // 5 seconds |
|
66 const int CXUI_RELEASE_CAMERA_TIMEOUT = 60000; // 60 seconds |
|
67 }; |
|
68 |
65 |
69 |
66 // --------------------------------------------------------------------------- |
70 // --------------------------------------------------------------------------- |
67 // CxuiPostcaptureView::CxuiPostcaptureView |
71 // CxuiPostcaptureView::CxuiPostcaptureView |
68 // |
72 // |
69 // --------------------------------------------------------------------------- |
73 // --------------------------------------------------------------------------- |
78 mShareUi(NULL), |
82 mShareUi(NULL), |
79 mStopViewfinderTimer(this), |
83 mStopViewfinderTimer(this), |
80 mReleaseCameraTimer(this), |
84 mReleaseCameraTimer(this), |
81 mPostcaptureTimer(this), |
85 mPostcaptureTimer(this), |
82 mTimersStarted(false), |
86 mTimersStarted(false), |
83 mDeleteNoteOpen(false) |
87 mDeleteNoteOpen(false), |
|
88 mFilename(QString::null), |
|
89 mThumbnailManager(NULL) |
84 { |
90 { |
85 CX_DEBUG_IN_FUNCTION(); |
91 CX_DEBUG_IN_FUNCTION(); |
86 |
92 |
87 CX_DEBUG_EXIT_FUNCTION(); |
93 CX_DEBUG_EXIT_FUNCTION(); |
88 } |
94 } |
95 CxuiPostcaptureView::~CxuiPostcaptureView() |
101 CxuiPostcaptureView::~CxuiPostcaptureView() |
96 { |
102 { |
97 CX_DEBUG_ENTER_FUNCTION(); |
103 CX_DEBUG_ENTER_FUNCTION(); |
98 QCoreApplication::instance()->removeEventFilter(this); |
104 QCoreApplication::instance()->removeEventFilter(this); |
99 stopTimers(); |
105 stopTimers(); |
|
106 delete mThumbnailManager; |
100 delete mShareUi; |
107 delete mShareUi; |
101 CX_DEBUG_EXIT_FUNCTION(); |
108 CX_DEBUG_EXIT_FUNCTION(); |
102 } |
109 } |
103 |
110 |
104 // --------------------------------------------------------------------------- |
111 // --------------------------------------------------------------------------- |
105 // CxuiPostcaptureView::construct |
112 // CxuiPostcaptureView::construct |
106 // |
113 // |
107 // --------------------------------------------------------------------------- |
114 // --------------------------------------------------------------------------- |
108 // |
115 // |
109 void CxuiPostcaptureView::construct(HbMainWindow *mainwindow, CxeEngine *engine, |
116 void CxuiPostcaptureView::construct(HbMainWindow *mainwindow, CxeEngine *engine, |
110 CxuiDocumentLoader *documentLoader) |
117 CxuiDocumentLoader *documentLoader, |
111 { |
118 CxuiCaptureKeyHandler *keyHandler, |
112 CX_DEBUG_ENTER_FUNCTION(); |
119 HbActivityManager *activityManager) |
113 |
120 { |
114 CxuiView::construct(mainwindow, engine, documentLoader, NULL); |
121 CX_DEBUG_ENTER_FUNCTION(); |
|
122 |
|
123 CxuiView::construct(mainwindow, engine, documentLoader, NULL, activityManager); |
115 |
124 |
116 // set back action to go back to pre-capture |
125 // set back action to go back to pre-capture |
117 HbAction *backAction = new HbAction(Hb::BackNaviAction, this); |
126 HbAction *backAction = new HbAction(Hb::BackNaviAction, this); |
118 connect(backAction, SIGNAL(triggered()), this, SLOT(goToPrecaptureView())); |
127 connect(backAction, SIGNAL(triggered()), this, SLOT(goToPrecaptureView())); |
119 setNavigationAction(backAction); |
128 setNavigationAction(backAction); |
207 /*! |
216 /*! |
208 Slot for starting video playing. |
217 Slot for starting video playing. |
209 */ |
218 */ |
210 void CxuiPostcaptureView::playVideo() |
219 void CxuiPostcaptureView::playVideo() |
211 { |
220 { |
212 |
221 CX_DEBUG_ENTER_FUNCTION(); |
213 launchNotSupportedNotification(); |
222 |
214 //! @todo needs an implementation |
223 stopTimers(); |
215 CX_DEBUG_IN_FUNCTION(); |
224 releaseCamera(); |
|
225 |
|
226 QString videoFile(getCurrentFilename()); |
|
227 |
|
228 XQAiwRequest *videoRequest = mAppManager.create( |
|
229 "com.nokia.symbian.IVideoView","playMedia(QString)", true); |
|
230 |
|
231 if (videoRequest) { |
|
232 QVariantList fileList; |
|
233 fileList.append(QVariant(videoFile)); |
|
234 videoRequest->setArguments(fileList); |
|
235 |
|
236 CX_DEBUG(("CxuiPostcaptureView: sending request")); |
|
237 QVariant result; |
|
238 bool res = videoRequest->send(result); |
|
239 if (res) { |
|
240 CX_DEBUG(("CxuiPostcaptureView: request sent, received \"%s\"", |
|
241 result.toString().toAscii().constData())); |
|
242 } else { |
|
243 CX_DEBUG(("CxuiPostcaptureView: request sending failed, error=%d", |
|
244 videoRequest->lastError())); |
|
245 } |
|
246 delete videoRequest; |
|
247 videoRequest = NULL; |
|
248 } |
|
249 |
|
250 CX_DEBUG_EXIT_FUNCTION(); |
216 |
251 |
217 } |
252 } |
218 |
253 |
219 // --------------------------------------------------------------------------- |
254 // --------------------------------------------------------------------------- |
220 // CxuiPostcaptureView::showDeleteNote |
255 // CxuiPostcaptureView::showDeleteNote |
312 mEngine->videoCaptureControl().state() != CxeVideoCaptureControl::Stopping) { |
347 mEngine->videoCaptureControl().state() != CxeVideoCaptureControl::Stopping) { |
313 stopTimers(); |
348 stopTimers(); |
314 // Re-enabling starting timers the next time we enter post capture view. |
349 // Re-enabling starting timers the next time we enter post capture view. |
315 mTimersStarted = false; |
350 mTimersStarted = false; |
316 |
351 |
317 // Make sure engine prepares for new image/video if necessary |
352 // reset saved filename |
318 mEngine->initMode(mEngine->mode()); |
353 mFilename = QString::null; |
319 |
354 |
320 // Switch to pre-capture view |
355 // Switch to pre-capture view |
321 emit changeToPrecaptureView(); |
356 emit changeToPrecaptureView(); |
322 } |
357 } |
323 |
358 |
390 * Paint method. |
425 * Paint method. |
391 * Used for performance tracing purposes. |
426 * Used for performance tracing purposes. |
392 */ |
427 */ |
393 void CxuiPostcaptureView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
428 void CxuiPostcaptureView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
394 { |
429 { |
395 OstTrace0(camerax_performance, CXUIPOSTCAPTUREVIEW_SNAPSHOT_DRAW, "msg: e_CX_SHOT_TO_SNAPSHOT 0"); |
430 OstTrace0(camerax_performance, CXUIPOSTCAPTUREVIEW_SNAPSHOT_DRAW, "msg: e_CX_SHOT_TO_SNAPSHOT 0"); |
396 QGraphicsWidget::paint(painter, option, widget); |
431 QGraphicsWidget::paint(painter, option, widget); |
|
432 } |
|
433 |
|
434 /*! |
|
435 * Restore view state from activity. |
|
436 * @param activityId Activity id |
|
437 * @param data Activity data |
|
438 */ |
|
439 void CxuiPostcaptureView::restoreActivity(const QString &activityId, const QVariant &data) |
|
440 { |
|
441 CX_DEBUG_ENTER_FUNCTION(); |
|
442 |
|
443 // get filename. if filename is not found (toString() returns empty string) |
|
444 // we will go back to pre-capture in updateSnapshotImage() |
|
445 mFilename = data.toMap()[FILENAME_KEY].toString(); |
|
446 CX_DEBUG(("Got filename %s from activity", mFilename.toAscii().data())); |
|
447 |
|
448 CX_DEBUG_EXIT_FUNCTION(); |
|
449 } |
|
450 |
|
451 /*! |
|
452 * Save view state to activity. |
|
453 */ |
|
454 void CxuiPostcaptureView::saveActivity() |
|
455 { |
|
456 CX_DEBUG_ENTER_FUNCTION(); |
|
457 QVariantMap data; |
|
458 QVariantHash params; |
|
459 |
|
460 QString filename = getCurrentFilename(); |
|
461 CX_DEBUG(("Saving filename %s", filename.toAscii().data())); |
|
462 data.insert(FILENAME_KEY, filename); |
|
463 |
|
464 QImage img(mMainWindow->rect().size(), QImage::Format_ARGB32_Premultiplied); |
|
465 QPainter p(&img); |
|
466 mMainWindow->render(&p, mMainWindow->rect(), mMainWindow->rect()); |
|
467 |
|
468 QPixmap screenshot = QPixmap::fromImage(img); |
|
469 |
|
470 params.insert("screenshot", screenshot); |
|
471 if (mEngine->mode() == Cxe::ImageMode) { |
|
472 mActivityManager->removeActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY); |
|
473 mActivityManager->addActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY, data, params); |
|
474 } else { |
|
475 mActivityManager->removeActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY); |
|
476 mActivityManager->addActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY, data, params); |
|
477 } |
|
478 CX_DEBUG_EXIT_FUNCTION(); |
|
479 } |
|
480 |
|
481 /*! |
|
482 * Clear activity from activity manager. |
|
483 */ |
|
484 void CxuiPostcaptureView::clearActivity() |
|
485 { |
|
486 CX_DEBUG_ENTER_FUNCTION(); |
|
487 mActivityManager->removeActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY); |
|
488 mActivityManager->removeActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY); |
|
489 CX_DEBUG_EXIT_FUNCTION(); |
397 } |
490 } |
398 |
491 |
399 // --------------------------------------------------------------------------- |
492 // --------------------------------------------------------------------------- |
400 // CxuiPostcaptureView::showEvent |
493 // CxuiPostcaptureView::showEvent |
401 // |
494 // |
490 } |
583 } |
491 |
584 |
492 CX_DEBUG_EXIT_FUNCTION(); |
585 CX_DEBUG_EXIT_FUNCTION(); |
493 } |
586 } |
494 |
587 |
495 // --------------------------------------------------------------------------- |
588 /*! |
496 // CxuiPostcaptureView::setImage |
589 * Updates snapshot image. In normal case snapshot is retrieved from engine |
497 // |
590 * but if we are restoring camera to post-capture through activity, then |
498 // --------------------------------------------------------------------------- |
591 * we get snapshot from thumbnail manager. |
499 // |
592 */ |
500 void CxuiPostcaptureView::updateSnapshotImage() |
593 void CxuiPostcaptureView::updateSnapshotImage() |
501 { |
594 { |
502 CX_DEBUG_ENTER_FUNCTION(); |
595 CX_DEBUG_ENTER_FUNCTION(); |
503 |
596 |
504 QPixmap snapshot; |
597 if (!mFilename.isNull()) { |
505 |
598 CX_DEBUG(("CxuiPostcaptureView::updateSnapshot restoring activity")); |
506 if (mEngine->mode() == ImageMode) { |
599 // filename set, we are restoring activity |
507 if( mEngine->stillCaptureControl().imageCount() > 0 ) { |
600 if (QFile::exists(mFilename)) { |
508 snapshot = mEngine->stillCaptureControl()[0].snapshot(); |
601 CX_DEBUG(("Filename ok, requesting thumbnail from TNM")); |
|
602 if (!mThumbnailManager) { |
|
603 mThumbnailManager = new ThumbnailManager(); |
|
604 connect(mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void *, int, int)), |
|
605 this, SLOT(handleThumbnailReady(QPixmap, void*, int, int))); |
|
606 mThumbnailManager->setThumbnailSize(ThumbnailManager::ThumbnailLarge); |
|
607 } |
|
608 mThumbnailManager->getThumbnail(mFilename); |
|
609 CX_DEBUG(("Thumbnail requested")); |
|
610 |
|
611 } else { |
|
612 // file deleted |
|
613 CX_DEBUG(("File %s has been deleted, going back to pre-capture", mFilename.toAscii().data())); |
|
614 goToPrecaptureView(); |
509 } |
615 } |
510 } else { |
616 } else { |
511 snapshot = mEngine->videoCaptureControl().snapshot(); |
617 QPixmap snapshot; |
512 } |
618 if (mEngine->mode() == ImageMode) { |
513 |
619 if( mEngine->stillCaptureControl().imageCount() > 0 ) { |
514 if (mImageLabel) { |
620 snapshot = mEngine->stillCaptureControl()[0].snapshot(); |
515 mImageLabel->setIcon(HbIcon(QIcon(snapshot))); |
621 } |
516 } else { |
622 } else { |
517 // do nothing |
623 snapshot = mEngine->videoCaptureControl().snapshot(); |
|
624 } |
|
625 if (mImageLabel) { |
|
626 mImageLabel->setIcon(HbIcon(QIcon(snapshot))); |
|
627 } else { |
|
628 // do nothing |
|
629 } |
518 } |
630 } |
519 |
631 |
520 CX_DEBUG_EXIT_FUNCTION(); |
632 CX_DEBUG_EXIT_FUNCTION(); |
521 } |
633 } |
522 |
634 |
525 */ |
637 */ |
526 QString CxuiPostcaptureView::getCurrentFilename() |
638 QString CxuiPostcaptureView::getCurrentFilename() |
527 { |
639 { |
528 CX_DEBUG_ENTER_FUNCTION(); |
640 CX_DEBUG_ENTER_FUNCTION(); |
529 |
641 |
|
642 if (!mFilename.isNull()) { |
|
643 // post-capture started by activity, engine doesn't contain correct |
|
644 // filename anymore so use the stored one |
|
645 CX_DEBUG(("Using filename saved in activity")); |
|
646 CX_DEBUG_EXIT_FUNCTION(); |
|
647 return mFilename; |
|
648 } |
|
649 |
|
650 CX_DEBUG(("Getting filename from engine")); |
530 QString filename; |
651 QString filename; |
531 |
652 |
532 if (mEngine->mode() == Cxe::VideoMode) { |
653 if (mEngine->mode() == Cxe::VideoMode) { |
533 filename = mEngine->videoCaptureControl().filename(); |
654 filename = mEngine->videoCaptureControl().filename(); |
534 } else { |
655 } else { |
558 QString filename = getCurrentFilename(); |
679 QString filename = getCurrentFilename(); |
559 serviceProvider->sendFilenameToClientAndExit(filename); |
680 serviceProvider->sendFilenameToClientAndExit(filename); |
560 } |
681 } |
561 |
682 |
562 /*! |
683 /*! |
563 Handle cases when we gain focus |
684 * Handle exiting standby. |
564 */ |
685 */ |
565 void CxuiPostcaptureView::handleFocusGained() |
686 void CxuiPostcaptureView::exitStandby() |
566 { |
687 { |
567 CX_DEBUG_ENTER_FUNCTION(); |
688 CX_DEBUG_ENTER_FUNCTION(); |
568 |
689 |
569 //Note: We should not start timers until we receive the ShowEvent |
690 // Common functionality first. |
|
691 CxuiView::exitStandby(); |
|
692 |
|
693 //!@note We should not start timers until we receive the ShowEvent |
570 showControls(); |
694 showControls(); |
571 |
695 |
572 CX_DEBUG_EXIT_FUNCTION(); |
696 CX_DEBUG_EXIT_FUNCTION(); |
573 } |
697 } |
574 |
698 |
575 /*! |
699 /*! |
576 Handle cases when we loose focus |
700 * Handle entering standby. |
577 */ |
701 */ |
578 void CxuiPostcaptureView::handleFocusLost() |
702 void CxuiPostcaptureView::enterStandby() |
579 { |
703 { |
580 CX_DEBUG_ENTER_FUNCTION(); |
704 CX_DEBUG_ENTER_FUNCTION(); |
581 |
705 |
582 // we have lost focus |
706 // Common functionality (release camera). |
583 releaseCamera(); |
707 CxuiView::enterStandby(); |
|
708 |
584 stopTimers(); |
709 stopTimers(); |
585 hideControls(); |
710 hideControls(); |
|
711 |
|
712 CX_DEBUG_EXIT_FUNCTION(); |
|
713 } |
|
714 |
|
715 /*! |
|
716 * Handle thumbnail received from ThumbnailManager. |
|
717 * |
|
718 * @param thumbnail Thumbnail as QPixmap |
|
719 * @param clientData Not used |
|
720 * @param id Thumbnail manager request id |
|
721 * @param errorCode Error code |
|
722 */ |
|
723 void CxuiPostcaptureView::handleThumbnailReady(QPixmap thumbnail, void *clientData, int id, int errorCode) |
|
724 { |
|
725 CX_DEBUG_ENTER_FUNCTION(); |
|
726 |
|
727 Q_UNUSED(clientData); |
|
728 Q_UNUSED(id); |
|
729 |
|
730 if (thumbnail.isNull()) { |
|
731 CX_DEBUG(("Received null thumbnail from TNM, going to pre-capture. Error=%d", errorCode)); |
|
732 // null thumbnail, go to precapture |
|
733 goToPrecaptureView(); |
|
734 } else if (mImageLabel) { |
|
735 mImageLabel->setIcon(HbIcon(QIcon(thumbnail))); |
|
736 } |
586 |
737 |
587 CX_DEBUG_EXIT_FUNCTION(); |
738 CX_DEBUG_EXIT_FUNCTION(); |
588 } |
739 } |
589 |
740 |
590 /*! |
741 /*! |
609 */ |
760 */ |
610 void CxuiPostcaptureView::startPostcaptureTimer() |
761 void CxuiPostcaptureView::startPostcaptureTimer() |
611 { |
762 { |
612 CX_DEBUG_ENTER_FUNCTION(); |
763 CX_DEBUG_ENTER_FUNCTION(); |
613 |
764 |
|
765 if (!mFilename.isNull()) { |
|
766 // restored from activity, don't do post-capture timeout |
|
767 CX_DEBUG_EXIT_FUNCTION(); |
|
768 return; |
|
769 } |
|
770 |
614 int postCaptureTimeout = 0; |
771 int postCaptureTimeout = 0; |
615 QString settingId; |
772 QString settingId; |
616 |
773 |
617 if (mEngine->mode() == ImageMode) { |
774 if (mEngine->mode() == ImageMode) { |
618 settingId = CxeSettingIds::STILL_SHOWCAPTURED; |
775 settingId = CxeSettingIds::STILL_SHOWCAPTURED; |
638 */ |
795 */ |
639 void CxuiPostcaptureView::startReleaseTimers() |
796 void CxuiPostcaptureView::startReleaseTimers() |
640 { |
797 { |
641 CX_DEBUG_ENTER_FUNCTION(); |
798 CX_DEBUG_ENTER_FUNCTION(); |
642 |
799 |
643 // Todo Note: Temporarily disabling release timer because of |
800 // Release camera and stop viewfinder if user stays in postcapture long enough. |
644 // graphics memory problems related to releasing and reserving again. |
801 // Battery could otherwise drain fast. |
645 // mReleaseCameraTimer.start(CXUI_RELEASE_CAMERA_TIMEOUT); |
802 mReleaseCameraTimer.start(CXUI_RELEASE_CAMERA_TIMEOUT); |
646 // mStopViewfinderTimer.start(CXUI_STOP_VIEWFINDER_TIMEOUT); |
803 mStopViewfinderTimer.start(CXUI_STOP_VIEWFINDER_TIMEOUT); |
647 |
804 |
648 CX_DEBUG_EXIT_FUNCTION(); |
805 CX_DEBUG_EXIT_FUNCTION(); |
649 } |
806 } |
650 |
807 |
651 void CxuiPostcaptureView::stopTimers() |
808 void CxuiPostcaptureView::stopTimers() |
656 mHideControlsTimeout.stop(); |
813 mHideControlsTimeout.stop(); |
657 mReleaseCameraTimer.stop(); |
814 mReleaseCameraTimer.stop(); |
658 mPostcaptureTimer.stop(); |
815 mPostcaptureTimer.stop(); |
659 mStopViewfinderTimer.stop(); |
816 mStopViewfinderTimer.stop(); |
660 |
817 |
661 // Note: mTimersStarted is intentionally not reset here. |
818 //!@note mTimersStarted is intentionally not reset here. |
662 // Once the timers are stopped, they are not to be started again until |
819 // Once the timers are stopped, they are not to be started again until |
663 // we come from precapture view again. |
820 // we come from precapture view again. |
664 // E.g. returning from background could otherwise restart the timers and |
821 // E.g. returning from background could otherwise restart the timers and |
665 // if post-capture timer would be on, user could be confused: camera |
822 // if post-capture timer would be on, user could be confused: camera |
666 // shows up with post-capture view, after couple seconds it disappears |
823 // shows up with post-capture view, after couple seconds it disappears |