|         |      1 /* | 
|         |      2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). | 
|         |      3 * All rights reserved. | 
|         |      4 * This component and the accompanying materials are made available | 
|         |      5 * under the terms of "Eclipse Public License v1.0" | 
|         |      6 * which accompanies this distribution, and is available | 
|         |      7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      8 * | 
|         |      9 * Initial Contributors: | 
|         |     10 * Nokia Corporation - initial contribution. | 
|         |     11 * | 
|         |     12 * Contributors: | 
|         |     13 * | 
|         |     14 * Description:  MsgBodyControl implementation | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18  | 
|         |     19  | 
|         |     20 // ========== INCLUDE FILES ================================ | 
|         |     21  | 
|         |     22 #include <txtrich.h>                       // for CRichText | 
|         |     23 #include <eikenv.h>                        // for CEikonEnv | 
|         |     24 #include <gulfont.h>                       // for TLogicalFont | 
|         |     25 #include <AknUtils.h>                      // for AknUtils | 
|         |     26 #include <aknenv.h>                        // for CAknEnv | 
|         |     27 #include <ItemFinder.h>                    // for automatic highlight | 
|         |     28 #include <AknsUtils.h>                     // for Skinned drawing | 
|         |     29 #include <AknDef.h> | 
|         |     30 #include <StringLoader.h>                   // for StringLoader (load and foramt strings from resources) | 
|         |     31 #include <MsgEditorAppUi.rsg> | 
|         |     32  | 
|         |     33 #include <applayout.cdl.h> // LAF | 
|         |     34 #include <aknlayoutscalable_apps.cdl.h> | 
|         |     35  | 
|         |     36 #include "MsgEditorCommon.h"               // | 
|         |     37 #include "MsgEditorView.h"                 // for CMsgEditorView | 
|         |     38 #include "MsgBodyControl.h"                // for CMsgBodyControl | 
|         |     39 #include "MsgBaseControlObserver.h"        // for MMsgBaseControlObserver | 
|         |     40 #include "MsgBodyControlEditor.h"          // for CMsgBodyControlEditor | 
|         |     41 #include "MsgEditorPanic.h"                // for MsgEditor panics | 
|         |     42  | 
|         |     43 #include "MsgEditorLogging.h" | 
|         |     44  | 
|         |     45 // ========== EXTERNAL DATA STRUCTURES ===================== | 
|         |     46  | 
|         |     47 // ========== EXTERNAL FUNCTION PROTOTYPES ================= | 
|         |     48  | 
|         |     49 // ========== CONSTANTS ==================================== | 
|         |     50  | 
|         |     51 // ========== MACROS ======================================= | 
|         |     52  | 
|         |     53 // ========== LOCAL CONSTANTS AND MACROS =================== | 
|         |     54  | 
|         |     55 // ========== MODULE DATA STRUCTURES ======================= | 
|         |     56  | 
|         |     57 // ========== LOCAL FUNCTION PROTOTYPES ==================== | 
|         |     58  | 
|         |     59 // ========== LOCAL FUNCTIONS ============================== | 
|         |     60  | 
|         |     61 // ========== MEMBER FUNCTIONS ============================= | 
|         |     62  | 
|         |     63 // --------------------------------------------------------- | 
|         |     64 // CMsgBodyControl::CMsgBodyControl | 
|         |     65 // | 
|         |     66 // Constructor. | 
|         |     67 // --------------------------------------------------------- | 
|         |     68 // | 
|         |     69 CMsgBodyControl::CMsgBodyControl( MMsgBaseControlObserver& aBaseControlObserver ) :  | 
|         |     70     CMsgExpandableTextEditorControl( aBaseControlObserver ) | 
|         |     71     { | 
|         |     72     } | 
|         |     73  | 
|         |     74 // --------------------------------------------------------- | 
|         |     75 // CMsgBodyControl::~CMsgBodyControl | 
|         |     76 // | 
|         |     77 // Destructor. | 
|         |     78 // --------------------------------------------------------- | 
|         |     79 // | 
|         |     80 CMsgBodyControl::~CMsgBodyControl() | 
|         |     81     { | 
|         |     82     AknsUtils::DeregisterControlPosition( iEditor ); | 
|         |     83     delete iEditor; | 
|         |     84     delete iCaptionText; | 
|         |     85     AknsUtils::DeregisterControlPosition( this ); | 
|         |     86     } | 
|         |     87  | 
|         |     88 // --------------------------------------------------------- | 
|         |     89 // CMsgBodyControl::NewL | 
|         |     90 // | 
|         |     91 // Factory method that creates this control. | 
|         |     92 // --------------------------------------------------------- | 
|         |     93 // | 
|         |     94 EXPORT_C CMsgBodyControl* CMsgBodyControl::NewL( CCoeControl* aParent ) | 
|         |     95     { | 
|         |     96     __ASSERT_DEBUG( aParent, Panic( EMsgNullPointer ) ); | 
|         |     97  | 
|         |     98     CMsgEditorView* obs = static_cast<CMsgEditorView*>( aParent ); | 
|         |     99     CMsgBodyControl* self = new ( ELeave ) CMsgBodyControl( *obs ); | 
|         |    100     self->SetMopParent( aParent ); | 
|         |    101      | 
|         |    102     CleanupStack::PushL( self ); | 
|         |    103     self->ConstructL(); | 
|         |    104     CleanupStack::Pop( self ); | 
|         |    105  | 
|         |    106     return self; | 
|         |    107     } | 
|         |    108  | 
|         |    109 // --------------------------------------------------------- | 
|         |    110 // CMsgBodyControl::ConstructL | 
|         |    111 // | 
|         |    112 // Creates the body control editor for the this control and sets necessary details. | 
|         |    113 // --------------------------------------------------------- | 
|         |    114 // | 
|         |    115 void CMsgBodyControl::ConstructL() | 
|         |    116     { | 
|         |    117     iControlType = EMsgBodyControl; | 
|         |    118  | 
|         |    119     iEditor = new ( ELeave ) CMsgBodyControlEditor( this,  | 
|         |    120                                                     iControlModeFlags,  | 
|         |    121                                                     iBaseControlObserver ); | 
|         |    122     iEditor->ConstructL(); | 
|         |    123      | 
|         |    124     iEditor->SetControlType(iControlType);    | 
|         |    125     iEditor->SetObserver( this ); | 
|         |    126     iEditor->SetEdwinSizeObserver( this ); | 
|         |    127     iEditor->AddEdwinObserverL( this ); | 
|         |    128     iEditor->SetMaxNumberOfChars( 0 ); | 
|         |    129     iEditor->SetBorder( TGulBorder::ENone ); | 
|         |    130     iEditor->SetAknEditorFlags( EAknEditorFlagUseSCTNumericCharmap | | 
|         |    131                                 EAknEditorFlagEnablePictographInput | | 
|         |    132                                 EAknEditorFlagAllowEntersWithScrollDown );    | 
|         |    133      | 
|         |    134     SetPlainTextMode( ETrue ); | 
|         |    135      | 
|         |    136     ResolveFontMetrics(); | 
|         |    137     SetIcfPromptTextL(); | 
|         |    138     CItemFinder* itemFinder = iEditor->ItemFinder(); | 
|         |    139     if ( itemFinder ) | 
|         |    140         { | 
|         |    141         // for automatic highlight | 
|         |    142         itemFinder->SetEditor( (CEikRichTextEditor**)&iEditor ); | 
|         |    143         } | 
|         |    144     } | 
|         |    145  | 
|         |    146 // --------------------------------------------------------- | 
|         |    147 // CMsgBodyControl::Editor | 
|         |    148 // | 
|         |    149 // Returns a reference to the editor control. | 
|         |    150 // --------------------------------------------------------- | 
|         |    151 // | 
|         |    152 EXPORT_C CEikRichTextEditor& CMsgBodyControl::Editor() const | 
|         |    153     { | 
|         |    154     return *iEditor; | 
|         |    155     } | 
|         |    156  | 
|         |    157 // --------------------------------------------------------- | 
|         |    158 // CMsgBodyControl::SetTextContentL | 
|         |    159 // | 
|         |    160 // Sets text content to the control editor. | 
|         |    161 // --------------------------------------------------------- | 
|         |    162 // | 
|         |    163 EXPORT_C void CMsgBodyControl::SetTextContentL( CRichText& aText ) | 
|         |    164     {    | 
|         |    165 	CItemFinder* autofind = ItemFinder(); | 
|         |    166 	 | 
|         |    167 	TBool alreadyBandFormatting( EFalse ); | 
|         |    168 	if ( iEditor->TextLayout( )->IsFormattingBand( ) ) | 
|         |    169         { | 
|         |    170         alreadyBandFormatting = ETrue; | 
|         |    171         } | 
|         |    172 	 | 
|         |    173     iEditor->SetTextContentL( aText ); | 
|         |    174      | 
|         |    175     // Text added after control has been set visible and  | 
|         |    176     // there is enough text to change editor to do band formatting. | 
|         |    177     // We have to update the editor size to maximum body control size | 
|         |    178     // and enable force control size updating to start size change really | 
|         |    179     // happening. | 
|         |    180     if ( iControlModeFlags & EMsgControlModeInitialized && | 
|         |    181          !alreadyBandFormatting && | 
|         |    182          iEditor->TextLayout( )->IsFormattingBand( ) ) | 
|         |    183         { | 
|         |    184         iControlModeFlags |= EMsgControlModeForceSizeUpdate; | 
|         |    185          | 
|         |    186         TSize newSize( iSize.iWidth, iMaxBodyHeight ); | 
|         |    187         iEditor->SetSize( newSize ); | 
|         |    188          | 
|         |    189         iControlModeFlags &= ~EMsgControlModeForceSizeUpdate; | 
|         |    190         } | 
|         |    191      | 
|         |    192 	if ( autofind ) // for automatic highlight | 
|         |    193 		{ | 
|         |    194 		autofind->SetEditor( (CEikRichTextEditor**)&iEditor ); | 
|         |    195         } | 
|         |    196          | 
|         |    197     iControlModeFlags |= EMsgControlModeModified; | 
|         |    198     } | 
|         |    199  | 
|         |    200 // --------------------------------------------------------- | 
|         |    201 // CMsgBodyControl::InsertCharacterL | 
|         |    202 // | 
|         |    203 // Inserts a character to the editor. | 
|         |    204 // --------------------------------------------------------- | 
|         |    205 // | 
|         |    206 EXPORT_C void CMsgBodyControl::InsertCharacterL( const TChar& aCharacter ) | 
|         |    207     { | 
|         |    208     BodyControlEditor()->InsertCharacterL( aCharacter ); | 
|         |    209     iControlModeFlags |= EMsgControlModeModified; | 
|         |    210     } | 
|         |    211  | 
|         |    212  | 
|         |    213 // --------------------------------------------------------- | 
|         |    214 // CMsgBodyControl::InsertTextL | 
|         |    215 // | 
|         |    216 // Inserts text to the editor. | 
|         |    217 // --------------------------------------------------------- | 
|         |    218 // | 
|         |    219 EXPORT_C void CMsgBodyControl::InsertTextL( const TDesC& aText ) | 
|         |    220     { | 
|         |    221     BodyControlEditor()->InsertTextL( aText ); | 
|         |    222     iControlModeFlags |= EMsgControlModeModified; | 
|         |    223  | 
|         |    224     //iBaseControlObserver->HandleBaseControlEventRequestL(this, EMsgEnsureCorrectFormPosition); | 
|         |    225     } | 
|         |    226  | 
|         |    227 // --------------------------------------------------------- | 
|         |    228 // CMsgBodyControl::NotifyViewEvent | 
|         |    229 // --------------------------------------------------------- | 
|         |    230 // | 
|         |    231 void CMsgBodyControl::NotifyViewEvent( TMsgViewEvent aEvent, TInt aParam ) | 
|         |    232     { | 
|         |    233     TRAP_IGNORE( DoNotifyViewEventL( aEvent, aParam ) ); | 
|         |    234     } | 
|         |    235  | 
|         |    236 // --------------------------------------------------------- | 
|         |    237 // CMsgBodyControl::DoNotifyViewEventL | 
|         |    238 // --------------------------------------------------------- | 
|         |    239 // | 
|         |    240 void CMsgBodyControl::DoNotifyViewEventL( TMsgViewEvent aEvent, TInt /*aParam*/ ) | 
|         |    241     { | 
|         |    242     switch ( aEvent ) | 
|         |    243         { | 
|         |    244         case EMsgViewEventPrepareFocusTransitionUp: | 
|         |    245             { | 
|         |    246             if ( IsFocused() && iEditor->TextView() ) | 
|         |    247                 { | 
|         |    248                 iEditor->ClearSelectionL(); | 
|         |    249                  | 
|         |    250                 iEditor->TextView()->FinishBackgroundFormattingL(); | 
|         |    251                 if ( iEditor->TextLayout()->FirstDocPosFullyInBand() != 0 ) | 
|         |    252                     { | 
|         |    253                     iEditor->NotifyNewDocumentL(); | 
|         |    254                     } | 
|         |    255  | 
|         |    256                 if ( IsReadOnly() ) | 
|         |    257                     { | 
|         |    258                     iEditor->SetCursorPosL( 0, EFalse ); | 
|         |    259                     } | 
|         |    260                 } | 
|         |    261              | 
|         |    262             BodyControlEditor()->PrepareFocusTransition(); | 
|         |    263             break; | 
|         |    264             } | 
|         |    265         case EMsgViewEventPrepareFocusTransitionDown: | 
|         |    266             { | 
|         |    267             if ( IsFocused() && iEditor->TextView() ) | 
|         |    268                 { | 
|         |    269                 iEditor->ClearSelectionL(); | 
|         |    270                  | 
|         |    271                 iEditor->TextView()->FinishBackgroundFormattingL(); | 
|         |    272                 if ( !iEditor->CursorInLastLine() ) | 
|         |    273                     { | 
|         |    274                     iEditor->TextView()->SetDocPosL( iEditor->TextLength(), EFalse ); | 
|         |    275                      | 
|         |    276                     // fills the screen | 
|         |    277                     TViewYPosQualifier yPosQualifier; | 
|         |    278                     yPosQualifier.SetFillScreen(); | 
|         |    279                     iEditor->TextView()->HandleGlobalChangeL( yPosQualifier ); | 
|         |    280                     } | 
|         |    281                      | 
|         |    282                 if ( IsReadOnly() ) | 
|         |    283                     { | 
|         |    284                     iEditor->SetCursorPosL( iEditor->TextLength(), EFalse ); | 
|         |    285                     } | 
|         |    286                 } | 
|         |    287              | 
|         |    288             BodyControlEditor()->PrepareFocusTransition(); | 
|         |    289             break; | 
|         |    290             } | 
|         |    291         case EMsgViewEventSetCursorFirstPos: | 
|         |    292             { | 
|         |    293             if ( iEditor->TextView() &&  | 
|         |    294                  !IsReadOnly() && | 
|         |    295                  !iEditor->CursorInFirstLine() ) | 
|         |    296                 { | 
|         |    297                 iEditor->SetCursorPosL( 0, EFalse ); | 
|         |    298                 } | 
|         |    299             break; | 
|         |    300             } | 
|         |    301         case EMsgViewEventSetCursorLastPos: | 
|         |    302             { | 
|         |    303             if ( iEditor->TextView() &&  | 
|         |    304                  !IsReadOnly() && | 
|         |    305                  !iEditor->CursorInLastLine() ) | 
|         |    306                 { | 
|         |    307                 iEditor->SetCursorPosL( iEditor->TextLength(), EFalse ); | 
|         |    308                 } | 
|         |    309             break; | 
|         |    310             } | 
|         |    311         case EMsgViewEventPrepareForViewing: | 
|         |    312             { | 
|         |    313             /* | 
|         |    314             iEditor->SetSuppressFormatting( EFalse );         | 
|         |    315             iEditor->NotifyNewFormatL(); | 
|         |    316             */ | 
|         |    317             } | 
|         |    318         default: | 
|         |    319             { | 
|         |    320             break; | 
|         |    321             } | 
|         |    322         } | 
|         |    323     } | 
|         |    324  | 
|         |    325 // --------------------------------------------------------- | 
|         |    326 // CMsgBodyControl::Reset | 
|         |    327 //  | 
|         |    328 // Resets the editor content and notifies view if EMsgControlModeBodyMaxHeight | 
|         |    329 // is enabled. Explicit function call is needed as control height is not actually | 
|         |    330 // changing on CMsgBodyControl::HandleEdwinSizeEventL. | 
|         |    331 // --------------------------------------------------------- | 
|         |    332 // | 
|         |    333 EXPORT_C void CMsgBodyControl::Reset() | 
|         |    334     { | 
|         |    335     iEditor->Reset();        | 
|         |    336      | 
|         |    337     if ( iControlModeFlags & EMsgControlModeBodyMaxHeight && | 
|         |    338          iControlModeFlags & EMsgControlModeInitialized ) | 
|         |    339         { | 
|         |    340         TRAP_IGNORE( iBaseControlObserver->HandleBaseControlEventRequestL( this,  | 
|         |    341                                                                            EMsgHeightChanged ) ); | 
|         |    342         } | 
|         |    343      | 
|         |    344     iControlModeFlags |= EMsgControlModeModified; | 
|         |    345     } | 
|         |    346  | 
|         |    347 // --------------------------------------------------------- | 
|         |    348 // CMsgBodyControl::SetAndGetSizeL | 
|         |    349 // | 
|         |    350 // Sets size for the editor and this control. | 
|         |    351 // --------------------------------------------------------- | 
|         |    352 // | 
|         |    353 EXPORT_C void CMsgBodyControl::SetAndGetSizeL( TSize& aSize ) | 
|         |    354     { | 
|         |    355     TSize bodySize( aSize ); | 
|         |    356  | 
|         |    357     if ( iControlModeFlags & EMsgControlModeBodyMaxHeight ) | 
|         |    358         { | 
|         |    359         bodySize.iHeight = iMaxBodyHeight; | 
|         |    360         } | 
|         |    361     else | 
|         |    362         { | 
|         |    363         if ( iEditor->TextLayout() ) | 
|         |    364             { | 
|         |    365             if ( iEditor->TextLayout()->IsFormattingBand() ) | 
|         |    366                 { | 
|         |    367                 // With band formatting the idea is that it is only | 
|         |    368                 // used when there is more than screen size of text. | 
|         |    369                 // If this is false then formatting limits should be | 
|         |    370                 // change. This is the reason we can safely use  | 
|         |    371                 // max body height with it. | 
|         |    372                 bodySize.iHeight = iMaxBodyHeight; | 
|         |    373                 } | 
|         |    374             else | 
|         |    375                 { | 
|         |    376                 // Force background formatting to stop so that correct  | 
|         |    377                 // height can be retrieved | 
|         |    378                 if ( iEditor->TextView() ) | 
|         |    379                     { | 
|         |    380                     iEditor->TextView()->FinishBackgroundFormattingL(); | 
|         |    381                     } | 
|         |    382                      | 
|         |    383                 bodySize.iHeight = iEditor->TextLayout()->NumFormattedLines() * iLineHeight; | 
|         |    384                 }     | 
|         |    385            } | 
|         |    386         } | 
|         |    387  | 
|         |    388     iEditor->SetAndGetSizeL( bodySize ); | 
|         |    389      | 
|         |    390     MsgEditorCommons::RoundToNextLine( bodySize.iHeight, iLineHeight ); | 
|         |    391          | 
|         |    392     SetSizeWithoutNotification( bodySize ); | 
|         |    393  | 
|         |    394     aSize = bodySize; | 
|         |    395     } | 
|         |    396  | 
|         |    397 // --------------------------------------------------------- | 
|         |    398 // CMsgBodyControl::IsFocusChangePossible | 
|         |    399 // | 
|         |    400 // Checks if the focus change up or down is possible and returns ETrue if it is. | 
|         |    401 // --------------------------------------------------------- | 
|         |    402 // | 
|         |    403 EXPORT_C TBool CMsgBodyControl::IsFocusChangePossible( TMsgFocusDirection aDirection ) const | 
|         |    404     { | 
|         |    405     TBool changeFocusPossible = EFalse; | 
|         |    406      | 
|         |    407     if ( IsReadOnly() ) | 
|         |    408         { | 
|         |    409         TRAPD( error, changeFocusPossible = BodyControlEditor()->IsFocusChangePossibleL( aDirection ) ); | 
|         |    410         if ( error != KErrNone ) | 
|         |    411             { | 
|         |    412             changeFocusPossible = ETrue; | 
|         |    413             } | 
|         |    414         } | 
|         |    415     else | 
|         |    416         { | 
|         |    417         if ( IsCursorLocation( aDirection == EMsgFocusUp ? EMsgTop :  | 
|         |    418                                                            EMsgBottom ) ) | 
|         |    419             { | 
|         |    420             changeFocusPossible = ETrue; | 
|         |    421             } | 
|         |    422         } | 
|         |    423      | 
|         |    424     return changeFocusPossible; | 
|         |    425     } | 
|         |    426  | 
|         |    427 // --------------------------------------------------------- | 
|         |    428 // CMsgBodyControl::PrepareForReadOnly | 
|         |    429 // | 
|         |    430 // Sets the editor read only or editable. | 
|         |    431 // --------------------------------------------------------- | 
|         |    432 // | 
|         |    433 void CMsgBodyControl::PrepareForReadOnly( TBool aReadOnly ) | 
|         |    434     { | 
|         |    435     TRAP_IGNORE( iEditor->PrepareForReadOnlyL( aReadOnly ) ); | 
|         |    436     } | 
|         |    437  | 
|         |    438 // --------------------------------------------------------- | 
|         |    439 // CMsgBodyControl::OfferKeyEventL | 
|         |    440 // | 
|         |    441 // Handles key events. | 
|         |    442 // --------------------------------------------------------- | 
|         |    443 // | 
|         |    444 EXPORT_C TKeyResponse CMsgBodyControl::OfferKeyEventL( const TKeyEvent& aKeyEvent,  | 
|         |    445                                                        TEventCode aType ) | 
|         |    446     {     | 
|         |    447     return iEditor->OfferKeyEventL( aKeyEvent, aType ); | 
|         |    448     } | 
|         |    449  | 
|         |    450 // --------------------------------------------------------- | 
|         |    451 // CMsgBodyControl::InputCapabilities | 
|         |    452 // | 
|         |    453 // Returns input capabilities. | 
|         |    454 // --------------------------------------------------------- | 
|         |    455 // | 
|         |    456 EXPORT_C TCoeInputCapabilities CMsgBodyControl::InputCapabilities() const | 
|         |    457     { | 
|         |    458     if ( iEditor->IsFocused() ) | 
|         |    459         { | 
|         |    460         TCoeInputCapabilities inputCapabilities( TCoeInputCapabilities::ENone,  | 
|         |    461                                                  NULL,  | 
|         |    462                                                  const_cast<CMsgBodyControl*>( this ) ); | 
|         |    463         inputCapabilities.MergeWith( iEditor->InputCapabilities() ); | 
|         |    464          | 
|         |    465         return inputCapabilities; | 
|         |    466         } | 
|         |    467     else | 
|         |    468         { | 
|         |    469         return TCoeInputCapabilities::ENone; | 
|         |    470         } | 
|         |    471     } | 
|         |    472  | 
|         |    473 // --------------------------------------------------------- | 
|         |    474 // CMsgBodyControl::HandleResourceChange | 
|         |    475 // | 
|         |    476 // | 
|         |    477 // --------------------------------------------------------- | 
|         |    478 // | 
|         |    479 void CMsgBodyControl::HandleResourceChange( TInt aType ) | 
|         |    480     {  | 
|         |    481     CMsgExpandableTextEditorControl::HandleResourceChange( aType ); | 
|         |    482          | 
|         |    483 	if ( aType == KEikDynamicLayoutVariantSwitch ) | 
|         |    484         { | 
|         |    485         ResolveFontMetrics(); | 
|         |    486  | 
|         |    487         CItemFinder* itemFinder = iEditor->ItemFinder(); | 
|         |    488         if ( itemFinder &&  | 
|         |    489              itemFinder->CurrentItemExt().iItemType != CItemFinder::ENoneSelected ) | 
|         |    490             { | 
|         |    491             // Refreshes the item finder highlight if present highlighted | 
|         |    492             TRAP_IGNORE( itemFinder->ResolveAndSetItemTypeL() ); | 
|         |    493             } | 
|         |    494         } | 
|         |    495     } | 
|         |    496  | 
|         |    497 // --------------------------------------------------------- | 
|         |    498 // CMsgBodyControl::CountComponentControls | 
|         |    499 // | 
|         |    500 // Returns a number of controls. | 
|         |    501 // --------------------------------------------------------- | 
|         |    502 // | 
|         |    503 TInt CMsgBodyControl::CountComponentControls() const | 
|         |    504     { | 
|         |    505     CCoeControl* controls[] = { iEditor }; | 
|         |    506  | 
|         |    507     TInt count = 0; | 
|         |    508     for ( TUint ii = 0; ii < sizeof( controls ) / sizeof( CCoeControl* ); ii++ ) | 
|         |    509         { | 
|         |    510         if ( controls[ii] ) | 
|         |    511             { | 
|         |    512             count++; | 
|         |    513             } | 
|         |    514         } | 
|         |    515  | 
|         |    516     return count; | 
|         |    517     } | 
|         |    518  | 
|         |    519 // --------------------------------------------------------- | 
|         |    520 // CMsgBodyControl::ComponentControl | 
|         |    521 // | 
|         |    522 // Returns a control of index aIndex. | 
|         |    523 // --------------------------------------------------------- | 
|         |    524 // | 
|         |    525 CCoeControl* CMsgBodyControl::ComponentControl( TInt aIndex ) const | 
|         |    526     { | 
|         |    527     CCoeControl* controls[] = { iEditor }; | 
|         |    528  | 
|         |    529     for ( TUint ii = 0; ii < sizeof( controls ) / sizeof( CCoeControl* ); ii++ ) | 
|         |    530         { | 
|         |    531         if ( controls[ii] && aIndex-- == 0 ) | 
|         |    532             { | 
|         |    533             return controls[ii]; | 
|         |    534             } | 
|         |    535         } | 
|         |    536  | 
|         |    537     return NULL; | 
|         |    538     } | 
|         |    539  | 
|         |    540 // --------------------------------------------------------- | 
|         |    541 // CMsgBodyControl::SizeChanged | 
|         |    542 // | 
|         |    543 // Sets position for the editor. | 
|         |    544 // --------------------------------------------------------- | 
|         |    545 // | 
|         |    546 void CMsgBodyControl::SizeChanged() | 
|         |    547     { | 
|         |    548     MEBLOGGER_ENTERFN("CMsgBodyControl::SizeChanged"); | 
|         |    549  | 
|         |    550     if ( iControlModeFlags & EMsgControlModeSizeChanging ) | 
|         |    551         { | 
|         |    552         MEBLOGGER_WRITE("EMsgControlModeSizeChanging"); | 
|         |    553         } | 
|         |    554     else | 
|         |    555         { | 
|         |    556         TPoint editorPosition( Position() ); | 
|         |    557         editorPosition.iY += iEditorTop; | 
|         |    558         iEditor->SetExtent( editorPosition, iEditor->Size() ); | 
|         |    559      | 
|         |    560         AknsUtils::RegisterControlPosition( this ); | 
|         |    561         AknsUtils::RegisterControlPosition( iEditor ); | 
|         |    562         } | 
|         |    563  | 
|         |    564     MEBLOGGER_LEAVEFN("CMsgBodyControl::SizeChanged"); | 
|         |    565     } | 
|         |    566  | 
|         |    567 // --------------------------------------------------------- | 
|         |    568 // CMsgBodyControl::FocusChanged | 
|         |    569 // | 
|         |    570 // This is called when the focus of the control is changed. | 
|         |    571 // --------------------------------------------------------- | 
|         |    572 // | 
|         |    573 void CMsgBodyControl::FocusChanged( TDrawNow aDrawNow ) | 
|         |    574     { | 
|         |    575     // For automatic highlight | 
|         |    576     iEditor->SetFocus( IsFocused(), aDrawNow ); | 
|         |    577     if ( aDrawNow == EDrawNow ) | 
|         |    578         { | 
|         |    579         DrawDeferred(); | 
|         |    580         }     | 
|         |    581     } | 
|         |    582  | 
|         |    583 // --------------------------------------------------------- | 
|         |    584 // CMsgBodyControl::SetContainerWindowL | 
|         |    585 // | 
|         |    586 // Sets container window. | 
|         |    587 // --------------------------------------------------------- | 
|         |    588 // | 
|         |    589 void CMsgBodyControl::SetContainerWindowL( const CCoeControl& aContainer ) | 
|         |    590     { | 
|         |    591     CCoeControl::SetContainerWindowL( aContainer ); | 
|         |    592      | 
|         |    593     iEditor->SetContainerWindowL( aContainer ); | 
|         |    594     } | 
|         |    595  | 
|         |    596 // --------------------------------------------------------- | 
|         |    597 // CMsgBodyControl::CheckCorrectControlYPos | 
|         |    598 // | 
|         |    599 // | 
|         |    600 // --------------------------------------------------------- | 
|         |    601 // | 
|         |    602 void CMsgBodyControl::CheckCorrectControlYPosL() | 
|         |    603     { | 
|         |    604     // SJK 06.09.2004: Added "IsReadOnly" check. Fixing KHAI-5KLH8L. | 
|         |    605     if ( IsReadOnly() && iEditor->TextView() && IsFocused() ) | 
|         |    606         { | 
|         |    607         TRect viewRect = iBaseControlObserver->ViewRect(); | 
|         |    608         TInt delta = viewRect.iTl.iY - iEditor->Rect().iTl.iY; | 
|         |    609         iEditor->TextView()->FinishBackgroundFormattingL(); | 
|         |    610         TInt msgBaseLineDelta( iLineHeight ); | 
|         |    611  | 
|         |    612         if ( delta % msgBaseLineDelta ) | 
|         |    613             { | 
|         |    614             if ( delta < 0 ) | 
|         |    615                 { | 
|         |    616                 delta = ( delta - delta % msgBaseLineDelta ); | 
|         |    617                 } | 
|         |    618             else | 
|         |    619                 { | 
|         |    620                 delta = ( delta - delta % msgBaseLineDelta ) + msgBaseLineDelta; | 
|         |    621                 } | 
|         |    622             } | 
|         |    623  | 
|         |    624         if ( ( ( delta < 0) &&  | 
|         |    625             ( iEditor->TextLayout()->FirstDocPosFullyInBand() != 0 ) ) | 
|         |    626             || ( delta > 0 ) ) | 
|         |    627             { | 
|         |    628             // these three lines must be here in order to | 
|         |    629             // keep text filled with the view. | 
|         |    630             TViewYPosQualifier yPosQualifier; | 
|         |    631             yPosQualifier.SetFillScreen(); | 
|         |    632             iEditor->TextView()->HandleGlobalChangeL( yPosQualifier ); | 
|         |    633  | 
|         |    634             iBaseControlObserver->HandleBaseControlEventRequestL( | 
|         |    635                 this, EMsgScrollForm, delta ); | 
|         |    636             } | 
|         |    637         } | 
|         |    638     } | 
|         |    639  | 
|         |    640 // --------------------------------------------------------- | 
|         |    641 // CMsgBodyControl::ItemFinder | 
|         |    642 // | 
|         |    643 // | 
|         |    644 // --------------------------------------------------------- | 
|         |    645 // | 
|         |    646 CItemFinder* CMsgBodyControl::ItemFinder() | 
|         |    647 	{ | 
|         |    648 	return IsReadOnly() ? iEditor->ItemFinder() :  | 
|         |    649 	                      NULL; | 
|         |    650 	} | 
|         |    651 	 | 
|         |    652 // --------------------------------------------------------- | 
|         |    653 // CMsgBodyControl::SetupAutomaticFindAfterFocusChangeL | 
|         |    654 // | 
|         |    655 // | 
|         |    656 // --------------------------------------------------------- | 
|         |    657 // | 
|         |    658 void CMsgBodyControl::SetupAutomaticFindAfterFocusChangeL( TBool aBeginning ) | 
|         |    659     { | 
|         |    660     BodyControlEditor()->SetupAutomaticFindAfterFocusChangeL( aBeginning ); | 
|         |    661     } | 
|         |    662  | 
|         |    663 // --------------------------------------------------------- | 
|         |    664 // CMsgBodyControl::ResolveFontMetrics | 
|         |    665 // | 
|         |    666 // | 
|         |    667 // --------------------------------------------------------- | 
|         |    668 // | 
|         |    669 void CMsgBodyControl::ResolveFontMetrics() | 
|         |    670     { | 
|         |    671     TAknLayoutText textLayout; | 
|         |    672     TAknTextLineLayout textLineLayout; | 
|         |    673      | 
|         |    674     TAknLayoutRect msgTextPane; | 
|         |    675     msgTextPane.LayoutRect( MsgEditorCommons::MsgDataPane(), | 
|         |    676                             AknLayoutScalable_Apps::msg_text_pane( 0 ).LayoutLine() ); | 
|         |    677     TAknLayoutRect msgBodyPane; | 
|         |    678     msgBodyPane.LayoutRect( msgTextPane.Rect(), | 
|         |    679                             AknLayoutScalable_Apps::msg_body_pane().LayoutLine() ); | 
|         |    680      | 
|         |    681     if ( IsReadOnly() ) | 
|         |    682         { | 
|         |    683         textLineLayout = AknLayoutScalable_Apps::msg_body_pane_t1( 0 ).LayoutLine(); | 
|         |    684         } | 
|         |    685     else | 
|         |    686         { | 
|         |    687         textLineLayout = AknLayoutScalable_Apps::msg_body_pane_t1( 1 ).LayoutLine(); | 
|         |    688         } | 
|         |    689      | 
|         |    690     textLayout.LayoutText( msgBodyPane.Rect(), | 
|         |    691                            textLineLayout ); | 
|         |    692                             | 
|         |    693     iEditorTop = textLayout.TextRect().iTl.iY - msgBodyPane.Rect().iTl.iY; | 
|         |    694      | 
|         |    695     // Set editor alignment | 
|         |    696     iEditor->SetAlignment( textLineLayout.iJ ); | 
|         |    697      | 
|         |    698     iEditor->SetMaximumHeight( MsgEditorCommons::MaxBodyHeight() - iEditorTop ); | 
|         |    699     } | 
|         |    700  | 
|         |    701 // --------------------------------------------------------- | 
|         |    702 // CMsgBodyControl::BodyControlEditor | 
|         |    703 // --------------------------------------------------------- | 
|         |    704 // | 
|         |    705 CMsgBodyControlEditor* CMsgBodyControl::BodyControlEditor() const | 
|         |    706     { | 
|         |    707     return static_cast<CMsgBodyControlEditor*>( iEditor ); | 
|         |    708     } | 
|         |    709  | 
|         |    710 // --------------------------------------------------------- | 
|         |    711 // CMsgBodyControl::GetCaptionForFep | 
|         |    712 // Returns the ICF Prompt text of Body control to FEP | 
|         |    713 // --------------------------------------------------------- | 
|         |    714 // | 
|         |    715 void CMsgBodyControl::GetCaptionForFep( TDes& aCaption ) const | 
|         |    716     {     | 
|         |    717     const TInt maximumLength = aCaption.MaxLength(); | 
|         |    718      | 
|         |    719     if ( iCaptionText->Length() < maximumLength ) | 
|         |    720         { | 
|         |    721         TPtr ptr = iCaptionText->Des(); | 
|         |    722         aCaption.Copy( ptr );  | 
|         |    723         }                    | 
|         |    724     } | 
|         |    725 // --------------------------------------------------------- | 
|         |    726 // CMsgBodyControl::SetIcfPromptTextL() | 
|         |    727 // Loads ICF Prompt text of Message Body control | 
|         |    728 // --------------------------------------------------------- | 
|         |    729 // | 
|         |    730 void CMsgBodyControl::SetIcfPromptTextL() | 
|         |    731     { | 
|         |    732      | 
|         |    733     if(iCaptionText) | 
|         |    734       { | 
|         |    735       delete iCaptionText;     | 
|         |    736       iCaptionText = NULL;             | 
|         |    737       }         | 
|         |    738     iCaptionText =   StringLoader::LoadLC( R_QTN_MSG_ICF_PROMPT_TEXT_MESSAGE, iCoeEnv );               | 
|         |    739     CleanupStack::Pop( iCaptionText ); | 
|         |    740  | 
|         |    741     } | 
|         |    742  | 
|         |    743 //  End of File |