emailuis/nmailuiengine/src/nmoperation.cpp
branchRCL_3
changeset 63 d189ee25cf9d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/nmailuiengine/src/nmoperation.cpp	Tue Aug 31 15:04:17 2010 +0300
@@ -0,0 +1,205 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "nmuiengineheaders.h"
+
+/*!
+    \brief Constructor
+    Constructor of NmOperation
+ */
+NmOperation::NmOperation()
+: mProgress(0),
+  mIsRunning(true)
+{
+    NM_FUNCTION;
+    
+    QMetaObject::invokeMethod(this, "runAsyncOperation", Qt::QueuedConnection);
+}
+
+/*!
+    \brief Destructor
+ */
+NmOperation::~NmOperation()
+{
+    NM_FUNCTION;
+    
+    while (!mPreliminaryOperations.isEmpty()) {
+        QPointer<NmOperation> operation = mPreliminaryOperations.takeLast();
+        if (operation && operation->isRunning()) {
+            operation->cancelOperation();
+        }
+    }
+}
+
+/*!
+    \brief Tells whether the operation is running or not
+ */
+bool NmOperation::isRunning() const
+{
+    NM_FUNCTION;
+    
+    return mIsRunning;
+}
+
+/*!
+    \brief Adds a "preliminary operation" which needs to end until this operation can start.
+ */
+void NmOperation::addPreliminaryOperation(NmOperation *operation)
+{
+    NM_FUNCTION;
+    
+    // if the preliminary operation is already completed
+    // the input parameter can be null
+    if (operation && operation->isRunning()) {
+        connect(operation, SIGNAL(operationCompleted()), this,
+            SLOT(handlePreliminaryOperationFinished()));
+    
+        connect(operation, SIGNAL(operationCancelled()), this,
+            SLOT(handlePreliminaryOperationFinished()));
+    
+        mPreliminaryOperations.append(operation);
+    }
+}
+
+/*!
+    \brief Slot, complete
+    The performer of the asynchronous function call should use this slot when
+    the operation is completed, this will emit the actionCompleted signal * 
+    \param result Result from operation
+ */
+void NmOperation::completeOperation(int result)
+{
+    NM_FUNCTION;
+    
+    mIsRunning = false;
+    // Operation is completed, emit the signal
+    doCompleteOperation();
+    emit this->operationCompleted(result);
+    QMetaObject::invokeMethod(this, "deleteOperation", Qt::QueuedConnection);
+}
+
+/*!
+    \brief Slot, cancel
+    The observer of the asynchronous function call should use this slot if it
+    wants to cancel the ongoing operation, it will emit the actionCancelled signal
+ */
+void NmOperation::cancelOperation()
+{
+    NM_FUNCTION;
+    
+    mIsRunning = false;
+    // Operation is canceled, emit the signal
+    this->doCancelOperation();
+    emit this->operationCancelled();
+    QMetaObject::invokeMethod(this, "deleteOperation", Qt::QueuedConnection);
+}
+/*!
+    \brief Slot, update progress
+    The performer of the asynchronous function call should use this slot when
+    updating the operation progress, this will emit the progressChanged signal
+ */
+void NmOperation::updateOperationProgress(int progress)
+{
+    NM_FUNCTION;
+    
+    mProgress = progress;
+    this->doUpdateOperationProgress();
+    emit this->operationProgressChanged(mProgress);
+}
+
+/*!
+    \brief Slot, run the operation if no preliminary operations are running.
+    Calls the pure virtual doRunAsyncOperation() of the derived class if there are no preliminary
+    operations running. Operation will be deleted after it has compeleted or cancelled and the control
+    returns to the event loop.
+ */
+void NmOperation::runAsyncOperation()
+{
+    NM_FUNCTION;
+    
+    int count = mPreliminaryOperations.count();
+    int ready = 0;
+    // go through preliminary operations
+    for (int i = 0; i < count; ++i) {
+        if (!mPreliminaryOperations[i] || !mPreliminaryOperations[i]->isRunning()) {
+            ready++;
+        }
+    }
+    // when all preliminary operations are either completed or cancelled
+    // start this one
+    if (count == ready) {
+        this->doRunAsyncOperation();
+    }
+}
+
+/*!
+    \brief Slot, update progress
+    This is signalled by a preliminary operation when its operation is completed or cancelled. 
+    Do not call runAsyncOperation immediately but let the signal be handled by other slots first. 
+ */
+void NmOperation::handlePreliminaryOperationFinished()
+{
+    NM_FUNCTION;
+    
+    QMetaObject::invokeMethod(this, "runAsyncOperation", Qt::QueuedConnection);
+}
+
+/*!
+    \brief Virtual function to be implemented by subclasses
+    This function is called from the completeAction before the signal is
+    emitted. Derived class can override this is some special actions
+    are needed.
+ */ 
+void NmOperation::doCompleteOperation()
+{
+    NM_FUNCTION;
+}
+
+/*!
+    \brief Virtual function to be implemented by subclasses
+    This function is called from the cancelAction after the trigger timer
+    and before the signal is emitted. Derived class can override this
+    and put its own cancellation operations here.
+ */
+void NmOperation::doCancelOperation()
+{
+    NM_FUNCTION;
+}
+
+/*!
+    \brief Virtual function to be implemented by subclasses
+    This function is called from the updateProgress after the progress
+    value has been updated and before the signal is emitted. Derived class
+    can override this.
+ */
+void NmOperation::doUpdateOperationProgress()
+{
+    NM_FUNCTION;
+}
+
+/*!
+    \brief Private slot for operation deleting
+    This is signalled when operation is completed or cancelled. 
+    Delete happens when the control returns to the event loop.
+ */
+void NmOperation::deleteOperation()
+{
+    NM_FUNCTION;
+    
+    this->deleteLater();   
+}
+