phonebookui/Phonebook/PbkAiwProviders/src/CPbkAssignRingingToneCmd.cpp
changeset 0 e686773b3f54
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/PbkAiwProviders/src/CPbkAssignRingingToneCmd.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,360 @@
+/*
+* Copyright (c) 2002 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: 
+*     Implements assign ringing tone functionality.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbkAssignRingingToneCmd.h"
+
+#include <aknnotedialog.h>
+#include <StringLoader.h>
+#include <PbkAiwProvidersRes.rsg>
+#include <PbkView.rsg>
+#include <CPbkContactEngine.h>
+#include <AknNoteWrappers.h>
+#include <AknWaitDialog.h>
+#include <CPbkContactItem.h>
+#include <MPbkCommandObserver.h>
+#include <CPbkRingingToneFetch.h>
+#include <AiwCommon.h>
+#include <AiwCommon.hrh>
+#include <CPbkFFSCheck.h>
+
+#include <pbkdebug.h>
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// Utility to check file existence without BAFL
+inline TBool FileExists( RFs& aFs, const TDesC& aFileName )
+    {
+    TEntry ignore;
+    return (aFs.Entry(aFileName, ignore) == KErrNone);
+    }
+
+#ifdef _DEBUG
+enum TPanicCode
+    {
+    ERunL_InvalidState
+    };
+
+void Panic(TPanicCode aReason)
+    {
+    _LIT(KPanicText, "CPbkAssignRingingToneCmd");
+    User::Panic(KPanicText, aReason);
+    }
+
+#endif  // _DEBUG
+}
+
+// ================= MEMBER FUNCTIONS =======================
+
+CPbkAssignRingingToneCmd* CPbkAssignRingingToneCmd::NewL
+        (const TDesC& aFileName, CContactIdArray* aContacts,
+        CPbkContactEngine& aEngine,
+        const CAiwGenericParamList& aInParamList,
+        MAiwNotifyCallback* aNotifyCallback)
+    {
+    CPbkAssignRingingToneCmd* self = new(ELeave) CPbkAssignRingingToneCmd
+        (aFileName, aContacts, aEngine, aInParamList, aNotifyCallback);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CPbkAssignRingingToneCmd::CPbkAssignRingingToneCmd
+        (const TDesC& aFileName, CContactIdArray* aContacts,
+        CPbkContactEngine& aEngine,
+        const CAiwGenericParamList& aInParamList,
+        MAiwNotifyCallback* aNotifyCallback):
+        CActive(CActive::EPriorityIdle),
+        iEngine(aEngine), iContacts(aContacts),
+        iFileName(aFileName),
+        iInParamList(aInParamList),
+        iNotifyCallback(aNotifyCallback)
+    {
+    CActiveScheduler::Add(this);
+    }
+
+void CPbkAssignRingingToneCmd::ConstructL()
+    {
+    iPbkFFSCheck = CPbkFFSCheck::NewL();
+    }
+
+CPbkAssignRingingToneCmd::~CPbkAssignRingingToneCmd()
+    {
+    Cancel();
+    delete iWaitNote;
+    delete iItem;
+    delete iContacts;
+    delete iTitleForNote;
+    delete iPbkFFSCheck;
+    }
+
+
+void CPbkAssignRingingToneCmd::AssignRingingToneL()
+    {
+    TInt count = iContacts->Count();
+
+    delete iItem;
+    iItem = NULL;
+
+    // Read the last contact of the array. Array is zerobased,
+    // therefore reduce one
+    iItem = iEngine.OpenContactL((*iContacts)[count-1]);
+
+    // Remove the last contact from the array
+    iContacts->Remove(count-1);
+
+    if (ConfirmAssignL(*iItem))
+        {
+        SetRingingToneL();
+        IssueRequest();
+        ShowWaitNoteL();
+        }
+    else
+        {
+        // Close contact and continue
+        iEngine.CloseContactL(iItem->Id());
+        IssueRequest();
+        }
+    }
+
+/**
+ * Returns ETrue, if it's ok to assign.
+ */
+inline TBool CPbkAssignRingingToneCmd::ConfirmAssignL(CPbkContactItem& aItem)
+    {
+    TBool ret = ETrue;
+
+    // Check does the contact already have a ringing tone
+    TPbkContactItemField* field =
+        aItem.FindField(EPbkFieldIdPersonalRingingToneIndication);
+
+    if (field && (field->StorageType() == KStorageTypeText))
+        {
+        // Check if the existing ringing tone file actually exists
+        if ( FileExists(iEngine.FsSession(), field->Text()) )
+            {
+            DismissWaitNoteL();
+
+            // Ask the user for confirmation
+            HBufC* title = aItem.GetContactTitleL();
+            CleanupStack::PushL(title);
+            HBufC* prompt = StringLoader::LoadL(
+                R_QTN_MG_CONTACT_RINGINGTONE_REPLACE, *title);
+            CleanupStack::PopAndDestroy(title);
+            CleanupStack::PushL(prompt);
+            CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+            CleanupStack::PushL(dlg);
+            dlg->SetPromptL(*prompt);
+            CleanupStack::Pop(); // dlg
+
+            if(!dlg->ExecuteLD(R_PBKAIW_GENERAL_CONFIRMATION_QUERY))
+                {
+                ret = EFalse;
+                }
+            CleanupStack::PopAndDestroy(prompt);
+            }
+        }
+
+    return ret;
+    }
+
+void CPbkAssignRingingToneCmd::SetRingingToneL()
+    {
+
+    // Check disk space before assigning.
+    // If not enough memory then leaves with KErrDiskFull.
+    iPbkFFSCheck->FFSClCheckL();
+
+    CPbkRingingToneFetch* toneFetch = CPbkRingingToneFetch::NewL(iEngine);
+    CleanupStack::PushL(toneFetch);
+    toneFetch->SetRingingToneL(*iItem, iFileName);
+    iEngine.CommitContactL(*iItem);
+    CleanupStack::PopAndDestroy(toneFetch);
+
+
+    // The title must be fetched and save here otherwise the contact
+    // title displayed in ShowEndNotesL function may be wrong.
+    HBufC* title = iItem->GetContactTitleL();
+    delete iTitleForNote;
+    iTitleForNote = title;
+
+    ++iTonesAdded;
+    }
+
+void CPbkAssignRingingToneCmd::ShowEndNotesL()
+    {
+    DismissWaitNoteL();
+
+    if (iTonesAdded > 0)
+        {
+        HBufC* prompt = NULL;
+
+        // Select prompt
+        if (iTonesAdded == 1)
+            {
+            prompt = StringLoader::LoadL(
+                R_QTN_MG_CONTACT_RINGINGTONE_ADD_ONE, *iTitleForNote);
+            CleanupStack::PushL(prompt);
+            }
+        else if (iTonesAdded > 1)
+            {
+            prompt = StringLoader::LoadLC(
+                R_QTN_MG_CONTACT_RINGINGTONE_ADD_SEVERAL, iTonesAdded);
+            }
+
+        // Prepare the note
+        CAknNoteWrapper * note = new (ELeave) CAknNoteWrapper;
+        CleanupStack::PushL(note);
+        note->SetTextL(*prompt);
+        CleanupStack::Pop(note);
+        CleanupStack::PopAndDestroy(prompt);
+
+        // Show the note
+        note->ExecuteLD(R_PBKAIW_GENERAL_NOTE);
+        }
+
+    // Destroy itself (observer performs deletion of this command)
+    iCmdObserver->CommandFinished(*this);
+    DoSendNotifyEventL(KAiwEventCompleted);
+    }
+
+
+void CPbkAssignRingingToneCmd::ShowWaitNoteL()
+    {
+    if (!iWaitNote)
+        {
+        CAknWaitDialog* waitNote = new(ELeave)
+        CAknWaitDialog(reinterpret_cast<CEikDialog**>(&iWaitNote));
+        waitNote->ExecuteLD(R_QTN_GEN_NOTE_PROCESSING);
+        iWaitNote = waitNote;
+        }
+    }
+
+void CPbkAssignRingingToneCmd::DismissWaitNoteL()
+    {
+    if (iWaitNote)
+        {
+        TRAPD(err, iWaitNote->ProcessFinishedL());
+        if (err != KErrNone)
+            {
+            delete iWaitNote;
+            iWaitNote = NULL;
+            }
+        }
+    }
+
+void CPbkAssignRingingToneCmd::ExecuteLD()
+    {
+    iState = EAssigning;
+    IssueRequest();
+    }
+
+void CPbkAssignRingingToneCmd::AddObserver(MPbkCommandObserver& aObserver)
+    {
+    iCmdObserver = &aObserver;
+    }
+
+void CPbkAssignRingingToneCmd::RunL()
+    {
+    switch (iState)
+        {
+        case EAssigning:
+            {
+            if (iContacts->Count() > 0)
+                {
+                // Assign ringing tone to next contact
+                AssignRingingToneL();
+                iState = EAssigning;
+                }
+            else
+                {
+                IssueStopRequest(KErrNone);
+                }
+            break;
+            }
+        case EStopping:
+            {
+            // Show notes to user
+            ShowEndNotesL();
+            break;
+            }
+        default:
+            {
+            __ASSERT_DEBUG(EFalse, Panic(ERunL_InvalidState));
+            break;
+            }
+        }
+    }
+
+
+void CPbkAssignRingingToneCmd::DoCancel()
+    {
+    // Safe to ignore this, notify is not so critical
+    TRAP_IGNORE(DoSendNotifyEventL(KAiwEventCanceled));
+    }
+
+TInt CPbkAssignRingingToneCmd::RunError(TInt aError)
+    {
+    if (iItem)
+        {
+        // We can ignore the error since stopping anyways
+        TRAP_IGNORE(iEngine.CloseContactL(iItem->Id()));
+        }
+    CCoeEnv::Static()->HandleError(aError);
+    IssueStopRequest(aError);
+    return KErrNone;
+    }
+
+void CPbkAssignRingingToneCmd::DoSendNotifyEventL(TInt aEvent)
+    {
+    if (iNotifyCallback)
+        {
+        CAiwGenericParamList* eventParamList = CAiwGenericParamList::NewL();
+        CleanupStack::PushL(eventParamList);
+        iNotifyCallback->HandleNotifyL(
+            KAiwCmdAssign,
+            aEvent,
+            *eventParamList,
+            iInParamList);
+        CleanupStack::PopAndDestroy(eventParamList);
+        }
+    }
+
+void CPbkAssignRingingToneCmd::IssueRequest()
+    {
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete(status, KErrNone);
+    SetActive();
+    }
+
+void CPbkAssignRingingToneCmd::IssueStopRequest(TInt /*aError*/)
+    {
+    iState = EStopping;
+    if (!IsActive())
+        {
+        IssueRequest();
+        }
+    }
+
+
+// End of File
+