/*
* Copyright (c) 2002-2008 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: Plugin implementation of global progress dialog.
*
*/
#include <AknNotifyStd.h>
#include <avkon.rsg>
#include <eikbtgpc.h>
#include <eikenv.h>
#include <avkon.hrh>
#include <bautils.h>
#include <aknnotpi.rsg>
#include <AknQueryDialog.h>
#include <AknProgressDialog.h>
#include <eikprogi.h>
#include <notelaf.h>
#include <AknUtils.h>
#include <AknBidiTextUtils.h>
#include "aknsystemprogresspopup.h"
#include "AknNotifyPlugin.hrh"
#include <s32mem.h>
#include <AknNotifySignature.h>
#include "aknnoteattributes.h"
#include <AknsUtils.h>
#include <aknconsts.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <AknMediatorFacade.h>
#include <aknSDData.h>
#include <SecondaryDisplay/AknSecondaryDisplayDefs.h>
#include "AknAppsKeyCleanup.inl"
const TInt KCharsInTInt = 4; // TInt32 takes 4 chars.
// =============================================================================
// Progress dialog subject.
// =============================================================================
CAknGlobalProgressDialogSubject* CAknGlobalProgressDialogSubject::NewL()
{
CAknGlobalProgressDialogSubject* self = new (ELeave) CAknGlobalProgressDialogSubject();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CAknGlobalProgressDialogSubject::CAknGlobalProgressDialogSubject()
:iPending(EFalse)
{
iStoredEikonEnv = CEikonEnv::Static();
}
void CAknGlobalProgressDialogSubject::ConstructL()
{
}
CAknGlobalProgressDialogSubject::~CAknGlobalProgressDialogSubject()
{
//delete iDlg;
delete iPrompt;
Cancel();
// Complete the RMessage if we need to.
if (iPending)
{
iMessage.Complete(KErrDied);
}
}
void CAknGlobalProgressDialogSubject::Release()
{
delete this;
}
CAknGlobalProgressDialogSubject::TNotifierInfo CAknGlobalProgressDialogSubject::RegisterL()
{
iInfo.iUid = KAknGlobalProgressDialogUid;
iInfo.iChannel = EAknNotifierChannelProgressDialog;
iInfo.iPriority = ENotifierPriorityHigh;
return iInfo;
}
CAknGlobalProgressDialogSubject::TNotifierInfo CAknGlobalProgressDialogSubject::Info() const
{
return iInfo;
}
TPtrC8 CAknGlobalProgressDialogSubject::StartL(const TDesC8& /*aBuffer*/)
{
return KNullDesC8();
}
void CAknGlobalProgressDialogSubject::StartL(const TDesC8& aBuffer, TInt /*aReplySlot*/,
const RMessagePtr2& aMessage)
{
if (iPending)
{
aMessage.Complete(KErrInUse);
return;
}
RDesReadStream readStream(aBuffer);
if (aBuffer.Length() < KCharsInTInt || readStream.ReadInt32L() != KAKNNOTIFIERSIGNATURE)
{
User::Leave(KErrArgument);
}
iMessage = aMessage;
TInt softkeys = readStream.ReadInt32L();
TInt imageId = readStream.ReadInt16L();
TInt imageMaskId = readStream.ReadInt16L();
TInt iconId = readStream.ReadInt16L();
TInt iconMaskId = readStream.ReadInt16L();
TInt finalValue = readStream.ReadInt32L();
TInt tone = readStream.ReadInt16L();
// Get prompt text
TInt promptLength = readStream.ReadInt16L();
delete iPrompt;
iPrompt = NULL;
iPrompt = HBufC::NewL(promptLength + KAknBidiExtraSpacePerLine);
TPtr promptPtr = iPrompt->Des();
readStream >> promptPtr;
// Get image file name.
TInt imageFileLength = readStream.ReadInt16L();
TFileName imageFile;
if (imageFileLength)
{
readStream >> imageFile;
}
// Get icon file name.
TInt iconFileLength = readStream.ReadInt16L();
TFileName iconFile;
if (iconFileLength)
{
readStream >> iconFile;
}
// Get icon text.
TInt iconTextLength = readStream.ReadInt16L();
HBufC* iconText = NULL;
if (iconTextLength)
{
iconText = HBufC::NewLC(iconTextLength + KAknBidiExtraSpacePerLine);
TPtr iconTextPtr = iconText->Des();
readStream >> iconTextPtr;
// Clip strings to fit in one line each.
// We also convert them to visual order.
const CFont* font = iStoredEikonEnv->NormalFont();
TAknLayoutRect layRect;
TAknLayoutText textLay;
AknLayoutUtils::TAknCbaLocation cbaLocation(AknLayoutUtils::CbaLocation());
TInt variety(0);
if (cbaLocation == AknLayoutUtils::EAknCbaLocationRight)
{
variety = 4;
}
else if (cbaLocation == AknLayoutUtils::EAknCbaLocationLeft)
{
variety = 7;
}
else
{
variety = 1;
}
layRect.LayoutRect(iAvkonAppUi->ApplicationRect(),
AknLayoutScalable_Avkon::popup_note_window(variety));
TAknTextLineLayout layLine = AKN_LAYOUT_TEXT_Note_pop_up_window_texts_Line_1(1);
textLay.LayoutText(layRect.Rect(), layLine);
TInt clipWidth = textLay.TextRect().Width();
AknBidiTextUtils::ConvertToVisualAndClipL(iconTextPtr, *font, clipWidth, clipWidth);
layLine = AKN_LAYOUT_TEXT_Note_pop_up_window_texts_Line_1(4);
textLay.LayoutText(layRect.Rect(), layLine);
clipWidth = textLay.TextRect().Width();
AknBidiTextUtils::ConvertToVisualAndClipL(promptPtr, *font, clipWidth, clipWidth);
// +1 for '\n'
iPrompt = iPrompt->ReAllocL(iPrompt->Length() + iconText->Length() + 1);
promptPtr.Set(iPrompt->Des());
promptPtr.Append('\n');
promptPtr.Append(*iconText);
CleanupStack::PopAndDestroy(iconText);
}
TInt skinsMajorImage = readStream.ReadInt32L();
TInt skinsMinorImage = readStream.ReadInt32L();
TInt skinsMajorIcon = readStream.ReadInt32L();
TInt skinsMinorIcon = readStream.ReadInt32L();
CAknSDData* sddata = 0;
if (readStream.ReadInt8L())
{
sddata = new (ELeave) CAknSDData();
CleanupStack::PushL(sddata);
readStream >> *sddata;
}
// Initialize dialog, done before image loading as eases up cleanupstack handling.
delete iDlg;
iDlg = NULL;
iDlg = new (ELeave) CAknProgressDialog(REINTERPRET_CAST(CEikDialog**, &iDlg), ETrue);
iDlg->SetCallback(this);
if (sddata)
{
iDlg->PublishDialogL(sddata->iDialogIdx, sddata->iCategory);
if (sddata->iAdditionalData)
{
CAknMediatorFacade* cover_info = AknMediatorFacade(iDlg);
if(cover_info)
{
cover_info->BufStream() << *(sddata->iAdditionalData);
cover_info->BufStream().CommitL();
}
}
CleanupStack::PopAndDestroy(sddata);
}
else
{
// If secondary display data hasn't been defined, then the unidentified
// progress note identifier is published to the secondary display.
iDlg->PublishDialogL(EAknUnidentifiedProgressNote, KAknSecondaryDisplayCategory);
}
if (!iAppsKeySuppressed)
{
((CAknNotifierAppServerAppUi*)(iStoredEikonEnv->EikAppUi()))->SuppressAppSwitching(ETrue);
}
CleanupStack::PushL(TCleanupItem(ReleaseAppsKey, 0));
iDlg->PrepareLC(R_GLOBAL_PROGRESS_DIALOG);
// Load image.
CEikImage* image = new (ELeave) CEikImage;
CleanupStack::PushL(image);
TAknsItemID id = {0,0};
if (skinsMajorImage||skinsMinorImage||imageFile.CompareF(KAvkonBitmapFile) == 0)
{
if (skinsMajorImage||skinsMinorImage)
{
id.Set(skinsMajorImage,skinsMinorImage);
}
else
{
id = CAknNoteAttributes::GetSkinnedBitmapID(imageId);
}
}
CFbsBitmap* bitmap = NULL;
CFbsBitmap* mask = NULL;
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
TRAPD(err, AknsUtils::CreateIconL(
skin,id,
bitmap, mask,
imageFile,
imageId, imageMaskId ));
if (!err)
{
image->SetPicture(bitmap,mask);
}
else
{
CleanupStack::PopAndDestroy(image);
image = 0;
}
// Load icon.
CEikImage* icon = new (ELeave) CEikImage;
CleanupStack::PushL(icon);
id.Set(0,0);
bitmap = NULL;
mask = NULL;
if (skinsMajorIcon || skinsMinorIcon || iconFile.CompareF(KAvkonBitmapFile) == 0)
{
if (skinsMajorIcon || skinsMinorIcon)
{
id.Set(skinsMajorIcon,skinsMinorIcon);
}
else
{
id = CAknNoteAttributes::GetSkinnedBitmapID(iconId);
}
}
TRAP(err, AknsUtils::CreateIconL(
skin,id,
bitmap, mask,
iconFile,
iconId, iconMaskId ));
if (!err)
{
icon->SetPicture(bitmap,mask);
}
else
{
CleanupStack::PopAndDestroy(icon);
icon = 0;
}
// Set icon.
if (icon)
{
iDlg->SetIconL(icon);
CleanupStack::Pop(icon);
}
// Set image.
if (image)
{
iDlg->SetImageL(image);
CleanupStack::Pop(image);
}
// Set progress info.
iProgressInfo = iDlg->GetProgressInfoL();
iProgressInfo->SetFinalValue(finalValue);
// Set softkeys.
if (softkeys)
{
// If softkeys are given, the resource id must point to a valid resource.
// Trying to use invalid softkeys can cause panic.
if (!(iStoredEikonEnv->IsResourceAvailableL(softkeys)))
{
User::Leave(KErrArgument);
}
iDlg->ButtonGroupContainer().SetCommandSetL(softkeys);
}
// If icon text was present, we processed the text ourselves.
// (Wrapped, truncated, converted from logical to visual.)
if (iconTextLength)
{
iDlg->SetTextProcessing(EFalse);
}
// Set label and tone.
iDlg->SetTextL(*iPrompt);
iDlg->SetTone((CAknNoteDialog::TTone)tone);
// Execute dialog.
iDlg->RunLD();
CleanupStack::Pop(); // Apps key cleanup.
iAppsKeySuppressed = ETrue;
delete iPrompt;
iPrompt = NULL;
iPending = ETrue;
}
void CAknGlobalProgressDialogSubject::Cancel()
{
delete iDlg;
iDlg = NULL;
TRAP_IGNORE(DialogDismissedL(EAknSoftkeyCancel));
}
TPtrC8 CAknGlobalProgressDialogSubject::UpdateL(const TDesC8& aBuffer)
{
if (!iDlg)
{
return KNullDesC8();
}
// Get parameters.
SAknNotifierPackage<SAknGlobalProgressDialogParams>* params
= (SAknNotifierPackage<SAknGlobalProgressDialogParams>*)aBuffer.Ptr();
if (aBuffer.Length() < 0
|| (TUint)aBuffer.Length() < sizeof(SAknNotifierPackage<SAknGlobalProgressDialogParams>)
|| params->iSignature != KAKNNOTIFIERSIGNATURE)
{
User::Leave(KErrArgument);
}
if (params->iParamData.iCmd == EAknCancelGlobalQuery)
{
delete iDlg;
iDlg = NULL;
DialogDismissedL(EAknSoftkeyCancel);
}
else if (params->iParamData.iCmd == EAknUpdateGlobalQuery)
{
// Update current and final value.
if (params->iParamData.iValue >= 0)
{
iProgressInfo->SetFinalValue(params->iParamData.iFinalValue);
}
iProgressInfo->SetAndDraw(params->iParamData.iValue);
CAknMediatorFacade* coverData = AknMediatorFacade(iDlg);
if (coverData)
{
coverData->ResetBuffer();
coverData->BufStream().WriteInt32L(EAknGlobalPDialogValuesUpdate);
coverData->BufStream().WriteInt32L(params->iParamData.iValue);
coverData->BufStream().WriteInt32L(params->iParamData.iFinalValue);
coverData->BufStream().CommitL();
coverData->PostUpdatedDataL();
}
}
else if (params->iParamData.iCmd == EAknFinishGlobalProgressDialog)
{
iDlg->ProcessFinishedL();
}
return KNullDesC8();
}
void CAknGlobalProgressDialogSubject::DialogDismissedL(TInt aButtonId)
{
if (iPending)
{
iMessage.Complete(aButtonId);
}
iPending = EFalse;
iReturnVal = NULL;
if (iAppsKeySuppressed)
{
((CAknNotifierAppServerAppUi*)(iStoredEikonEnv->EikAppUi()))->SuppressAppSwitching(EFalse);
}
iAppsKeySuppressed = EFalse;
}
// End of file