/*
* Copyright (c) 2005 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: PostcardAppUi implementation
*
*/
// ========== INCLUDE FILES ================================
#include <e32std.h>
#include <w32std.h>
#include <eikapp.h> // CEikApplication
#include <eikdialg.h> // CEikDialog
#include <eikenv.h> // Eikon Enviroment
#include <eikmenub.h> // CEikMenuBar
#include <eikmenup.h> // CEikMenuPane
#include <bamdesca.h> // MDesCArray
#include <bautils.h> // NearestLanguageFile
#include <bldvariant.hrh>
#include <centralrepository.h>
#include <data_caging_path_literals.hrh>
#include <ErrorUI.h>
#include <featmgr.h>
#include <StringLoader.h>
#include <aknenv.h>
#include <aknconsts.h>
#include <AknGlobalMsgQuery.h> // Global Msg Query
#include <AknIndicatorContainer.h>
#include <akninputblock.h> // CAknInputBlock
#include <aknnavi.h> // CAknNavigationControlContainer
#include <aknnotewrappers.h>
#include <akntitle.h>
#include <AknWaitDialog.h>
#include <avkon.hrh>
#include <avkon.mbg>
#include <AknsConstants.h>
#include <AknsUtils.h>
#include <fbs.h>
#include <gulicon.h>
#include <txtetext.h>
#include <hlplch.h> // For HlpLauncher
#include <csxhelp/postcard.hlp.hrh>
#include <cntfield.h>
#include <cntfldst.h>
#include <cntitem.h> // for ContactItem
#include <mtmdef.h> // TMsvPartList
#include <mtmuibas.h> // MTM UI
#include <msvapi.h>
#include <msvstd.hrh> // KUidMsvMessageEntryValue
#include <cmsvattachment.h>
#include <mmsvattachmentmanager.h>
#include <mmsvattachmentmanagersync.h>
#include <msgoperationwait.h> // for CMsgOperationWait
#include <MtmExtendedCapabilities.hrh> // for KMtmUiFunctionMessageInfo
#include <MuiuMsvUiServiceUtilities.h> // for Diskspace check
#include <muiumsvuiserviceutilitiesinternal.h> // for Offline mode check
#include <MsgEditorAppUi.rsg>
#include <MsgEditorAppUiExtension.h>// for iMsgEditorAppUiExtension (zoom)
#include <MsgEditorCommon.h>
#include <mmsclient.h>
#include <mmsmsventry.h>
#include <messaginginternalcrkeys.h>
#include <messagingvariant.hrh> // postcard feature (variation) bits
#include <MsgMediaResolver.h>
#include <MsgMedia.hrh> // TMmsMediaType
#include <MsgImageInfo.h>
#include <MsgMimeTypes.h>
#include <Postcard.rsg> // resource identifiers
#include <postcard.mbg> // icons
#include "Postcard.hrh" // for EPostcardCmds
#include "PostcardAddressForm.h" // for editing recipient address
#include "PostcardAppUi.h" // class header
#include "PostcardCenRep.h"
#include "PostcardController.h" // Controller class
#include "PostcardLaf.h"
#include "PostcardOperationInsertImage.h" // for inserting images
#include "PostcardOperationOpen.h" // for opening the application
#include "PostcardOperationSave.h" // for saving or sending the postcard
#include "PostcardPointerObserver.h"// MPocaPointerEventObserver
#include "PostcardPrivateCRKeys.h" // cenrep keys
#include "PostcardQueryWaiter.h" // for PostcardQueryWaiter
#include "PostcardTextDialog.h" // for editing greeting text
#include "PostcardUtils.h"
// ========== EXTERNAL DATA STRUCTURES =====================
// ========== EXTERNAL FUNCTION PROTOTYPES =================
// ========== CONSTANTS ====================================
const TInt KPostcardMaxSendConfirmationLength = 320;
const TInt KPostcardMaxMiniatureCharsPerLine = 100;
const TInt KPostcardLegacyWidth = 208; // the width of legacy display
const TInt KPostcardQvgaWidth = 320; // the width of legacy display
const TInt KPostcardMaxAddressFocusLines = 5; // max number of address focus lines
// ========== MACROS =======================================
// ========== LOCAL CONSTANTS AND MACROS ===================
// ========== MODULE DATA STRUCTURES =======================
// ========== LOCAL FUNCTION PROTOTYPES ====================
// ========== LOCAL FUNCTIONS ==============================
// ========== MEMBER FUNCTIONS =============================
// ---------------------------------------------------------
// CPostcardAppUi::CPostcardAppUi
// ---------------------------------------------------------
CPostcardAppUi::CPostcardAppUi()
{
}
// ---------------------------------------------------------
// CPostcardAppUi::ConstructL
// ---------------------------------------------------------
void CPostcardAppUi::ConstructL()
{
CMsgEditorAppUi::ConstructL();
// We don't have any app ui if launched from idle
if ( iEikonEnv->EikAppUi() )
{
iAbsorber = CAknInputBlock::NewLC();
CleanupStack::Pop( iAbsorber );
}
// Create central repository interface
iCenRep = CPostcardCenRep::NewL();
// initialize feature manager to check supported features
FeatureManager::InitializeLibL();
if ( FeatureManager::FeatureSupported( KFeatureIdCamera ) )
{
iPocaFlags |= EPostcardCamcorder;
}
if( FeatureManager::FeatureSupported( KFeatureIdHelp ) )
{
iPocaFlags |= EPostcardHelp;
}
if( FeatureManager::FeatureSupported( KFeatureIdOfflineMode ) )
{
iPocaFlags |= EPostcardFeatureOffline;
}
FeatureManager::UnInitializeLib( );
// In case the postcard application is installed somewhere else than "Z" drive
// we find out the right drive for postcard resource file
TParse parseDrive;
parseDrive.Set( Application( )->AppFullName( ), NULL, NULL );
TPtrC drive = parseDrive.Drive( );
TParse parse;
parse.Set( KPostcardResourceFile, &KDC_APP_RESOURCE_DIR, NULL );
TFileName fileName( parse.FullName() );
fileName.Insert( 0, drive );
BaflUtils::NearestLanguageFile( iCoeEnv->FsSession(), fileName );
iResourceFile = iEikonEnv->AddResourceFileL( fileName );
parse.Set( KMsgEditorAppUiResourceFile, &KDC_RESOURCE_FILES_DIR, NULL );
fileName.Zero( );
fileName.Append( parse.FullName() );
BaflUtils::NearestLanguageFile( iCoeEnv->FsSession(), fileName );
iBaseResourceFile = iEikonEnv->AddResourceFileL( fileName );
iNaviPane = static_cast<CAknNavigationControlContainer*>
( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) );
iTitlePane = static_cast<CAknTitlePane*>
( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) );
if( !iEikonEnv->StartedAsServerApp( ) )
{
Document().PrepareToLaunchL( this );
}
iIdle = CPeriodic::NewL( EPriorityNormal - 1 );
}
// ---------------------------------------------------------
// CPostcardAppUi::~CPostcardAppUi
// ---------------------------------------------------------
CPostcardAppUi::~CPostcardAppUi()
{
// remove resource file from CONE-maintained resource file list.
if ( iResourceFile )
{
iEikonEnv->DeleteResourceFile( iResourceFile );
}
if ( iBaseResourceFile )
{
iEikonEnv->DeleteResourceFile( iBaseResourceFile );
}
delete iController;
delete iGreeting;
delete iContact;
delete iImageInfo;
delete iIdle;
delete iAppIcon;
if( iMessageQuery )
{
iMessageQuery->CancelMsgQuery();
delete iMessageQuery;
iMessageQuery = NULL;
}
delete iSendText;
delete iCenRep;
}
// ---------------------------------------------------------
// LaunchViewL
// ---------------------------------------------------------
void CPostcardAppUi::LaunchViewL()
{
// First show wait note and start the launch process
ShowWaitNoteL( R_POSTCARD_WAIT_OPENING, EFalse );
const TMsvEntry& entry = Document( ).Entry( );
if ( entry.iType.iUid != KUidMsvMessageEntryValue )
{
User::Leave( KErrGeneral );
}
TRAPD( error, Document( ).Mtm( ).LoadMessageL( ) );
if ( error )
{
User::Leave( error );
}
Document( ).SetMessageType( );
if ( !entry.ReadOnly() ) // editor
{
// End key should not close application in editor
CMsgEditorAppUi::SetCloseWithEndKey( EFalse );
}
if( entry.ReadOnly() && !iNaviDecorator )
{
CreateViewerNaviPaneL( Document().Entry().iDate, EMsgEditorMsgPriorityNormal, ETrue );
iNaviPane->PushL( *iNaviDecorator ); // <- This has nothing to do with cleanup-stack!
}
delete iAbsorber;
iAbsorber = NULL;
iController = CPostcardController::NewL( Document()
#ifdef RD_SCALABLE_UI_V2
, *this
#endif
);
CreateAndSetTitleIconL();
RefreshFocusLinesL( );
iOperation = CPostcardOperationOpen::NewL(
*this,
Document(),
*this,
FsSession() );
iOperation->Start( EFalse );
}
// ---------------------------------------------------------
// CanSaveMessageL
// ---------------------------------------------------------
TBool CPostcardAppUi::CanSaveMessageL( TInt aAmount )
{
return !( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL(
Document().Session(),
aAmount ) );
}
// ---------------------------------------------------------
// DoMsgSaveExitL - called from options menu
// ---------------------------------------------------------
void CPostcardAppUi::DoMsgSaveExitL()
{
if( iMsgType == EPostcardSent )
{ // Msg is a sent one so just close the application
Exit();
return;
}
if ( CAknEnv::AppWithShutterRunning() )
{
iPocaFlags |= EPostcardRunAppShutterAtExit;
}
if ( IsMessageEmpty() )
{
if ( Document().Mtm().Entry().Entry().Visible() )
{
ShowInformationNoteL( R_POSTCARD_MESSAGE_DELETED, ETrue );
}
DeleteCurrentEntryL();
}
else if ( Document( ).Modified( ) && CanSaveMessageL() )
{
if ( IsForeground() )
{
TInt resId = R_POSTCARD_SAVING_NEW;
if( iMsgType == EPostcardDraft )
{ // We are saving an old postcard
resId = R_POSTCARD_SAVING;
}
iPocaFlags |= EPostcardClosing;
DoSaveL();
ShowWaitNoteL( resId, EFalse );
}
else
{
TRAP_IGNORE( DoSaveL() );
}
BeginActiveWait();
if ( iPocaFlags & EPostcardRunAppShutterAtExit )
{
RunAppShutter();
}
}
}
// ---------------------------------------------------------
// CompleteLaunchViewL
// ---------------------------------------------------------
void CPostcardAppUi::CompleteLaunchViewL( )
{
iController->ActivateL( );
RemoveWaitNote( );
iMsgType = Document( ).MessageType( );
if( iMsgType == EPostcardSent )
{
iController->SetFocused( EPostcardImage );
}
else
{
iController->SetFocused( EPostcardRecipient );
// If postcard editor is opened then disable the dialer
iAvkonAppUi->SetKeyEventFlags(
CAknAppUiBase::EDisableSendKeyShort |
CAknAppUiBase::EDisableSendKeyLong );
}
SetMiddleSoftkeyL(); // set msk for this view
if( iMsgType == EPostcardSendAs )
{
CheckLengthsL( );
}
else if( iMsgType == EPostcardForward )
{
DoEditAddressL( );
}
iController->DrawDeferred( );
iPocaFlags |= EPostcardLaunchSuccessful;
}
// ---------------------------------------------------------
// CPostcardAppUi::HandleKeyEventL
// ---------------------------------------------------------
TKeyResponse CPostcardAppUi::HandleKeyEventL(
const TKeyEvent& aKeyEvent, TEventCode aType )
{
if ( !Document( ).IsLaunched( ) )
{ // still launching
return EKeyWasConsumed;
}
if( aType != EEventKey )
{
return EKeyWasNotConsumed;
}
switch ( aKeyEvent.iCode )
{
case EKeyOK:
case EKeyEnter: //Enter Key
{
// Selection key: Show context menus
DoSelectionKeyL();
return EKeyWasConsumed;
}
case EKeyYes:
{
// In view mode there's no function in Yes key
if( iMsgType != EPostcardSent )
{
if( !ContactHasData( *iContact ) )
{ // If there's no contact data -> open edit address dialog
DoEditAddressL( );
}
else
{ // Else start sending process
DoSendL( );
}
}
return EKeyWasConsumed;
}
case EKeyBackspace:
case EKeyDelete:
{
// Either delete image or the whole postcard entry
DoBackspaceL( );
return EKeyWasConsumed;
}
default:
break;
}
switch ( aKeyEvent.iScanCode )
{
case EStdKeyLeftArrow: // FALLTHROUGH
case EStdKeyRightArrow:
if( iMsgType == EPostcardSent && iController->Focused( ) == EPostcardImage )
{
return NavigateBetweenMessagesL(
aKeyEvent.iScanCode == EStdKeyRightArrow ?
ETrue : EFalse );
}
//lint -fallthrough
case EStdKeyUpArrow: // FALLTHROUGH
case EStdKeyDownArrow: // FALLTHROUGH
{
if( !( iPocaFlags & EPostcardGreetingActive ) &&
!( iPocaFlags & EPostcardRecipientActive ) )
{
iController->Move( aKeyEvent.iScanCode );
SetMiddleSoftkeyL(); // set msk for this view
if ( iMsgType == EPostcardSent )
{
// In viewer
if ( iController->Focused() != EPostcardImage )
{
// Viewer does not have navigation arrows in text side
iNaviPane->Pop( iNaviDecorator );
}
else
{
iNaviPane->PushL( *iNaviDecorator );
}
}
}
return EKeyWasConsumed;
}
default:
{
if( iMsgType != EPostcardSent && iController->Focused( ) == EPostcardText )
{
if( !( iPocaFlags & EPostcardGreetingActive ) )
{
if( aKeyEvent.iCode >= 35 && aKeyEvent.iCode <= 255 )
{
DoEditGreetingL( aKeyEvent );
}
}
}
else if( iMsgType != EPostcardSent && iController->Focused( ) == EPostcardRecipient )
{
if( !( iPocaFlags & EPostcardRecipientActive ) )
{
if( aKeyEvent.iCode >= 35 && aKeyEvent.iCode <= 255 )
{
DoEditAddressL( aKeyEvent );
}
}
}
break;
}
}
return EKeyWasNotConsumed;
}
// ---------------------------------------------------------
// HandleCommandL
// ---------------------------------------------------------
void CPostcardAppUi::HandleCommandL( TInt aCommand )
{
if ( aCommand != EEikCmdExit &&
!Document().IsLaunched() )
{
return;
}
switch (aCommand)
{
case EPostcardCmdSend:
DoSendL( );
break;
case EPostcardCmdEditAddress:
DoEditAddressL( );
break;
case EPostcardCmdEditGreeting:
DoEditGreetingL( );
break;
case EPostcardCmdInsertFromGallery:
DoInsertImageL( MsgAttachmentUtils::EImage );
break;
case EPostcardCmdInsertFromCamera:
DoInsertImageL( MsgAttachmentUtils::ENewImage );
break;
case EPostcardCmdReplaceFromGallery:
DoInsertImageL( MsgAttachmentUtils::EImage );
break;
case EPostcardCmdReplaceFromCamera:
DoInsertImageL( MsgAttachmentUtils::ENewImage );
break;
case EPostcardCmdDelete:
DoBackspaceL( );
break;
case EPostcardCmdMessageInfo:
DoUpdateEntryAndShowMessageInfoL( );
break;
case EPostcardCmdForward:
DoForwardMessageL( );
break;
case EAknSoftkeyClose:
DoBackSaveL( );
break;
case EAknSoftkeyEdit: // falltrough
case EAknSoftkeyOpen:
DoSelectionKeyL( );
break;
case EAknCmdHelp:
{
if( iMsgType == EPostcardSent )
{
LaunchHelpL( KMMS_POSTCARD_HLP_MAIN_VIEW() );
}
else
{
LaunchHelpL( KMMS_POSTCARD_HLP_MAIN_EDIT() );
}
break;
}
case EAknCmdExit:
case EEikCmdExit:
RemoveWaitNote();
ExitAndSaveL();
break;
default:
break;
}
return;
}
// ---------------------------------------------------------
// DynInitMenuPaneL
// ---------------------------------------------------------
void CPostcardAppUi::DynInitMenuPaneL( TInt aMenuId, CEikMenuPane* aMenuPane )
{
switch ( aMenuId )
{
case R_POSTCARD_MAIN_OPTIONS:
DynInitMainMenuL( aMenuPane );
break;
case R_POSTCARD_INSERT_SUBMENU:
case R_POSTCARD_REPLACE_SUBMENU:
DynInitInsertSubMenuL( aMenuPane );
break;
case R_POSTCARD_CONTEXT_OPTIONS:
DynInitContextMenuL( aMenuPane );
break;
default:
break;
}
}
// ---------------------------------------------------------
// DynInitMainMenuL
// ---------------------------------------------------------
void CPostcardAppUi::DynInitMainMenuL( CEikMenuPane* aMenuPane )
{
aMenuPane->SetItemDimmed( EPostcardCmdSend,
IsMainMenuOptionInvisible( EPostcardCmdSend ));
aMenuPane->SetItemDimmed( EPostcardCmdEditAddress,
IsMainMenuOptionInvisible( EPostcardCmdEditAddress ));
aMenuPane->SetItemDimmed( EPostcardCmdEditGreeting,
IsMainMenuOptionInvisible( EPostcardCmdEditGreeting ));
aMenuPane->SetItemDimmed( EPostcardCmdInsertSubmenu,
IsMainMenuOptionInvisible( EPostcardCmdInsertSubmenu ));
aMenuPane->SetItemDimmed( EPostcardCmdReplaceSubmenu,
IsMainMenuOptionInvisible( EPostcardCmdReplaceSubmenu ));
aMenuPane->SetItemDimmed( EPostcardCmdInsertFromGallery,
IsMainMenuOptionInvisible( EPostcardCmdInsertFromGallery ));
aMenuPane->SetItemDimmed( EPostcardCmdReplaceFromGallery,
IsMainMenuOptionInvisible( EPostcardCmdReplaceFromGallery ));
aMenuPane->SetItemDimmed( EPostcardCmdForward,
IsMainMenuOptionInvisible( EPostcardCmdForward ));
aMenuPane->SetItemDimmed( EPostcardCmdDelete,
IsMainMenuOptionInvisible( EPostcardCmdDelete ));
aMenuPane->SetItemDimmed( EPostcardCmdMessageInfo,
IsMainMenuOptionInvisible( EPostcardCmdMessageInfo ));
aMenuPane->SetItemDimmed( EAknCmdHelp,
IsMainMenuOptionInvisible( EAknCmdHelp ));
aMenuPane->SetItemDimmed( EAknCmdExit,
IsMainMenuOptionInvisible( EAknCmdExit ));
}
// ---------------------------------------------------------
// DynInitInsertSubMenuL
// ---------------------------------------------------------
void CPostcardAppUi::DynInitInsertSubMenuL( CEikMenuPane* aMenuPane )
{
// If insert/replace submenu is visible -> from Gallery is always visible!
if ( !iImage )
{
aMenuPane->SetItemDimmed( EPostcardCmdInsertFromCamera,
IsMainMenuOptionInvisible( EPostcardCmdInsertFromCamera ));
}
else
{
aMenuPane->SetItemDimmed( EPostcardCmdReplaceFromCamera,
IsMainMenuOptionInvisible( EPostcardCmdReplaceFromCamera ));
}
}
// ---------------------------------------------------------
// DynInitContextMenuL
// ---------------------------------------------------------
void CPostcardAppUi::DynInitContextMenuL( CEikMenuPane* aMenuPane )
{
aMenuPane->SetItemDimmed( EPostcardCmdInsertSubmenu,
IsMainMenuOptionInvisible( EPostcardCmdInsertSubmenu ));
aMenuPane->SetItemDimmed( EPostcardCmdReplaceSubmenu,
IsMainMenuOptionInvisible( EPostcardCmdReplaceSubmenu ));
aMenuPane->SetItemDimmed( EPostcardCmdInsertFromGallery,
IsMainMenuOptionInvisible( EPostcardCmdInsertFromGallery ));
aMenuPane->SetItemDimmed( EPostcardCmdReplaceFromGallery,
IsMainMenuOptionInvisible( EPostcardCmdReplaceFromGallery ));
}
// ---------------------------------------------------------
// IsMainMenuOptionInvisible
// ---------------------------------------------------------
TBool CPostcardAppUi::IsMainMenuOptionInvisible( TInt aMenuItem )
{
TBool retVal( ETrue ); // Everything first invisible
TPostcardPart focused = iController->Focused( );
switch ( aMenuItem )
{
case EPostcardCmdSend:
if( iMsgType != EPostcardSent )
{
if( ContactHasData( *iContact ) )
{
// If there's contact data -> show "Send"
retVal = EFalse;
}
}
break;
case EPostcardCmdEditAddress:
if( iMsgType != EPostcardSent && focused != EPostcardImage )
{
retVal = EFalse;
}
break;
case EPostcardCmdEditGreeting:
if( iMsgType != EPostcardSent && focused != EPostcardImage )
{
retVal = EFalse;
}
break;
case EPostcardCmdInsertSubmenu:
if( iMsgType != EPostcardSent && !iImage )
{
if( iPocaFlags & EPostcardCamcorder )
{
retVal = EFalse;
}
}
break;
case EPostcardCmdReplaceSubmenu:
if( iMsgType != EPostcardSent && iImage )
{
if( iPocaFlags & EPostcardCamcorder )
{
retVal = EFalse;
}
}
break;
case EPostcardCmdInsertFromGallery:
if( iMsgType != EPostcardSent && !iImage )
{
if( !(iPocaFlags & EPostcardCamcorder ) )
{
retVal = EFalse;
}
}
break;
case EPostcardCmdReplaceFromGallery:
if( iMsgType != EPostcardSent && iImage )
{
if( !(iPocaFlags & EPostcardCamcorder ) )
{
retVal = EFalse;
}
}
break;
case EPostcardCmdInsertFromCamera:
if( iMsgType != EPostcardSent )
{
if( iPocaFlags & EPostcardCamcorder )
{
retVal = EFalse;
}
}
break;
case EPostcardCmdReplaceFromCamera:
if( iMsgType != EPostcardSent && iImage )
{
if( iPocaFlags & EPostcardCamcorder )
{
retVal = EFalse;
}
}
break;
case EPostcardCmdForward:
if( iMsgType == EPostcardSent )
{
retVal = EFalse;
}
break;
case EPostcardCmdDelete:
if( iMsgType == EPostcardSent )
{
retVal = EFalse;
}
break;
case EPostcardCmdMessageInfo:
retVal = EFalse;
break;
case EAknCmdHelp:
if( iPocaFlags & EPostcardHelp )
{
retVal = EFalse;
}
break;
case EAknCmdExit:
retVal = EFalse;
break;
default:
;
}
return retVal;
}
// ---------------------------------------------------------
// DoSendL
// ---------------------------------------------------------
void CPostcardAppUi::DoSendL()
{
// Let's first check all the fields are present
if( !iImage )
{
ShowInformationNoteL( R_POSTCARD_SEND_INSERT_IMAGE, EFalse );
iController->SetFocused( EPostcardImage );
SetMiddleSoftkeyL();
iController->DrawDeferred( );
return;
}
// Check that mandatory address fields are present
TInt mandatories = MandatoryAddressFields();
CContactItemFieldSet& fields = iContact->CardFields();
TBool allFilled = ETrue;
TInt i = EPostcardAddressName;
for( ; mandatories && allFilled ; i++, mandatories >>= 1 )
{
if( mandatories & 1 )
{
const CContactItemField* field = TPostcardUtils::FieldOrNull( fields,
TPostcardUtils::ContactItemNameFromId( i ) );
allFilled = ( field && field->TextStorage()->IsFull() );
}
}
// If not all filled, open the edit address dialog with the right field
if( !allFilled )
{
DoEditAddressL( TKeyEvent(), i - 1 );
return;
}
// Address is ok, let's still check the lengths..
if( !CheckLengthsL( ) )
{
return;
}
// Here we are ready to send -> now let's ask the confirmation
if( iMessageQuery )
{
iMessageQuery->CancelMsgQuery();
delete iMessageQuery;
iMessageQuery = NULL;
}
iMessageQuery = CAknGlobalMsgQuery::NewL();
HBufC* addressString = CreateAddressStringForSendConfirmLC();
delete iSendText; iSendText = NULL;
iSendText = StringLoader::LoadL( R_POSTCARD_RECIPIENT_PROMPT_TEXT,
*addressString );
CleanupStack::PopAndDestroy( addressString ); // addressString
CPostcardQueryWaiter* queryWaiter = new (ELeave) CPostcardQueryWaiter( this );
CleanupStack::PushL( queryWaiter );
iMessageQuery->ShowMsgQueryL(
queryWaiter->iStatus,
*iSendText,
R_AVKON_SOFTKEYS_SEND_CANCEL__SEND,
KNullDesC(),
KAvkonBitmapFile,
EMbmAvkonQgn_note_query,
EMbmAvkonQgn_note_query_mask );
queryWaiter->SetActiveD(); // Will be deleted when the query is dismissed.
CleanupStack::Pop( queryWaiter ); // queryWaiter
// The rest of the sending process is done in QueryWaiterCallback !!
}
// ---------------------------------------------------------
// DoSaveL
// ---------------------------------------------------------
void CPostcardAppUi::DoSaveL( )
{
if ( iOperation && iOperation->IsActive() )
{
// Save operation already in progress, don't start another
return;
}
delete iOperation;
iOperation = NULL;
iOperation = CPostcardOperationSave::NewL(
*this,
Document(),
*this,
FsSession( ),
*iContact,
*iGreeting
);
iOperation->Start( EFalse ); // EFalse means no sending
iAbsorber = CAknInputBlock::NewLC();
CleanupStack::Pop( iAbsorber );
}
// ---------------------------------------------------------
// DoBackSaveL
// ---------------------------------------------------------
void CPostcardAppUi::DoBackSaveL()
{
if( iMsgType == EPostcardSent )
{
// Msg is a sent one so just close the application
Exit( EAknSoftkeyClose );
return;
}
if ( IsMessageEmpty() )
{
if ( Document().Mtm().Entry().Entry().Visible() )
{
ShowInformationNoteL( R_POSTCARD_MESSAGE_DELETED, ETrue );
}
DeleteAndExitL();
}
else
{
TInt closeVal = ShowCloseQueryL( );
if ( closeVal == EPostcardCloseCancel )
{
// User cancels the query
return;
}
else if ( closeVal == EPostcardCloseDelete )
{
DeleteAndExitL();
}
else
{
// Save message
if ( Document( ).Modified( ) )
{
if ( CanSaveMessageL() )
{
TInt resId = R_POSTCARD_SAVING_NEW;
if( iMsgType == EPostcardDraft )
{
// We are saving an old postcard
resId = R_POSTCARD_SAVING;
}
iPocaFlags |= EPostcardClosing;
DoSaveL( );
ShowWaitNoteL( resId, ETrue );
BeginActiveWait();
}
else
{
if ( ShowConfirmationQueryL( R_POSTCARD_NO_SPACE_TO_SAVE ) )
{
// Exit without saving.
Exit( EAknSoftkeyClose );
}
//else nothing.
}
}
else
{
// No changes -> just close.
Exit( EAknSoftkeyClose );
}
}
}
}
// ---------------------------------------------------------
// IsMessageEmpty
// ---------------------------------------------------------
TBool CPostcardAppUi::IsMessageEmpty( )
{
if( !iImage && iGreetingLength == 0 &&
( !iContact || !ContactHasData( *iContact ) ) )
{
return ETrue;
}
return EFalse;
}
// ---------------------------------------------------------
// DoUpdateEntryAndShowMessageInfoL
// ---------------------------------------------------------
void CPostcardAppUi::DoUpdateEntryAndShowMessageInfoL( )
{
// First update the TMsvEntry
if( iMsgType != EPostcardSent )
{
// We are dealing with unsent message -> save recipient/text for now
TMmsMsvEntry tEntry = static_cast<TMmsMsvEntry>( Document().Entry() );
tEntry.iDate.UniversalTime();
// Let's find name field
_LIT( KEmptyName, "");
TPtrC namePtr( KEmptyName );
CContactItemFieldSet& fieldSet = iContact->CardFields();
for( TInt i = 0; i<fieldSet.Count(); i++ )
{
if( !fieldSet[i].Label().Compare( TPostcardUtils::ContactItemNameFromId( EPostcardAddressName ) ) )
{
namePtr.Set( fieldSet[i].TextStorage()->Text() );
break;
}
}
tEntry.iDetails.Set( namePtr ) ;
// Let's set the subject
tEntry.iDescription.Set(
iGreeting->Read( 0, Min( iGreetingLength, 20 ) ) );
tEntry.iBioType = KUidMsgSubTypeMmsPostcard.iUid;
Document().CurrentEntry().ChangeL( tEntry );
}
// And now call message info
DoShowMessageInfoL();
}
// ---------------------------------------------------------
// DoShowMessageInfoL
// ---------------------------------------------------------
void CPostcardAppUi::DoShowMessageInfoL()
{
// Selection is not really used, just given as a parameter
CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
CleanupStack::PushL( selection );
TBuf8<1> param;
param.Zero();
CMsvSingleOpWatcher* watch = CMsvSingleOpWatcher::NewLC( Document() );
CMsvOperation* op = Document().MtmUi().InvokeAsyncFunctionL(
KMtmUiFunctionMessageInfo,
*selection,
watch->iStatus,
param );
CleanupStack::Pop( watch ); // watch
Document().AddSingleOperationL( op, watch );
CleanupStack::PopAndDestroy( selection ); // selection
}
// ---------------------------------------------------------
// DoBackspaceL
// ---------------------------------------------------------
void CPostcardAppUi::DoBackspaceL( )
{
if( iMsgType == EPostcardSent )
{
if( ShowConfirmationQueryL( R_POSTCARD_DELETE_MESSAGE ) )
{
DeleteAndExitL( );
}
}
else
{
if( iController->Focused( ) == EPostcardImage && iImage )
{
if( ShowConfirmationQueryL( R_POSTCARD_REMOVE_IMAGE ) )
{
// Lets go thru the attas to find the right atta
CMsvStore* editStore = Document( ).Mtm( ).Entry( ).EditStoreL( );
MMsvAttachmentManager* manager = &( editStore->AttachmentManagerL( ) );
TInt count = manager->AttachmentCount( );
CMsvAttachment* atta = NULL;
TInt a = 0;
for( ; a < count; a++)
{
atta = manager->GetAttachmentInfoL( a );
CleanupStack::PushL( atta );
if( Document( ).IsImage( atta->MimeType( ) ) )
{
CleanupStack::PopAndDestroy( atta );
break;
}
CleanupStack::PopAndDestroy( atta );
}
if( a > -1 && a < count )
{
// and delete atta if found
editStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( a );
}
editStore->CommitL( );
delete editStore;
// Lets nullify the icon in Controller
iController->SetBitmap( EPostcardImage, NULL );
iImage = NULL;
// And draw the UI again
iController->DrawDeferred( );
}
}
}
}
// ---------------------------------------------------------
// DoForwardMessageL
// ---------------------------------------------------------
void CPostcardAppUi::DoForwardMessageL( )
{
TMsvPartList parts =
KMsvMessagePartBody |
KMsvMessagePartDescription |
KMsvMessagePartAttachments;
CBaseMtmUi& mtmUi = Document().MtmUi();
CMsgOperationWait* wait =
CMsgOperationWait::NewLC( EActivePriorityWsEvents + 10 );
mtmUi.SetPreferences( mtmUi.Preferences() | EMtmUiFlagEditorPreferEmbedded );
CMsvOperation* oper = mtmUi.ForwardL( KMsvDraftEntryIdValue, parts, wait->iStatus );
CleanupStack::PushL( oper );
wait->Start();
CleanupStack::PopAndDestroy( 2 ); // wait, oper
}
// ---------------------------------------------------------
// DoEditAddressL
// ---------------------------------------------------------
void CPostcardAppUi::DoEditAddressL( TKeyEvent aKeyEvent /*=TKeyEvent()*/,
TInt aFirstFocused /*=-1*/)
{
CPostcardAddressForm* form = NULL;
TInt ret = 0;
iController->SetFocused( EPostcardRecipient );
form = CPostcardAddressForm::NewL( *this, Document(), *iContact, ret,
aFirstFocused, aKeyEvent );
form->SetMopParent( iController );
iPocaFlags |= EPostcardRecipientActive;
// Form might leave with KLeaveExit from CPostcardContact,
// so we need to trap it and take proper actions. If it leaves,
// it means that Messaging is closed from FSW and there has been
// an active AIW to phonebook.
TRAPD( err, form->ExecLD() );
iPocaFlags &= ~EPostcardRecipientActive;
if ( err )
{
// form must be deleted here, since for some reason its destructor is
// not called, if leave oocurs in ExecLD.
delete form;
form = NULL;
User::Leave( err );
}
if( ret == EPostcardDialogExit )
{
// If exit -> we need to save if possible
iPocaFlags |= EPostcardExitCalledFromDialog;
if ( Document( ).Modified( ) )
{
if ( CanSaveMessageL() )
{
TInt resId = R_POSTCARD_SAVING;
ShowWaitNoteL( resId, ETrue );
DoSaveL( );
}
else
{
// No space -> exit without saving.
Exit( EEikCmdExit );
}
}
else
{
Exit( EEikCmdExit );
}
}
else if( iMsgType == EPostcardSent )
{
if( ret == EPostcardDialogForward )
{
DoForwardMessageL( );
return;
}
iController->DrawDeferred( );
}
else
{
Document( ).SetChanged( EPostcardRecipient );
iController->DrawDeferred( );
if( ret == EPostcardDialogSend )
{
DoSendL( );
}
}
}
// ---------------------------------------------------------
// DoEditGreetingL
// ---------------------------------------------------------
void CPostcardAppUi::DoEditGreetingL( TKeyEvent aKeyEvent )
{
CPostcardTextDialog* dialog = NULL;
TInt ret = 0;
iController->SetFocused( EPostcardText );
dialog = CPostcardTextDialog::NewL(*this, Document(), *iGreeting,
ret, aKeyEvent );
dialog->SetMopParent( iController );
iPocaFlags |= EPostcardGreetingActive;
TRAP_IGNORE( dialog->ExecLD() );
iPocaFlags &= ~EPostcardGreetingActive;
if( ret == EPostcardDialogExit )
{
// If exit -> we need to save if possible
iPocaFlags |= EPostcardExitCalledFromDialog;
if ( Document( ).Modified( ) )
{
if ( CanSaveMessageL() )
{
TInt resId = R_POSTCARD_SAVING;
ShowWaitNoteL( resId, ETrue );
DoSaveL( );
}
else
{
// No space -> exit without saving.
Exit( EEikCmdExit );
}
}
else
{
Exit( EEikCmdExit );
}
}
else if( iMsgType == EPostcardSent )
{
if( ret == EPostcardDialogForward )
{
DoForwardMessageL( );
return;
}
iController->DrawDeferred( );
}
else
{
Document( ).SetChanged( EPostcardText );
iController->DrawDeferred( );
if( ret == EPostcardDialogSend )
{
// Send chosen in greeting dialog
if( ContactHasData( *iContact ) )
{
// If there's contact data -> start sending
DoSendL( );
}
else
{
// If no contact data -> open address dialog
DoEditAddressL( );
}
}
}
}
// ---------------------------------------------------------
// DoInsertImageL
// ---------------------------------------------------------
void CPostcardAppUi::DoInsertImageL( MsgAttachmentUtils::TMsgAttachmentFetchType aFetchType )
{
iController->SetFocused( EPostcardImage );
SetMiddleSoftkeyL(); // set msk for the view
if ( FetchFileL( aFetchType ) )
{
// The file is selected and iImageInfo created
ShowWaitNoteL( R_POSTCARD_WAIT_INSERTING, EFalse );
iOperation = CPostcardOperationInsertImage::NewL(
*this,
Document(),
*this,
iImageInfo,
FsSession() );
iImageInfo = NULL; // ownership moves
iOperation->Start( EFalse );
iAbsorber = CAknInputBlock::NewLC();
CleanupStack::Pop( iAbsorber );
}
iController->DrawDeferred( );
}
// ---------------------------------------------------------
// FetchFileL
// ---------------------------------------------------------
TBool CPostcardAppUi::FetchFileL( MsgAttachmentUtils::TMsgAttachmentFetchType aFetchType )
{
CDesCArrayFlat* dummy = new ( ELeave ) CDesCArrayFlat( 1 );
CleanupStack::PushL( dummy );
TFileName fileName;
TBool fetchOK = MsgAttachmentUtils::FetchFileL(
aFetchType,
fileName,
*dummy,
ETrue,
EFalse,
this );
CleanupStack::PopAndDestroy( dummy );
switch ( aFetchType )
{
case MsgAttachmentUtils::ENewImage:
case MsgAttachmentUtils::ENewAudio:
case MsgAttachmentUtils::ENewVideo:
{
if ( fetchOK )
{
// Something was fetched
fetchOK = CreateMediaInfoForInsertL( fileName )
? ETrue
: EFalse;
}
}
break;
case MsgAttachmentUtils::EImage:
case MsgAttachmentUtils::EAudio:
case MsgAttachmentUtils::EVideo:
default:
// CreateMediaInfoForInsertL is called in VeritySelectionL
break;
}
return fetchOK;
}
// ---------------------------------------------------------
// VerifySelectionL
// ---------------------------------------------------------
TBool CPostcardAppUi::VerifySelectionL( const MDesCArray* aSelectedFiles )
{
CAknInputBlock* blocker = CAknInputBlock::NewLC();
TBool ret = EFalse;
if ( aSelectedFiles->MdcaCount() == 1 )
{
TPtrC ptr = aSelectedFiles->MdcaPoint( 0 );
if ( CreateMediaInfoForInsertL( ptr ) )
{
ret = ETrue;
}
}
CleanupStack::PopAndDestroy( blocker ); // Input blocker
return ret;
}
// ---------------------------------------------------------
// CreateMediaInfoForInsertL
// ---------------------------------------------------------
TBool CPostcardAppUi::CreateMediaInfoForInsertL( const TDesC& aFileName )
{
if( iImageInfo )
{
delete iImageInfo;
iImageInfo = NULL;
}
RFile fileHandle = Document().MediaResolver()->FileHandleL( aFileName );
CleanupClosePushL( fileHandle );
iImageInfo = static_cast<CMsgImageInfo*>( Document().MediaResolver()->CreateMediaInfoL( fileHandle ) );
Document().MediaResolver()->ParseInfoDetailsL( iImageInfo, fileHandle );
CleanupStack::PopAndDestroy( &fileHandle );
TInt errResId = 0;
if ( !CanSaveMessageL( iImageInfo->FileSize() ) )
{
User::Leave( KErrDiskFull );
}
// Supported type check
if( iImageInfo->Protection( ) )
{
errResId = R_POSTCARD_CANNOT_SEND_PROTECTED;
}
else if ( iImageInfo->Corrupt() )
{
// Corrupt is set to only supported media types
errResId = R_POSTCARD_OBJECT_CORRUPTED;
}
else if( !Document( ).IsImage( iImageInfo->MimeType( ) ) )
{
errResId = R_POSTCARD_FORMAT_NOT_SUPPORTED;
}
// DRM check
else if ( iImageInfo->MediaType() != EMsgMediaImage )
{
// Keep this after DRM check!
errResId = R_POSTCARD_FORMAT_NOT_SUPPORTED;
}
else if ( iImageInfo->IsAnimation( ) )
{
errResId = R_POSTCARD_FORMAT_NOT_SUPPORTED;
}
if ( errResId != 0 )
{
delete iImageInfo;
iImageInfo = NULL;
ShowInformationNoteL( errResId, EFalse );
return EFalse;
}
return ETrue;
}
// ---------------------------------------------------------
// DoSelectionKeyL
// ---------------------------------------------------------
void CPostcardAppUi::DoSelectionKeyL()
{
if( iMsgType != EPostcardSent )
{
// We are in editor mode
TPostcardPart focused = iController->Focused( );
switch ( focused )
{
case EPostcardImage:
{
MenuBar( )->SetMenuTitleResourceId( R_POSTCARD_CONTEXT_MENUBAR );
MenuBar()->SetMenuType(CEikMenuBar::EMenuContext);
// if display fails set old menu back
TRAPD( err, MenuBar( )->TryDisplayMenuBarL( ) );
MenuBar( )->SetMenuTitleResourceId( R_POSTCARD_MAIN_MENUBAR );
MenuBar()->SetMenuType(CEikMenuBar::EMenuOptions);
User::LeaveIfError( err );
break;
}
case EPostcardRecipient:
{
DoEditAddressL( );
break;
}
case EPostcardText:
{
DoEditGreetingL( );
break;
}
default:
break;
}
}
else
{
// We are in viewer mode
TPostcardPart focused = iController->Focused( );
switch ( focused )
{
case EPostcardImage:
{
break;
}
case EPostcardRecipient:
{
DoEditAddressL( );
break;
}
case EPostcardText:
{
DoEditGreetingL( );
break;
}
default:
break;
}
}
return;
}
// ---------------------------------------------------------
// LaunchHelpL
// ---------------------------------------------------------
void CPostcardAppUi::LaunchHelpL( const TDesC& aContext )
{
CArrayFix<TCoeHelpContext>*
helpContext = new(ELeave) CArrayFixFlat<TCoeHelpContext>( 1 );
TCoeHelpContext context( TUid::Uid(0x10207247), aContext );
helpContext->AppendL( context );
HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession( ), helpContext );
}
// ---------------------------------------------------------
// FsSession
// ---------------------------------------------------------
RFs& CPostcardAppUi::FsSession() const
{
return ( iCoeEnv->FsSession() );
}
#ifdef RD_SCALABLE_UI_V2
// ---------------------------------------------------------
// CPostcardAppUi::PocaPointerEvent
// ---------------------------------------------------------
void CPostcardAppUi::PocaPointerEventL( TPocaPointerEvent aEvent,
TPocaPointerEventType aEventType )
{
if ( AknLayoutUtils::PenEnabled() )
{
// Handle pointer (pen) events to areas in main pane
switch( aEvent )
{
case EPocaPointerEventUpIcon:
case EPocaPointerEventDownIcon:
iController->MoveVertically( aEvent == EPocaPointerEventUpIcon ? ETrue : EFalse );
if ( iMsgType == EPostcardSent )
{
// In viewer
if ( iController->Focused() != EPostcardImage )
{
// Viewer does not have navigation arrows in text side
iNaviPane->Pop( iNaviDecorator );
}
else
{
iNaviPane->PushL( *iNaviDecorator );
}
}
break;
case EPocaPointerEventGreeting:
if( iController->Focused() == EPostcardText )
{
DoSelectionKeyL();
}
else
{
iController->MoveHorizontally(
aEvent == EPocaPointerEventAddress ? ETrue : EFalse );
}
break;
case EPocaPointerEventAddress:
if( iController->Focused() == EPostcardRecipient )
{
DoSelectionKeyL();
}
else
{
iController->MoveHorizontally(
aEvent == EPocaPointerEventAddress ? ETrue : EFalse );
}
break;
case EPocaPointerEventFrontBg: // front picture area
DoSelectionKeyL();
break;
default:
;
}
SetMiddleSoftkeyL(); // set msk for the view
}
else
{
// Suppress warnings
aEvent = aEvent;
aEventType = aEventType;
}
}
#endif // RD_SCALABLE_UI_V2
// ---------------------------------------------------------
// CPostcardAppUi::MenuBar
// Returns application menubar.
// ---------------------------------------------------------
CEikMenuBar* CPostcardAppUi::MenuBar() const
{
return iEikonEnv->AppUiFactory()->MenuBar();
}
// ---------------------------------------------------------
// CPostcardAppUi::HandleResourceChangeL
// ---------------------------------------------------------
void CPostcardAppUi::HandleResourceChangeL(TInt aType)
{
CMsgEditorAppUi::HandleResourceChangeL(aType);
if ( aType == KEikDynamicLayoutVariantSwitch )
{
// The layout is changing -> reread coordinates
if ( iController )
{
iController->RefreshCoordinates( );
}
if ( iGreetingLength )
{
CreateGreetingBitmapL( );
}
if ( ContactHasData( ) )
{
RefreshRecipientBitmapL( );
}
RefreshFocusLinesL( );
if ( iController )
{
iController->DrawDeferred( );
}
SetTitleIconL();
}
else if ( aType == KAknsMessageSkinChange )
{
CreateAndSetTitleIconL();
// The skin is changing -> recreate icons and refresh coordinates
if( iController )
{
iController->ReLoadIconsL( );
}
}
}
// ---------------------------------------------------------
// CPostcardAppUi::ShowCloseQueryL
// ---------------------------------------------------------
TInt CPostcardAppUi::ShowCloseQueryL()
{
TInt selectedIndex( 0 );
CAknListQueryDialog* dlg = new ( ELeave ) CAknListQueryDialog( &selectedIndex );
dlg->PrepareLC( R_POSTCARD_CLOSE_QUERY );
if ( dlg->RunLD() )
{
return ( selectedIndex == 0 )
? EPostcardCloseSave
: EPostcardCloseDelete;
}
else
{
return EPostcardCloseCancel;
}
}
// ---------------------------------------------------------
// CPostcardAppUi::ExitAndSaveL
// ---------------------------------------------------------
void CPostcardAppUi::ExitAndSaveL()
{
if ( iPocaFlags & EPostcardClosing )
{
Exit( EAknSoftkeyClose );
return;
}
if ( CAknEnv::AppWithShutterRunning() )
{
iPocaFlags |= EPostcardRunAppShutterAtExit;
}
if ( iPocaFlags & EPostcardLaunchSuccessful &&
Document().MediaAvailable() )
{
DoMsgSaveExitL();
}
Exit();
}
// ---------------------------------------------------------
// CPostcardAppUi::PostcardOperationEvent
// ---------------------------------------------------------
void CPostcardAppUi::PostcardOperationEvent(
TPostcardOperationType aOperation,
TPostcardOperationEvent aEvent )
{
// If a large image is inserted, it may take enough time for a screen
// backlight to go off. It wouldn't reactivate unless inactivity timer
// is reseted (or user presses a key).
User::ResetInactivityTime();
delete iAbsorber;
iAbsorber = NULL;
if( aOperation == EPostcardOperationOpen )
{
if( aEvent == EPostcardOperationError )
{
RemoveWaitNote( );
TInt error = iOperation->GetError( );
if( error == R_POSTCARD_FORMAT_NOT_SUPPORTED ||
error == R_POSTCARD_MULTIPLE_FILES ||
error == R_POSTCARD_CANNOT_SEND_PROTECTED ||
error == R_POSTCARD_PROCESS_NOT_SUCCESSFUL ||
error == R_POSTCARD_OBJECT_CORRUPTED )
{
TRAP_IGNORE( ShowInformationNoteL( error, EFalse ) );
}
iOperation->Cancel( );
delete iOperation;
iOperation = NULL;
TRAP_IGNORE( iController->ActivateL( ) ); // This is called to give infonote more time
DoDelayedExit( 0 );
}
else
{
// Delete opening operation. CompleteLaunchViewL() may start
// a save operation.
delete iOperation;
iOperation = NULL;
// Change state only if opening an existing message. State for a changed
// item is changed when it is really edited. This prevents saving of empty
// messages to drafts.
if ( Document().MessageType() != EPostcardNew &&
Document().MessageType() != EPostcardSent )
{
if ( iImage )
{
Document().SetChanged( EPostcardImage );
}
if ( iGreeting )
{
Document().SetChanged( EPostcardText );
}
if ( iContact )
{
Document().SetChanged( EPostcardRecipient );
}
}
TRAP_IGNORE( CompleteLaunchViewL( ) );
}
}
else if( aOperation == EPostcardOperationSave )
{
if( iOperation->GetError( ) )
{
TRAP_IGNORE( ShowGlobalInformationNoteL( iOperation->GetError( ), EFalse ) );
}
delete iOperation;
iOperation = NULL;
RemoveWaitNote();
if( aEvent == EPostcardOperationError )
{
Exit( EAknSoftkeyClose );
}
else
{
DoDelayedExit( 0 );
}
EndActiveWait();
}
else
{
// Insert image operation
TInt error = iOperation->GetError( );
if( error )
{
if( error == R_POSTCARD_FORMAT_NOT_SUPPORTED ||
error == R_POSTCARD_PROCESS_NOT_SUCCESSFUL )
{
TRAP_IGNORE( ShowInformationNoteL( error, EFalse ) );
}
}
delete iOperation;
iOperation = NULL;
delete iImageInfo;
iImageInfo = NULL;
RemoveWaitNote( );
iController->DrawDeferred( );
Document( ).SetChanged( EPostcardImage );
}
}
// ---------------------------------------------------------
// DoDelayedExit
// ---------------------------------------------------------
void CPostcardAppUi::DoDelayedExit( TInt aDelayTime )
{
// Coverty fix , Forward NULL http://ousrv057/cov.cgi?cid=36248
if ( iIdle )
{
iIdle->Cancel();
iIdle->Start( aDelayTime,
aDelayTime,
TCallBack( DelayedExit, this ));
}
}
// ---------------------------------------------------------
// DelayedExit
// ---------------------------------------------------------
TInt CPostcardAppUi::DelayedExit( TAny* aThis )
{
CPostcardAppUi* editor = static_cast<CPostcardAppUi*>( aThis );
editor->DoExternalExit();
CAknEnv::RunAppShutter( );
return KErrNone;
}
// ---------------------------------------------------------
// DoExternalExit
// ---------------------------------------------------------
void CPostcardAppUi::DoExternalExit()
{
RemoveWaitNote( );
if( iOperation )
{
delete iOperation;
iOperation = NULL;
}
if( iPocaFlags & EPostcardExitCalledFromDialog )
{
Exit( EAknCmdExit );
}
else
{
Exit( EAknSoftkeyClose );
}
}
// ---------------------------------------------------------
// CPostcardAppUi::SetImageL
// ---------------------------------------------------------
void CPostcardAppUi::SetImage( CGulIcon* aIcon )
{
iImage = aIcon;
iController->SetBitmap( EPostcardImage, aIcon );
}
// ---------------------------------------------------------
// CPostcardAppUi::SetTextL
// ---------------------------------------------------------
void CPostcardAppUi::SetTextL( CPlainText& aPlainText )
{
delete iGreeting;
iGreeting = &aPlainText;
iGreetingLength = iGreeting->DocumentLength();
if( iGreetingLength )
{
CreateGreetingBitmapL( );
}
else
{
iController->RemoveBitmap( EPostcardText );
}
}
// ---------------------------------------------------------
// CPostcardAppUi::MaxTextLength
// ---------------------------------------------------------
TInt CPostcardAppUi::MaxTextLength( TInt aControlId )
{
const TInt KFirstControlId = EPostcardTextEditor;
__ASSERT_DEBUG( aControlId >= KFirstControlId &&
aControlId <= EPostcardAddressCountry, Panic( EPostcardPanicCoding ) );
// Keys has to be in the same order in the table as control IDs in
// TPostcardControls
static const TUint32 keys[ENumPostcardControls] =
{
KPocaKeyMaxGreetingLength, KPocaKeyMaxNameLength,
KPocaKeyMaxInfoLength, KPocaKeyMaxStreetLength,
KPocaKeyMaxZipLength, KPocaKeyMaxCityLength,
KPocaKeyMaxStateLength, KPocaKeyMaxCountryLength
};
return iCenRep->Get( keys[ aControlId - KFirstControlId ] );
}
// ---------------------------------------------------------
// CPostcardAppUi::CenRep
// ---------------------------------------------------------
const CPostcardCenRep& CPostcardAppUi::CenRep()
{
return *iCenRep;
}
// ---------------------------------------------------------
// CPostcardAppUi::SetRecipientL
// ---------------------------------------------------------
void CPostcardAppUi::SetRecipientL( CContactCard& aRecipient )
{
delete iContact;
iContact = &aRecipient;
if( !ContactHasData( aRecipient ) )
{
iController->RemoveBitmap( EPostcardRecipient );
return;
}
RefreshRecipientBitmapL( );
}
// ---------------------------------------------------------
// CPostcardAppUi::RefreshRecipientBitmapL
// ---------------------------------------------------------
void CPostcardAppUi::RefreshRecipientBitmapL( )
{
// Get the contact set
CContactItemFieldSet& set = iContact->CardFields( );
CDesCArrayFlat* strings = new (ELeave) CDesCArrayFlat( CPostcardAddressForm::ENumAddrFields );
CleanupStack::PushL( strings );
CArrayFixFlat<TInt>* indexes =
new ( ELeave ) CArrayFixFlat<TInt>(CPostcardAddressForm::ENumAddrFields);
CleanupStack::PushL( indexes );
for( TInt a=0; a<CPostcardAddressForm::ENumAddrFields; a++ )
{
indexes->AppendL(-1);
}
// Lets first find the indexes of different fields from the ContactItemFieldSet
for( TInt i = 0; i<set.Count( ); i++ )
{
CContactItemField& field = set[i];
for( TInt a = EPostcardAddressName; a <= EPostcardAddressCountry; a++ )
{
if( !field.Label( ).Compare( TPostcardUtils::ContactItemNameFromId( a ) ) )
{ // Label found so store the index of ContactItemField
indexes->Delete( a-EPostcardAddressName ); // remove -1
indexes->InsertL( a-EPostcardAddressName, i ); // add right one
continue;
}
}
}
// Lets put them into right order
for( TInt a = EPostcardAddressName; a<=EPostcardAddressCountry; a++ )
{
TInt id = indexes->At( a - EPostcardAddressName );
if( id != -1 )
{
CContactItemField& field = set[ id ];
if( field.TextStorage( )->Text( ).Length( ) > 0 )
{
strings->AppendL( field.TextStorage()->Text() );
}
}
}
CleanupStack::PopAndDestroy( indexes );
// And create a transparent bitmap of the address strings
CGulIcon* icon = CreateTransparentIconL( *strings );
iController->SetBitmap( EPostcardRecipient, icon );
CleanupStack::PopAndDestroy( strings );
}
// ---------------------------------------------------------
// CreateGreetingBitmapL
// ---------------------------------------------------------
void CPostcardAppUi::CreateGreetingBitmapL( )
{
TPtrC16 text( iGreeting->Read( 0, iGreetingLength ) );
CGulIcon* icon = CreateTransparentIconL( text );
iController->SetBitmap( EPostcardText, icon );
}
// ---------------------------------------------------------
// CreateTransparentIconL
// ---------------------------------------------------------
CGulIcon* CPostcardAppUi::CreateTransparentIconL( const TDesC& aText )
{
TSize iconSize = PostcardLaf::GreetingText( ).Size( );
// The bitmap
CFbsBitmap* bitmap = CreateEmptyBitmapLC( iconSize ); // pushes to stack
// The mask bitmap
CFbsBitmap* bitmapMask = new (ELeave) CFbsBitmap( );
CleanupStack::PushL( bitmapMask );
bitmapMask->Create( iconSize, EGray2 );
CFbsBitmapDevice* deviceMask = CFbsBitmapDevice::NewL( bitmapMask );
CleanupStack::PushL( deviceMask );
CBitmapContext* contextMask = NULL;
deviceMask->CreateBitmapContext( contextMask );
CleanupStack::PushL( contextMask );
contextMask->SetPenStyle(CGraphicsContext::ENullPen);
contextMask->SetBrushStyle(CGraphicsContext::ESolidBrush);
contextMask->SetBrushColor( KRgbBlack );
contextMask->DrawRect(TRect(TPoint(0,0), iconSize));
contextMask->SetPenStyle(CGraphicsContext::ESolidPen);
contextMask->SetBrushStyle(CGraphicsContext::ENullBrush);
contextMask->SetPenColor(KRgbWhite);
CFont* font = NULL;
CParaFormat paraFormat;
TParaFormatMask paraFormatMask;
TCharFormat charFormat;
TCharFormatMask charFormatMask;
PostcardLaf::MiniatureFont( charFormat, charFormatMask, paraFormat, paraFormatMask );
deviceMask->GetNearestFontToDesignHeightInTwips( font, charFormat.iFontSpec );
contextMask->UseFont( font );
TInt top = PostcardLaf::BaselineTop( );
TInt delta = PostcardLaf::BaselineDelta( );
TInt leftMargin = PostcardLaf::LeftMargin( );
HBufC* buf = HBufC::NewLC( KPostcardMaxMiniatureCharsPerLine );
TPtr strPtr = buf->Des( );
TBool linesLeft = ETrue;
TInt lineIndex = 0;
TInt charTotalIndex = 0;
TBool mirrored = AknLayoutUtils::LayoutMirrored();
TInt lineWidth = iconSize.iWidth - leftMargin; // We use the same margin on right side, too
const TInt greetingLineCount = PostcardLaf::GreetingFocusLineCount();
// Insert lines until there is something to add or
// maximum amount of greeting focus lines is reached.
// This prevents drawing of text without a focus line,
// which can happen for the last row of the greeting text.
while( linesLeft && lineIndex < greetingLineCount )
{
strPtr.Zero( );
TPtrC origPtr = aText.Mid( charTotalIndex );
TInt index = 0;
while( index < origPtr.Length( )
&& font->TextWidthInPixels( origPtr.Mid( 0, index ) ) + leftMargin < lineWidth )
{
index++;
charTotalIndex++;
TChar ch = origPtr[index-1];
if( ch == 0x2029 ) // If enter, break from the while
{
charTotalIndex++; // increase now as it will be decreased next
break;
}
}
if( index < origPtr.Length( ) - 1 )
{ // This is the last character in the text so lets still include that
index--;
charTotalIndex--;
}
if( index > 0 )
{ // There's actually something to draw on this line
strPtr.Append( origPtr.Mid( 0, index ) );
if( strPtr[index-1] == 0x2029 )
{ // Remove the last character if it's CR
strPtr.Delete( index-1, 1 );
index--;
charTotalIndex--;
}
if( index == 0 )
{ // There are probably many empty lines so thats why we got here.. just increase line
lineIndex++;
}
else
{ // Now we can draw it
TInt deltaX = leftMargin;
if( mirrored )
{
deltaX = iconSize.iWidth - leftMargin - font->TextWidthInPixels( strPtr );
}
TPoint point = TPoint( deltaX, top + ( lineIndex * delta ) );
lineIndex++; // lets change the line
if( mirrored )
{
CGraphicsContext::TDrawTextExtendedParam params;
params.iParRightToLeft = ETrue; // change the direction of text
contextMask->DrawTextExtended( strPtr, point, params );
}
else
{
contextMask->DrawText( strPtr, point );
}
}
if( index >= origPtr.Length( ) )
{
linesLeft = EFalse;
}
}
else // Nothing left -> return
{
if( origPtr.Length( ) == 0)
{ // Nothing left -> return
linesLeft = EFalse;
}
else
{ // Just an empty line -> increase line counter
lineIndex++;
}
}
}
CleanupStack::PopAndDestroy( 3, deviceMask ); // deviceMask, contextMask, buf
CGulIcon* icon = CGulIcon::NewL( bitmap, bitmapMask );
// Ownership moves, so just pop.
CleanupStack::Pop( 2, bitmap ); // bitmapMask and bitmap
return icon;
}
// ---------------------------------------------------------
// CreateTransparentIconL
// ---------------------------------------------------------
CGulIcon* CPostcardAppUi::CreateTransparentIconL( const MDesCArray& aStrings )
{
TSize iconSize = PostcardLaf::Address( ).Size( );
CFbsBitmap* bitmap = CreateEmptyBitmapLC( iconSize ); // pushes to stack
CFbsBitmap* bitmapMask = new (ELeave) CFbsBitmap( );
CleanupStack::PushL( bitmapMask );
bitmapMask->Create( iconSize, EGray2 );
CFbsBitmapDevice* deviceMask = CFbsBitmapDevice::NewL( bitmapMask );
CleanupStack::PushL( deviceMask );
CBitmapContext* contextMask = NULL;
deviceMask->CreateBitmapContext( contextMask );
CleanupStack::PushL( contextMask );
contextMask->SetPenStyle(CGraphicsContext::ENullPen);
contextMask->SetBrushStyle(CGraphicsContext::ESolidBrush);
contextMask->SetBrushColor( KRgbBlack );
contextMask->DrawRect(TRect(TPoint(0,0), iconSize));
contextMask->SetPenStyle(CGraphicsContext::ESolidPen);
contextMask->SetBrushStyle(CGraphicsContext::ENullBrush);
contextMask->SetPenColor(KRgbWhite);
CFont* font = NULL;
CParaFormat paraFormat;
TParaFormatMask paraFormatMask;
TCharFormat charFormat;
TCharFormatMask charFormatMask;
PostcardLaf::MiniatureFont( charFormat, charFormatMask, paraFormat, paraFormatMask );
deviceMask->GetNearestFontToDesignHeightInTwips( font, charFormat.iFontSpec );
contextMask->UseFont( font );
TInt top = PostcardLaf::BaselineTop( );
TInt delta = PostcardLaf::BaselineDelta( );
TInt leftMargin = PostcardLaf::LeftMargin( );
HBufC* buf = HBufC::NewLC( KPostcardMaxMiniatureCharsPerLine );
TPtr strPtr = buf->Des( );
TBool mirrored = AknLayoutUtils::LayoutMirrored();
TInt ellipsisWidth = font->CharWidthInPixels( CEditableText::EEllipsis );
TInt lineWidth = iconSize.iWidth - leftMargin - ellipsisWidth; // We use the same margin on right side, too
TInt lines = aStrings.MdcaCount() > KPostcardMaxAddressFocusLines ?
KPostcardMaxAddressFocusLines :
aStrings.MdcaCount();
// Following characters are converted to spaces, before showing them on text side.
TBuf<1> replaceChars;
replaceChars.Zero();
replaceChars.Append( CEditableText::EParagraphDelimiter );
for( TInt a = 0; a < lines; a++ )
{
strPtr.Zero( );
TPtrC origPtr = aStrings.MdcaPoint( a );
if( origPtr.Length( ) < 1 )
{ // There's no text so skip this..
continue;
}
TInt index = 0;
while( index < origPtr.Length( ) && font->TextWidthInPixels( origPtr.Mid( 0, index ) ) + leftMargin < ( lineWidth ) )
{
index++;
}
strPtr.Append( origPtr.Mid( 0, index ) );
if( index < origPtr.Length( ) )
{
strPtr.Append( CEditableText::EEllipsis );
index++;
}
TInt deltaX = leftMargin;
if( mirrored )
{
deltaX = iconSize.iWidth - font->TextWidthInPixels( strPtr ) - leftMargin;
}
TPoint point = TPoint( deltaX, top + ( a * delta ) );
// Convert all line changes to spaces
AknTextUtils::ReplaceCharacters(
strPtr,
replaceChars,
CEditableText::ESpace );
if( mirrored )
{
CGraphicsContext::TDrawTextExtendedParam params;
params.iParRightToLeft = ETrue; // change the direction of text
contextMask->DrawTextExtended( strPtr, point, params );
}
else
{
contextMask->DrawText( strPtr, point );
}
}
CleanupStack::PopAndDestroy( 3, deviceMask ); // deviceMask, contextMask, buf
CGulIcon* icon = CGulIcon::NewL( bitmap, bitmapMask );
// Ownership moves, so just pop.
CleanupStack::Pop( 2, bitmap ); // bitmapMask and bitmap
return icon;
}
// ---------------------------------------------------------
// RefreshFocusLinesL
// ---------------------------------------------------------
void CPostcardAppUi::RefreshFocusLinesL( )
{
// Lets refresh the location of lines in greeting and recipients rects
if( !iController )
{
// If there's no controller -> just return
return;
}
CFbsBitmap* dummyBmp = new (ELeave) CFbsBitmap( );
CleanupStack::PushL( dummyBmp );
dummyBmp->Create( TSize( 1, 1), EGray2 );
CFbsBitmapDevice* dummyDevice = CFbsBitmapDevice::NewL( dummyBmp );
CleanupStack::PushL( dummyDevice );
CFont* font = NULL;
CParaFormat paraFormat;
TParaFormatMask paraFormatMask;
TCharFormat charFormat;
TCharFormatMask charFormatMask;
PostcardLaf::MiniatureFont( charFormat, charFormatMask, paraFormat, paraFormatMask );
dummyDevice->GetNearestFontToDesignHeightInTwips( font, charFormat.iFontSpec );
TInt descent = font->DescentInPixels( );
CleanupStack::PopAndDestroy( 2, dummyBmp ); // dummyBmp, dummyDevice
TInt delta = PostcardLaf::BaselineDelta( );
TInt top = PostcardLaf::BaselineTop( );
TInt leftMargin = PostcardLaf::LeftMargin( );
TInt extraHeight = MsgEditorCommons::ScreenWidth( )>KPostcardLegacyWidth?1:0;
if( MsgEditorCommons::ScreenWidth( ) > KPostcardQvgaWidth )
{
extraHeight++;
}
TInt rectLoop = EPostcardFocusAreaGreeting;
for ( rectLoop = 0; rectLoop < EPostcardFocusAreaLast; rectLoop++ )
{
TRect focusRect = rectLoop == EPostcardFocusAreaGreeting ?
PostcardLaf::GreetingText() :
PostcardLaf::Address(); // Indicates the are where focus lines are drawn
// Indicates number of focus lines to draw. There is always 5 focus line in address side.
// Focus line count in greeting text side depends on the used layout.
TInt rectLineCount = rectLoop == EPostcardFocusAreaGreeting ?
PostcardLaf::GreetingFocusLineCount() :
KPostcardMaxAddressFocusLines;
CArrayPtrFlat<TRect>* lineRects = new (ELeave) CArrayPtrFlat<TRect>( rectLineCount );
CleanupStack::PushL( lineRects );
TRect* rect = NULL;
for (TInt i = 0; i < rectLineCount; i++)
{
rect = new (ELeave) TRect;
CleanupStack::PushL( rect );
lineRects->InsertL( i, rect );
CleanupStack::Pop( rect ); // rect -> just pop as it will be in lineRects
}
TInt maxHeight = focusRect.Height( );
TInt lineNumber = 1;
while( ETrue )
{
TInt y = focusRect.iTl.iY + top + ( lineNumber - 1 ) * delta + descent;
lineRects->At( lineNumber - 1 )->SetRect(
focusRect.iTl.iX + leftMargin,
y,
focusRect.iBr.iX - leftMargin,
y + extraHeight );
if( lineNumber >= rectLineCount || top + lineNumber * delta > maxHeight )
{
break;
}
lineNumber++;
}
// ownership moves to controller
CleanupStack::Pop( lineRects );
if( rectLoop == 0 )
{
iController->SetGreetingLines( *lineRects );
}
else
{
iController->SetRecipientLines( *lineRects );
}
}
}
// ---------------------------------------------------------
// CreateEmptyBitmapLC
// ---------------------------------------------------------
CFbsBitmap* CPostcardAppUi::CreateEmptyBitmapLC( const TSize& aSize )
{
CFbsBitmap* bitmap = new (ELeave) CFbsBitmap( );
CleanupStack::PushL( bitmap );
bitmap->Create( aSize, EGray2 );
CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( bitmap );
CleanupStack::PushL( device );
CBitmapContext* context = NULL;
device->CreateBitmapContext( context );
CleanupStack::PushL( context );
context->SetPenStyle( CGraphicsContext::ENullPen );
context->SetBrushStyle( CGraphicsContext::ESolidBrush );
context->SetBrushColor( KRgbRed );
context->DrawRect( TRect( TPoint( 0, 0 ), aSize ) );
CleanupStack::PopAndDestroy( 2, device ); // context, device
return bitmap;
}
// ---------------------------------------------------------
// ShowGlobalInformationNoteL
// ---------------------------------------------------------
void CPostcardAppUi::ShowGlobalInformationNoteL( TInt aResourceId, TBool aWaiting )
{
CErrorUI* errorUi = CErrorUI::NewLC(*iCoeEnv);
aWaiting ? errorUi->ShowGlobalErrorQueryL( aResourceId ) :
errorUi->ShowGlobalErrorNoteL( aResourceId );
CleanupStack::PopAndDestroy( errorUi );
}
// ---------------------------------------------------------
// ShowInformationNoteL
// ---------------------------------------------------------
void CPostcardAppUi::ShowInformationNoteL( TInt aResourceId, TBool aWaiting )
{
HBufC* prompt = StringLoader::LoadLC( aResourceId, iCoeEnv );
ShowInformationNoteL( *prompt, aWaiting );
CleanupStack::PopAndDestroy( prompt );
}
// ---------------------------------------------------------
// ShowInformationNoteL
// ---------------------------------------------------------
void CPostcardAppUi::ShowInformationNoteL( const TDesC& aText, TBool aWaiting )
{
CAknInformationNote* note = new ( ELeave )
CAknInformationNote( aWaiting );
note->ExecuteLD( aText );
}
// ---------------------------------------------------------
// ShowConfirmationQueryL
// ---------------------------------------------------------
TInt CPostcardAppUi::ShowConfirmationQueryL( TInt aResourceId, TBool aOnlyOK/*=EFalse*/ ) const
{
HBufC* prompt = StringLoader::LoadLC( aResourceId, iCoeEnv );
TInt retVal = ShowConfirmationQueryL( *prompt, aOnlyOK );
CleanupStack::PopAndDestroy( prompt );
return retVal;
}
// ---------------------------------------------------------
// ShowConfirmationQueryL
// ---------------------------------------------------------
TInt CPostcardAppUi::ShowConfirmationQueryL( const TDesC& aText, TBool aOnlyOK/*=EFalse*/ ) const
{
TInt dialogType=aOnlyOK?R_POSTCARD_CONFIRMABLE_QUERY:R_POSTCARD_CONFIRMATION_QUERY;
CAknQueryDialog* dlg = CAknQueryDialog::NewL();
TInt retVal = dlg->ExecuteLD( dialogType, aText );
return retVal;
}
// ---------------------------------------------------------
// ShowWaitNoteL
// ---------------------------------------------------------
TBool CPostcardAppUi::ShowWaitNoteL( TInt aResourceId, TBool aNoTimeout )
{
TInt waitNoteResource = R_POSTCARD_WAIT_NOTE;
HBufC* string = StringLoader::LoadLC( aResourceId, iCoeEnv );
iWaitDialog = new( ELeave )CAknWaitDialog(
reinterpret_cast<CEikDialog**>( &iWaitDialog ), aNoTimeout ); // ETrue means no delay in showing the note.
iWaitDialog->PrepareLC( waitNoteResource );
iWaitDialog->SetTextL( *string );
TInt success = iWaitDialog->RunLD();
CleanupStack::PopAndDestroy( string );
return success;
}
// ---------------------------------------------------------
// RemoveWaitNote
// ---------------------------------------------------------
void CPostcardAppUi::RemoveWaitNote()
{
delete iWaitDialog;
iWaitDialog = NULL;
}
// ---------------------------------------------------------
// Document
// ---------------------------------------------------------
CPostcardDocument& CPostcardAppUi::Document()
{
CMsgEditorDocument& doc = static_cast <CMsgEditorDocument&> ( *CEikAppUi::Document() );
return static_cast <CPostcardDocument&> ( doc );
}
// ---------------------------------------------------------
// ContactHasData
// ---------------------------------------------------------
TBool CPostcardAppUi::ContactHasData( const CContactCard& aContact )
{
CContactItemFieldSet& fields = aContact.CardFields( );
for( TInt i = 0; i < fields.Count( ); i++ )
{
CContactItemField& field = fields[i];
if( field.TextStorage( )->Text( ).Length( ) > 0 )
{
return ETrue;
}
}
return EFalse;
}
// ---------------------------------------------------------
// ContactHasData
// ---------------------------------------------------------
TBool CPostcardAppUi::ContactHasData( )
{
// Call the overriden function with iContact
if(!iContact)
return EFalse;
return ContactHasData( *iContact );
}
// ---------------------------------------------------------
// MandatoryAddressFields
// ---------------------------------------------------------
TInt CPostcardAppUi::MandatoryAddressFields( )
{
return iCenRep->Get( KPocaKeyMandatoryFields );
}
// ---------------------------------------------------------
// ReadFromResourceLC
// ---------------------------------------------------------
HBufC* CPostcardAppUi::ReadFromResourceLC( TInt& aResourceId )
{
return StringLoader::LoadLC( aResourceId, iCoeEnv );
}
// ---------------------------------------------------------
// NavigateBetweenMessagesL
// ---------------------------------------------------------
TKeyResponse CPostcardAppUi::NavigateBetweenMessagesL( TBool aNextMessage )
{
if( IsNextMessageAvailableL( aNextMessage ) )
{
NextMessageL( aNextMessage );
}
return EKeyWasConsumed;
}
// ---------------------------------------------------------
// CheckLengthsL
// ---------------------------------------------------------
TBool CPostcardAppUi::CheckLengthsL( )
{
if( iGreetingLength > MaxTextLength( EPostcardTextEditor ) )
{
DoEditGreetingL();
return EFalse;
}
if( !ContactHasData( *iContact ) )
{
// No contact -> no need to show anything..
return ETrue;
}
// Get length of address fields into a table. Table is initialized to
// zero because contact may be missing some address fields. Lengths are
// first fetched into a table and checked after that in order to do the
// check in correct order. If a some fields are too long they are presented
// to user in correct order for fixing.
TInt lengths[CPostcardAddressForm::ENumAddrFields];
Mem::FillZ( lengths, sizeof( lengths ) );
CContactItemFieldSet& set = iContact->CardFields();
for( TInt i = 0; i < set.Count(); i++ )
{
CContactItemField& field = set[i];
CContactTextField* textField = set[i].TextStorage();
if (textField)
{
TInt id = TPostcardUtils::IdFromContactItemName( field.Label() );
__ASSERT_DEBUG( id >= EPostcardAddressName &&
id <= EPostcardAddressCountry, Panic( EPostcardPanicCoding ) );
lengths[id - EPostcardAddressName] = textField->Text().Length();
}
}
// Check length of fields
for( TInt i = EPostcardAddressName; i <= EPostcardAddressCountry; i++ )
{
if (lengths[i - EPostcardAddressName] > MaxTextLength(i))
{
// A field is too long, open the address dialog..
DoEditAddressL( TKeyEvent(), i );
return EFalse;
}
}
return ETrue;
}
// ---------------------------------------------------------
// CreateAddressStringForSendConfirmLC
// ---------------------------------------------------------
HBufC* CPostcardAppUi::CreateAddressStringForSendConfirmLC()
{
HBufC* buf = HBufC::NewLC( KPostcardMaxSendConfirmationLength );
TPtr bufPtr = buf->Des();
_LIT( KNewline, "\n" );
CContactItemFieldSet& set = iContact->CardFields( );
for(TInt i = EPostcardAddressName; i <= EPostcardAddressCountry; i++ )
{
const CContactItemField* field = TPostcardUtils::FieldOrNull( set,
TPostcardUtils::ContactItemNameFromId( i ) );
if ( field )
{
TPtrC text = field->TextStorage()->Text();
TInt len = text.Length();
if( len && len < ( bufPtr.MaxLength() - bufPtr.Length() ) )
{
bufPtr.Append( text );
bufPtr.Append( KNewline );
}
}
}
// Remove the last "\n" in case there's question mark in the end of the loc string
bufPtr.Delete( bufPtr.Length() - 1, 1 );
return buf;
}
// ---------------------------------------------------------
// QueryWaiterCallback
// ---------------------------------------------------------
void CPostcardAppUi::QueryWaiterCallbackL( TInt aResult )
{
if( aResult == EAknSoftkeySend )
{
// Proceed if send query result is send
// Displaying extra charge query is optional
aResult = EAknSoftkeyOk;
if( iCenRep->FeatureBits() & KPostcardFeatureIdExtraChargeNotification)
{
CAknQueryDialog* dlg = CAknQueryDialog::NewL();
aResult = dlg->ExecuteLD( R_POSTCARD_EXTRA_CHARGE_QUERY );
}
if( aResult == EAknSoftkeyOk )
{
// OK, start sending
TInt resourceId = R_POSTCARD_SENDING_POSTCARD;
if( IsPhoneOfflineL() )
{
resourceId = R_POSTCARD_SAVED_OUTBOX;
}
ShowWaitNoteL( resourceId, ETrue );
iOperation = CPostcardOperationSave::NewL(
*this,
Document(),
*this,
FsSession(),
*iContact,
*iGreeting
);
iOperation->Start( ETrue );
iAbsorber = CAknInputBlock::NewLC();
CleanupStack::Pop( iAbsorber );
iPocaFlags |= EPostcardClosing;
}
}
if( iMessageQuery )
{
iMessageQuery->CancelMsgQuery();
delete iMessageQuery;
iMessageQuery = NULL;
}
delete iSendText;
iSendText = NULL;
}
// ---------------------------------------------------------
// QueryWaiterCallbackError
// ---------------------------------------------------------
void CPostcardAppUi::QueryWaiterCallbackError()
{
// Cleanup after QueryWaiterCallbackL() leaves
if( iMessageQuery )
{
iMessageQuery->CancelMsgQuery();
delete iMessageQuery;
iMessageQuery = NULL;
}
delete iSendText;
iSendText = NULL;
RemoveWaitNote();
delete iOperation;
iOperation = NULL;
}
// ---------------------------------------------------------
// SetMiddleSoftkeyL
// ---------------------------------------------------------
void CPostcardAppUi::SetMiddleSoftkeyL()
{
TInt resourceId;
if ( iController->Frontpage() )
{
// Frontside is focused
if ( iMsgType == EPostcardSent )
{
resourceId = R_POSTCARD_MSK_BUTTON_EMPTY;
}
else
{
resourceId = R_POSTCARD_MSK_BUTTON_OPTIONS;
MenuBar()->SetContextMenuTitleResourceId(
R_POSTCARD_CONTEXT_MENUBAR );
}
}
else
{
// Backside is focused
resourceId = iMsgType == EPostcardSent ?
R_POSTCARD_MSK_BUTTON_OPEN : R_POSTCARD_MSK_BUTTON_EDIT;
}
if ( resourceId != iMskResource )
{
const TInt KMskPosition = 3;
CEikButtonGroupContainer *cba = Cba();
cba->SetCommandL( KMskPosition, resourceId );
cba->DrawDeferred();
iMskResource = resourceId;
}
}
// ---------------------------------------------------------
// GetZoomLevelL
// ---------------------------------------------------------
void CPostcardAppUi::GetZoomLevelL( TInt& aZoomLevel )
{
TInt err = iMsgEditorAppUiExtension->iSettingCachePlugin.GetValue( KAknLocalZoomLayoutSwitch,
aZoomLevel );
if ( err != KErrNone )
{
User::Leave( err );
}
}
// ---------------------------------------------------------
// HandleLocalZoomChangeL
// ---------------------------------------------------------
//
void CPostcardAppUi::HandleLocalZoomChangeL( TMsgCommonCommands aNewZoom )
{
// Forward to base, which sets new zoom level to cenrep.
CMsgEditorAppUi::HandleLocalZoomChangeL( aNewZoom );
}
// ---------------------------------------------------------
// CPostcardAppUi::BeginActiveWait
// ---------------------------------------------------------
//
void CPostcardAppUi::BeginActiveWait()
{
if ( iWait.IsStarted() )
{
return;
}
iWait.Start();
}
// ---------------------------------------------------------
// CPostcardAppUi::EndActiveWait
// ---------------------------------------------------------
//
void CPostcardAppUi::EndActiveWait()
{
if ( iWait.IsStarted() )
{
iWait.AsyncStop();
}
}
// ---------------------------------------------------------
// CPostcardAppUi::SetTitleIconL
// ---------------------------------------------------------
//
void CPostcardAppUi::SetTitleIconL()
{
SetTitleIconSizeL( iAppIcon->Bitmap() );
// Create duplicates of the icon to be used
CFbsBitmap* bitmap = new( ELeave ) CFbsBitmap();
CleanupStack::PushL( bitmap );
CFbsBitmap* bitmapMask = new( ELeave ) CFbsBitmap();
CleanupStack::PushL( bitmapMask );
User::LeaveIfError( bitmap->Duplicate( iAppIcon->Bitmap()->Handle() ) );
User::LeaveIfError( bitmapMask->Duplicate( iAppIcon->Mask()->Handle() ) );
iTitlePane->SetSmallPicture( bitmap, bitmapMask, ETrue );
iTitlePane->DrawNow();
CleanupStack::Pop( bitmapMask );
CleanupStack::Pop( bitmap );
}
// ---------------------------------------------------------
// CPostcardAppUi::CreateAndSetTitleIconL
// ---------------------------------------------------------
//
void CPostcardAppUi::CreateAndSetTitleIconL()
{
if ( iAppIcon )
{
delete iAppIcon;
iAppIcon = NULL;
}
TParse parseDrive;
parseDrive.Set( Document().AppFullName( ), NULL, NULL );
TPtrC drive = parseDrive.Drive( );
TParse fileParse;
fileParse.Set( KPostcardMifFile, &KDC_APP_BITMAP_DIR, NULL );
TFileName fileName( fileParse.FullName( ) );
fileName.Insert( 0, drive );
iAppIcon = AknsUtils::CreateGulIconL(
AknsUtils::SkinInstance(),
KAknsIIDQgnPropMcePostcardTitle,
fileParse.FullName(),
EMbmPostcardQgn_prop_mce_postcard_title,
EMbmPostcardQgn_prop_mce_postcard_title_mask );
SetTitleIconL();
}
// ---------------------------------------------------------
// CPostcardAppUi::IsPhoneOfflineL
// ---------------------------------------------------------
//
TBool CPostcardAppUi::IsPhoneOfflineL() const
{
if ( iPocaFlags & EPostcardFeatureOffline )
{
return MsvUiServiceUtilitiesInternal::IsPhoneOfflineL();
}
else
{
return EFalse;
}
}
// End of File