homescreenapp/stateplugins/hshomescreenstateplugin/src/hsselectbackgroundstate.cpp
changeset 62 341166945d65
parent 57 2e2dc3d30ca8
child 63 52b0f64eeb51
equal deleted inserted replaced
57:2e2dc3d30ca8 62:341166945d65
     1 /*
       
     2 * Copyright (c) 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 
       
    18 #include <QAction>
       
    19 #include <QApplication>
       
    20 #include <QDir>
       
    21 #include <QFileInfo>
       
    22 
       
    23 #include <HbMainWindow>
       
    24 #include <HbProgressDialog>
       
    25 
       
    26 #include "hsselectbackgroundstate.h"
       
    27 #include "hsscene.h"
       
    28 #include "hsdomainmodeldatastructures.h"
       
    29 #include "hswallpaper.h"
       
    30 #include "hsdatabase.h"
       
    31 #include "hshomescreenstatecommon.h"
       
    32 #include "hsconfiguration.h"
       
    33 
       
    34 #ifdef Q_OS_SYMBIAN
       
    35 #include "hsimagefetcherclient.h"
       
    36 #else
       
    37 #include "xqaiwgetimageclient.h"
       
    38 #include "xqaiwcommon.h"
       
    39 #endif
       
    40 
       
    41 const char hsLocTextId_ProgressDialog_WallpaperLoading[] =
       
    42             "txt_homescreen_dpopinfo_loading_wallpaper";
       
    43 
       
    44 /*! 
       
    45     \class HsSelectBackgroundState
       
    46     \ingroup group_hshomescreenstateprovider
       
    47     \brief Implements imagefetcher event listening and handles those events.
       
    48 
       
    49     \sa StateMachine
       
    50 */
       
    51 
       
    52 /*!
       
    53     Constructor.         
       
    54     \a parent Owner.
       
    55 */
       
    56 HsSelectBackgroundState::HsSelectBackgroundState(QState *parent):
       
    57     QState(parent),
       
    58     mImageFetcher(0),
       
    59     mSourceView(0),
       
    60     mPortraitWallpaperImageReader(0),
       
    61     mLandscapeWallpaperImageReader(0),
       
    62     mProgressDialog(0),
       
    63     mRunningThreadAmount(0),
       
    64     mShowAnimation(false)
       
    65 {
       
    66 #ifdef Q_OS_SYMBIAN
       
    67     mImageFetcher = new HsImageFetcherClient(this);
       
    68 #else    
       
    69     mImageFetcher = new XQAIWGetImageClient;
       
    70 #endif
       
    71 
       
    72     connect(this, SIGNAL(entered()), SLOT(action_selectWallpaper()));
       
    73     connect(this, SIGNAL(exited()), SLOT(action_disconnectImageFetcher()));
       
    74     connect(this, SIGNAL(handleError()), SLOT(onHandleError()));
       
    75 }
       
    76 
       
    77 /*!
       
    78     Destructor.
       
    79     
       
    80 */
       
    81 HsSelectBackgroundState::~HsSelectBackgroundState()
       
    82 {
       
    83     delete mImageFetcher;
       
    84     delete mPortraitWallpaperImageReader;
       
    85     delete mLandscapeWallpaperImageReader;
       
    86 }
       
    87 
       
    88 /*!
       
    89     \internal
       
    90     Connects to image fetcher and launches "remote" ui from photos
       
    91     from which user can select background image
       
    92 */
       
    93 void HsSelectBackgroundState::action_selectWallpaper()
       
    94 {
       
    95     mSourceView = HsScene::mainWindow()->currentView();
       
    96 
       
    97     mRunningThreadAmount = 0;
       
    98     mShowAnimation = false;
       
    99 
       
   100 #ifdef Q_OS_SYMBIAN
       
   101     connect(mImageFetcher, SIGNAL(fetchCompleted(const QString&)),
       
   102             this, SLOT(fetchCompleted(const QString&)));
       
   103     connect(mImageFetcher, SIGNAL(fetchFailed(int, const QString&)),
       
   104             this, SLOT(fetchFailed(int, const QString&)));
       
   105     mImageFetcher->fetch();
       
   106 #else
       
   107     connect(mImageFetcher, SIGNAL(fetchComplete(QStringList)),
       
   108             SLOT(onFetchComplete(QStringList)));
       
   109     connect(mImageFetcher, SIGNAL(fetchFailed(int)),
       
   110             SLOT(onFetchFailed(int)));
       
   111     mImageFetcher->fetch(QVariantMap(), SelectionSingle);
       
   112 #endif
       
   113 }
       
   114 
       
   115 /*!
       
   116     \internal
       
   117     disconnects photos image fetcher services slots.
       
   118 */
       
   119 void HsSelectBackgroundState::action_disconnectImageFetcher()
       
   120 {
       
   121     HsScene::mainWindow()->setCurrentView(mSourceView);
       
   122     mImageFetcher->disconnect(this);
       
   123 }
       
   124 
       
   125 /*!
       
   126     \internal
       
   127     Called when user has selected an image 
       
   128 */
       
   129 void HsSelectBackgroundState::onFetchComplete(QStringList imageStringList)
       
   130 {
       
   131     // start animation immediately
       
   132     onShowAnimation();
       
   133 
       
   134     // check that sceneData is available
       
   135     HsDatabase *db = HsDatabase::instance();
       
   136     Q_ASSERT(db);
       
   137     HsSceneData sceneData;
       
   138     if (!db->scene(sceneData)) {
       
   139         emit handleError();
       
   140         return;
       
   141     }
       
   142 
       
   143     // clean thread instances
       
   144     delete mPortraitWallpaperImageReader;
       
   145     delete mLandscapeWallpaperImageReader;
       
   146     mPortraitWallpaperImageReader = NULL;
       
   147     mLandscapeWallpaperImageReader = NULL;
       
   148 
       
   149     mPortraitWallpaperImageReader = new HsWallpaperImageReader();
       
   150     mLandscapeWallpaperImageReader = new HsWallpaperImageReader();
       
   151 
       
   152     mRunningThreadAmount = 2;
       
   153 
       
   154     // delete old wallpapers
       
   155     QFile::remove(sceneData.portraitWallpaper);
       
   156     QFile::remove(sceneData.landscapeWallpaper);
       
   157 
       
   158     QString wallpaperDir = HsWallpaper::wallpaperDirectory();            
       
   159     QDir dir(wallpaperDir);
       
   160     if (!dir.exists()) {
       
   161         dir.mkpath(wallpaperDir);
       
   162     }
       
   163 
       
   164     // left empty to signal we want to use full size image as source
       
   165     QRect sourceRect;
       
   166 
       
   167     // Initialize portrait image threading
       
   168     QRect targetRectPortrait(0, 0, (2 * 360) + HsConfiguration::bounceEffect(), 640);
       
   169     mPortraitWallpaperImageReader->setSourcePath(imageStringList.first());
       
   170     mPortraitWallpaperImageReader->setSourceRect(sourceRect);
       
   171     mPortraitWallpaperImageReader->setTargetRect(targetRectPortrait);
       
   172     mPortraitWallpaperImageReader->setCenterTarget(true);
       
   173 
       
   174     connect(mPortraitWallpaperImageReader,
       
   175             SIGNAL(finished()),
       
   176             SLOT(onImageProcessed()));
       
   177 
       
   178     // Initialize landscape image threading
       
   179     QRect targetRectLandscape(0, 0, (2 * 640) + HsConfiguration::bounceEffect(), 360);
       
   180     mLandscapeWallpaperImageReader->setSourcePath(imageStringList.first());
       
   181     mLandscapeWallpaperImageReader->setSourceRect(sourceRect);
       
   182     mLandscapeWallpaperImageReader->setTargetRect(targetRectLandscape);
       
   183     mLandscapeWallpaperImageReader->setCenterTarget(true);
       
   184 
       
   185     connect(mLandscapeWallpaperImageReader,
       
   186             SIGNAL(finished()),
       
   187             SLOT(onImageProcessed()));
       
   188   
       
   189     // start image processing in thread
       
   190     mPortraitWallpaperImageReader->start();
       
   191     mLandscapeWallpaperImageReader->start();
       
   192 }
       
   193 
       
   194 /*!
       
   195     \internal
       
   196     Called when selection of background image fails  
       
   197 */
       
   198 void HsSelectBackgroundState::onFetchFailed(int error)
       
   199 {
       
   200     Q_UNUSED(error)
       
   201     emit handleError();
       
   202 }
       
   203 
       
   204 /*!
       
   205     \internal
       
   206     Called when image processing is finished in thread  
       
   207 */
       
   208 void HsSelectBackgroundState::onImageProcessed()
       
   209 {
       
   210     mRunningThreadAmount--;
       
   211 
       
   212     HsDatabase *db = HsDatabase::instance();
       
   213     Q_ASSERT(db);
       
   214     HsSceneData sceneData;
       
   215     if (!db->scene(sceneData)) {
       
   216         emit handleError();
       
   217         return;
       
   218     }
       
   219 
       
   220     QFileInfo fileInfo;
       
   221     // get image path
       
   222     if (sender() == mPortraitWallpaperImageReader) {
       
   223         fileInfo = mPortraitWallpaperImageReader->sourcePath();
       
   224     } else {
       
   225         fileInfo = mLandscapeWallpaperImageReader->sourcePath();
       
   226     }
       
   227     // suffix is same for both orientations
       
   228     QString fileExtension("");
       
   229     if (!fileInfo.suffix().isEmpty()) {
       
   230         fileExtension = fileInfo.suffix();
       
   231     }
       
   232 
       
   233     QImage image;
       
   234     // set portrait image path to sceneData
       
   235     QString portraitPath(HsWallpaper::wallpaperPath(Qt::Vertical, QString(),
       
   236                                                     fileExtension));
       
   237     // we need to set this always as image to be activated can be either orientation
       
   238     sceneData.portraitWallpaper = portraitPath;
       
   239     QString landscapePath(HsWallpaper::wallpaperPath(Qt::Horizontal, QString(),
       
   240                                                      fileExtension));
       
   241     sceneData.landscapeWallpaper = landscapePath;
       
   242 
       
   243     if (sender() == mPortraitWallpaperImageReader) {
       
   244         // get image from thread
       
   245         image = mPortraitWallpaperImageReader->processedImage();
       
   246         // save image
       
   247         image.save(portraitPath);
       
   248     } else {
       
   249         image = mLandscapeWallpaperImageReader->processedImage();
       
   250         image.save(landscapePath);
       
   251     }
       
   252 
       
   253     if (image.isNull()) {
       
   254         emit handleError();
       
   255         return;
       
   256     }
       
   257     // update scenedata and set new image to background
       
   258     if (db->updateScene(sceneData)) {
       
   259         HsScene *scene = HsScene::instance();
       
   260         // set image to wallpaper (don't activate yet)
       
   261         if (sender() == mPortraitWallpaperImageReader) {
       
   262             scene->wallpaper()->setPortraitImage(portraitPath, false);
       
   263         } else {
       
   264             scene->wallpaper()->setLandscapeImage(landscapePath, false);
       
   265         }
       
   266         // if last thread running
       
   267         if (mRunningThreadAmount == 0) {
       
   268             // if current orientation matches -> set to active wallpaper
       
   269             if (HsScene::orientation() == Qt::Vertical) {
       
   270                 scene->wallpaper()->setPortraitImage(portraitPath, true);
       
   271             } else {
       
   272                 scene->wallpaper()->setLandscapeImage(landscapePath, true);
       
   273             }
       
   274             // finish progress bar
       
   275             if (mShowAnimation) {
       
   276                 mProgressDialog->setProgressValue(3);
       
   277             }
       
   278             // let user control again homescreen
       
   279             emit event_waitInput();
       
   280         } else {
       
   281             // update progress information
       
   282             if (mShowAnimation) {
       
   283                 mProgressDialog->setProgressValue(2);
       
   284             }
       
   285         }
       
   286     }     
       
   287 }
       
   288 
       
   289 /*!
       
   290     \internal
       
   291     Shows animation for longer processing
       
   292 */
       
   293 void HsSelectBackgroundState::onShowAnimation()
       
   294 {
       
   295     delete mProgressDialog;
       
   296     mProgressDialog = new HbProgressDialog(HbProgressDialog::ProgressDialog);
       
   297     /* TODO: workaround to remove cancel button (setPrimaryAction(0) is deprecated).
       
   298      * clearActions does the same but crashes, fix should be in wk16, check orbit list
       
   299      */
       
   300     QList<QAction*> actions = mProgressDialog->actions();
       
   301     actions[0]->setVisible(false);
       
   302     mProgressDialog->setIcon(HbIcon("note_info"));
       
   303     mProgressDialog->setText(hbTrId(hsLocTextId_ProgressDialog_WallpaperLoading));
       
   304     mProgressDialog->setMinimum(0);
       
   305     mProgressDialog->setMaximum(3);
       
   306     mProgressDialog->setBackgroundFaded(true);
       
   307     mProgressDialog->setAutoClose(true);
       
   308     // set initial value to appear as loading
       
   309     mProgressDialog->setProgressValue(1);
       
   310     mProgressDialog->show();
       
   311     mShowAnimation = true;
       
   312 }
       
   313 
       
   314 /*!
       
   315     \internal
       
   316     Called when error occurs during image processing  
       
   317 */
       
   318 void HsSelectBackgroundState::onHandleError()
       
   319 {
       
   320     if (mShowAnimation) {
       
   321         mProgressDialog->close();
       
   322     }
       
   323     emit event_waitInput();
       
   324 }
       
   325 
       
   326 /*!
       
   327     \internal
       
   328     Called when user has selected an image on emulator or HW
       
   329 */
       
   330 #ifdef Q_OS_SYMBIAN
       
   331 void HsSelectBackgroundState::fetchCompleted(const QString& imageFileName)
       
   332 {
       
   333     QStringList imageFileNameAsList(imageFileName);
       
   334     onFetchComplete(imageFileNameAsList);
       
   335 }
       
   336 #endif
       
   337 
       
   338 /*!
       
   339     \internal
       
   340     Called when selection of background image fails on emulator or HW
       
   341 */
       
   342 #ifdef Q_OS_SYMBIAN
       
   343 void HsSelectBackgroundState::fetchFailed(int error, const QString& errorString)
       
   344 {
       
   345     Q_UNUSED(errorString)
       
   346     onFetchFailed(error);        
       
   347 }
       
   348 #endif