--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/viewframework/commandhandlers/commandhandlerbase/src/glxmpxcommandcommandhandler.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,666 @@
+/*
+* 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: Media List Command Handler
+*
+*/
+
+
+
+
+#include <e32base.h>
+
+#include "glxmpxcommandcommandhandler.h"
+
+#include <AknProgressDialog.h>
+#include <bautils.h>
+#include <data_caging_path_literals.hrh>
+#include <eikprogi.h>
+#include <mpxmediageneraldefs.h>
+#include <mpxmessagegeneraldefs.h>
+#include <mpxmessageprogressdefs.h>
+#include <mpxcommandgeneraldefs.h>
+#include <StringLoader.h>
+
+#include <glxgeneraluiutilities.h>
+#include <mglxmedialist.h>
+#include <glxfetchcontextremover.h>
+#include <glxmedialistiterator.h>
+#include <glxattributecontext.h>
+#include <glxattributeretriever.h>
+#include <glxuistd.h>
+#include <glxuiutilities.rsg>
+#include <glxcommandhandlers.hrh>
+#include <glxresourceutilities.h> // for CGlxResourceUtilities
+
+/// @todo Move elsewhere
+const TInt KGlxMaxNoteLength = 256;
+
+// -----------------------------------------------------------------------------
+// ConstructL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxMpxCommandCommandHandler::
+ CGlxMpxCommandCommandHandler(MGlxMediaListProvider* aMediaListProvider, TBool aHasToolbarItem)
+ : CGlxMediaListCommandHandler(aMediaListProvider, aHasToolbarItem)
+ {
+ iAppUi = static_cast< CAknAppUi* >( CCoeEnv::Static()->AppUi() );
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGlxMpxCommandCommandHandler::~CGlxMpxCommandCommandHandler()
+ {
+ // cancel command if running
+ if (iProgressComplete)
+ {
+// MediaList().Cancel();
+ }
+
+ delete iProgressDialog;
+
+ if ( iResourceOffset )
+ {
+ CCoeEnv::Static()->DeleteResourceFile(iResourceOffset);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DoExecuteL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CGlxMpxCommandCommandHandler::DoExecuteL(TInt aCommandId,
+ MGlxMediaList& aList)
+ {
+ // reset progress complete flag
+ iProgressComplete = EFalse;
+
+ // deriving class consumes command by default
+ TBool consume = ETrue;
+ TInt selectionCount = aList.SelectionCount();
+ const TGlxMedia& focusedMedia = aList.Item(aList.FocusIndex());
+ // show confirmation note
+ consume = ConfirmationNoteL(aCommandId, aList);
+
+ // Check if the selected / focused file(s)s have been deleted from
+ // another application while the confirmation note is displayed
+ if (((selectionCount > 0) && (aList.SelectionCount() == 0)) ||
+ ((selectionCount == 0) &&
+ (focusedMedia.Id() != aList.Item(aList.FocusIndex()).Id())))
+ {
+ // All the selected / focused item(s) have been deleted,
+ // do not allow the command to execute.
+ consume = EFalse;
+ }
+
+ if ( consume )
+ {
+ // get a command object from the deriving class.
+ // Allow deriving class modify the consume value, even without
+ // creating a commmand (in case it wants to filter out a command)
+ CMPXCommand* command = CreateCommandL(aCommandId, aList, consume);
+
+ if (command)
+ {
+ CleanupStack::PushL(command);
+
+ if ( CommandInfo(aCommandId).iStopAnimationForExecution )
+ {
+ // Stop GIF animation
+ iAppUi->ProcessCommandL(EGlxCmdDisableAnimations);
+ iAnimationStopped = ETrue;
+ }
+
+ // Add the pointer of this command handler as session id into the message
+ // This can be used to ensure that this object is the intended recipient
+ // of a message
+ command->SetTObjectValueL<TAny*>(KMPXCommandGeneralSessionId,
+ static_cast<TAny*>(this));
+
+ aList.AddMediaListObserverL(this);
+
+ // @todo TRAP this?
+ aList.CommandL(*command);
+
+ // raise progress note. Note will be closed when complete message received
+ ProgressNoteL(aCommandId);
+
+ CleanupStack::PopAndDestroy(command);
+ }
+ }
+
+ return consume;
+ }
+
+// -----------------------------------------------------------------------------
+// TryExitL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::TryExitL(TInt aErrorCode)
+ {
+ // any error will abort the command execution
+ if ( KErrNone != aErrorCode )
+ {
+ // error received. Close progress note
+ DismissProgressNoteL();
+
+ // Remove medialist observer
+ RemoveMediaListObserver();
+
+ // handle error
+ HandleErrorL(aErrorCode);
+ }
+ else if (iProgressComplete)
+ {
+ // ask deriving class if it is ready to exit (i.e., to close progress note).
+ // (It may be waiting for another message, etc.)
+ if (OkToExit())
+ {
+ // close progress note
+ DismissProgressNoteL();
+
+ // Remove medialist observer
+ RemoveMediaListObserver();
+
+ // show completion note
+ CompletionNoteL();
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// Default implementation shows an error note
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleErrorL(TInt aErrorCode)
+ {
+ // show error note
+ GlxGeneralUiUtilities::ShowErrorNoteL(aErrorCode);
+ }
+
+// -----------------------------------------------------------------------------
+// Update progress
+// -----------------------------------------------------------------------------
+//
+TBool CGlxMpxCommandCommandHandler::UpdateProgressL(const CMPXMessage& aMessage,
+ TInt& aError)
+ {
+ TBool isComplete = EFalse;
+
+ // should not receive any progress messages after progress is completed
+ __ASSERT_DEBUG(!iProgressComplete, Panic(EGlxPanicIllegalState));
+
+ /// @todo remove progress update error handling
+ TMPXAttribute currentCountAttr(KMPXMessageContentIdProgress, EMPXMessageProgressCurrentCount);
+ TMPXAttribute totalCountAttr(KMPXMessageContentIdProgress, EMPXMessageProgressTotalCount);
+ if ( ( KErrNone == aError ) && (aMessage.IsSupported(currentCountAttr))
+ && (aMessage.IsSupported(totalCountAttr) ) )
+ {
+ // get current and total count from the message
+ TInt currentValue = aMessage.ValueTObjectL<TInt>(currentCountAttr);
+ TInt total= aMessage.ValueTObjectL<TInt>(totalCountAttr);
+
+ // update progress bar if not complete yet, otherwise remember completion
+ if ( currentValue < total )
+ {
+ // Progress info construction may have failed, but command was issued before
+ if (iProgressInfo)
+ {
+ iProgressInfo->SetFinalValue(total);
+ iProgressInfo->SetAndDraw(currentValue);
+ }
+ }
+ else
+ {
+ isComplete = ETrue;
+
+ if ( iAnimationStopped )
+ {
+ // Restart animation
+ iAppUi->ProcessCommandL(EGlxCmdEnableAnimations);
+ iAnimationStopped = EFalse;
+ }
+ }
+ }
+
+ return isComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// Default implementation of advanced command handling does nothing
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::DoHandleCommandCompleteL(TAny* /*aSessionId*/,
+ CMPXCommand* /*aCommandResult*/, TInt /*aError*/, MGlxMediaList* /*aList*/)
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// Default implementation of advanced message handling does nothing
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CGlxMpxCommandCommandHandler::DoHandleMessageL(const CMPXMessage& /*aMessage*/,
+ MGlxMediaList& /*aList*/)
+ {
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// Default implementation DoHandleItemAddedL does not do anything
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::DoHandleItemAddedL(TInt /*aStartIndex*/,
+ TInt /*aEndIndex*/, MGlxMediaList* /*aList*/)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Default implementation is always ready to exit
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CGlxMpxCommandCommandHandler::OkToExit() const
+ {
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// Show confirmation note
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CGlxMpxCommandCommandHandler::ConfirmationNoteL(TInt aCommandId,
+ MGlxMediaList& aMediaList) const
+ {
+ TInt selectionCount = aMediaList.SelectionCount();
+
+ // If media list is not empty, treat focused item as selected
+ // At this point can assume that the command was disabled
+ // if static items were not supported
+ if ( selectionCount == 0 && aMediaList.Count() > 0 )
+ {
+ selectionCount = 1;
+ }
+
+ // Show confirmation note
+ TBool confirmed = EFalse;
+ if ( selectionCount == 1 )
+ {
+ confirmed = ConfirmationNoteSingleL(aCommandId, aMediaList);
+ }
+ else
+ {
+ confirmed = ConfirmationNoteMultipleL(aCommandId, aMediaList);
+ }
+
+ return confirmed;
+ }
+
+// -----------------------------------------------------------------------------
+// So confirmation note if a single item is selected
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CGlxMpxCommandCommandHandler::ConfirmationNoteSingleL(TInt aCommandId,
+ MGlxMediaList& aMediaList) const
+ {
+ // if no confirmation note shown, assume command is confirmed
+ TBool confirmed = ETrue;
+
+ // get confirmation note text for single selection
+ HBufC* noteText = ConfirmationTextL(aCommandId, EFalse); // EFalse for single selection
+ if ( noteText )
+ {
+ CleanupStack::PushL(noteText);
+
+ // Retrieve title string for selected item from the collection plugin
+
+ // create fetch context
+ TGlxSelectionIterator iterator;
+ iterator.SetRange(1);
+ CGlxAttributeContext* attributeContext = new(ELeave) CGlxAttributeContext(&iterator);
+ CleanupStack::PushL(attributeContext);
+ attributeContext->AddAttributeL(KMPXMediaGeneralTitle);
+
+ // add context to media list
+ aMediaList.AddContextL(attributeContext, KGlxFetchContextPriorityLow);
+
+ // TGlxContextRemover will remove the context when it goes out of scope
+ // Used here to avoid a trap and still have safe cleanup
+ TGlxFetchContextRemover contextRemover(attributeContext, aMediaList);
+ // put to cleanupstack as cleanupstack is emptied before stack objects
+ // are deleted
+ CleanupClosePushL( contextRemover);
+ // retrieve title attribute
+ TInt err = GlxAttributeRetriever::RetrieveL(*attributeContext, aMediaList, EFalse);
+ // context off the list
+ CleanupStack::PopAndDestroy( &contextRemover );
+
+ if ( err == KErrNone )
+ {
+ // use iterator to get the index of the right item
+ iterator.SetToFirst(&aMediaList);
+ const CGlxMedia* media = aMediaList.Item(iterator++).Properties();
+
+ // noteText has a place for a title string in it
+ const TDesC& itemName = media->ValueText(KMPXMediaGeneralTitle);
+
+ TBuf<KGlxMaxNoteLength> text;
+ StringLoader::Format(text, *noteText, -1, itemName);
+
+ // show popup
+ confirmed = GlxGeneralUiUtilities::ConfirmQueryL(R_GLX_QUERY_YES_NO, text);
+ }
+ // (else) If error, assume confirmed anyway
+
+ CleanupStack::PopAndDestroy(attributeContext);
+ CleanupStack::PopAndDestroy(noteText);
+ }
+ return confirmed;
+ }
+
+// -----------------------------------------------------------------------------
+// Confirmation note if multiple items are selected
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CGlxMpxCommandCommandHandler::ConfirmationNoteMultipleL(TInt aCommandId,
+ MGlxMediaList& aMediaList) const
+ {
+ // if no confirmation note shown, assume command is confirmed
+ TBool confirmed = ETrue;
+
+ // get confirmation note text for multiselection
+ HBufC* noteText = ConfirmationTextL(aCommandId, ETrue); // ETrue for Multiselection
+ if ( noteText )
+ {
+ CleanupStack::PushL(noteText);
+
+ // string has a place for number in it, and that number should be populated with selected
+ // item count
+ TInt count = aMediaList.SelectionCount();
+
+ TBuf<KGlxMaxNoteLength> text;
+ GlxGeneralUiUtilities::FormatString(text, *noteText, -1, count, ETrue);
+
+ // show popup
+ confirmed = GlxGeneralUiUtilities::ConfirmQueryL(R_GLX_QUERY_YES_NO, text);
+
+ CleanupStack::PopAndDestroy(noteText);
+ }
+ return confirmed;
+ }
+
+// -----------------------------------------------------------------------------
+// Default implementation returns null, and no confirmation note will be shown
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC* CGlxMpxCommandCommandHandler::ConfirmationTextL(TInt /*aCommandId*/,
+ TBool /*aMultiSelection*/) const
+ {
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// Return default progress string
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC* CGlxMpxCommandCommandHandler::ProgressTextL(TInt /*aCommandId*/) const
+ {
+ // Lazy construction for resource file
+ if (iResourceOffset == 0)
+ {
+ // Load resource file
+ TParse parse;
+ parse.Set(KGlxUiUtilitiesResource, &KDC_APP_RESOURCE_DIR, NULL);
+ TFileName resourceFile;
+ resourceFile.Append(parse.FullName());
+ CGlxResourceUtilities::GetResourceFilenameL(resourceFile);
+
+ // Store resource offset as member variable, so don't have to trap the
+ // leaving calls here
+ iResourceOffset = CCoeEnv::Static()->AddResourceFileL(resourceFile);
+ }
+
+ // get progress note string
+ return StringLoader::LoadL( R_GLX_PROGRESS_GENERAL );
+ }
+
+// -----------------------------------------------------------------------------
+// Default implementation returns null, and no completion note will be shown
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC* CGlxMpxCommandCommandHandler::CompletionTextL() const
+ {
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// ProgressNoteL
+// -----------------------------------------------------------------------------
+//
+void CGlxMpxCommandCommandHandler::ProgressNoteL(TInt aCommandId)
+ {
+ //MGlxMediaList& mediaList = MediaList();
+
+ // get progress note
+ HBufC* progressText = ProgressTextL(aCommandId);
+ __ASSERT_DEBUG(progressText, Panic(EGlxPanicNullDescriptor));
+ CleanupStack::PushL(progressText);
+ // construct progress dialog
+ iProgressDialog = new(ELeave)CAknProgressDialog(
+ (REINTERPRET_CAST(CEikDialog**,&iProgressDialog)));
+ iProgressDialog->PrepareLC(R_GLX_PROGRESS_NOTE);
+ iProgressDialog->SetTextL(*progressText);
+ iProgressDialog->SetCallback(this);
+
+ // pick up progress info so that progress notification can be later updated
+ iProgressInfo = iProgressDialog->GetProgressInfoL();
+
+ // launch the note
+ iProgressDialog->RunLD();
+ CleanupStack::PopAndDestroy(progressText);
+ }
+
+// -----------------------------------------------------------------------------
+// DismissProgressNoteL
+// -----------------------------------------------------------------------------
+//
+void CGlxMpxCommandCommandHandler::DismissProgressNoteL()
+ {
+ // Close the progress note, if displayed
+ if (iProgressDialog)
+ {
+ iProgressDialog->ProcessFinishedL();
+ iProgressDialog = NULL;
+ iProgressInfo = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Remove MediaList Observer
+// -----------------------------------------------------------------------------
+//
+void CGlxMpxCommandCommandHandler::RemoveMediaListObserver()
+ {
+ MGlxMediaList& mediaList = MediaList();
+ mediaList.RemoveMediaListObserver(this);
+ }
+
+// -----------------------------------------------------------------------------
+// Show a completion note
+// -----------------------------------------------------------------------------
+//
+void CGlxMpxCommandCommandHandler::CompletionNoteL() const
+ {
+ // Get completion note text
+ HBufC* noteText = CompletionTextL();
+ if ( noteText )
+ {
+ CleanupStack::PushL(noteText);
+ GlxGeneralUiUtilities::ShowConfirmationNoteL(*noteText, ETrue);
+ CleanupStack::PopAndDestroy(noteText);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemAddedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleItemAddedL(TInt /*aStartIndex*/, TInt /*aEndIndex*/, MGlxMediaList* /*aList*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// HandleMediaL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleMediaL(TInt /*aListIndex*/, MGlxMediaList* /*aList*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemRemovedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleItemRemovedL(TInt /*aStartIndex*/, TInt /*aEndIndex*/, MGlxMediaList* /*aList*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemModifiedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleItemModifiedL(const RArray<TInt>& /*aItemIndexes*/,
+ MGlxMediaList* /*aList*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// HandleAttributesAvailableL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleAttributesAvailableL(TInt /*aItemIndex*/,
+ const RArray<TMPXAttribute>& /*aAttributes*/, MGlxMediaList* /*aList*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// HandleFocusChangedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleFocusChangedL(NGlxListDefs::TFocusChangeType /*aType*/,
+ TInt /*aNewIndex*/, TInt /*aOldIndex*/, MGlxMediaList* /*aList*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// HandleItemSelectedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleItemSelectedL(TInt /*aIndex*/,
+ TBool /*aSelected*/, MGlxMediaList* /*aList*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// HandleMessageL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleMessageL(const CMPXMessage& aMessage,
+ MGlxMediaList* aList)
+ {
+ if ((aMessage.IsSupported(KMPXMessageGeneralId) &&
+ (aMessage.IsSupported(KMPXCommandGeneralSessionId))))
+ {
+ TInt msgId = aMessage.ValueTObjectL<TInt>(KMPXMessageGeneralId);
+ TAny* sessionId = aMessage.ValueTObjectL<TAny*>(KMPXCommandGeneralSessionId);
+
+ TInt error = KErrNone;
+ // Check if this is a progress message and intended for this object
+ if ( KMPXMessageContentIdProgress == msgId && static_cast<TAny*>(this) == sessionId )
+ {
+ // Update progress note
+ iProgressComplete = UpdateProgressL(aMessage, error);
+ }
+ else
+ {
+ // This is not a progress message - let deriving class handle
+ error = DoHandleMessageL(aMessage, *aList);
+ }
+
+ // Check if ready to exit, i.e., to close progress note, and allow user
+ // to select another menu option
+ TryExitL(error);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// HandleMessageL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::HandleCommandCompleteL(TAny* aSessionId,
+ CMPXCommand* aCommandResult, TInt aError, MGlxMediaList* aList)
+ {
+ // Unmark all medialist items. Exit Multiple marking mode upon command completion
+ iAppUi->ProcessCommandL(EGlxCmdEndMultipleMarking);
+
+ ///@todo Enforce a single command request at a time on the media list.
+ DoHandleCommandCompleteL(aSessionId, aCommandResult, aError, aList);
+ iProgressComplete = ETrue;
+ TryExitL(aError);
+ }
+
+// -----------------------------------------------------------------------------
+// DialogDismissedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::DialogDismissedL(TInt /*aButtonId*/)
+ {
+ if (!iProgressComplete)
+ {
+ // Remove as media list observer
+ MGlxMediaList& mediaList = MediaList();
+ mediaList.CancelCommand();
+ mediaList.RemoveMediaListObserver(this);
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// DoActivateL
+//-----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::DoActivateL(TInt /*aViewId*/)
+ {
+ // Do nothing
+ }
+
+// -----------------------------------------------------------------------------
+// Deactivate - Deactivate this command handler
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGlxMpxCommandCommandHandler::Deactivate()
+ {
+ // Close the progress note, if displayed
+ if (iProgressDialog)
+ {
+ TRAP_IGNORE(DismissProgressNoteL());
+ }
+ }