diff -r 7d48bed6ce0c -r 987c9837762f cbs/cbsui/UiSrc/CCbsUiMsgView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbs/cbsui/UiSrc/CCbsUiMsgView.cpp Wed Sep 01 12:15:03 2010 +0100 @@ -0,0 +1,1030 @@ +/* +* Copyright (c) 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: +* Implementation of CCbsUiMsgView. +* +* +*/ + + + +// INCLUDES +#include //AknTextUtils +#include // for feature flags +#include // for feature manager +#include +#include +#include +#include +#include +#include // CRichText +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "CCbsUIMsgView.h" +#include "Cbsuiapp.hrh" +#include "CCbsUIMsgViewContainer.h" +#include "CbsUiPanic.h" +#include "CbsUiConstants.h" +#include "CbsUiUtility.h" +#include "CbsUiDebug.h" +#include "MCbs.h" +#include "CbsUiId.h" //KUidCbsUiappDef + + + +// CONSTANTS + +static const TUid KUidCbsUiappApp = { KUidCbsUiappDef }; +const TInt KCbsImmediateMessageIdInt = 313; +const TInt KMaxAssumedDateTimeLength = 30; + +_LIT(KSpace, " "); +_LIT(KLineBreak, "\n"); +const TInt KMaxSeparatorLenght = 5; +const TInt KOneHotMarkedMessage = 1; + + + + + +// ================= MEMBER FUNCTIONS ======================= + +// C++ default constructor can NOT contain any code, that +// might leave. + +CCbsUiMsgView::CCbsUiMsgView( MCbs& aServer ) +: +iServer( aServer ) + { + } + +// Symbian OS default constructor can leave. +void CCbsUiMsgView::ConstructL() + { + BaseConstructL( R_CBSUI_MSGVIEW ); + iFindItemMenu = CFindItemMenu::NewL( ECbsUiCmdFindItem ); + iFromOtherApplication = EFalse; + + CEikStatusPane* statusPane = StatusPane(); + + iNaviContainer = + STATIC_CAST( CAknNavigationControlContainer*, statusPane-> + ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) ); + + } + +// Two-phased constructor. +CCbsUiMsgView* CCbsUiMsgView::NewL( MCbs& aServer ) + { + CCbsUiMsgView* self = new (ELeave) CCbsUiMsgView( aServer ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// Destructor +CCbsUiMsgView::~CCbsUiMsgView() + { + CloseContextMenu(); + + if ( iContainer ) + { + AppUi()->RemoveFromViewStack( *this, iContainer ); + } + + delete iContainer; + delete iFindItemMenu; + + if ( iNaviContainer && iDecoratedLabel ) + { + iNaviContainer->Pop ( iDecoratedLabel ); + delete iDecoratedLabel; + } + iDecoratedLabel = NULL; + + if ( iNaviContainer && iPreviousDecoratedLabel ) + { + iNaviContainer->Pop ( iPreviousDecoratedLabel ); + delete iPreviousDecoratedLabel; + } + iPreviousDecoratedLabel = NULL; + + delete iMessage; + } + +// --------------------------------------------------------- +// CCbsUiMsgView::HandleNaviDecoratorEventL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::HandleNaviDecoratorEventL( TInt aEventID ) + { + + switch ( aEventID ) + { + // Left arrow tapped from the navi pane + case MAknNaviDecoratorObserver::EAknNaviDecoratorEventLeftTabArrow: + { + if( AknLayoutUtils::LayoutMirrored() ) + { + MoveToNextMessageL(); + } + else + { + MoveToPreviousMessageL(); + } + break; + } + // Right arrow tapped from the navi pane + case MAknNaviDecoratorObserver::EAknNaviDecoratorEventRightTabArrow: + { + if( AknLayoutUtils::LayoutMirrored() ) + { + MoveToPreviousMessageL(); + } + else + { + MoveToNextMessageL(); + } + break; + } + default: + { + break; + } + } + + } + +// --------------------------------------------------------- +// CCbsUiMsgView::DynInitMenuPaneL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + __ASSERT_DEBUG( aMenuPane, CbsUiPanic( EMenuPaneNullError ) ); + __ASSERT_DEBUG( iFindItemMenu, CbsUiPanic( EFindItemNullError ) ); + + switch ( aResourceId ) + { + case R_CBSUI_MSGVIEW_MENU: + { + iFindItemMenu->DisplayFindItemMenuItemL( + *aMenuPane, + ECbsUiappCmdMsgMenuDelete ); + + if ( CbsUiUtility::IsSavedL(iCurrentHandle, iServer) ) + { + aMenuPane->DeleteMenuItem( ECbsUiappCmdMsgMenuKeep ); + } + if( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + aMenuPane->DeleteMenuItem( EAknCmdHelp ); + } + break; + } + case R_FINDITEMMENU_MENU: + { + iFindItemMenu->DisplayFindItemCascadeMenuL( *aMenuPane ); + break; + } + default: + break; + } + } + +// --------------------------------------------------------- +// CCbsUiMsgView::ProcessCommandL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::ProcessCommandL( TInt aCommand ) + { + if ( iContextMenu ) + { + iContextMenu->StopDisplayingMenuBar(); + CloseContextMenu(); + } + + // Context sensitive menu should be opened when MSK pressed + switch ( aCommand ) + { + case EAknSoftkeyContextOptions: + HandleCommandL( EAknSoftkeyContextOptions ); + break; + default: + break; + } + // Call base class + CAknView::ProcessCommandL( aCommand ); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::Id +// +// +// --------------------------------------------------------- +// +TUid CCbsUiMsgView::Id() const + { + return TUid::Uid( ECbsUiMsgViewId ); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::MoveToNextMessage +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::MoveToNextMessageL() + { + // if a message is class 0, then changing the message + // content is not allowed. + if ( iIsClass0 ) + { + return; + } + + if ( SetHandleTo(iCurrentHandle, EToNext) ) + { + DoLoadMessageL(); + } + + } + +// --------------------------------------------------------- +// CCbsUiMsgView::MoveToPreviousMessage +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::MoveToPreviousMessageL() + { + // if a message is class 0, then changing the message + // content is not allowed. + if ( iIsClass0 ) + { + return; + } + + if ( SetHandleTo(iCurrentHandle, EToPrevious) ) + { + DoLoadMessageL(); + } + } + +// --------------------------------------------------------- +// CCbsUiMsgView::HandleCommandL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::HandleCommandL( TInt aCommand ) + { + if ( iFindItemMenu && iFindItemMenu->CommandIsValidL( aCommand ) ) + { + DoSearchL( aCommand ); + } + + TBool exit(EFalse); // program exits if true + + switch ( aCommand ) + { + case EAknSoftkeyBack: + { + ActivateTopicViewL( CurrentTopicNumber(), iCurrentHandle ); + break; + } + case ECbsUiappCmdMsgMenuKeep: + { + if ( CbsUiUtility::SaveCurrentMessageL(iCurrentHandle, *this) == + KErrNone && iIsClass0 ) + { + exit = ETrue; + + // show modal note + CbsUiUtility::ShowConfirmationNoteL( + R_TEXT_NOTE_MSG_KEPT, ETrue); + } + break; + } + case ECbsUiCmdCopyToClipboard: + { + iContainer->CopyToClipboardL(); + CbsUiUtility::ShowConfirmationNoteL(R_TEXT_NOTE_MSG_TO_CLIP); + break; + } + case ECbsUiappCmdMsgMenuDelete: + { + if ( DeleteMessageL(iCurrentHandle) && iIsClass0 ) + { + exit = ETrue; + } + break; + } + case EAknSoftkeyContextOptions: + case ECbsUiappCmdOkKey: + { + LaunchContextMenuL(); + break; + } + case EAknCmdHelp: + AppUi()->HandleCommandL(aCommand); + break; + case EAknSoftkeyExit: // let it run through + case EAknCmdExit: + { + if ( !iFromOtherApplication ) + { + // if it has been CBSUI then do this + ActivateTopicListViewL(); + } + else + { + exit = ETrue; + } + iFromOtherApplication = EFalse; + break; + } + default: + break; + } + + if ( exit ) + { + STATIC_CAST( + MEikCommandObserver*, AppUi() )->ProcessCommandL(EAknCmdExit); + } + } + +// --------------------------------------------------------- +// CCbsUiMsgView::DoActivateL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::DoActivateL( const TVwsViewId& aPrevViewId, + TUid aCustomMessageId, + const TDesC8& aCustomMessage ) + { + iIsClass0 = EFalse; + TBool topicListViewActivated(EFalse); + + switch ( aCustomMessageId.iUid ) + { + case KCbsUiCustomMessageIdInt: + iFromOtherApplication = EFalse; + Cba()->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_BACK); + SetCurrentMessageHandle(aCustomMessage); + break; + case KCbsImmediateMessageIdInt: + if ( aPrevViewId.iAppUid != KUidCbsUiappApp ) + { + iFromOtherApplication = ETrue; + } + SetCurrentMessageHandle(aCustomMessage); + Cba()->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_EXIT); + Cba()->DrawDeferred(); + iIsClass0 = ETrue; + break; + default: // this should be soft notification + iFromOtherApplication = EFalse; + Cba()->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_BACK); + topicListViewActivated = HandleSoftNotificationL(); + break; + } + + if ( !topicListViewActivated ) + { + if ( !iContainer ) + { + iContainer = CCbsUiMsgViewContainer::NewL(*this, ClientRect()); + AppUi()->AddToViewStackL(*this, iContainer); + } + + TInt err( DoLoadMessageL() ); + + // if it is class 0 message and some error occurs + if ( err != KErrNone && iIsClass0 ) + { + User::Leave(err); + } + + if ( iMessage ) + { + iContainer->ActivateL(); + } + else + { + // some error occured + ActivateTopicViewL( CurrentTopicNumber(), iCurrentHandle ); + } + } + } + +// --------------------------------------------------------- +// CCbsUiMsgView::DoDeactivate() +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::DoDeactivate() + { + iServer.LockMessage(NULL); + + CloseContextMenu(); + if ( iContainer ) + { + AppUi()->RemoveFromViewStack( *this, iContainer ); + delete iContainer; + iContainer = NULL; + } + + delete iDecoratedLabel; + iDecoratedLabel = NULL; + + DeleteOldMessage(); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::UpdateNaviPaneL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::UpdateNaviPaneL() + { + + TInt currentPosition( KCbsErrValue ); + TInt totalMessages( KCbsErrValue ); + + TInt err ( + GetMessagePosition( iCurrentHandle, currentPosition, totalMessages ) ); + + TBool prev( currentPosition != 0 ); + TBool next( ( currentPosition + 1 ) < totalMessages ); + + // If a message is class 0, then the navipane is empty + if ( iIsClass0 || err != KErrNone ) + { + // Delete the existed label before creating a new one + // in case of memory leak + CAknNavigationDecorator* oldLabel = iDecoratedLabel; + iDecoratedLabel = CbsUiUtility::CreateEmptyNavigationPaneL(); + delete oldLabel; + return; + } + + // Create a new decorator + CArrayFixFlat* array = new( ELeave ) CArrayFixFlat( 2 ); + CleanupStack::PushL( array ); + array->AppendL( currentPosition + 1 ); + array->AppendL( totalMessages ); + HBufC* messageLocationInTopic = StringLoader::LoadL( R_MESSAGE_LOCATION_IN_TOPIC, *array, iCoeEnv ); + CleanupStack::PopAndDestroy(); // array + CleanupStack::PushL( messageLocationInTopic ); + + CAknNavigationDecorator* newDecoratedLabel = iNaviContainer->CreateNavigationLabelL( *messageLocationInTopic ); + CleanupStack::PopAndDestroy(); // messageLocationInTopic + + CleanupStack::PushL( newDecoratedLabel ); + + // Set new decorator on top of navi pane's decorator stack + // ( topmost decorator is the one to show ) + iNaviContainer->PushL( *newDecoratedLabel ); + + // Remove previous decorator from decorator stack and delete it + if ( iPreviousDecoratedLabel ) + { + iNaviContainer->Pop( iPreviousDecoratedLabel ); + delete iPreviousDecoratedLabel; + iPreviousDecoratedLabel = NULL; + } + + // Update decorator pointers to new ones + iPreviousDecoratedLabel = iDecoratedLabel; + iDecoratedLabel = newDecoratedLabel; + + __ASSERT_DEBUG( iDecoratedLabel, CbsUiPanic( EErrNullPointer ) ); + + // Set observer for navi pane + iDecoratedLabel->SetNaviDecoratorObserver( this ); + + CleanupStack::Pop( newDecoratedLabel ); + + iDecoratedLabel->MakeScrollButtonVisible( ETrue ); + + if( AknLayoutUtils::LayoutMirrored() ) + { + iDecoratedLabel->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, !next ); + iDecoratedLabel->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, !prev ); + } + else + { + iDecoratedLabel->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, !prev ); + iDecoratedLabel->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, !next ); + } + + } + + +// --------------------------------------------------------- +// CCbsUiMsgView::SaveMessage +// +// +// --------------------------------------------------------- +// +TInt CCbsUiMsgView::SaveMessage( const TCbsMessageHandle& aHandle ) + { + return iServer.SaveMessage(aHandle); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::DoSearchL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::DoSearchL( TInt aCommand ) + { + CFindItemDialog* dialog = CFindItemDialog::NewL( + iContainer->GetEditor()->Read(0), + iFindItemMenu->SearchCase(aCommand) ); + dialog->ExecuteLD(); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::TopicListChangedL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::TopicListChangedL( TCbsTopicListEvent /*aEvent*/, TCbsTopicNumber aTopicNumber ) + { + if ( iContainer && (CurrentTopicNumber() == aTopicNumber) ) + { + UpdateNaviPaneL(); + } + } + + + +// --------------------------------------------------------- +// CCbsUiMsgView::HandleRectChangeInContainerL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::HandleRectChangeInContainerL() + { + if ( iContainer ) + { + iContainer->SetRect( ClientRect() ); + iContainer->UpdateMessageL( *iMessage ); + } + + } + +// --------------------------------------------------------- +// CCbsUiMsgView::CloseContextMenu +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::CloseContextMenu() + { + if ( iContextMenu ) + { + AppUi()->RemoveFromViewStack(*this, iContextMenu); + delete iContextMenu; + iContextMenu = NULL; + } + } + +// --------------------------------------------------------- +// CCbsUiMsgView::LaunchContextMenuL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::LaunchContextMenuL() + { + TInt rssName = R_CBSUI_MSG_KEEP_AND_DELETE_CONTEXT_MENUBAR; + + if ( CbsUiUtility::IsSavedL(iCurrentHandle, iServer) ) + { + rssName = R_CBSUI_MSG_DELETE_CONTEXT_MENUBAR; + } + + CloseContextMenu(); + + __ASSERT_DEBUG( !iContextMenu, CbsUiPanic(EErrAllreadyExists) ); + + iContextMenu = new (ELeave) CEikMenuBar; + iContextMenu->ConstructL( + this, + 0, + rssName ); + + // Set type to context sensitive + iContextMenu->SetMenuType( CEikMenuBar::EMenuContext ); + + AppUi()->AddToViewStackL( + *this, + iContextMenu, + ECoeStackPriorityMenu, + ECoeStackFlagRefusesFocus ); + + iContextMenu->TryDisplayMenuBarL(); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::DeleteOldMessage +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::DeleteOldMessage() + { + delete iMessage; + iMessage = NULL; + } + +// --------------------------------------------------------- +// CCbsUiMsgView::DoLoadMessageL +// +// +// --------------------------------------------------------- +// +TInt CCbsUiMsgView::DoLoadMessageL() + { + TRAPD( err, LoadMessageL() ); + + switch ( err ) + { + case KErrNotFound: + { + // If the message cannot be found + // it is not necessary to do anything. + // It is just showing some other message (current). + break; + } + case KErrNone: + { + // normal case + __ASSERT_DEBUG( iMessage, CbsUiPanic(EErrNullPointer) ); + iContainer->UpdateMessageL(*iMessage); + // navi pane has to be updated in all cases; expect when leave + UpdateNaviPaneL(); + Cba()->SetCommandSetL( R_CBS_SOFTKEYS_OPTIONS_BACK__CONTEXTOPTIONS ); + break; + } + default: + User::Leave( err ); + break; + } + + return err; + } + +// --------------------------------------------------------- +// CCbsUiMsgView::ActivateTopicViewL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::ActivateTopicViewL( TCbsTopicNumber aTopicNumber, TCbsMessageHandle aHandle ) + { + TPckgBuf message; + message().iTopicNumber = aTopicNumber; + message().iMessageHandle = aHandle; + + AppUi()->ActivateLocalViewL( + TUid::Uid(ECbsUiTopicViewId), KSetFocusToId, message ); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::SetCurrentMessageHandle +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::SetCurrentMessageHandle( const TDesC8& aMessageHandle ) + { + TPckgBuf pckgMessageHandle; + pckgMessageHandle.Copy(aMessageHandle); + iCurrentHandle = pckgMessageHandle(); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::LoadMessageL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::LoadMessageL() + { + User::LeaveIfError( iServer.LockMessage(iCurrentHandle) ); + + TCbsMessage message; + TInt err( iServer.FindMessageByHandle(iCurrentHandle, message) ); + __CBSUI_ASSERT( err == KErrNone, CbsUiPanic(EErrMsgHandleNotFound) ); + User::LeaveIfError(err); + + // mark the message as read + err = iServer.ReadMessage(iCurrentHandle); + User::LeaveIfError(err); + + DeleteOldMessage(); + iMessage = HBufC::NewMaxL(message.iLength); + TPtr messageContent = iMessage->Des(); + + err = iServer.GetMessageContents(iCurrentHandle, messageContent); + + __CBSUI_ASSERT( err == KErrNone, + CbsUiPanic(EMessageContentsError) ); + + if ( err != KErrNone ) + { + DeleteOldMessage(); + User::Leave(err); + } + + AddDateAndTimeL( + message.iDateTime, + &iMessage, // address of pointer variable + R_CBS_DATE_FORMAT_ARRAY ); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::AddDateAndTime +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::AddDateAndTimeL( const TInt64 aTime, HBufC** aMessage, TUint aResourceArrayId ) const + { + __ASSERT_DEBUG( aTime >= 0, CbsUiPanic(EErrInvalidValue) ); + __ASSERT_DEBUG( *aMessage, CbsUiPanic(EErrNullPointer) ); + __ASSERT_DEBUG( (*aMessage)->Length() > 0, CbsUiPanic(EErrEmptyDesc) ); + __ASSERT_DEBUG( aResourceArrayId > 0, CbsUiPanic(EErrInvalidValue) ); + + HBufC* timeBuffer = HBufC::NewMaxLC( KMaxAssumedDateTimeLength ); + TInt bufLen( 0 ); + TTime time( aTime ); + + // change universal time to local time + TLocale locale; + time += locale.UniversalTimeOffset(); + + TPtr des = timeBuffer->Des(); + TInt length( ( *aMessage )->Length() ); + + // for adding date and time to message + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC( reader, aResourceArrayId ); + TInt count( reader.ReadInt16() ); + + TBuf separator( KLineBreak ); + TInt separatorsLength( KLineBreak().Length() + KSpace().Length() ); + + for ( TInt i( 0 ); i < count; i++ ) + { + TUint resourceId( reader.ReadUint32() ); + + HBufC* format = iCoeEnv->AllocReadResourceLC( resourceId ); + + time.FormatL( des, *format ); + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( des ); + + if ( i > 0 ) + { + separator = KSpace; + } + + bufLen += timeBuffer->Length(); + (*aMessage) = (*aMessage)->ReAllocL( + length + bufLen + separatorsLength ); + + // have to get a new pointer after reallocation + TPtr ptr2 = ( *aMessage )->Des(); + ptr2.Append( separator ); + ptr2.Append( *timeBuffer ); + + CleanupStack::PopAndDestroy(); // format + } + + CleanupStack::PopAndDestroy( 2 ); // timeBuffer, reader + } + +// --------------------------------------------------------- +// CCbsUiMsgView::CurrentTopicNumber +// +// +// --------------------------------------------------------- +// +TCbsTopicNumber CCbsUiMsgView::CurrentTopicNumber() const + { + return STATIC_CAST( TCbsTopicNumber, (iCurrentHandle >> 16) & 0xFFFF ); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::GetMessagePosition +// +// +// --------------------------------------------------------- +// +TInt CCbsUiMsgView::GetMessagePosition( TCbsMessageHandle aHandle, TInt& aPosition, TInt& aTotal ) + { + TInt err( iServer.GetMessageIndexByHandle(aHandle, aPosition) ); + + __CBSUI_ASSERT( err == KErrNone, CbsUiPanic(EErrMsgHandleNotFound) ); + __CBSUI_ASSERT( aPosition != KCbsErrValue, CbsUiPanic(EErrInvalidValue) ); + + if ( err == KErrNone ) + { + err = iServer.GetMessageCount( CurrentTopicNumber(), aTotal ); + } + + __CBSUI_ASSERT( err == KErrNone, CbsUiPanic(EErrMsgHandleNotFound) ); + __CBSUI_ASSERT( aPosition + 1 <= aTotal, CbsUiPanic(EErrMsgImbalance) ); + + return err; + } + +// --------------------------------------------------------- +// CCbsUiMsgView::SetHandleTo +// +// +// --------------------------------------------------------- +// +TBool CCbsUiMsgView::SetHandleTo( TCbsMessageHandle& aHandle, TMsgViewSetHandle aTo ) + { + TCbsMessageHandle prev; + TCbsMessageHandle next; + TInt position(KCbsErrValue); + TBool result(EFalse); + + TInt err( iServer.GetNextAndPrevMessageHandle( + aHandle, prev, next, position) ); + + if ( err == KErrNone ) + { + __ASSERT_DEBUG( + position >= 0 && position <= (ECbsTail | ECbsHead), + CbsUiPanic(EErrInvalidValue) ); + + switch ( aTo ) + { + case EToPrevious: + // if position is head it cannot go thru + if ( (position & ECbsHead) == 0 ) + { + aHandle = prev; + result = ETrue; + } + break; + case EToNext: + // if position is tail it cannot go thru + if ( (position & ECbsTail) == 0 ) + { + aHandle = next; + result = ETrue; + } + break; + default: + __ASSERT_DEBUG(0, CbsUiPanic(EErrInvalidValue)); + break; + } + } + + return result; + } + +// --------------------------------------------------------- +// CCbsUiMsgView::DeleteMessageL +// +// +// --------------------------------------------------------- +// +TBool CCbsUiMsgView::DeleteMessageL( TCbsMessageHandle aHandle ) + { + TBool result(EFalse); + + CAknQueryDialog* dlg = CAknQueryDialog::NewL(); + + if ( dlg->ExecuteLD(R_DELETE_MSG_CONFIRMATION_QUERY) ) + { + TCbsMessageHandle handleToBeFocused(aHandle); + + if ( !SetHandleTo(handleToBeFocused, EToNext) ) + { + if ( !SetHandleTo(handleToBeFocused, EToPrevious) ) + { + // next or previous could not be set, 0 will unlock message + handleToBeFocused = 0; + } + } + + // Unlock message to be deleted and lock next message before delete + __ASSERT_DEBUG(handleToBeFocused != aHandle, + CbsUiPanic(EErrInvalidValue)); + + iServer.LockMessage(handleToBeFocused); + iServer.DeleteMessage(aHandle); + + // free handleToBeFocused message + if ( handleToBeFocused != 0) + { + iServer.LockMessage(NULL); + } + + // Topic number is still the same even if the message is + // deleted. + ActivateTopicViewL( CurrentTopicNumber(), handleToBeFocused ); + result = ETrue; + } + + return result; + } + +// --------------------------------------------------------- +// CCbsUiMsgView::ActivateTopicListViewL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgView::ActivateTopicListViewL() const + { + AppUi()->ActivateLocalViewL( TUid::Uid(ECbsUiTopicListViewId) ); + } + +// --------------------------------------------------------- +// CCbsUiMsgView::HandleSoftNotification +// +// +// --------------------------------------------------------- +// +TBool CCbsUiMsgView::HandleSoftNotificationL() + { + TCbsTopic topic; + TInt err; + TBool result( EFalse ); + TInt count( iServer.NumberOfUnreadHotmarkedMessages() ); + __ASSERT_DEBUG( + count >= KOneHotMarkedMessage, CbsUiPanic(EErrInvalidValue) ); + + switch ( count ) + { + case KOneHotMarkedMessage: + iServer.GetHotmarkedMessageHandle( iCurrentHandle ); + err = iServer.FindTopicByNumber( CurrentTopicNumber(), topic ); + if ( err == KErrNone ) + { + //Update Title pane + CEikStatusPane* sp = StatusPane(); + CAknTitlePane* title = + STATIC_CAST(CAknTitlePane*, sp->ControlL( TUid::Uid( EEikStatusPaneUidTitle) ) ); + title->SetTextL( topic.iName ); + } + break; + default: // Many hot marked messages + ActivateTopicListViewL(); + result = ETrue; + break; + } + + return result; + } + + +// End of File