camerauis/cameraxui/cxui/src/cxuipostcaptureview.cpp
changeset 48 42ba2d16bf40
parent 37 64817133cd1d
child 63 415ff50d2eca
--- a/camerauis/cameraxui/cxui/src/cxuipostcaptureview.cpp	Tue Jul 06 14:04:02 2010 +0300
+++ b/camerauis/cameraxui/cxui/src/cxuipostcaptureview.cpp	Wed Aug 18 09:37:18 2010 +0300
@@ -29,9 +29,9 @@
 #include <hbtoolbar.h>
 #include <hbaction.h>
 #include <hbmessagebox.h>
-#include <hbnotificationdialog.h>
 #include <hbactivitymanager.h>
 
+#include <xqaiwdecl.h>
 #include <shareui.h>
 #include <thumbnailmanager_qt.h>
 
@@ -50,10 +50,12 @@
 #include "cxenamespace.h"
 #include "cxuiserviceprovider.h"
 
+#ifdef Q_OS_SYMBIAN
 #include "OstTraceDefinitions.h"
 #ifdef OST_TRACE_COMPILER_IN_USE
 #include "cxuipostcaptureviewTraces.h"
 #endif
+#endif //Q_OS_SYMBIAN
 
 
 using namespace CxUiLayout;
@@ -64,14 +66,12 @@
     const QString FILENAME_KEY = "filename";
     const int CXUI_STOP_VIEWFINDER_TIMEOUT = 5000; //  5 seconds
     const int CXUI_RELEASE_CAMERA_TIMEOUT = 60000; // 60 seconds
-};
+}
 
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::CxuiPostcaptureView
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Constructor.
+*/
 CxuiPostcaptureView::CxuiPostcaptureView(QGraphicsItem *parent) :
     CxuiView(parent),
     mStillToolbar(NULL),
@@ -93,11 +93,9 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::~CxuiPostcaptureView
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Destructor.
+*/
 CxuiPostcaptureView::~CxuiPostcaptureView()
 {
     CX_DEBUG_ENTER_FUNCTION();
@@ -108,16 +106,15 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::construct
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Second phase construction.
+*/
 void CxuiPostcaptureView::construct(HbMainWindow *mainwindow, CxeEngine *engine,
                                     CxuiDocumentLoader *documentLoader,
                                     CxuiCaptureKeyHandler *keyHandler,
                                     HbActivityManager *activityManager)
 {
+    Q_UNUSED(keyHandler);
     CX_DEBUG_ENTER_FUNCTION();
 
     CxuiView::construct(mainwindow, engine, documentLoader, NULL, activityManager);
@@ -181,11 +178,9 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::handleCaptureKeyPressed
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Handle pressing capture key.
+*/
 void CxuiPostcaptureView::handleCaptureKeyPressed()
 {
     CX_DEBUG_ENTER_FUNCTION();
@@ -197,11 +192,9 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::handleAutofocusKeyPressed
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Handle pressing auto focus key.
+*/
 void CxuiPostcaptureView::handleAutofocusKeyPressed()
 {
     CX_DEBUG_ENTER_FUNCTION();
@@ -225,8 +218,7 @@
 
     QString videoFile(getCurrentFilename());
 
-    XQAiwRequest *videoRequest = mAppManager.create(
-        "com.nokia.symbian.IVideoView","playMedia(QString)", true);
+    XQAiwRequest *videoRequest = mAppManager.create(XQI_VIDEO_PLAY, XQOP_VIDEO_PLAY, true);
 
     if (videoRequest) {
         QVariantList fileList;
@@ -238,7 +230,7 @@
         bool res = videoRequest->send(result);
         if (res) {
             CX_DEBUG(("CxuiPostcaptureView: request sent, received \"%s\"",
-                      result.toString().toAscii().constData()));
+                      qPrintable(result.toString())));
         } else {
             CX_DEBUG(("CxuiPostcaptureView: request sending failed, error=%d",
                       videoRequest->lastError()));
@@ -251,50 +243,42 @@
 
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::showDeleteNote
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Show delete query.
+*/
 void CxuiPostcaptureView::showDeleteNote()
 {
     CX_DEBUG_ENTER_FUNCTION();
 
     hideControls();
 
-    if (mEngine->mode() == Cxe::VideoMode) {
-        HbMessageBox::question(hbTrId("txt_cam_other_delete_video_clip"),
-                               this,
-                               SLOT(handleDeleteDialogClosed(HbAction*)));
-    } else {
-        HbMessageBox::question(hbTrId("txt_cam_other_delete_image"),
-                               this,
-                               SLOT(handleDeleteDialogClosed(HbAction*)));
-    }
+    QString text(mEngine->mode() == Cxe::VideoMode
+               ? hbTrId("txt_cam_other_delete_video_clip")
+               : hbTrId("txt_cam_other_delete_image"));
+
+    HbMessageBox::question(text,
+                           this,
+                           SLOT(handleDeleteDialogClosed(int)),
+                           HbMessageBox::Yes | HbMessageBox::No);
 
     mDeleteNoteOpen = true;
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::handleDeleteDialogClosed
-//
-// ---------------------------------------------------------------------------
-//
-void CxuiPostcaptureView::handleDeleteDialogClosed(HbAction *action)
+/*!
+* Handle closing delete query dialog.
+* @param action HbMessageBox::Yes if user accepted the delete query, HbMessageBox::No if not.
+*/
+void CxuiPostcaptureView::handleDeleteDialogClosed(int action)
 {
     CX_DEBUG_ENTER_FUNCTION();
 
     hideControls();
     mDeleteNoteOpen = false;
 
-    HbMessageBox *dlg = qobject_cast<HbMessageBox*>(sender());
-
-    // check that it was "primary action" that closed the dialog
-    if (dlg && dlg->actions().at(0) == action) {
-        // User confirmed delete
-        QString filename = getCurrentFilename();
-        QFileInfo fileInfo(filename);
+    // Check that user confirmed delete
+    if (action == HbMessageBox::Yes) {
+        QFileInfo fileInfo(getCurrentFilename());
         if (fileInfo.exists()) {
             //! @todo
             // We can retry deletion if file deletion does'nt succeed,
@@ -303,7 +287,7 @@
             // is being harvested by MdS etc.
             QDir dir = fileInfo.absolutePath();
             bool ok = dir.remove(fileInfo.fileName());
-            CX_DEBUG(("Delete file [%s], status %d", fileInfo.fileName().toAscii().constData(), ok));
+            CX_DEBUG(("Delete file [%s], status %d", qPrintable(fileInfo.fileName()), ok));
 
             // Go back to precapture view
             goToPrecaptureView();
@@ -333,11 +317,9 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::goToPrecaptureView
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Go to pre-capture view.
+*/
 void CxuiPostcaptureView::goToPrecaptureView()
 {
     CX_DEBUG_ENTER_FUNCTION();
@@ -359,11 +341,9 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::stopViewfinder
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Stop viewfinder.
+*/
 void CxuiPostcaptureView::stopViewfinder()
 {
     CX_DEBUG_ENTER_FUNCTION();
@@ -394,11 +374,10 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::eventFilter
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Handle events.
+* Needed for restarting timers.
+*/
 bool CxuiPostcaptureView::eventFilter(QObject *object, QEvent *event)
 {
     Q_UNUSED(object)
@@ -427,7 +406,12 @@
 */
 void CxuiPostcaptureView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
 {
-    OstTrace0(camerax_performance, CXUIPOSTCAPTUREVIEW_SNAPSHOT_DRAW, "msg: e_CX_SHOT_TO_SNAPSHOT 0");
+    // Performance trace for checking shot to snapshot time.
+    // Guard that we actually have the snapshot set before outputting the trace.
+    if (mImageLabel && !mImageLabel->icon().isNull()) {
+        OstTrace0(camerax_performance, CXUIPOSTCAPTUREVIEW_SNAPSHOT_DRAW, "msg: e_CX_SHOT_TO_SNAPSHOT 0");
+    }
+
     QGraphicsWidget::paint(painter, option, widget);
 }
 
@@ -438,12 +422,13 @@
  */
 void CxuiPostcaptureView::restoreActivity(const QString &activityId, const QVariant &data)
 {
+    Q_UNUSED(activityId);
     CX_DEBUG_ENTER_FUNCTION();
 
     // get filename. if filename is not found (toString() returns empty string)
     // we will go back to pre-capture in updateSnapshotImage()
     mFilename = data.toMap()[FILENAME_KEY].toString();
-    CX_DEBUG(("Got filename %s from activity", mFilename.toAscii().data()));
+    CX_DEBUG(("Got filename [%s] from activity", qPrintable(mFilename)));
 
     CX_DEBUG_EXIT_FUNCTION();
 }
@@ -458,7 +443,7 @@
     QVariantHash params;
 
     QString filename = getCurrentFilename();
-    CX_DEBUG(("Saving filename %s", filename.toAscii().data()));
+    CX_DEBUG(("Saving filename [%s]", qPrintable(filename)));
     data.insert(FILENAME_KEY, filename);
 
     QImage img(mMainWindow->rect().size(), QImage::Format_ARGB32_Premultiplied);
@@ -489,11 +474,10 @@
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::showEvent
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Show event for this view.
+* Update snapshot and start timers.
+*/
 void CxuiPostcaptureView::showEvent(QShowEvent *event)
 {
     CX_DEBUG_ENTER_FUNCTION();
@@ -503,20 +487,27 @@
     if (event->type() == QEvent::Show) {
         QCoreApplication::instance()->installEventFilter(this);
 
+        // Update snapshot for current file.
+        // If the current file does not exist anymore, return to pre-capture view.
         updateSnapshotImage();
-        showControls();
-        startTimers();
+
+        // If the image / video has been deleted, control returned to pre-capture view.
+        // No point to start timers or show controls then.
+        if (mMainWindow->currentView() == this) {
+            showControls();
+            startTimers();
+        }
+
         event->accept();
     }
 
     CX_DEBUG_EXIT_FUNCTION();
 }
 
-// ---------------------------------------------------------------------------
-// CxuiPostcaptureView::hideEvent
-//
-// ---------------------------------------------------------------------------
-//
+/*!
+* Hide event.
+* Release snapshot and stop timers.
+*/
 void CxuiPostcaptureView::hideEvent(QHideEvent *event)
 {
     CX_DEBUG_ENTER_FUNCTION();
@@ -594,73 +585,109 @@
 {
     CX_DEBUG_ENTER_FUNCTION();
 
-    if (!mFilename.isNull()) {
-        CX_DEBUG(("CxuiPostcaptureView::updateSnapshot restoring activity"));
+    if (isFileDeleted()) {
+        // File deleted, go to pre-capture view.
+        CX_DEBUG(("File has been deleted, going back to pre-capture"));
+        goToPrecaptureView();
+
+    } else if (!mFilename.isNull()) {
         // filename set, we are restoring activity
-        if (QFile::exists(mFilename)) {
-            CX_DEBUG(("Filename ok, requesting thumbnail from TNM"));
-            if (!mThumbnailManager) {
-                mThumbnailManager = new ThumbnailManager();
-                connect(mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void *, int, int)),
-                                                this, SLOT(handleThumbnailReady(QPixmap, void*, int, int)));
-                mThumbnailManager->setThumbnailSize(ThumbnailManager::ThumbnailLarge);
-            }
-            mThumbnailManager->getThumbnail(mFilename);
-            CX_DEBUG(("Thumbnail requested"));
+        if (!mThumbnailManager) {
+            mThumbnailManager = new ThumbnailManager();
+            connect(mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void *, int, int)),
+                    this, SLOT(handleThumbnailReady(QPixmap)));
+            mThumbnailManager->setThumbnailSize(ThumbnailManager::ThumbnailLarge);
+        }
+        mThumbnailManager->getThumbnail(mFilename);
+        CX_DEBUG(("Thumbnail requested"));
 
-        } else {
-            // file deleted
-            CX_DEBUG(("File %s has been deleted, going back to pre-capture", mFilename.toAscii().data()));
-            goToPrecaptureView();
-        }
     } else {
+        // Normal use of post-capture view
         QPixmap snapshot;
         if (mEngine->mode() == ImageMode) {
-            if( mEngine->stillCaptureControl().imageCount() > 0 ) {
+
+            if (mEngine->stillCaptureControl().imageCount() > 0) {
                 snapshot = mEngine->stillCaptureControl()[0].snapshot();
             }
         } else {
             snapshot = mEngine->videoCaptureControl().snapshot();
         }
-        if (mImageLabel) {
-                mImageLabel->setIcon(HbIcon(QIcon(snapshot)));
-            } else {
-                // do nothing
-        }
+
+        // Update the snapshot image
+        handleThumbnailReady(snapshot);
     }
 
     CX_DEBUG_EXIT_FUNCTION();
 }
 
+/*!
+* Check if the file we show this post-capture view for is deleted.
+* This can happen e.g. if we send camera to background and delete
+* the file in other application. When used as activity, we may also
+* get the name of already deleted file as activity parameter.
+* @return True if the current file is deleted, false if not.
+*/
+bool CxuiPostcaptureView::isFileDeleted()
+{
+    CX_DEBUG_ENTER_FUNCTION();
+
+    bool deleted(false);
+
+    // Check how we entered this view.
+    if (mFilename.isNull()) {
+        CX_DEBUG(("Checking engine filename"));
+        // Normally entered post-capture view.
+        if (mEngine->mode() == ImageMode) {
+            // Check that the image have been saved already.
+            // If not, it cannot have been deleted in that case.
+            CxeStillImage &image(mEngine->stillCaptureControl()[0]);
+            CX_DEBUG(("Image filename [%s]", qPrintable(image.filename())));
+            CX_DEBUG(("Image file saved: %d exists: %d", image.saved(), QFile::exists(image.filename())));
+            deleted = image.saved() && !QFile::exists(image.filename());
+        } else {
+            // Check that video has been stopped fully.
+            // If it's still stopping, QFile may not work.
+            CX_DEBUG(("Video filename [%s]", qPrintable(mEngine->videoCaptureControl().filename())));
+            deleted = mEngine->videoCaptureControl().state() != CxeVideoCaptureControl::Stopping
+                   && !QFile::exists(mEngine->videoCaptureControl().filename());
+        }
+    } else {
+        // Started as activity, check the filename given when restoring activity.
+        CX_DEBUG(("Checking filename saved in activity"));
+        deleted = !QFile::exists(mFilename);
+    }
+
+    CX_DEBUG_EXIT_FUNCTION();
+    return deleted;
+}
+
 /* !
  * gets the filename of the current file
  */
 QString CxuiPostcaptureView::getCurrentFilename()
 {
     CX_DEBUG_ENTER_FUNCTION();
+    QString filename;
 
     if (!mFilename.isNull()) {
         // post-capture started by activity, engine doesn't contain correct
         // filename anymore so use the stored one
         CX_DEBUG(("Using filename saved in activity"));
-        CX_DEBUG_EXIT_FUNCTION();
-        return mFilename;
+        filename = mFilename;
+    } else {
+        CX_DEBUG(("Getting filename from engine"));
+        if (mEngine->mode() == Cxe::VideoMode) {
+            filename = mEngine->videoCaptureControl().filename();
+        } else {
+            //!@todo Currently only gets index 0 from the still capture control.
+            CxeStillCaptureControl& stillCaptureControl = mEngine->stillCaptureControl();
+            if (stillCaptureControl.imageCount() > 0) {
+                filename = stillCaptureControl[0].filename();
+            }
+        }
     }
 
-    CX_DEBUG(("Getting filename from engine"));
-    QString filename;
-
-    if (mEngine->mode() == Cxe::VideoMode) {
-        filename = mEngine->videoCaptureControl().filename();
-    } else {
-        //!@todo Currently only gets index 0 from the still capture control.
-        CxeStillCaptureControl& stillCaptureControl = mEngine->stillCaptureControl();
-        if (stillCaptureControl.imageCount()) {
-            filename = stillCaptureControl[0].filename();
-        }
-    }
-    CX_DEBUG((filename.toAscii()));
-
+    CX_DEBUG(("Got filename [%s]", qPrintable(filename)));
     CX_DEBUG_EXIT_FUNCTION();
 
     return filename;
@@ -690,8 +717,12 @@
     // Common functionality first.
     CxuiView::exitStandby();
 
-    //!@note We should not start timers until we receive the ShowEvent
-    showControls();
+    // Update snapshot and check the current file is not deleted.
+    updateSnapshotImage();
+
+    if (mMainWindow->currentView() == this) {
+        showControls();
+    }
 
     CX_DEBUG_EXIT_FUNCTION();
 }
@@ -716,19 +747,13 @@
  * Handle thumbnail received from ThumbnailManager.
  *
  * @param thumbnail Thumbnail as QPixmap
- * @param clientData Not used
- * @param id Thumbnail manager request id
- * @param errorCode Error code
  */
-void CxuiPostcaptureView::handleThumbnailReady(QPixmap thumbnail, void *clientData, int id, int errorCode)
+void CxuiPostcaptureView::handleThumbnailReady(QPixmap thumbnail)
 {
     CX_DEBUG_ENTER_FUNCTION();
 
-    Q_UNUSED(clientData);
-    Q_UNUSED(id);
-
     if (thumbnail.isNull()) {
-        CX_DEBUG(("Received null thumbnail from TNM, going to pre-capture. Error=%d", errorCode));
+        CX_DEBUG(("[WARNING] Received null thumbnail from TNM, going to pre-capture."));
         // null thumbnail, go to precapture
         goToPrecaptureView();
     } else if (mImageLabel) {
@@ -778,9 +803,9 @@
     }
 
     if (!CxuiServiceProvider::isCameraEmbedded()) {
-        CxeError::Id err = mEngine->settings().get(settingId, postCaptureTimeout);
+        postCaptureTimeout = mEngine->settings().get<int>(settingId, 0);
 
-        if (postCaptureTimeout > 0 && err == CxeError::None) {
+        if (postCaptureTimeout > 0) {
             mPostcaptureTimer.start(postCaptureTimeout);
         } else {
             // do nothing