diff -r 2922f70fca82 -r 67457b2ffb33 camerauis/cameraxui/cxui/src/cxuipostcaptureview.cpp --- a/camerauis/cameraxui/cxui/src/cxuipostcaptureview.cpp Thu Jul 15 01:49:11 2010 +0300 +++ b/camerauis/cameraxui/cxui/src/cxuipostcaptureview.cpp Thu Jul 15 01:52:14 2010 +0300 @@ -30,8 +30,10 @@ #include #include #include +#include #include +#include #include "cxeviewfindercontrol.h" #include "cxuienums.h" @@ -39,7 +41,6 @@ #include "cxeengine.h" #include "cxecameradevicecontrol.h" #include "cxestillcapturecontrol.h" -#include "cxeviewfindercontrol.h" #include "cxevideocapturecontrol.h" #include "cxestillimage.h" #include "cxutils.h" @@ -59,9 +60,12 @@ using namespace Cxe; -//!@todo Temporarily disabled. -//const int CXUI_STOP_VIEWFINDER_TIMEOUT = 5000; // 5 seconds -//const int CXUI_RELEASE_CAMERA_TIMEOUT = 10000; // 10 seconds +namespace { + 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 @@ -80,7 +84,9 @@ mReleaseCameraTimer(this), mPostcaptureTimer(this), mTimersStarted(false), - mDeleteNoteOpen(false) + mDeleteNoteOpen(false), + mFilename(QString::null), + mThumbnailManager(NULL) { CX_DEBUG_IN_FUNCTION(); @@ -97,6 +103,7 @@ CX_DEBUG_ENTER_FUNCTION(); QCoreApplication::instance()->removeEventFilter(this); stopTimers(); + delete mThumbnailManager; delete mShareUi; CX_DEBUG_EXIT_FUNCTION(); } @@ -107,11 +114,13 @@ // --------------------------------------------------------------------------- // void CxuiPostcaptureView::construct(HbMainWindow *mainwindow, CxeEngine *engine, - CxuiDocumentLoader *documentLoader) + CxuiDocumentLoader *documentLoader, + CxuiCaptureKeyHandler *keyHandler, + HbActivityManager *activityManager) { CX_DEBUG_ENTER_FUNCTION(); - CxuiView::construct(mainwindow, engine, documentLoader, NULL); + CxuiView::construct(mainwindow, engine, documentLoader, NULL, activityManager); // set back action to go back to pre-capture HbAction *backAction = new HbAction(Hb::BackNaviAction, this); @@ -209,10 +218,36 @@ */ void CxuiPostcaptureView::playVideo() { - - launchNotSupportedNotification(); - //! @todo needs an implementation - CX_DEBUG_IN_FUNCTION(); + CX_DEBUG_ENTER_FUNCTION(); + + stopTimers(); + releaseCamera(); + + QString videoFile(getCurrentFilename()); + + XQAiwRequest *videoRequest = mAppManager.create( + "com.nokia.symbian.IVideoView","playMedia(QString)", true); + + if (videoRequest) { + QVariantList fileList; + fileList.append(QVariant(videoFile)); + videoRequest->setArguments(fileList); + + CX_DEBUG(("CxuiPostcaptureView: sending request")); + QVariant result; + bool res = videoRequest->send(result); + if (res) { + CX_DEBUG(("CxuiPostcaptureView: request sent, received \"%s\"", + result.toString().toAscii().constData())); + } else { + CX_DEBUG(("CxuiPostcaptureView: request sending failed, error=%d", + videoRequest->lastError())); + } + delete videoRequest; + videoRequest = NULL; + } + + CX_DEBUG_EXIT_FUNCTION(); } @@ -314,8 +349,8 @@ // Re-enabling starting timers the next time we enter post capture view. mTimersStarted = false; - // Make sure engine prepares for new image/video if necessary - mEngine->initMode(mEngine->mode()); + // reset saved filename + mFilename = QString::null; // Switch to pre-capture view emit changeToPrecaptureView(); @@ -392,8 +427,66 @@ */ void CxuiPostcaptureView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { - OstTrace0(camerax_performance, CXUIPOSTCAPTUREVIEW_SNAPSHOT_DRAW, "msg: e_CX_SHOT_TO_SNAPSHOT 0"); - QGraphicsWidget::paint(painter, option, widget); + OstTrace0(camerax_performance, CXUIPOSTCAPTUREVIEW_SNAPSHOT_DRAW, "msg: e_CX_SHOT_TO_SNAPSHOT 0"); + QGraphicsWidget::paint(painter, option, widget); +} + +/*! + * Restore view state from activity. + * @param activityId Activity id + * @param data Activity data + */ +void CxuiPostcaptureView::restoreActivity(const QString &activityId, const QVariant &data) +{ + 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_EXIT_FUNCTION(); +} + +/*! + * Save view state to activity. + */ +void CxuiPostcaptureView::saveActivity() +{ + CX_DEBUG_ENTER_FUNCTION(); + QVariantMap data; + QVariantHash params; + + QString filename = getCurrentFilename(); + CX_DEBUG(("Saving filename %s", filename.toAscii().data())); + data.insert(FILENAME_KEY, filename); + + QImage img(mMainWindow->rect().size(), QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + mMainWindow->render(&p, mMainWindow->rect(), mMainWindow->rect()); + + QPixmap screenshot = QPixmap::fromImage(img); + + params.insert("screenshot", screenshot); + if (mEngine->mode() == Cxe::ImageMode) { + mActivityManager->removeActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY); + mActivityManager->addActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY, data, params); + } else { + mActivityManager->removeActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY); + mActivityManager->addActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY, data, params); + } + CX_DEBUG_EXIT_FUNCTION(); +} + +/*! + * Clear activity from activity manager. + */ +void CxuiPostcaptureView::clearActivity() +{ + CX_DEBUG_ENTER_FUNCTION(); + mActivityManager->removeActivity(CxuiActivityIds::STILL_POSTCAPTURE_ACTIVITY); + mActivityManager->removeActivity(CxuiActivityIds::VIDEO_POSTCAPTURE_ACTIVITY); + CX_DEBUG_EXIT_FUNCTION(); } // --------------------------------------------------------------------------- @@ -492,29 +585,48 @@ CX_DEBUG_EXIT_FUNCTION(); } -// --------------------------------------------------------------------------- -// CxuiPostcaptureView::setImage -// -// --------------------------------------------------------------------------- -// +/*! + * Updates snapshot image. In normal case snapshot is retrieved from engine + * but if we are restoring camera to post-capture through activity, then + * we get snapshot from thumbnail manager. + */ void CxuiPostcaptureView::updateSnapshotImage() { CX_DEBUG_ENTER_FUNCTION(); - QPixmap snapshot; + if (!mFilename.isNull()) { + CX_DEBUG(("CxuiPostcaptureView::updateSnapshot restoring activity")); + // 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 (mEngine->mode() == ImageMode) { - if( mEngine->stillCaptureControl().imageCount() > 0 ) { - snapshot = mEngine->stillCaptureControl()[0].snapshot(); + } else { + // file deleted + CX_DEBUG(("File %s has been deleted, going back to pre-capture", mFilename.toAscii().data())); + goToPrecaptureView(); } } else { - snapshot = mEngine->videoCaptureControl().snapshot(); - } - - if (mImageLabel) { - mImageLabel->setIcon(HbIcon(QIcon(snapshot))); - } else { - // do nothing + QPixmap snapshot; + if (mEngine->mode() == ImageMode) { + 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 + } } CX_DEBUG_EXIT_FUNCTION(); @@ -527,6 +639,15 @@ { CX_DEBUG_ENTER_FUNCTION(); + 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; + } + + CX_DEBUG(("Getting filename from engine")); QString filename; if (mEngine->mode() == Cxe::VideoMode) { @@ -560,27 +681,31 @@ } /*! - Handle cases when we gain focus +* Handle exiting standby. */ -void CxuiPostcaptureView::handleFocusGained() +void CxuiPostcaptureView::exitStandby() { CX_DEBUG_ENTER_FUNCTION(); - //Note: We should not start timers until we receive the ShowEvent + // Common functionality first. + CxuiView::exitStandby(); + + //!@note We should not start timers until we receive the ShowEvent showControls(); CX_DEBUG_EXIT_FUNCTION(); } /*! - Handle cases when we loose focus +* Handle entering standby. */ -void CxuiPostcaptureView::handleFocusLost() +void CxuiPostcaptureView::enterStandby() { CX_DEBUG_ENTER_FUNCTION(); - // we have lost focus - releaseCamera(); + // Common functionality (release camera). + CxuiView::enterStandby(); + stopTimers(); hideControls(); @@ -588,6 +713,32 @@ } /*! + * 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) +{ + 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)); + // null thumbnail, go to precapture + goToPrecaptureView(); + } else if (mImageLabel) { + mImageLabel->setIcon(HbIcon(QIcon(thumbnail))); + } + + CX_DEBUG_EXIT_FUNCTION(); +} + +/*! Start the timers */ void CxuiPostcaptureView::startTimers() @@ -611,6 +762,12 @@ { CX_DEBUG_ENTER_FUNCTION(); + if (!mFilename.isNull()) { + // restored from activity, don't do post-capture timeout + CX_DEBUG_EXIT_FUNCTION(); + return; + } + int postCaptureTimeout = 0; QString settingId; @@ -640,10 +797,10 @@ { CX_DEBUG_ENTER_FUNCTION(); - // Todo Note: Temporarily disabling release timer because of - // graphics memory problems related to releasing and reserving again. - // mReleaseCameraTimer.start(CXUI_RELEASE_CAMERA_TIMEOUT); - // mStopViewfinderTimer.start(CXUI_STOP_VIEWFINDER_TIMEOUT); + // Release camera and stop viewfinder if user stays in postcapture long enough. + // Battery could otherwise drain fast. + mReleaseCameraTimer.start(CXUI_RELEASE_CAMERA_TIMEOUT); + mStopViewfinderTimer.start(CXUI_STOP_VIEWFINDER_TIMEOUT); CX_DEBUG_EXIT_FUNCTION(); } @@ -658,7 +815,7 @@ mPostcaptureTimer.stop(); mStopViewfinderTimer.stop(); - // Note: mTimersStarted is intentionally not reset here. + //!@note mTimersStarted is intentionally not reset here. // Once the timers are stopped, they are not to be started again until // we come from precapture view again. // E.g. returning from background could otherwise restart the timers and