--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/viewframework/uiutilities/src/glxattributeretriever.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,711 @@
+/*
+* Copyright (c) 2008-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: Blocking attribute retriever
+*
+*/
+
+
+
+
+#include "glxattributeretriever.h"
+
+#include <AknWaitDialog.h>
+#include <avkon.rsg>
+#include <eikenv.h>
+#include <AknUtils.h>
+#include <bautils.h>
+#include <data_caging_path_literals.hrh>
+#include <StringLoader.h>
+
+#include <mpxattributespecs.h>
+#include <mpxcollectionpath.h>
+
+#include <glxlog.h>
+#include <glxmedialist.h>
+#include <glxpanic.h>
+#include <glxuistd.h>
+#include <glxuiutilities.rsg>
+#include <mglxfetchcontext.h>
+#include <mglxmedialistobserver.h>
+#include <glxresourceutilities.h>
+
+
+
+/**
+ * Observer that should be implemented by users of the
+ * CGlxAttributeRetriever class to inform them when attribute retrieval is complete
+ */
+class MGlxAttributeRetrieverObserver
+ {
+public:
+ /**
+ * Called when attribute retrieval is complete
+ * @param aError symbian os error code.
+ */
+ virtual void AttributeRetrievalCompleteL(TInt aError) = 0;
+ };
+
+/**
+ * CGlxAttributeRetriever
+ * This class informs the MGlxAttributeRetrieverObserver when all
+ * requested metadata has been retrived.
+ * @ingroup mlm_media_list_manager_design
+ * @lib glxuiutlities.lib
+ */
+NONSHARABLE_CLASS( CGlxAttributeRetriever )
+ : public CActive, public MGlxMediaListObserver
+ {
+public:
+ /**
+ * Constructor
+ * @param aObserver observer to be informed when attribute retrieval is complete
+ */
+ CGlxAttributeRetriever(MGlxAttributeRetrieverObserver& aObserver);
+
+ /**
+ * Destructor
+ */
+ ~CGlxAttributeRetriever();
+
+ /**
+ * Retrieve the attrubutes
+ * @param aContext the fetch context containing the attribute to be retrieved
+ * @param aList the medialist containing the item for which the attributes are retrieved
+ * @return Error code
+ */
+ void RetrieveL(const MGlxFetchContext* aContext, MGlxMediaList* aList);
+
+ void CancelRetrieve();
+
+private: // from CActive
+ void RunL();
+ void DoCancel();
+
+public: // From MGlxMediaListObserver
+ void HandleAttributesAvailableL(TInt aItemIndex, const RArray<TMPXAttribute>& aAttributes, MGlxMediaList* aList);
+ void HandleItemAddedL(TInt aStartIndex, TInt aEndIndex, MGlxMediaList* aList);
+ void HandleItemRemovedL(TInt aStartIndex, TInt aEndIndex, MGlxMediaList* aList);
+ void HandleItemModifiedL(const RArray<TInt>& aItemIndexes, MGlxMediaList* aList);
+ void HandleFocusChangedL(NGlxListDefs::TFocusChangeType aType, TInt aNewIndex, TInt aOldIndex, MGlxMediaList* aList);
+ void HandleMediaL(TInt aListIndex, MGlxMediaList* aList);
+ void HandleItemSelectedL(TInt aIndex, TBool aSelected, MGlxMediaList* aList);
+ void HandleMessageL(const CMPXMessage& aMessage, MGlxMediaList* aList);
+ void HandlePopulatedL(MGlxMediaList* aList);
+ void HandleError(TInt aError);
+
+private:
+ /**
+ * Asynchronously notifies the observer is attribute retrieval is complete
+ */
+ void NotifyObserverIfCompleteL();
+
+ /**
+ * Completes the active object causing a call from the
+ * active scheduler to RunL()
+ * @param aError error code passed to RunL()
+ * (test in RunL using iStatus.Int())
+ */
+ void CompleteSelf(TInt aError);
+
+private:
+ /// pointer to a Fetch Context associated with the desired attribute. Not owned
+ const MGlxFetchContext* iContext;
+
+ /// pointer to the Media List. Not owned
+ MGlxMediaList* iList;
+
+ /**
+ * observer
+ */
+ MGlxAttributeRetrieverObserver& iObserver;
+
+ /**
+ * Internal cache of objects still to retrieve
+ */
+ TInt iRequestCount;
+ };
+
+/**
+ * Abstract interface for a blocking attribute retriever
+ */
+class MGlxBlockingAttributeRetriever
+ {
+public:
+ /**
+ * Retrieve the attrubutes (call blocks until attribute retrieval is complete)
+ * @param aContext the fetch context containing the attribute to be retrieved
+ * @param aList the medialist containing the item for which the attributes are retrieved
+ * @return Error code
+ */
+ virtual TInt RetrieveL(const MGlxFetchContext* aContext, MGlxMediaList* aList) = 0;
+ virtual ~MGlxBlockingAttributeRetriever() {};
+ };
+
+/**
+ * This class displays a wait dialog and blocks until all requested metadata has been retrieved.
+ */
+class CGlxWaitDialogAttributeRetriever : public CBase,
+ public MProgressDialogCallback,
+ public MGlxBlockingAttributeRetriever,
+ public MGlxAttributeRetrieverObserver
+ {
+public:
+ static CGlxWaitDialogAttributeRetriever* NewLC();
+
+public: // from MGlxBlockingAttributeRetriever
+ /**
+ * See @ref MGlxBlockingAttributeRetriever::RetrieveL
+ */
+ TInt RetrieveL(const MGlxFetchContext* aContext, MGlxMediaList* aList);
+
+private: // from MGlxAttributeRetrieverObserver
+ /**
+ * See @ref MGlxAttributeRetrieverObserver::AttributeRetrievalCompleteL
+ */
+ void AttributeRetrievalCompleteL(TInt aError);
+
+public: // From MProgressDialogCallback
+ void DialogDismissedL(TInt aButtonId);
+
+private:
+ /**
+ * Constructor
+ */
+ CGlxWaitDialogAttributeRetriever();
+
+ /**
+ * Destructor
+ */
+ ~CGlxWaitDialogAttributeRetriever();
+
+ /**
+ * Second stage constructor
+ */
+ void ConstructL();
+
+private:
+ /**
+ * Loads the resource file for this dll
+ */
+ void AddResourceFileL();
+
+ /**
+ * Unloads the resource file for this dll
+ */
+ void RemoveResourceFile();
+
+private:
+ /// App environment used for accessing resource file (not owned)
+ CCoeEnv* iCoeEnv;
+
+ /// Wait dialog
+ CAknWaitDialog* iWaitDialog;
+
+ /// Resource file offset
+ TInt iResourceOffset;
+
+ /**
+ * Attribute retriever (owned)
+ */
+ CGlxAttributeRetriever* iAttributeRetriever;
+
+ /**
+ * Attribute retrieval error
+ */
+ TInt iError;
+ };
+
+/**
+ * This class blocks until all requested metadata has been retrieved
+ */
+class CGlxSynchronousAttributeRetriever : public CBase,
+ public MGlxBlockingAttributeRetriever,
+ public MGlxAttributeRetrieverObserver
+ {
+public:
+ static CGlxSynchronousAttributeRetriever* NewLC();
+
+public: // from MGlxBlockingAttributeRetriever
+ /**
+ * See @ref MGlxBlockingAttributeRetriever::RetrieveL
+ */
+ TInt RetrieveL(const MGlxFetchContext* aContext, MGlxMediaList* aList);
+
+private: // from MGlxAttributeRetrieverObserver
+ /**
+ * See @ref MGlxAttributeRetrieverObserver::AttributeRetrievalCompleteL
+ */
+ void AttributeRetrievalCompleteL(TInt aError);
+
+private:
+ /**
+ * StopScheduler
+ */
+ void StopScheduler();
+
+private:
+ /**
+ * Second stage constructor
+ */
+ void ConstructL();
+
+ /**
+ * Destructor
+ */
+ ~CGlxSynchronousAttributeRetriever();
+
+private:
+ /// Active scheduler wait object. Owned
+ CActiveSchedulerWait* iSchedulerWait;
+
+ /**
+ * Attribute retriever (owned)
+ */
+ CGlxAttributeRetriever* iAttributeRetriever;
+
+ /**
+ * Attribute retrieval error
+ */
+ TInt iError;
+ };
+
+// -----------------------------------------------------------------------------
+// RetrieveL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt GlxAttributeRetriever::RetrieveL(const MGlxFetchContext& aContext,
+ MGlxMediaList& aList, TBool aShowDialog)
+ {
+ MGlxBlockingAttributeRetriever* retriever = NULL;
+ if (aShowDialog)
+ {
+ retriever = CGlxWaitDialogAttributeRetriever::NewLC();
+ }
+ else
+ {
+ retriever = CGlxSynchronousAttributeRetriever::NewLC();
+ }
+ TInt err = retriever->RetrieveL(&aContext, &aList);
+ /**
+ * This will cause a code scanner warning, but it is not possible to do
+ * CleanupStack::PopAndDestroy(retriever) because the pointer pushed
+ * onto the cleanup stack was either of class CGlxWaitDialogAttributeRetriever
+ * or a CGlxSynchronousAttributeRetriever and the object 'retriever' is of
+ * class MGlxBlockingAttributeRetriever
+ */
+ CleanupStack::PopAndDestroy();
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+CGlxAttributeRetriever::CGlxAttributeRetriever(MGlxAttributeRetrieverObserver& aObserver)
+ : CActive(EPriorityHigh), iObserver(aObserver) // We want out RunL to be serviced ASAP
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CGlxAttributeRetriever::~CGlxAttributeRetriever()
+ {
+ Cancel();
+
+ if ( iList )
+ {
+ iList->RemoveMediaListObserver( this );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CGlxAttributeRetriever::RetrieveL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::RetrieveL(const MGlxFetchContext* aContext, MGlxMediaList* aList)
+ {
+ iContext = aContext;
+ iList = aList;
+ iList->AddMediaListObserverL(this);
+
+ if(iList->IsPopulated())
+ {
+ NotifyObserverIfCompleteL();
+ }
+ }
+
+void CGlxAttributeRetriever::CancelRetrieve()
+ {
+ // Simply remove media list observer to prevent call backs from the media list
+ iList->RemoveMediaListObserver(this);
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxAttributeRetriever::RunL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::RunL()
+ {
+ iObserver.AttributeRetrievalCompleteL(iStatus.Int());
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxAttributeRetriever::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::DoCancel()
+ {
+ // No need to do anything
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxAttributeRetriever::NotifyObserverIfCompleteL()
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::NotifyObserverIfCompleteL()
+ {
+ iRequestCount--;
+
+ if( iRequestCount <= 0 )
+ {
+ iRequestCount = iContext->RequestCountL(iList);
+ if(iRequestCount <= 0)
+ {
+ iList->RemoveMediaListObserver(this); // prevent any more callbacks from the media list
+ CompleteSelf(iRequestCount); // request count is an error
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CGlxDataSource::CompleteSelf
+// ---------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::CompleteSelf(TInt aError)
+ {
+ TRequestStatus* status=&iStatus;
+ User::RequestComplete(status, aError);
+ SetActive();
+ }
+
+// -----------------------------------------------------------------------------
+// HandleAttributesAvailableL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleAttributesAvailableL(TInt /* aItemIndex */,
+ const RArray<TMPXAttribute>& /* aAttributes */, MGlxMediaList* /*aList*/)
+ {
+ NotifyObserverIfCompleteL();
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemAddedL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleItemAddedL(TInt /* aStartIndex */,
+ TInt /* aEndIndex */, MGlxMediaList* /* aList */)
+ {
+ // No implementaion
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemRemovedL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleItemRemovedL(TInt /* aStartIndex */,
+ TInt /* aEndIndex */, MGlxMediaList* /* aList */)
+ {
+ // No implementaion
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemModifiedL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleItemModifiedL(const RArray<TInt>& /* aItemIndexes */,
+ MGlxMediaList* /* aList */)
+ {
+ // No implementaion
+ }
+
+// -----------------------------------------------------------------------------
+// HandleFocusChangedL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleFocusChangedL(NGlxListDefs::TFocusChangeType /* aType */,
+ TInt /* aNewIndex */, TInt /* aOldIndex */, MGlxMediaList* /* aList */)
+ {
+ // No implementaion
+ }
+
+// -----------------------------------------------------------------------------
+// HandleMediaL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleMediaL(TInt /* aListIndex */,
+ MGlxMediaList* /* aList */)
+ {
+ // No implementaion
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemSelectedL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleItemSelectedL(TInt /* aIndex */,
+ TBool /* aSelected */, MGlxMediaList* /* aList */)
+ {
+ // No implementaion
+ }
+
+// -----------------------------------------------------------------------------
+// HandleMessageL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleMessageL(const CMPXMessage& /* aMessage */,
+ MGlxMediaList* /* aList */)
+ {
+ // No implementaion
+ }
+
+// -----------------------------------------------------------------------------
+// HandleError
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandleError(TInt /* aError */)
+ {
+ // An error has been reported. But is it ours?
+ // If the request is not complete then the error is not ours
+ iRequestCount = 0;
+ TRAP_IGNORE(NotifyObserverIfCompleteL());
+
+ }
+
+// -----------------------------------------------------------------------------
+// HandlePopulatedL
+// -----------------------------------------------------------------------------
+//
+void CGlxAttributeRetriever::HandlePopulatedL(MGlxMediaList* /*aList*/)
+ {
+ // If the media list is empty we will never get the HandleAttributesAvailableL callback,
+ // therefore the call to NotifyObserversIfCompleteL below is necessary.
+ NotifyObserverIfCompleteL();
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxWaitDialogAttributeRetriever
+// -----------------------------------------------------------------------------
+//
+
+// -----------------------------------------------------------------------------
+// CGlxWaitDialogAttributeRetriever::NewLC
+// -----------------------------------------------------------------------------
+//
+CGlxWaitDialogAttributeRetriever* CGlxWaitDialogAttributeRetriever::NewLC()
+ {
+ CGlxWaitDialogAttributeRetriever* self = new (ELeave) CGlxWaitDialogAttributeRetriever();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxWaitDialogAttributeRetriever::RetrieveL
+// -----------------------------------------------------------------------------
+//
+TInt CGlxWaitDialogAttributeRetriever::RetrieveL(const MGlxFetchContext* aContext, MGlxMediaList* aList)
+ {
+ // Load the resource file for this dll containing the wait dialog
+ AddResourceFileL();
+
+ // prepare the wait dialog
+ iWaitDialog = new( ELeave ) CAknWaitDialog(reinterpret_cast<CEikDialog**>(&iWaitDialog));
+ iWaitDialog->PrepareLC(R_GLX_WAIT_NOTE_BLOCKING); // Pushes a point to a CEikDialog onto the CleanupStack. RunLD Pops it.
+
+ iWaitDialog->SetCallback(this);
+
+ // Load string for dialog
+ HBufC* title = StringLoader::LoadLC( R_GLX_PROGRESS_GENERAL );
+ iWaitDialog->SetTextL(*title);
+ CleanupStack::PopAndDestroy(title);
+
+ // The cancel key is specified in the resource
+ CEikButtonGroupContainer* cba = CEikButtonGroupContainer::Current();
+ cba->AddCommandSetToStackL(R_AVKON_SOFTKEYS_CANCEL);
+
+ iAttributeRetriever->RetrieveL(aContext, aList);
+ iWaitDialog->RunLD(); // starts another active scheduler and blocks
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxWaitDialogAttributeRetriever::AttributeRetrievalComplete
+// -----------------------------------------------------------------------------
+//
+void CGlxWaitDialogAttributeRetriever::AttributeRetrievalCompleteL(TInt aError)
+ {
+ iError = aError;
+ iWaitDialog->ProcessFinishedL();
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxWaitDialogAttributeRetriever::DialogDismissedL
+// -----------------------------------------------------------------------------
+//
+void CGlxWaitDialogAttributeRetriever::DialogDismissedL(TInt aButtonId)
+ {
+ if (aButtonId == EEikBidCancel)
+ {
+ iAttributeRetriever->CancelRetrieve();
+ iError = KErrCancel;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Constructor
+// -----------------------------------------------------------------------------
+//
+CGlxWaitDialogAttributeRetriever::CGlxWaitDialogAttributeRetriever()
+ {
+ iCoeEnv = CCoeEnv::Static();
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CGlxWaitDialogAttributeRetriever::~CGlxWaitDialogAttributeRetriever()
+ {
+ RemoveResourceFile();
+ delete iAttributeRetriever;
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxWaitDialogAttributeRetriever::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CGlxWaitDialogAttributeRetriever::ConstructL()
+ {
+ iAttributeRetriever = new (ELeave) CGlxAttributeRetriever(*this);
+ }
+
+// -----------------------------------------------------------------------------
+// AddResourceFileL
+// -----------------------------------------------------------------------------
+//
+void CGlxWaitDialogAttributeRetriever::AddResourceFileL()
+ {
+ if (!iResourceOffset) // Lazy construction - ensure that this is only run once
+ {
+ GLX_LOG_INFO("Adding attribute retriever resource file");
+ TParse parse;
+ parse.Set(KGlxUiUtilitiesResource, &KDC_APP_RESOURCE_DIR, NULL);
+ TFileName resourceFile;
+ resourceFile.Append(parse.FullName());
+ CGlxResourceUtilities::GetResourceFilenameL(resourceFile);
+ iResourceOffset = iCoeEnv->AddResourceFileL(resourceFile);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// RemoveResourceFile
+// -----------------------------------------------------------------------------
+//
+void CGlxWaitDialogAttributeRetriever::RemoveResourceFile()
+ {
+ if (iResourceOffset) // Check that the resource has been loaded
+ {
+ GLX_LOG_INFO("Removing attribute retriever resource file");
+ iCoeEnv->DeleteResourceFile( iResourceOffset );
+ iResourceOffset = 0;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxSynchronousAttributeRetriever
+// -----------------------------------------------------------------------------
+//
+
+// -----------------------------------------------------------------------------
+// CGlxSynchronousAttributeRetriever::NewLC
+// -----------------------------------------------------------------------------
+//
+CGlxSynchronousAttributeRetriever* CGlxSynchronousAttributeRetriever::NewLC()
+ {
+ CGlxSynchronousAttributeRetriever* self = new (ELeave) CGlxSynchronousAttributeRetriever();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CGlxSynchronousAttributeRetriever::RetrieveL
+// -----------------------------------------------------------------------------
+//
+TInt CGlxSynchronousAttributeRetriever::RetrieveL(const MGlxFetchContext* aContext, MGlxMediaList* aList)
+ {
+ iAttributeRetriever->RetrieveL(aContext,aList);
+ iSchedulerWait->Start();
+ return iError;
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxSynchronousAttributeRetriever::AttributeRetrievalCompleteL
+// -----------------------------------------------------------------------------
+//
+void CGlxSynchronousAttributeRetriever::AttributeRetrievalCompleteL(TInt aError)
+ {
+ iError = aError;
+ StopScheduler();
+ }
+
+// -----------------------------------------------------------------------------
+// StopScheduler
+// -----------------------------------------------------------------------------
+//
+void CGlxSynchronousAttributeRetriever::StopScheduler()
+ {
+ if (iSchedulerWait)
+ {
+ if (iSchedulerWait->IsStarted())
+ {
+ iSchedulerWait->AsyncStop();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CGlxSynchronousAttributeRetriever::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CGlxSynchronousAttributeRetriever::ConstructL()
+ {
+ iSchedulerWait = new (ELeave) CActiveSchedulerWait();
+ iAttributeRetriever = new (ELeave) CGlxAttributeRetriever(*this);
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CGlxSynchronousAttributeRetriever::~CGlxSynchronousAttributeRetriever()
+ {
+ delete iSchedulerWait;
+ delete iAttributeRetriever;
+ }