emailuis/nmailui/src/nmapplication.cpp
changeset 54 997a02608b3a
parent 53 bf7eb7911fc5
child 59 16ed8d08d0b1
equal deleted inserted replaced
53:bf7eb7911fc5 54:997a02608b3a
     1 /*
     1 /*
     2 * Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies).
     2  * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3  * All rights reserved.
     4 * This component and the accompanying materials are made available
     4  * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5  * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6  * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     8  *
     9 * Initial Contributors:
     9  * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10  * Nokia Corporation - initial contribution.
    11 *
    11  *
    12 * Contributors:
    12  * Contributors:
    13 *
    13  *
    14 * Description:
    14  * Description:
    15 *
    15  *
    16 */
    16  */
    17 
    17 
    18 #include "nmuiheaders.h"
    18 #include "nmuiheaders.h"
    19 #ifdef Q_OS_SYMBIAN
       
    20 #include <email_services_api.h>
    19 #include <email_services_api.h>
    21 #include <e32base.h>
    20 #include <e32base.h>
    22 #else
       
    23 #define NM_WINS_ENV
       
    24 #endif
       
    25 
    21 
    26 static const QString NmSendServiceName = "nmail.com.nokia.symbian.IFileShare";
    22 static const QString NmSendServiceName = "nmail.com.nokia.symbian.IFileShare";
    27 
    23 
    28 /*!
    24 /*!
    29 	\class NmApplication
    25     \class NmApplication
    30 	\brief Application class, creates main window and handles view switching
    26     \brief Application class, creates main window and handles view switching.
    31 */
    27 */
    32 
    28 
    33 /*!
    29 /*!
    34     Constructor
    30     Constructor.
    35 */
    31 */
    36 NmApplication::NmApplication(QObject *parent)
    32 NmApplication::NmApplication(QObject *parent, quint32 accountId)
    37 :QObject(parent),
    33 : QObject(parent),
    38 mMainWindow(NULL),
    34   mMainWindow(NULL),
    39 mViewStack(NULL),
    35   mViewStack(NULL),
    40 mActiveViewId(NmUiViewNone),
    36   mActiveViewId(NmUiViewNone),
    41 mUiEngine(NULL),
    37   mUiEngine(NULL),
    42 mBackAction(NULL),
    38   mBackAction(NULL),
    43 mExtensionManager(NULL),
    39   mExtensionManager(NULL),
    44 mMbListModel(NULL),
    40   mMbListModel(NULL),
    45 mServiceViewId(NmUiViewNone),
    41   mServiceViewId(NmUiViewNone),
    46 mForegroundService(false),
    42   mForegroundService(false),
    47 mEffects(NULL),
    43   mEffects(NULL),
    48 mAttaManager(NULL),
    44   mAttaManager(NULL),
    49 mSettingsViewLauncher(NULL),
    45   mSettingsViewLauncher(NULL),
    50 mViewReady(false),
    46   mViewReady(false),
    51 mQueryDialog(NULL)
    47   mQueryDialog(NULL),
    52 {
    48   mBackButtonPressed(false)
    53     NM_FUNCTION;
    49 {
    54 
       
    55     // TEMPORARY WORKAROUND TO PREVENT PANIC User panic 66, where there is
       
    56     // a PushL call to cleanup stack without any TRAP.
       
    57 #ifdef Q_OS_SYMBIAN
       
    58     TRAP_IGNORE(mUiEngine = NmUiEngine::instance());
    50     TRAP_IGNORE(mUiEngine = NmUiEngine::instance());
    59 #else
    51     
    60     mUiEngine = NmUiEngine::instance();
       
    61 #endif
       
    62 
       
    63     // Create network access manager and cache for application use.
    52     // Create network access manager and cache for application use.
    64     mNetManager = new NmViewerViewNetManager(*mUiEngine);
    53     mNetManager = new NmViewerViewNetManager(*mUiEngine);
    65     QNetworkDiskCache *cache = new QNetworkDiskCache();
    54     QNetworkDiskCache *cache = new QNetworkDiskCache();
    66     cache->setCacheDirectory(QDesktopServices::storageLocation(QDesktopServices::CacheLocation));
    55     cache->setCacheDirectory(
       
    56         QDesktopServices::storageLocation(QDesktopServices::CacheLocation));
    67     mNetManager->setCache(cache);
    57     mNetManager->setCache(cache);
    68 
    58     
    69     createMainWindow();
    59     createMainWindow();
    70 
    60     
    71     // attachment manager can be shared between viewer and editor, ownership in application class
    61     // Attachment manager can be shared between viewer and editor.
       
    62     // The application class has the ownership.
    72     mAttaManager = new NmAttachmentManager(*mUiEngine);
    63     mAttaManager = new NmAttachmentManager(*mUiEngine);
    73 
    64     
    74 #ifndef NM_WINS_ENV
       
    75     mSendServiceInterface =
    65     mSendServiceInterface =
    76             new NmSendServiceInterface(NmSendServiceName, NULL, *mUiEngine, this);
    66         new NmSendServiceInterface(NmSendServiceName, NULL, *mUiEngine, this);
    77     mSendServiceInterface2 =
    67     mSendServiceInterface2 =
    78             new NmSendServiceInterface(emailFullServiceNameSend, NULL, *mUiEngine, this);
    68         new NmSendServiceInterface(emailFullServiceNameSend, NULL, *mUiEngine, this);
    79     mUriServiceInterface =
    69     mUriServiceInterface =
    80         new NmUriServiceInterface(NULL, *mUiEngine, this);
    70         new NmUriServiceInterface(NULL, *mUiEngine, this);
    81     mMailboxServiceInterface =
    71     mMailboxServiceInterface =
    82             new NmMailboxServiceInterface(NULL, *mUiEngine, this);
    72         new NmMailboxServiceInterface(NULL, *mUiEngine, this);
    83     mViewerServiceInterface =
    73     mViewerServiceInterface =
    84             new NmViewerServiceInterface(NULL, this, *mUiEngine);
    74         new NmViewerServiceInterface(NULL, this, *mUiEngine);
    85 #endif
    75     
    86 
    76     if(accountId != 0) {
       
    77         QVariant mailbox;
       
    78         mailbox.setValue(mUiEngine->getPluginIdByMailboxId(accountId).id());
       
    79         mMailboxServiceInterface->displayInboxByMailboxId(mailbox);
       
    80     }
       
    81     
    87     mEffects = new NmUiEffects(*mMainWindow);
    82     mEffects = new NmUiEffects(*mMainWindow);
    88 }
    83 }
    89 
    84 
    90 /*!
    85 /*!
    91     Destructor
    86     Destructor.
    92 */
    87 */
    93 NmApplication::~NmApplication()
    88 NmApplication::~NmApplication()
    94 {
    89 {
    95     NM_FUNCTION;
    90     if (mQueryDialog) {
    96 
       
    97     if (mQueryDialog){
       
    98         delete mQueryDialog;
    91         delete mQueryDialog;
    99         mQueryDialog=NULL;
    92         mQueryDialog = NULL;
   100     }
    93     }
   101 
    94     
   102 #ifndef NM_WINS_ENV
    95     delete mSendServiceInterface;
   103 	delete mSendServiceInterface;
    96     delete mSendServiceInterface2;
   104 	delete mSendServiceInterface2;
    97     delete mUriServiceInterface;
   105 	delete mUriServiceInterface;
    98     delete mMailboxServiceInterface;
   106 	delete mMailboxServiceInterface;
    99     delete mViewerServiceInterface;
   107 	delete mViewerServiceInterface;
   100     
   108 #endif
   101     resetViewStack();
   109 
       
   110 	resetViewStack();
       
   111     delete mViewStack;
   102     delete mViewStack;
       
   103     
   112     NmIcons::freeIcons();
   104     NmIcons::freeIcons();
   113     NmUiEngine::releaseInstance(mUiEngine);
   105     NmUiEngine::releaseInstance(mUiEngine);
   114     mUiEngine = NULL;
   106     mUiEngine = NULL;
       
   107     
   115     delete mBackAction;
   108     delete mBackAction;
       
   109     
       
   110     // Workaround: the main window has to be closed (hidden) before deleting
       
   111     // the extension manager in order to prevent the main window's title bar
       
   112     // from showing when the application is closed.
       
   113     if (mMainWindow) {
       
   114         // Workaround: assert failure may happen if an open main window is
       
   115         // deleted.
       
   116         mMainWindow->close();
       
   117     }
       
   118     
   116     delete mExtensionManager;
   119     delete mExtensionManager;
   117     if (mNetManager){
   120     
   118         if (mNetManager->cache()){
   121     if (mNetManager) {
       
   122         if (mNetManager->cache()) {
   119             mNetManager->cache()->clear();
   123             mNetManager->cache()->clear();
   120         }
   124         }
   121     delete mNetManager;
   125     delete mNetManager;
   122     mNetManager=NULL;
   126     mNetManager = NULL;
   123     }
   127     }
   124     // Effects needs to be deleted before MainWindow.
   128     
       
   129     // Effects need to be deleted before MainWindow.
   125     delete mEffects;
   130     delete mEffects;
   126     if (mMainWindow) {
       
   127         // workaround: assert failure may happen otherwise
       
   128         mMainWindow->close();
       
   129     }
       
   130     delete mMainWindow;
   131     delete mMainWindow;
   131     delete mAttaManager;
   132     delete mAttaManager;
   132     delete mSettingsViewLauncher;
   133     delete mSettingsViewLauncher;
   133 }
   134 }
   134 
   135 
   135 /*!
   136 /*!
   136     Main application window creation
   137     Main application window creation.
   137 */
   138 */
   138 void NmApplication::createMainWindow()
   139 void NmApplication::createMainWindow()
   139 {
   140 {
   140     NM_FUNCTION;
   141     NM_FUNCTION;
   141 
   142     
   142 #ifndef NM_WINS_ENV
       
   143     bool service = XQServiceUtil::isService();
   143     bool service = XQServiceUtil::isService();
   144 #else
   144     
   145     bool service = false;
   145     // Register custom widget files.
   146 #endif
       
   147 
       
   148     // Register custom widget files
       
   149     HbStyleLoader::registerFilePath(":nmmessagelistviewitem.widgetml");
   146     HbStyleLoader::registerFilePath(":nmmessagelistviewitem.widgetml");
   150     HbStyleLoader::registerFilePath(":nmmessagelistviewitem.css");
   147     HbStyleLoader::registerFilePath(":nmmessagelistviewitem.css");
   151     HbStyleLoader::registerFilePath(":nmviewerheader.widgetml");
   148     HbStyleLoader::registerFilePath(":nmviewerheader.widgetml");
   152     HbStyleLoader::registerFilePath(":nmviewerheader.css");
   149     HbStyleLoader::registerFilePath(":nmviewerheader.css");
   153 
   150     
   154     // Create main window
   151     // Create main window.
   155     mMainWindow = new HbMainWindow();
   152     mMainWindow = new HbMainWindow();
   156 
   153     
   157     // Connect to lazy loading signal
   154     // Connect to lazy loading signal.
   158     QObject::connect(mMainWindow, SIGNAL(viewReady ()),
   155     QObject::connect(mMainWindow, SIGNAL(viewReady ()),
   159                      this, SLOT(viewReady()));
   156                      this, SLOT(viewReady()));
   160 
   157     
   161     // Create extension manager
   158     // Create extension manager.
   162     mExtensionManager = new NmUiExtensionManager();
   159     mExtensionManager = new NmUiExtensionManager();
   163 
   160     
   164     // Create view stack
   161     // Create view stack.
   165     mViewStack = new QStack<NmBaseView*>;
   162     mViewStack = new QStack<NmBaseView*>;
   166 
   163     
   167     // Create back action and connect it to prepareForPopView()
   164     // Create back action and connect it to prepareForPopView().
   168     if (mMainWindow) {
   165     if (mMainWindow) {
   169         mBackAction = new HbAction(Hb::BackNaviAction,this);
   166         mBackAction = new HbAction(Hb::BackNaviAction,this);
   170         connect(mBackAction, SIGNAL(triggered()), this, SLOT(prepareForPopView()));
   167         connect(mBackAction,
   171 
   168                 SIGNAL(triggered()),
   172         // Show mainwindow
   169                 this,
   173         // Services will active it when the view is ready
   170                 SLOT(prepareForPopView()));
       
   171         
       
   172         // Show mainwindow.
       
   173         // Services will active it when the view is ready.
   174         if (!service) {
   174         if (!service) {
   175             mMainWindow->show();
   175             mMainWindow->show();
   176         }
   176         }
   177     }
   177     }
   178 
   178     
   179     // async operation completion related notifications
   179     // Asynchronous operation completion related notifications.
   180     connect(
   180     connect(mUiEngine,
   181         mUiEngine, SIGNAL(operationCompleted(const NmOperationCompletionEvent &)),
   181             SIGNAL(operationCompleted(const NmOperationCompletionEvent &)),
   182         this, SLOT(handleOperationCompleted(const NmOperationCompletionEvent &)));
   182             this,
   183 
   183             SLOT(handleOperationCompleted(const NmOperationCompletionEvent &)));
       
   184     
   184     mMbListModel = &mUiEngine->mailboxListModel();
   185     mMbListModel = &mUiEngine->mailboxListModel();
   185 
   186     
   186     // Start application to mailbox view
   187     // ----------------------------------------------------------------------
   187     // If started as service, there is no need to create views
   188     // TODO: Remove or comment out the following code block when the mail
       
   189     //       wizard starts to work with Mfe.
       
   190     // ----------------------------------------------------------------------
       
   191     // Start application to mailbox view. If started as service, there is no
       
   192     // need to create views.
   188     if (!service) {
   193     if (!service) {
   189         NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMailboxList);
   194         NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMailboxList);
   190         enterNmUiView(startParam);
   195         enterNmUiView(startParam);
   191     }
   196     }
   192 
   197     // ----------------------------------------------------------------------
   193     // Start to filter main window events to get "end key" event in all possible situations. Using
   198     
   194     // event() is not enough to catch the event as it is only called if the view widget has the
   199     if (mMainWindow) {
   195     // focus. Note: if key capturing (xqkeycapture.h) is required it is probably best to implement
   200         // Start to filter main window events to get "end key" event in all
   196     // an own QMainWindow class and do the capturing there, not in the views.
   201         // possible situations. Using event()is not enough to catch the event
   197     mMainWindow->installEventFilter(this);
   202         // as it is only called if the view widget has the focus. Note: if
   198 }
   203         // key capturing (xqkeycapture.h) is required it is probably best to
   199 
   204         // implement an own QMainWindow class and do the capturing there, not
   200 /*!
   205         // in the views.
   201     Slot. React to view ready signal and call
   206         mMainWindow->installEventFilter(this);
   202     current view method.
   207         // Optimize the custom paint functions.
       
   208         // Currently effects to NmViewerHeader::paint() and
       
   209         // NmAttachmentListWidget::paint().
       
   210         mMainWindow->setOptimizationFlag(QGraphicsView::DontSavePainterState);    
       
   211     }
       
   212 }
       
   213 
       
   214 /*!
       
   215     Slot. React to view ready signal and call current view method.
   203 */
   216 */
   204 void NmApplication::viewReady()
   217 void NmApplication::viewReady()
   205 {
   218 {
   206     NM_FUNCTION;
       
   207 
       
   208     mViewReady = true;
   219     mViewReady = true;
   209     if (!mViewStack->isEmpty()) {
   220     if (mViewStack && !mViewStack->isEmpty()) {
   210     	NmBaseView *currentView = mViewStack->top();
   221     	NmBaseView *currentView = mViewStack->top();
   211         if (currentView){
   222         if (currentView) {
   212             currentView->viewReady();
   223             currentView->viewReady();
   213         }
   224         }
   214     }
   225     }
   215 }
   226 }
   216 
   227 
   217 /*!
   228 /*!
   218     Event filter. End key is filtered from the main window and either the view takes case of the
   229     Event filter. End key is filtered from the main window and either the
   219 	or the app is exited by default.
   230     view takes case of the or the app is exited by default.
   220 */
   231 */
   221 bool NmApplication::eventFilter(QObject *obj, QEvent *event)
   232 bool NmApplication::eventFilter(QObject *obj, QEvent *event)
   222 {
   233 {
   223     NM_FUNCTION;
   234     bool consumed(false);
   224 
   235     
   225     bool consumed = false;
       
   226 
       
   227     if (obj && obj == mMainWindow && event && event->type() == QEvent::KeyPress) {
   236     if (obj && obj == mMainWindow && event && event->type() == QEvent::KeyPress) {
   228         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
   237         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
   229 
   238         if (keyEvent->key() == Qt::Key_No) {
   230         if (keyEvent->key() == Qt::Key_No) { // end key, the "red" key
   239             // End key, the "red" key.
   231 
   240             // Exit application if no pending operations are on-going.
   232             // exit application if no pending operations are on-going
   241         }
   233         }
   242     }
   234     }
   243     
   235 
       
   236     if (!consumed) {
   244     if (!consumed) {
   237         consumed = QObject::eventFilter(obj, event);
   245         consumed = QObject::eventFilter(obj, event);
   238     }
   246     }
   239 
   247     
   240     return consumed;
   248     return consumed;
   241 }
   249 }
   242 
   250 
   243 /*!
   251 /*!
   244     Push view to view stack
   252     Push view to view stack.
   245 */
   253 */
   246 void NmApplication::pushView(NmBaseView *newView)
   254 void NmApplication::pushView(NmBaseView *newView)
   247 {
   255 {
   248     NM_FUNCTION;
   256     if (newView && mViewStack) {
   249 
   257         NM_COMMENT("NmApplication::pushView() : view exists.");
   250     if (newView) {
       
   251         NM_COMMENT("nmailui: view exists");
       
   252         newView->setNavigationAction(mBackAction);
   258         newView->setNavigationAction(mBackAction);
   253 
   259         
   254         // Store view to be hidden
   260         // Store view to be hidden.
   255         NmBaseView *hideView(NULL);
   261         NmBaseView *hideView(NULL);
   256         if (!mViewStack->isEmpty()) {
   262         if (!mViewStack->isEmpty()) {
   257             hideView = mViewStack->top();
   263             hideView = mViewStack->top();
   258         }
   264         }
   259 		else {
   265 		else {
   260 			// viewReady should be informed immediatelly
   266 			// viewReady should be informed immediately.
   261 			if (mViewReady) {
   267 			if (mViewReady) {
   262 				newView->viewReady();
   268 				newView->viewReady();
   263 			}
   269 			}
   264 		}
   270 		}
   265 
   271         
   266         // activate new view
   272         // Activate new view.
   267     	NM_COMMENT("nmailui: addView");
   273     	NM_COMMENT("NmApplication::pushView() : add view.");
   268         mMainWindow->addView(newView);
   274         mMainWindow->addView(newView);
   269         mViewStack->push(newView);
   275         mViewStack->push(newView);
   270         mMainWindow->setCurrentView(newView);
   276         mMainWindow->setCurrentView(newView);
   271         mActiveViewId=newView->nmailViewId();
   277         mActiveViewId=newView->nmailViewId();
   272 
   278         
   273         // Set toolbars orientation
   279         // Set toolbars orientation.
   274         HbToolBar *tb = newView->toolBar();
   280         HbToolBar *tb = newView->toolBar();
   275         if(tb){
   281         if (tb) {
   276             tb->setOrientation(Qt::Horizontal);
   282             tb->setOrientation(Qt::Horizontal);
   277         }
   283         }
   278 
   284         
   279         // hide old view
   285         // Hide old view.
   280         NM_COMMENT("nmailui: removeView");
   286         NM_COMMENT("NmApplication::pushView() : remove view.");
   281         if (hideView){
   287         if (hideView) {
   282             mMainWindow->removeView(hideView);
   288             mMainWindow->removeView(hideView);
   283         }
   289         }
   284 
   290     }
   285         NM_COMMENT("nmailui: pushView done");
   291 }
   286     }
   292 
   287 }
   293 /*!
   288 
   294     Ask from view that is it ok to pop view. This kind of 2-phase popView is
   289 /*!
   295     needed because view may show query dialog for user response.
   290     Ask from view that is it ok to pop view. This kind of 2-phase popView is needed
       
   291     because view may show query dialog for user response.
       
   292  */
   296  */
   293 void NmApplication::prepareForPopView()
   297 void NmApplication::prepareForPopView()
   294 {
   298 {
   295     if (mViewStack->size() > 0) {
   299     if (mViewStack && mViewStack->size() > 0) {
   296         // Get view pointer
   300         // Get view pointer.
   297         NmBaseView *view = mViewStack->top();
   301         NmBaseView *view = mViewStack->top();
   298 
   302         if (view){
   299         // View will call/signal popView if exitting is ok.
   303 			NmUiViewId topViewId = view->nmailViewId();
   300         view->okToExitView();
   304 			
   301     }
   305 			// We must know in popView, are we coming with back button from
   302     // If the view stack is now empty quit the app
   306 			// message view to prevent the send animation.
   303     // This happens also when the app has been started as a service
   307 			if (topViewId == NmUiViewMessageEditor) {
   304     else if (mViewStack->size() == 0) {
   308 				mBackButtonPressed = true;
       
   309 			}
       
   310             
       
   311             // View will call/signal popView if exitting is ok.
       
   312             view->okToExitView();        
       
   313         }
       
   314     }
       
   315     // If the view stack is now empty quit the app. This happens also when
       
   316     // the app has been started as a service
       
   317     else if (mViewStack && mViewStack->size() == 0) {
   305         exitApplication();
   318         exitApplication();
   306     }
   319     }
   307 }
   320 }
   308 
   321 
   309 /*!
   322 /*!
   310     Pop view from view stack. View object is deleted.
   323     Pop view from view stack. View object is deleted.
   311 */
   324 */
   312 void NmApplication::popView()
   325 void NmApplication::popView()
   313 {
   326 {
   314     NM_FUNCTION;
   327     if (mViewStack && mViewStack->size() > 0) {
   315 
   328         NmBaseView *view = mViewStack->top();    
   316     if (mViewStack->size() > 0) {
   329         if (view) {
   317         // Get view pointer
   330             // Get top view id.
   318         NmBaseView *view = mViewStack->top();
   331             NmUiViewId topViewId = view->nmailViewId();
   319 
   332             
   320         // ask view if it's ok to exit
   333             // Prepare for send animation if returing from editor and message
   321         NmUiViewId topViewId = view->nmailViewId();
   334             // has been sent.
   322 
   335             if (topViewId == NmUiViewMessageEditor && mUiEngine->isSendingMessage()) {
   323         // Prepare for send animation if returing from editor and message has been sent.
   336 				// If we are coming from message editor with back button.
   324         if (topViewId == NmUiViewMessageEditor && mUiEngine->isSendingMessage()) {
   337 				// do not prepare the send animation.
   325             mEffects->prepareEffect(NmUiEffects::NmEditorSendMessageAnimation);
   338 				if (!mBackButtonPressed) {
   326         }
   339 					mEffects->prepareEffect(NmUiEffects::NmEditorSendMessageAnimation);
   327         mViewStack->pop();
   340 				}
   328         // Call custom exit function
   341 	        }
   329         view->aboutToExitView();
   342             mBackButtonPressed = false;
   330         // Remove view from stack.
   343             mViewStack->pop();
   331         mMainWindow->removeView(view);
   344             // Call custom exit function.
   332 
   345             view->aboutToExitView();
   333         // if we were in editor and sent a message, pop viewer from stack first
   346             // Remove view from stack.
   334         // so we can go straight to mail list
   347             mMainWindow->removeView(view);
   335         if (!mViewStack->isEmpty() && topViewId == NmUiViewMessageEditor &&
   348             
   336             mUiEngine->isSendingMessage() &&
   349             // If we were in editor and sent a message, pop viewer from stack
   337             mViewStack->top()->nmailViewId() == NmUiViewMessageViewer) {
   350             // first so we can go straight to mail list.
   338             NmBaseView *tmpView = mViewStack->pop();
   351             if (!mViewStack->isEmpty() && topViewId == NmUiViewMessageEditor &&
   339             mMainWindow->removeView(tmpView);
   352                 mUiEngine->isSendingMessage() &&
   340             delete tmpView;
   353                 mViewStack->top()->nmailViewId() == NmUiViewMessageViewer) {
   341             tmpView = NULL;
   354                 NmBaseView *tmpView = mViewStack->pop();
   342         }
   355                 mMainWindow->removeView(tmpView);
   343 
   356                 delete tmpView;
   344         if (!mViewStack->isEmpty()) {
   357                 tmpView = NULL;
   345             // Activate next view in stack
   358             }
   346             NmBaseView *showView = mViewStack->top();
   359             
   347             mMainWindow->addView(showView);
   360             if (!mViewStack->isEmpty()) {
   348             mMainWindow->setCurrentView(showView);
   361                 // Activate next view in stack.
   349             // Store activated view id
   362                 NmBaseView *showView = mViewStack->top();
   350             mActiveViewId=showView->nmailViewId();
   363                 mMainWindow->addView(showView);
   351             // Perform send animation if requested.
   364                 mMainWindow->setCurrentView(showView);
   352             mEffects->startEffect(NmUiEffects::NmEditorSendMessageAnimation);
   365                 // Store activated view id.
   353         }
   366                 mActiveViewId=showView->nmailViewId();
   354 
   367                 // Perform send animation if requested.
   355         delete view;
   368                 mEffects->startEffect(NmUiEffects::NmEditorSendMessageAnimation);
   356         view = NULL;
   369             }
   357 
   370             
   358 #ifndef NM_WINS_ENV
   371             delete view;
   359         // If view was started as service, move the app now
   372             view = NULL;
   360         // to the background, unless it was started when the app
   373             
   361         // was already in foreground..
   374             // If view was started as service, move the app now to the
   362         if (mServiceViewId == topViewId) {
   375             // background, unless it was started when the app was already in
   363             mServiceViewId = NmUiViewNone;
   376             // foreground.
   364             NM_COMMENT("Returned from service view");
   377             if (mServiceViewId == topViewId) {
   365 
   378                 mServiceViewId = NmUiViewNone;
   366             // if started as embedded or while the app was in foreground,
   379                 NM_COMMENT("NmApplication::popView() : returned from service view.");
   367             // do not hide the app
   380                 // If started as embedded or while the app was in foreground,
   368             if (!XQServiceUtil::isEmbedded() &&
   381                 // do not hide the app.
   369                 !mForegroundService) {
   382                 if (!XQServiceUtil::isEmbedded() &&
   370                 XQServiceUtil::toBackground(true);
   383                     !mForegroundService) {
   371             }
   384                     XQServiceUtil::toBackground(true);
   372         }
   385                 }
   373 #endif
   386             }
   374     }
   387         }
   375 
   388     }
   376     // If the view stack is now empty quit the app
   389     
   377     // This happens also when the app has been started as a service
   390     // If the view stack is now empty quit the app. This happens also when
   378     if (mViewStack->size()==0) {
   391     // the app has been started as a service.
       
   392     if (mViewStack && mViewStack->size() == 0) {
   379         exitApplication();
   393         exitApplication();
   380     }
   394     }
   381 }
   395 }
   382 
   396 
   383 /*!
   397 /*!
   384     Reset view stack. Remove and destroy view objects.
   398     Reset view stack. Remove and destroy view objects.
   385 */
   399 */
   386 void NmApplication::resetViewStack()
   400 void NmApplication::resetViewStack()
   387 {
   401 {
   388     NM_FUNCTION;
       
   389 
       
   390     if (mViewStack && !mViewStack->isEmpty()) {
   402     if (mViewStack && !mViewStack->isEmpty()) {
   391 	    int viewCount = mViewStack->count();
   403 	    int viewCount = mViewStack->count();
   392         // Pop and destroy all views
   404         // Pop and destroy all views
   393 	    for (int i=0;i<viewCount;i++) {
   405 	    for (int i=0 ; i < viewCount ; i++) {
   394 		    NmBaseView *view = mViewStack->pop();
   406 		    NmBaseView *view = mViewStack->pop();
   395             mMainWindow->removeView(view);
   407             mMainWindow->removeView(view);
   396             delete view;
   408             delete view;
   397         }
   409         }
   398 	    mActiveViewId=NmUiViewNone;
   410 	    mActiveViewId = NmUiViewNone;
   399     }
   411     }
   400 }
   412 }
   401 
   413 
   402 /*!
   414 /*!
   403     Function activates view based on viewId parameter.
   415     Function activates view based on viewId parameter. If requested view is
   404     If requested view is already open, it is requested to reload.
   416     already open, it is requested to reload. Otherwise view object is created
   405     Otherwise view object is created and pushed to view stack
   417     and pushed to view stack.
   406 */
   418 */
   407 void NmApplication::enterNmUiView(NmUiStartParam* startParam)
   419 void NmApplication::enterNmUiView(NmUiStartParam *startParam)
   408 {
   420 {
   409     NM_FUNCTION;
   421     NM_FUNCTION;
   410 
   422     
   411     // Check the validity of start parameter object
   423     // Check the validity of start parameter object.
   412     if (startParam) {
   424     if (startParam) {
   413 
   425         
   414         if (startParam->service() && mMainWindow) {
   426         if (startParam->service() && mMainWindow) {
   415 			// When the message list is started as a service previous views are removed
   427 			// When the message list is started as a service previous views
   416 			// from the stack. Open editors are not closed.
   428             // are removed from the stack. Open editors are not closed. Also
   417 			// Also if the view is same than the new one, keep it open (reload the content).
   429             // if the view is same than the new one, keep it open (reload the
   418 
   430             // content).
   419 
   431             
   420 		    // reset the foreground service flag while popping the views
   432 		    // Reset the foreground service flag while popping the views.
   421 		    bool previousForegroundService = mForegroundService;
   433 		    bool previousForegroundService = mForegroundService;
   422 		    mForegroundService = true;
   434 		    mForegroundService = true;
   423 
   435 		    
   424 		    // at least one view must remain in the stack
   436 		    // At least one view must remain in the stack.
   425 			while (mViewStack->count()>1) {
   437 			while (mViewStack->count( )> 1) {
   426 			    NmUiViewId topId = mViewStack->top()->nmailViewId();
   438 			    NmUiViewId topId = mViewStack->top()->nmailViewId();
   427 			    if (topId!=NmUiViewMessageEditor &&
   439 			    if (topId != NmUiViewMessageEditor &&
   428 			        topId!=NmUiViewMailboxList &&
   440 			        topId != NmUiViewMailboxList &&
   429 			        topId!=startParam->viewId()) {
   441 			        topId != startParam->viewId()) {
   430 			        prepareForPopView();
   442 			        prepareForPopView();
   431 			    }
   443 			    }
   432 			    else {
   444 			    else {
   433 			        // Editor or mailbox list in the top. Stop the loop.
   445 			        // Editor or mailbox list in the top. Stop the loop.
   434 			        break;
   446 			        break;
   435 			    }
   447 			    }
   436 			}
   448 			}
   437 			mForegroundService = previousForegroundService;
   449 			mForegroundService = previousForegroundService;
   438         }
   450         }
   439 
   451         
   440         // Check whether requested view is already active
   452         // Check whether requested view is already active and if so, ask it
   441         // and if so, ask it to reload contents with new start parameter data
   453         // to reload contents with new start parameter data. Do not reuse the
   442         // Do not reuse the view if started as service to editor view (ShareUI)
   454         // view if started as service to editor view (ShareUI).
   443         if (mActiveViewId==startParam->viewId() &&
   455         if (mActiveViewId == startParam->viewId() &&
   444         	(!startParam->service() || mActiveViewId!=NmUiViewMessageEditor)) {
   456         	(!startParam->service() || mActiveViewId!=NmUiViewMessageEditor)) {
   445             mViewStack->top()->reloadViewContents(startParam);
   457             mViewStack->top()->reloadViewContents(startParam);
   446         }
   458         }
   447         else {
   459         else {
   448             switch (startParam->viewId()) {
   460             switch (startParam->viewId()) {
   455                 }
   467                 }
   456                 break;
   468                 break;
   457                 case NmUiViewMessageList:
   469                 case NmUiViewMessageList:
   458                 {
   470                 {
   459                     // Check the topmost view. If it is an editor, do not open
   471                     // Check the topmost view. If it is an editor, do not open
   460                     // a new mail list view
   472                     // a new mail list view.
   461                     if (startParam->service() && !mViewStack->isEmpty() &&
   473                     if (startParam->service() && !mViewStack->isEmpty() &&
   462                         mViewStack->top()->nmailViewId()==NmUiViewMessageEditor) {
   474                         mViewStack->top()->nmailViewId()==NmUiViewMessageEditor) {
   463                         break;
   475                         break;
   464                     }
   476                     }
   465                     NmMessageListModel *messageListModel = &mUiEngine->messageListModel(
   477                     NmMessageListModel *messageListModel = &mUiEngine->messageListModel(
   476                     // a new mail search list view.
   488                     // a new mail search list view.
   477                     if (startParam->service() && !mViewStack->isEmpty() &&
   489                     if (startParam->service() && !mViewStack->isEmpty() &&
   478                         mViewStack->top()->nmailViewId() == NmUiViewMessageEditor) {
   490                         mViewStack->top()->nmailViewId() == NmUiViewMessageEditor) {
   479                         break;
   491                         break;
   480                     }
   492                     }
   481 
   493                     
   482                     NmMessageListModel &model =
   494                     NmMessageListModel &model =
   483                         mUiEngine->messageListModelForSearch(startParam->mailboxId());
   495                         mUiEngine->messageListModelForSearch(startParam->mailboxId());
   484 
   496                     
   485                     NmMessageSearchListView *searchListView = new NmMessageSearchListView(
   497                     NmMessageSearchListView *searchListView = new NmMessageSearchListView(
   486                         *this, startParam, *mUiEngine, model,
   498                         *this, startParam, *mUiEngine, model,
   487                         new HbDocumentLoader(mMainWindow));
   499                         new HbDocumentLoader(mMainWindow));
   488 
   500                     
   489                     pushView(searchListView);
   501                     pushView(searchListView);
   490                 }
   502                 }
   491                 break;
   503                 break;
   492                 case NmUiViewMessageViewer:
   504                 case NmUiViewMessageViewer:
   493                     pushView(new NmViewerView(*this, startParam, *mUiEngine,
   505                     pushView(new NmViewerView(*this, startParam, *mUiEngine,
   495                     break;
   507                     break;
   496                 case NmUiViewMessageEditor:
   508                 case NmUiViewMessageEditor:
   497                     pushView(new NmEditorView(*this, startParam, *mUiEngine, *mAttaManager));
   509                     pushView(new NmEditorView(*this, startParam, *mUiEngine, *mAttaManager));
   498                     break;
   510                     break;
   499                 default:
   511                 default:
   500                     // Reset view stack and exit application
   512                     // Reset view stack and exit application.
   501                     delete startParam;
   513                     delete startParam;
   502                     startParam=NULL;
   514                     startParam = NULL;
   503                     resetViewStack();
   515                     resetViewStack();
   504                     break;
   516                     break;
   505             }
   517             }
   506         }
   518         }
   507 
   519         
   508         if (startParam && startParam->service()) {
   520         if (startParam && startParam->service()) {
   509             // Store the view id that was launched as service
   521             // Store the view id that was launched as service.
   510             mServiceViewId = mActiveViewId;
   522             mServiceViewId = mActiveViewId;
   511 		}
   523 		}
   512     }
   524     }
   513 }
   525 }
   514 
   526 
   515 /*!
   527 /*!
   516     Function can be used from views to exit the application
   528     Function can be used from views to exit the application. View stack is
   517     View stack is cleared. Views can connect exit menu
   529     cleared. Views can connect exit menu selection to this slot.
   518     selection to this slot.
       
   519 */
   530 */
   520 void NmApplication::exitApplication()
   531 void NmApplication::exitApplication()
   521 {
   532 {
   522     NM_FUNCTION;
   533     NM_FUNCTION;
   523 
   534     
   524 #ifndef NM_WINS_ENV
       
   525     delete mSendServiceInterface;
   535     delete mSendServiceInterface;
   526     mSendServiceInterface = NULL;
   536     mSendServiceInterface = NULL;
   527     delete mSendServiceInterface2;
   537     delete mSendServiceInterface2;
   528     mSendServiceInterface2 = NULL;
   538     mSendServiceInterface2 = NULL;
   529     delete mUriServiceInterface;
   539     delete mUriServiceInterface;
   530     mUriServiceInterface = NULL;
   540     mUriServiceInterface = NULL;
   531     delete mMailboxServiceInterface;
   541     delete mMailboxServiceInterface;
   532     mMailboxServiceInterface = NULL;
   542     mMailboxServiceInterface = NULL;
   533     delete mViewerServiceInterface;
   543     delete mViewerServiceInterface;
   534     mViewerServiceInterface = NULL;
   544     mViewerServiceInterface = NULL;
   535 #endif
       
   536     resetViewStack();
   545     resetViewStack();
   537     // Do housekeeping if needed.
       
   538     qApp->quit();
   546     qApp->quit();
   539 }
   547 }
   540 
   548 
   541 /*!
   549 /*!
   542    Exit the application in the next event loop
   550    Exit the application in the next event loop.
   543 */
   551 */
   544 void NmApplication::delayedExitApplication()
   552 void NmApplication::delayedExitApplication()
   545 {
   553 {
   546     NM_FUNCTION;
   554     // Exit the application in the next event loop.
   547 
   555     QMetaObject::invokeMethod(this, "exitApplication", Qt::QueuedConnection);
   548     // Exit the application in the next event loop
       
   549     QTimer::singleShot(0, this, SLOT(exitApplication()));
       
   550 }
   556 }
   551 
   557 
   552 /*!
   558 /*!
   553     Getter for main window instance.
   559     Getter for main window instance.
   554 */
   560 */
   555 HbMainWindow* NmApplication::mainWindow()
   561 HbMainWindow *NmApplication::mainWindow()
   556 {
   562 {
   557     NM_FUNCTION;
       
   558 
       
   559     return mMainWindow;
   563     return mMainWindow;
   560 }
   564 }
   561 
   565 
   562 /*!
   566 /*!
   563     Getter for main UI extension manager
   567     Getter for main UI extension manager.
   564 */
   568 */
   565 NmUiExtensionManager& NmApplication::extManager()
   569 NmUiExtensionManager &NmApplication::extManager()
   566 {
   570 {
   567     NM_FUNCTION;
       
   568 
       
   569     return *mExtensionManager;
   571     return *mExtensionManager;
   570 }
   572 }
   571 
   573 
   572 /*!
   574 /*!
   573     Getter for network access manager
   575     Getter for network access manager.
   574 */
   576 */
   575 NmViewerViewNetManager& NmApplication::networkAccessManager()
   577 NmViewerViewNetManager &NmApplication::networkAccessManager()
   576 {
   578 {
   577     NM_FUNCTION;
       
   578 
       
   579     return *mNetManager;
   579     return *mNetManager;
   580 }
   580 }
   581 
   581 
   582 /*!
   582 /*!
   583     screen size. Function returns curtent screen size
   583     Get the screen size. Function returns curtent screen size.
   584 */
   584 */
   585 QSize NmApplication::screenSize()
   585 QSize NmApplication::screenSize()
   586 {
   586 {
   587     NM_FUNCTION;
       
   588 
       
   589     QSize ret(0,0);
   587     QSize ret(0,0);
   590     if (mMainWindow){
   588     if (mMainWindow){
   591         HbDeviceProfile currentP = HbDeviceProfile::current();
   589         HbDeviceProfile currentP = HbDeviceProfile::current();
   592         HbDeviceProfile altP(currentP.alternateProfileName());
   590         HbDeviceProfile altP(currentP.alternateProfileName());
   593         QSize curPSize = currentP.logicalSize();
   591         QSize curPSize = currentP.logicalSize();
   594         QSize altPSize = altP.logicalSize();
   592         QSize altPSize = altP.logicalSize();
   595         if (mMainWindow->orientation()==Qt::Horizontal){
   593         if (mMainWindow->orientation() == Qt::Horizontal) {
   596             // Get wide profile size in landscape
   594             // Get wide profile size in landscape.
   597             if (curPSize.width()>altPSize.width()){
   595             if (curPSize.width() > altPSize.width()) {
   598                 ret = curPSize;
   596                 ret = curPSize;
   599             }
   597             }
   600             else{
   598             else{
   601                 ret = altPSize;
   599                 ret = altPSize;
   602             }
   600             }
   603         }
   601         }
   604         else {
   602         else {
   605             // Get narrow profile size in portrait
   603             // Get narrow profile size in portrait.
   606             if (curPSize.width()<altPSize.width()){
   604             if (curPSize.width() < altPSize.width()) {
   607                 ret = curPSize;
   605                 ret = curPSize;
   608             }
   606             }
   609             else{
   607             else{
   610                 ret = altPSize;
   608                 ret = altPSize;
   611             }
   609             }
   613     }
   611     }
   614     return ret;
   612     return ret;
   615 }
   613 }
   616 
   614 
   617 /*!
   615 /*!
   618     handles all asynchronous operation's completions at UI level
   616     Handles all asynchronous operation's completions at UI level.
   619 */
   617 */
   620 void NmApplication::handleOperationCompleted(const NmOperationCompletionEvent &event)
   618 void NmApplication::handleOperationCompleted(const NmOperationCompletionEvent &event)
   621 {
   619 {
   622     NM_FUNCTION;
   620     if (event.mCompletionCode != NmNoError && event.mCompletionCode != NmCancelError) {
   623 
   621         if (event.mOperationType == Synch && event.mCompletionCode == NmAuthenticationError) {
   624     if(event.mCompletionCode != NmNoError && event.mCompletionCode != NmCancelError) {
   622             mLastOperationMailbox = event.mMailboxId;
   625         if(event.mOperationType == Synch && event.mCompletionCode == NmAuthenticationError) {
   623             if (mQueryDialog) {
   626             mLastOperationMailbox=event.mMailboxId;
       
   627             if (mQueryDialog){
       
   628                 delete mQueryDialog;
   624                 delete mQueryDialog;
   629                 mQueryDialog=NULL;
   625                 mQueryDialog = NULL;
   630             }
   626             }
   631             mQueryDialog = NmUtilities::displayQuestionNote(hbTrId("txt_mail_dialog_address_or_password_incorrect"),
   627             mQueryDialog = NmUtilities::displayQuestionNote(hbTrId("txt_mail_dialog_address_or_password_incorrect"),
   632                                                     this, SLOT(launchSettings(HbAction*)));
   628                                                     this, SLOT(launchSettings(HbAction*)));
   633         }
   629         }
   634         if(event.mOperationType == Synch && event.mCompletionCode == NmServerConnectionError) {
   630         if (event.mOperationType == Synch && event.mCompletionCode == NmServerConnectionError) {
   635             mLastOperationMailbox=event.mMailboxId;
   631             mLastOperationMailbox=event.mMailboxId;
   636             if (mQueryDialog){
   632             if (mQueryDialog) {
   637                 delete mQueryDialog;
   633                 delete mQueryDialog;
   638                 mQueryDialog=NULL;
   634                 mQueryDialog = NULL;
   639             }
   635             }
   640             mQueryDialog = NmUtilities::displayQuestionNote(hbTrId("txt_mail_dialog_server_settings_incorrect"),
   636             mQueryDialog = NmUtilities::displayQuestionNote(hbTrId("txt_mail_dialog_server_settings_incorrect"),
   641                                                     this, SLOT(launchSettings(HbAction*)));
   637                                                     this, SLOT(launchSettings(HbAction*)));
   642         }
   638         }
   643         // following applies to all operation/event types
   639         // Following applies to all operation/event types.
   644         if(event.mCompletionCode == NmConnectionError) {
   640         if (event.mCompletionCode == NmConnectionError) {
   645             NmUtilities::displayWarningNote(hbTrId("txt_mail_dialog_mail_connection_error"));
   641             NmUtilities::displayWarningNote(hbTrId("txt_mail_dialog_mail_connection_error"));
   646         }
   642         }
   647     }
   643     }
   648 }
   644 }
   649 
   645 
   650 /*!
   646 /*!
   651     launches settings view of the specified mailbox
   647     Launches settings view of the specified mailbox.
   652 */
   648 */
   653 void NmApplication::launchSettings(HbAction* action)
   649 void NmApplication::launchSettings(HbAction* action)
   654 {
   650 {
   655     NM_FUNCTION;
   651     // Check whether yes button was pressed.
   656 
       
   657     // Check whether yes button was pressed
       
   658     if (mQueryDialog&& action == mQueryDialog->actions().at(0)) {
   652     if (mQueryDialog&& action == mQueryDialog->actions().at(0)) {
   659         // create settingslauncher if doesn't exist
   653         // Create settingslauncher if doesn't exist.
   660         if(!mSettingsViewLauncher) {
   654         if(!mSettingsViewLauncher) {
   661             mSettingsViewLauncher = new NmSettingsViewLauncher();
   655             mSettingsViewLauncher = new NmSettingsViewLauncher();
   662             }
   656             }
   663 
   657         // Mailboxname required.
   664         if(mSettingsViewLauncher) {
   658         NmMailboxMetaData *mailboxMetaData = mUiEngine->mailboxById(mLastOperationMailbox); // No ownership.
   665             // mailboxname required
   659         if( mailboxMetaData ) {
   666             NmMailboxMetaData *mailboxMetaData = mUiEngine->mailboxById(mLastOperationMailbox); // no ownership
   660             // Launch.
   667             if( mailboxMetaData ) {
   661             mSettingsViewLauncher->launchSettingsView(mLastOperationMailbox, mailboxMetaData->name());
   668                 // launch
       
   669                 mSettingsViewLauncher->launchSettingsView(mLastOperationMailbox, mailboxMetaData->name());
       
   670             }
       
   671         }
   662         }
   672     }
   663     }
   673 }
   664 }
   674 
   665 
   675 /*!
   666 /*!
   676 	Stores the visibility state, e.g. when the service was launched.
   667 	Stores the visibility state, e.g. when the service was launched.
   677 	\return true if the app was visible
   668 	\return true if the app was visible.
   678 */
   669 */
   679 bool NmApplication::updateVisibilityState()
   670 bool NmApplication::updateVisibilityState()
   680 {
   671 {
   681     // At the moment there is no good way to check the foreground state
   672     // At the moment there is no good way to check the foreground state.
   682     QWindowSurface *surface = mMainWindow->windowSurface();
   673     QWindowSurface *surface = mMainWindow->windowSurface();
   683 	mForegroundService = (surface != NULL);
   674 	mForegroundService = (surface != 0);
   684 	NM_COMMENT(QString("NmApplication::updateVisibilityState fg=%1").arg(mForegroundService));
   675 	NM_COMMENT(QString("NmApplication::updateVisibilityState() : mForegroundService == %1").arg(mForegroundService));
   685 	return mForegroundService;
   676 	return mForegroundService;
   686 }
   677 }