messagingappbase/msgeditor/viewsrc/MsgExpandableControl.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002-2006 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:  MsgExpandableControl implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ========== INCLUDE FILES ================================
       
    21 
       
    22 #include <coeinput.h>                      // for TCoeInputCapabilities
       
    23 #include <barsread.h>                      // for TResourceReader
       
    24 #include <eiklabel.h>                      // for CEikLabel
       
    25 #include <eikenv.h>                        // for CEikonEnv
       
    26 #include <eikedwin.h>                      // for TClipboardFunc
       
    27 #include <txtrich.h>                       // for CRichText
       
    28 #include <AknUtils.h>                      // for AknUtils
       
    29 #include <aknenv.h>                        // for CAknEnv
       
    30 #include <AknDef.h>
       
    31 #include <AknsUtils.h>                     // for Skinned drawing
       
    32 #include <aknbutton.h>                     // for CAknButton
       
    33 
       
    34 #include <applayout.cdl.h> // LAF
       
    35 #include <aknlayoutscalable_apps.cdl.h>
       
    36 
       
    37 #include "MsgEditorCommon.h"               //
       
    38 #include "MsgExpandableControl.h"          // for CMsgExpandableControl
       
    39 #include "MsgExpandableControlEditor.h"    // for CMsgExpandableControlEditor
       
    40 #include "MsgBaseControlObserver.h"        // for MMsgBaseControlObserver
       
    41 #include "MsgEditorPanic.h"                // for CMsgEditor panics
       
    42 #include "MsgEditorLogging.h"
       
    43 
       
    44 // ========== EXTERNAL DATA STRUCTURES =====================
       
    45 
       
    46 // ========== EXTERNAL FUNCTION PROTOTYPES =================
       
    47 
       
    48 // ========== CONSTANTS ====================================
       
    49 
       
    50 // ========== MACROS =======================================
       
    51 
       
    52 // ========== LOCAL CONSTANTS AND MACROS ===================
       
    53 
       
    54 _LIT(KMsgDefaultCaption, " ");
       
    55 
       
    56 // ========== MODULE DATA STRUCTURES =======================
       
    57 
       
    58 // ========== LOCAL FUNCTION PROTOTYPES ====================
       
    59 
       
    60 // ========== LOCAL FUNCTIONS ==============================
       
    61 
       
    62 // ========== MEMBER FUNCTIONS =============================
       
    63 
       
    64 // ---------------------------------------------------------
       
    65 // CMsgExpandableControl::CMsgExpandableControl
       
    66 //
       
    67 // Constructor.
       
    68 // ---------------------------------------------------------
       
    69 //
       
    70 EXPORT_C CMsgExpandableControl::CMsgExpandableControl()
       
    71     {
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------
       
    75 // CMsgExpandableControl::CMsgExpandableControl
       
    76 //
       
    77 // Constructor.
       
    78 // ---------------------------------------------------------
       
    79 //
       
    80 EXPORT_C CMsgExpandableControl::CMsgExpandableControl( MMsgBaseControlObserver& aBaseControlObserver ) :
       
    81     CMsgExpandableTextEditorControl( aBaseControlObserver )
       
    82     {
       
    83     }
       
    84 
       
    85 // ---------------------------------------------------------
       
    86 // CMsgExpandableControl::ConstructFromResourceL
       
    87 //
       
    88 // Creates this control from resource.
       
    89 // ---------------------------------------------------------
       
    90 //
       
    91 void CMsgExpandableControl::ConstructFromResourceL( TInt aResourceId )
       
    92     {
       
    93     BaseConstructL();  // Sets margins only
       
    94 
       
    95     TResourceReader reader;
       
    96     iCoeEnv->CreateResourceReaderLC( reader, aResourceId );
       
    97 
       
    98     // Create caption
       
    99     iCaption = CreateCaptionFromResourceL( reader );
       
   100 
       
   101     // Read control details from resource
       
   102     ReadControlPropertiesFromResourceL( reader );
       
   103 
       
   104     // Create editor
       
   105     iEditor = CreateEditorFromResourceL( reader );
       
   106     
       
   107     iEditor->SetControlType(EMsgExpandableControl); 
       
   108     iCtrltype = EMsgExpandableControl;
       
   109     iEditor->SetObserver( this );
       
   110     iEditor->SetEdwinSizeObserver( this );
       
   111     iEditor->AddEdwinObserverL( this );
       
   112     iEditor->SetBorder( TGulBorder::ENone );
       
   113 
       
   114     SetPlainTextMode( ETrue );
       
   115 
       
   116     ResolveLayoutsL();
       
   117 
       
   118     CleanupStack::PopAndDestroy();  // reader
       
   119     }
       
   120 
       
   121 // ---------------------------------------------------------
       
   122 // CMsgExpandableControl::~CMsgExpandableControl
       
   123 //
       
   124 // Destructor.
       
   125 // ---------------------------------------------------------
       
   126 //
       
   127 EXPORT_C CMsgExpandableControl::~CMsgExpandableControl()
       
   128     {
       
   129     AknsUtils::DeregisterControlPosition( iCaption );
       
   130     delete iCaption;
       
   131 
       
   132 #ifdef RD_SCALABLE_UI_V2
       
   133     if ( iButton )
       
   134         {
       
   135         AknsUtils::DeregisterControlPosition( iButton );
       
   136         delete iButton;
       
   137         }    
       
   138 #endif // RD_SCALABLE_UI_V2
       
   139     
       
   140     AknsUtils::DeregisterControlPosition( iEditor );
       
   141     delete iEditor;
       
   142         
       
   143     AknsUtils::DeregisterControlPosition( this );
       
   144     }
       
   145 
       
   146 // ---------------------------------------------------------
       
   147 // CMsgExpandableControl::Editor
       
   148 //
       
   149 // Returns a reference to the editor control.
       
   150 // ---------------------------------------------------------
       
   151 //
       
   152 EXPORT_C CEikRichTextEditor& CMsgExpandableControl::Editor() const
       
   153     {
       
   154     return *iEditor;
       
   155     }
       
   156 
       
   157 // ---------------------------------------------------------
       
   158 // CMsgExpandableControl::Caption
       
   159 //
       
   160 // Returns a reference to the label control.
       
   161 // ---------------------------------------------------------
       
   162 //
       
   163 EXPORT_C CEikLabel& CMsgExpandableControl::Caption() const
       
   164     {
       
   165     return *iCaption;
       
   166     }
       
   167 
       
   168 // ---------------------------------------------------------
       
   169 // CMsgExpandableControl::SetTextContentL
       
   170 //
       
   171 // Sets text content to the control editor.
       
   172 // ---------------------------------------------------------
       
   173 //
       
   174 EXPORT_C void CMsgExpandableControl::SetTextContentL( CRichText& aText )
       
   175     {
       
   176     iEditor->SetTextContentL( aText );
       
   177     
       
   178     if ( iControlModeFlags & EMsgControlModeInitialized )
       
   179         {
       
   180         iControlModeFlags |= EMsgControlModeModified;
       
   181         }
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------
       
   185 // CMsgExpandableControl::SetTextContentL
       
   186 //
       
   187 // Sets text content to the control editor.
       
   188 // ---------------------------------------------------------
       
   189 //
       
   190 EXPORT_C void CMsgExpandableControl::SetTextContentL( const TDesC& aText )
       
   191     {
       
   192     iEditor->SetTextL( &aText );
       
   193     
       
   194     if ( iControlModeFlags & EMsgControlModeInitialized )
       
   195         {
       
   196         iControlModeFlags |= EMsgControlModeModified;
       
   197         }
       
   198     }
       
   199 
       
   200 // ---------------------------------------------------------
       
   201 // CMsgExpandableControl::TextContentStrippedL
       
   202 //
       
   203 // Copies stripped content to aBuf. Control chars, newlines and if
       
   204 // aNoExtraSemicolons is ETrue, also two consecutive semicolons are
       
   205 // replaced with semicolon and space.
       
   206 // ---------------------------------------------------------
       
   207 //
       
   208 EXPORT_C void CMsgExpandableControl::TextContentStrippedL( TDes& aBuf, 
       
   209                                                            TInt aMaxLen, 
       
   210                                                            TBool aNoExtraSemicolons )
       
   211     {
       
   212     CRichText& text = TextContent();
       
   213     TInt len = text.DocumentLength();
       
   214     HBufC* buf = HBufC::NewLC( len );
       
   215     TPtr ptr = buf->Des();
       
   216     text.ExtractSelectively( ptr, 0, len, CPlainText::EExtractVisible );
       
   217 
       
   218     if ( aNoExtraSemicolons )
       
   219         {
       
   220         TText ch0 = 0;
       
   221         len = ptr.Length();
       
   222         for (TInt i = 0; i < len; i++)
       
   223             {
       
   224             TText& ch1 = ptr[i];
       
   225             if ( i > 0 )
       
   226                 {
       
   227                 ch0 = ptr[i - 1];
       
   228                 }
       
   229             if ( ( ch1 == KSemicolon || 
       
   230                    ch1 == KArabicSemicolon ) && 
       
   231                  ( ch0 == KSemicolon || 
       
   232                    ch0 == KArabicSemicolon ) )
       
   233                 {
       
   234                 ch1 = ' ';
       
   235                 }
       
   236             }
       
   237         }
       
   238 
       
   239     ptr.TrimAll();
       
   240 
       
   241     len = ptr.Length();
       
   242     if ( len > aMaxLen )
       
   243         {
       
   244         ptr.Delete( aMaxLen, len - aMaxLen );
       
   245         }
       
   246 
       
   247     aBuf.Copy( ptr );
       
   248 
       
   249     CleanupStack::PopAndDestroy( buf );
       
   250     }
       
   251 
       
   252 // ---------------------------------------------------------
       
   253 // CMsgExpandableControl::NotifyViewEvent
       
   254 //
       
   255 // Notifies editor about the scroll event.
       
   256 // ---------------------------------------------------------
       
   257 //
       
   258 void CMsgExpandableControl::NotifyViewEvent( TMsgViewEvent aEvent, TInt aParam )
       
   259     {
       
   260     TRAP_IGNORE( DoNotifyViewEventL( aEvent, aParam ) );
       
   261     }
       
   262 
       
   263 // ---------------------------------------------------------
       
   264 // CMsgExpandableControl::DoNotifyViewEventL
       
   265 // ---------------------------------------------------------
       
   266 //
       
   267 void CMsgExpandableControl::DoNotifyViewEventL( TMsgViewEvent aEvent, TInt aParam )
       
   268     {
       
   269     switch ( aEvent )
       
   270         {
       
   271         case EMsgViewEventPrepareFocusTransitionUp:
       
   272             {
       
   273             if ( IsFocused() )
       
   274                 {
       
   275                 iEditor->ClearSelectionL();
       
   276                 }
       
   277             break;
       
   278             }
       
   279         case EMsgViewEventPrepareFocusTransitionDown:
       
   280             {
       
   281             if ( IsFocused() )
       
   282                 {
       
   283                 iEditor->ClearSelectionL();
       
   284                 }
       
   285             break;
       
   286             }
       
   287         case EMsgViewEventSetCursorFirstPos:
       
   288             {
       
   289             if ( iEditor->TextView() )
       
   290                 {
       
   291                 if ( IsReadOnly() )
       
   292                     {
       
   293                     // Do not set document position if autohightlight is
       
   294                     // used as it cancels current hightlight if used.
       
   295                     if ( !( aParam & EMsgViewEventAutoHighlight ) )
       
   296                         {
       
   297                         iEditor->SetCursorPosL( 0, EFalse );
       
   298                         }
       
   299                     }
       
   300                 else
       
   301                     {
       
   302                     if ( !iEditor->CursorInFirstLine() )
       
   303                         {
       
   304                         iEditor->SetCursorPosL( 0, EFalse );
       
   305                         }
       
   306                     }
       
   307                 }
       
   308             break;
       
   309             }
       
   310         case EMsgViewEventSetCursorLastPos:
       
   311             {
       
   312             if ( iEditor->TextView() )
       
   313                 {
       
   314                 TInt len = iEditor->TextLength();
       
   315                 
       
   316                 if ( IsReadOnly() )
       
   317                     {
       
   318                     // Do not set document position if autohightlight is
       
   319                     // used as it cancels current hightlight if used.
       
   320                     if ( !( aParam & EMsgViewEventAutoHighlight ) )
       
   321                         {
       
   322                         iEditor->SetCursorPosL( len, EFalse );
       
   323                         }
       
   324                     }
       
   325                 else
       
   326                     {
       
   327                     if ( !iEditor->CursorInLastLine() )
       
   328                         {
       
   329                         iEditor->SetCursorPosL( len, EFalse );
       
   330                         }
       
   331                     }
       
   332                 }
       
   333             break;
       
   334             }
       
   335         case EMsgViewEventPrepareForViewing:
       
   336             {    
       
   337             /*
       
   338             iEditor->SetSuppressFormatting( EFalse );
       
   339             iEditor->NotifyNewFormatL();
       
   340             */
       
   341             }
       
   342         default:
       
   343             {
       
   344             break;
       
   345             }
       
   346         }
       
   347     }
       
   348 
       
   349 // ---------------------------------------------------------
       
   350 // CMsgExpandableControl::Reset
       
   351 //
       
   352 // Reset contents of the editor.
       
   353 // ---------------------------------------------------------
       
   354 //
       
   355 EXPORT_C void CMsgExpandableControl::Reset()
       
   356     {
       
   357     iEditor->Reset();
       
   358     iControlModeFlags |= EMsgControlModeModified;
       
   359     }
       
   360 
       
   361 // ---------------------------------------------------------
       
   362 // CMsgExpandableControl::SetAndGetSizeL
       
   363 //
       
   364 // Sets sizes for the caption and control according to aSize.
       
   365 // ---------------------------------------------------------
       
   366 //
       
   367 EXPORT_C void CMsgExpandableControl::SetAndGetSizeL( TSize& aSize )
       
   368     {   
       
   369 #ifdef RD_SCALABLE_UI_V2
       
   370     
       
   371     iCaption->SetSize( iCaptionLayout.TextRect().Size() );
       
   372     
       
   373     if ( iButton )
       
   374         {
       
   375         iButton->SetSize( iButtonLayout.Rect().Size() );
       
   376         }
       
   377 #else
       
   378     iCaption->SetSize( iCaptionLayout.TextRect().Size() );
       
   379 #endif // RD_SCALABLE_UI_V2
       
   380     
       
   381     TSize editorSize( iEditorLayout.TextRect().Width(),
       
   382                       iBaseControlObserver->ViewRect().Height() );    
       
   383     iEditor->SetAndGetSizeL( editorSize );
       
   384     
       
   385     TSize thisSize( aSize.iWidth, 0 );
       
   386     if( iEditor->TextLayout() && iEditor->TextLayout()->IsFormattingBand( ) )
       
   387         {
       
   388         thisSize.iHeight = MsgEditorCommons::MaxBodyHeight( );
       
   389         }
       
   390     else
       
   391         {
       
   392         thisSize.iHeight = iSize.iHeight;
       
   393         }
       
   394     
       
   395     // Control height is always atleast one line height
       
   396     thisSize.iHeight = Max( MsgEditorCommons::MsgBaseLineDelta(), thisSize.iHeight );
       
   397         
       
   398     SetSizeWithoutNotification( thisSize );
       
   399     aSize = iSize;
       
   400     }
       
   401 
       
   402 // ---------------------------------------------------------
       
   403 // CMsgExpandableControl::IsFocusChangePossible
       
   404 //
       
   405 // Checks if focus up or down depending on aDirection is possible and returns
       
   406 // ETrue if it is.
       
   407 // ---------------------------------------------------------
       
   408 //
       
   409 EXPORT_C TBool CMsgExpandableControl::IsFocusChangePossible( TMsgFocusDirection aDirection ) const
       
   410     {
       
   411     switch ( aDirection )
       
   412         {
       
   413         case EMsgFocusUp:
       
   414             {
       
   415             if ( IsReadOnly() )
       
   416                 {
       
   417                 return iEditor->IsFirstLineVisible();
       
   418                 }
       
   419             else
       
   420                 {
       
   421                 return IsCursorLocation( EMsgTop );
       
   422                 }
       
   423             }
       
   424         case EMsgFocusDown:
       
   425             {
       
   426             if ( IsReadOnly() )
       
   427                 {
       
   428                 return iEditor->IsLastLineVisible();
       
   429                 }
       
   430             else
       
   431                 {
       
   432                 return IsCursorLocation( EMsgBottom );
       
   433                 }
       
   434             }
       
   435         default:
       
   436             {
       
   437             break;
       
   438             }
       
   439         }
       
   440 
       
   441     return EFalse;
       
   442     }
       
   443 
       
   444 // ---------------------------------------------------------
       
   445 // CMsgExpandableControl::SetContainerWindowL
       
   446 //
       
   447 // Sets container window.
       
   448 // ---------------------------------------------------------
       
   449 //
       
   450 EXPORT_C void CMsgExpandableControl::SetContainerWindowL( const CCoeControl& aContainer )
       
   451     {
       
   452     CCoeControl::SetContainerWindowL( aContainer );
       
   453     
       
   454     iCaption->SetContainerWindowL( *this );
       
   455     iEditor->SetContainerWindowL( *this );
       
   456 
       
   457 #ifdef RD_SCALABLE_UI_V2
       
   458     if ( iButton )
       
   459         {
       
   460         iButton->SetContainerWindowL( *this );
       
   461         }
       
   462 #endif // RD_SCALABLE_UI_V2
       
   463     }
       
   464 
       
   465 // ---------------------------------------------------------
       
   466 // CMsgExpandableControl::OfferKeyEventL
       
   467 //
       
   468 // Handles key events.
       
   469 // ---------------------------------------------------------
       
   470 //
       
   471 EXPORT_C TKeyResponse CMsgExpandableControl::OfferKeyEventL( const TKeyEvent& aKeyEvent, 
       
   472                                                              TEventCode aType )
       
   473     {
       
   474     return iEditor->OfferKeyEventL( aKeyEvent, aType );
       
   475     }
       
   476 
       
   477 // ---------------------------------------------------------
       
   478 // CMsgExpandableControl::MinimumSize
       
   479 //
       
   480 //
       
   481 // ---------------------------------------------------------
       
   482 //
       
   483 EXPORT_C TSize CMsgExpandableControl::MinimumSize()
       
   484     {
       
   485     return TSize( iSize.iWidth,
       
   486                   iEditor->MinimumDefaultHeight() + iMargins.iTop + iMargins.iBottom );
       
   487     }
       
   488 
       
   489 // ---------------------------------------------------------
       
   490 // CMsgExpandableControl::InputCapabilities
       
   491 //
       
   492 // Returns input capabilities.
       
   493 // ---------------------------------------------------------
       
   494 //
       
   495 EXPORT_C TCoeInputCapabilities CMsgExpandableControl::InputCapabilities() const
       
   496     {
       
   497     if ( iEditor->IsFocused() )
       
   498         {
       
   499         TCoeInputCapabilities inputCapabilities( TCoeInputCapabilities::ENone, 
       
   500                                                  NULL, 
       
   501                                                  const_cast<CMsgExpandableControl*>( this ) );
       
   502         inputCapabilities.MergeWith( iEditor->InputCapabilities() );
       
   503         
       
   504         return inputCapabilities;
       
   505         }
       
   506     else
       
   507         {
       
   508         return TCoeInputCapabilities::ENone;
       
   509         }
       
   510     }
       
   511 
       
   512 // ---------------------------------------------------------
       
   513 // CMsgExpandableControl::HandleResourceChange
       
   514 //
       
   515 // Updates caption text color if skin is changed.
       
   516 // ---------------------------------------------------------
       
   517 //
       
   518 EXPORT_C void CMsgExpandableControl::HandleResourceChange( TInt aType )
       
   519     {
       
   520     if ( aType == KEikDynamicLayoutVariantSwitch )
       
   521         {
       
   522         TRAP_IGNORE( ResolveLayoutsL() );
       
   523         }
       
   524         
       
   525     CMsgExpandableTextEditorControl::HandleResourceChange( aType );
       
   526     
       
   527     // Control size can be updated only after editor has updated
       
   528     // virtual height accordong to current font
       
   529     if ( aType == KEikDynamicLayoutVariantSwitch )
       
   530         {
       
   531         // Control height can change if new layout uses
       
   532         // font with different height. After HandleResourceChange
       
   533         // controls must know their correct height because
       
   534         // control distances are adjusted related to other controls
       
   535         // before GetAndSetSize is called. This is the reason why
       
   536         // this must be done here.
       
   537         TSize desirableSize( iEditorLayout.TextRect().Width(), 
       
   538                              iEditor->VirtualHeight() );
       
   539         
       
   540         if ( desirableSize.iHeight != Size().iHeight )
       
   541             {
       
   542             TInt maxBodyHeight( iMaxBodyHeight );
       
   543 
       
   544             if ( desirableSize.iHeight > maxBodyHeight )
       
   545                 {
       
   546                 desirableSize.iHeight = maxBodyHeight;
       
   547                 }
       
   548             
       
   549             SetSizeWithoutNotification( desirableSize );
       
   550             
       
   551             TRAP_IGNORE( iEditor->SetAndGetSizeL( desirableSize ) ); 
       
   552             }
       
   553         }
       
   554     else if ( aType == KAknsMessageSkinChange )
       
   555         {   
       
   556         TRAP_IGNORE( UpdateCaptionTextColorL() );
       
   557         }
       
   558     }
       
   559 
       
   560 // ---------------------------------------------------------
       
   561 // CMsgExpandableControl::HandleControlEventL
       
   562 //
       
   563 //
       
   564 // ---------------------------------------------------------
       
   565 //
       
   566 #ifdef RD_SCALABLE_UI_V2
       
   567 EXPORT_C void CMsgExpandableControl::HandleControlEventL( CCoeControl* aControl, 
       
   568                                                           TCoeEvent aEventType )
       
   569     {
       
   570     CMsgExpandableTextEditorControl::HandleControlEventL( aControl, aEventType );
       
   571     
       
   572     if ( aEventType == MCoeControlObserver::EEventStateChanged &&
       
   573          iButton && 
       
   574          aControl == iButton)
       
   575         {
       
   576         iBaseControlObserver->HandleEditObserverEventRequestL( this, EMsgButtonPressed, this );
       
   577         }
       
   578     }
       
   579 #else
       
   580 EXPORT_C void CMsgExpandableControl::HandleControlEventL( CCoeControl* aControl, 
       
   581                                                           TCoeEvent aEventType )
       
   582     {
       
   583     CMsgExpandableTextEditorControl::HandleControlEventL( aControl, aEventType );
       
   584     }
       
   585 #endif // RD_SCALABLE_UI_V2
       
   586 
       
   587 // ---------------------------------------------------------
       
   588 // CMsgExpandableControl::CreateEditorL
       
   589 //
       
   590 // Creates the editor for the control.
       
   591 // ---------------------------------------------------------
       
   592 //
       
   593 CMsgExpandableControlEditor* CMsgExpandableControl::CreateEditorL()
       
   594     {
       
   595     // Create control editor
       
   596     CMsgExpandableControlEditor* editor = 
       
   597                         new ( ELeave ) CMsgExpandableControlEditor( this, 
       
   598                                                                     iControlModeFlags, 
       
   599                                                                     iBaseControlObserver );
       
   600 
       
   601     CleanupStack::PushL( editor );
       
   602     editor->ConstructL();
       
   603     CleanupStack::Pop( editor );
       
   604 
       
   605     return editor;
       
   606     }
       
   607 
       
   608 // ---------------------------------------------------------
       
   609 // CMsgExpandableControl::ReadControlPropertiesFromResourceL
       
   610 //
       
   611 // Reads control properties from resource.
       
   612 // ---------------------------------------------------------
       
   613 //
       
   614 void CMsgExpandableControl::ReadControlPropertiesFromResourceL( TResourceReader& aReader )
       
   615     {
       
   616     iControlModeFlags = aReader.ReadUint32();
       
   617     iControlId = aReader.ReadInt32();
       
   618     iDistanceFromComponentAbove = aReader.ReadInt32();
       
   619     iMaxNumberOfChars = aReader.ReadInt32();
       
   620     }
       
   621 
       
   622 // ---------------------------------------------------------
       
   623 // CMsgExpandableControl::CreateCaptionFromResourceL
       
   624 //
       
   625 // Creates caption for the control from resource.
       
   626 // ---------------------------------------------------------
       
   627 //
       
   628 CEikLabel* CMsgExpandableControl::CreateCaptionFromResourceL( TResourceReader& aReader )
       
   629     {
       
   630     CEikLabel* caption = new ( ELeave ) CEikLabel;
       
   631     CleanupStack::PushL( caption );
       
   632 
       
   633     HBufC* captionText = aReader.ReadHBufCL();
       
   634     
       
   635     if ( captionText == NULL )
       
   636         {
       
   637         caption->SetTextL( KMsgDefaultCaption );
       
   638         }
       
   639     else
       
   640         {
       
   641         CleanupStack::PushL( captionText );
       
   642         caption->SetTextL( *captionText );
       
   643         CleanupStack::PopAndDestroy( captionText );
       
   644         }
       
   645 
       
   646     caption->CropText();
       
   647     
       
   648     CleanupStack::Pop( caption );
       
   649 
       
   650     return caption;
       
   651     }
       
   652 
       
   653 // ---------------------------------------------------------
       
   654 // CMsgExpandableControl::CreateEditorFromResourceL
       
   655 //
       
   656 // This virtual function does nothing but inherited function of this creates
       
   657 // the editor for the control from resource.
       
   658 // ---------------------------------------------------------
       
   659 //
       
   660 CMsgExpandableControlEditor* CMsgExpandableControl::CreateEditorFromResourceL( TResourceReader& aReader )
       
   661     {
       
   662     CMsgExpandableControlEditor* editor = 
       
   663             new ( ELeave ) CMsgExpandableControlEditor( this, 
       
   664                                                         iControlModeFlags, 
       
   665                                                         iBaseControlObserver );
       
   666 
       
   667     CleanupStack::PushL( editor );
       
   668     editor->SetMaxNumberOfChars( iMaxNumberOfChars );
       
   669     editor->ConstructFromResourceL( aReader );
       
   670     CleanupStack::Pop( editor );
       
   671 
       
   672     return editor;
       
   673     }
       
   674 
       
   675 // ---------------------------------------------------------
       
   676 // CMsgExpandableControl::PrepareForReadOnly
       
   677 //
       
   678 // Prepares read only or non read only state.
       
   679 // ---------------------------------------------------------
       
   680 //
       
   681 void CMsgExpandableControl::PrepareForReadOnly( TBool aReadOnly )
       
   682     {
       
   683     TRAP_IGNORE( iEditor->PrepareForReadOnlyL( aReadOnly ) );
       
   684     }
       
   685 
       
   686 // ---------------------------------------------------------
       
   687 // CMsgExpandableControl::CountComponentControls
       
   688 //
       
   689 // Returns a number of controls.
       
   690 // ---------------------------------------------------------
       
   691 //
       
   692 EXPORT_C TInt CMsgExpandableControl::CountComponentControls() const
       
   693     {
       
   694     CCoeControl* labelControl = NULL;
       
   695     
       
   696     if ( iButton )
       
   697         {
       
   698         labelControl = iButton;
       
   699         }
       
   700     else
       
   701         {
       
   702         labelControl = iCaption;
       
   703         }
       
   704         
       
   705     CCoeControl* controls[] = { labelControl, iEditor };
       
   706 
       
   707     TInt count = 0;
       
   708     for ( TUint ii = 0; ii < sizeof( controls ) / sizeof( CCoeControl* ); ii++ )
       
   709         {
       
   710         if ( controls[ii] )
       
   711             {
       
   712             count++;
       
   713             }
       
   714         }
       
   715 
       
   716     return count;
       
   717     }
       
   718 
       
   719 // ---------------------------------------------------------
       
   720 // CMsgExpandableControl::ComponentControl
       
   721 //
       
   722 // Returns a control of index aIndex.
       
   723 // ---------------------------------------------------------
       
   724 //
       
   725 EXPORT_C CCoeControl* CMsgExpandableControl::ComponentControl( TInt aIndex ) const
       
   726     {
       
   727     CCoeControl* labelControl = NULL;
       
   728     
       
   729     if ( iButton )
       
   730         {
       
   731         labelControl = iButton;
       
   732         }
       
   733     else
       
   734         {
       
   735         labelControl = iCaption;
       
   736         }
       
   737         
       
   738     CCoeControl* controls[] = { labelControl, iEditor };
       
   739 
       
   740     for ( TUint ii = 0; ii < sizeof( controls ) / sizeof( CCoeControl* ); ii++ )
       
   741         {
       
   742         if ( controls[ii] && aIndex-- == 0 )
       
   743             {
       
   744             return controls[ii];
       
   745             }
       
   746         }
       
   747 
       
   748     return NULL;
       
   749     }
       
   750 
       
   751 // ---------------------------------------------------------
       
   752 // CMsgExpandableControl::SizeChanged
       
   753 //
       
   754 // Sets positions for the caption and the editor.
       
   755 // ---------------------------------------------------------
       
   756 //
       
   757 EXPORT_C void CMsgExpandableControl::SizeChanged()
       
   758     {
       
   759     // TODO: No point to do all these calculations every time!
       
   760 
       
   761     MEBLOGGER_ENTERFN("CMsgExpandableControl::SizeChanged");
       
   762 
       
   763     if ( iControlModeFlags & EMsgControlModeSizeChanging )
       
   764         {
       
   765         MEBLOGGER_WRITE( "EMsgControlModeSizeChanging" );
       
   766         }
       
   767     else
       
   768         {
       
   769         TPoint editorPosition( iEditorLayout.TextRect().iTl.iX,
       
   770                                iPosition.iY + iEditorTop );
       
   771                                
       
   772 #ifdef RD_SCALABLE_UI_V2
       
   773         
       
   774         TPoint captionPosition( iCaptionLayout.TextRect().iTl.iX,
       
   775                                 iPosition.iY + iCaptionTop );
       
   776 
       
   777         iCaption->SetPosition( captionPosition );
       
   778         iCaption->MakeVisible( captionPosition.iY >= 0 );    
       
   779         
       
   780         if ( iButton )
       
   781             {
       
   782             TPoint buttonPosition( iButtonLayout.Rect().iTl.iX,
       
   783                                    iPosition.iY + iButtonTop );
       
   784                                 
       
   785             iButton->SetPosition( buttonPosition );
       
   786             iButton->MakeVisible( buttonPosition.iY >= 0 );
       
   787             }
       
   788 #else
       
   789         TPoint captionPosition( iCaptionLayout.TextRect().iTl.iX,
       
   790                                 iPosition.iY + iCaptionTop );
       
   791         
       
   792         iCaption->SetPosition( captionPosition );
       
   793         iCaption->MakeVisible( captionPosition.iY >= 0 );
       
   794 #endif // RD_SCALABLE_UI_V2
       
   795         
       
   796         TRect editorRect( editorPosition, iEditor->Size() );
       
   797         
       
   798         if ( editorRect != iEditor->Rect() )
       
   799             {
       
   800             iEditor->SetRect( editorRect );  // SetPosition cannot be used here
       
   801             }
       
   802 
       
   803         AknsUtils::RegisterControlPosition( this );
       
   804         AknsUtils::RegisterControlPosition( iCaption );
       
   805         
       
   806 #ifdef RD_SCALABLE_UI_V2
       
   807         if ( iButton )
       
   808             {
       
   809             AknsUtils::RegisterControlPosition( iButton );
       
   810             }
       
   811 #endif // RD_SCALABLE_UI_V2
       
   812         
       
   813         AknsUtils::RegisterControlPosition( iEditor );
       
   814         }
       
   815 
       
   816     MEBLOGGER_LEAVEFN("CMsgExpandableControl::SizeChanged");
       
   817     }
       
   818 
       
   819 // ---------------------------------------------------------
       
   820 // CMsgExpandableControl::FocusChanged
       
   821 //
       
   822 // This is called when the focus of the control is changed.
       
   823 // ---------------------------------------------------------
       
   824 //
       
   825 EXPORT_C void CMsgExpandableControl::FocusChanged( TDrawNow aDrawNow )
       
   826     {
       
   827     iEditor->SetFocus( IsFocused(), aDrawNow );
       
   828     
       
   829     if ( aDrawNow == EDrawNow )
       
   830         {
       
   831         DrawDeferred();
       
   832         }
       
   833     }
       
   834 
       
   835 // ---------------------------------------------------------
       
   836 // CMsgExpandableControl::Draw
       
   837 //
       
   838 //
       
   839 // ---------------------------------------------------------
       
   840 //
       
   841 EXPORT_C void CMsgExpandableControl::Draw( const TRect& /*aRect*/ ) const
       
   842     {
       
   843     // All drawing is done by iEditor, iCaption and CMsgHeader
       
   844     // class (and CMsgCaptionedHighlight owned by the header)
       
   845     }
       
   846 
       
   847 // ---------------------------------------------------------
       
   848 // CMsgExpandableControl::ActivateL
       
   849 //
       
   850 // Sets caption text color from skin. This is the only common
       
   851 // synchronization point before the control is drawn to the screen
       
   852 // for expandable control and all the derived classes.
       
   853 // ---------------------------------------------------------
       
   854 //
       
   855 EXPORT_C void CMsgExpandableControl::ActivateL()
       
   856     {
       
   857     UpdateCaptionTextColorL();
       
   858     
       
   859     CMsgExpandableTextEditorControl::ActivateL();
       
   860     }
       
   861 
       
   862 // ---------------------------------------------------------
       
   863 // CMsgExpandableControl::ResolveLayoutsL
       
   864 //
       
   865 //
       
   866 // ---------------------------------------------------------
       
   867 //
       
   868 void CMsgExpandableControl::ResolveLayoutsL()
       
   869     {
       
   870     TAknTextLineLayout editorLineLayout;
       
   871 
       
   872     TAknLayoutRect msgTextPane;
       
   873     msgTextPane.LayoutRect( MsgEditorCommons::MsgDataPane(),
       
   874                             AknLayoutScalable_Apps::msg_text_pane( 0 ).LayoutLine() );
       
   875                             
       
   876     TAknLayoutRect msgHeaderPane;
       
   877     msgHeaderPane.LayoutRect( msgTextPane.Rect(),
       
   878                               AknLayoutScalable_Apps::msg_header_pane().LayoutLine() );
       
   879                               
       
   880     // iFrameLayout is not really used with "scalable layouts"
       
   881     iFrameLayout.LayoutRect( msgHeaderPane.Rect(),
       
   882                              AknLayoutScalable_Apps::input_focus_pane_cp07().LayoutLine() );
       
   883                              
       
   884     iCaptionLayout.LayoutText( msgHeaderPane.Rect(),
       
   885                                AknLayoutScalable_Apps::msg_header_pane_t1( 0 ).LayoutLine() );
       
   886                                
       
   887     editorLineLayout = AknLayoutScalable_Apps::msg_header_pane_t2( 0 ).LayoutLine();
       
   888     
       
   889     iEditorLayout.LayoutText( msgHeaderPane.Rect(),
       
   890                               editorLineLayout );
       
   891 
       
   892     iEditorTop = iEditorLayout.TextRect().iTl.iY -
       
   893                  msgHeaderPane.Rect().iTl.iY;
       
   894     
       
   895     iEditor->SetMaximumHeight( MsgEditorCommons::MaxBodyHeight() - iEditorTop * 2 );
       
   896                                    
       
   897 #ifdef RD_SCALABLE_UI_V2
       
   898     
       
   899     iCaptionTop = iCaptionLayout.TextRect().iTl.iY - msgHeaderPane.Rect().iTl.iY;
       
   900 
       
   901     iCaption->SetFont( iCaptionLayout.Font() );
       
   902 
       
   903     iCaption->SetAlignment( iCaptionLayout.Align() == CGraphicsContext::ELeft ? EHLeftVTop : 
       
   904                                                                                 EHRightVTop );                    
       
   905     if ( iButton )
       
   906         {
       
   907         iButtonLayout.LayoutRect( msgHeaderPane.Rect(),
       
   908                                   AknLayoutScalable_Apps::bg_button_pane_cp01().LayoutLine() );
       
   909                               
       
   910         iButtonTop = iButtonLayout.Rect().iTl.iY - msgHeaderPane.Rect().iTl.iY;
       
   911         
       
   912         LayoutButton();
       
   913         }
       
   914 #else
       
   915 
       
   916     iCaptionTop = iCaptionLayout.TextRect().iTl.iY -
       
   917                   msgHeaderPane.Rect().iTl.iY;
       
   918 
       
   919     iCaption->SetFont( iCaptionLayout.Font() );
       
   920     iCaption->SetAlignment( iCaptionLayout.Align() == CGraphicsContext::ELeft ? EHLeftVTop : 
       
   921                                                                                 EHRightVTop );
       
   922 #endif // RD_SCALABLE_UI_V2
       
   923     
       
   924     iEditor->SetAlignment( editorLineLayout.iJ );
       
   925     }
       
   926 
       
   927 // ---------------------------------------------------------
       
   928 // CMsgExpandableControl::HandleFrameSizeChange
       
   929 // ---------------------------------------------------------
       
   930 //
       
   931 void CMsgExpandableControl::HandleFrameSizeChange()
       
   932     {
       
   933     TRAP_IGNORE( iEditor->HandleFrameSizeChangeL( ) );
       
   934     }
       
   935 
       
   936 // ---------------------------------------------------------
       
   937 // CMsgExpandableControl::Button
       
   938 // ---------------------------------------------------------
       
   939 //
       
   940 CAknButton* CMsgExpandableControl::Button() const
       
   941     {
       
   942     return iButton;
       
   943     }
       
   944 
       
   945 // ---------------------------------------------------------
       
   946 // CMsgExpandableControl::LayoutButton
       
   947 // ---------------------------------------------------------
       
   948 //
       
   949 void CMsgExpandableControl::LayoutButton()
       
   950     {
       
   951 #ifdef RD_SCALABLE_UI_V2
       
   952     if ( iButton )
       
   953         {
       
   954         iButton->SetTextFont( iCaptionLayout.Font() );
       
   955         iButton->SetTextColorIds( KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG63 );
       
   956 
       
   957         iButton->SetTextHorizontalAlignment( iCaptionLayout.Align() );
       
   958 
       
   959         if ( iCaptionLayout.Align() == CGraphicsContext::ELeft )
       
   960             {
       
   961             iButton->SetIconHorizontalAlignment( CAknButton::ELeft );
       
   962             }
       
   963         else
       
   964             {
       
   965             iButton->SetIconHorizontalAlignment( CAknButton::ERight );
       
   966             }        
       
   967         }
       
   968 #endif // RD_SCALABLE_UI_V2
       
   969     }
       
   970 
       
   971 // ---------------------------------------------------------
       
   972 // CMsgExpandableControl::UpdateCaptionTextColorL
       
   973 //
       
   974 // Sets the correct text color for caption from currently 
       
   975 // used theme. 
       
   976 // ---------------------------------------------------------
       
   977 //
       
   978 void CMsgExpandableControl::UpdateCaptionTextColorL()
       
   979     {
       
   980     TRgb textColor;
       
   981     if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
       
   982                                     textColor,
       
   983                                     KAknsIIDQsnTextColors,
       
   984                                     EAknsCIQsnTextColorsCG6 ) != KErrNone )
       
   985         {
       
   986         /*
       
   987         From "AknsConstants.h":
       
   988         // text #6	main area	main area texts	#215
       
   989         EAknsCIQsnTextColorsCG6    = 5,
       
   990         */
       
   991         textColor = AKN_LAF_COLOR_STATIC( 215 );
       
   992         }
       
   993     
       
   994     iCaption->OverrideColorL( EColorLabelText, textColor );
       
   995     }
       
   996 
       
   997 // ---------------------------------------------------------
       
   998 // CMsgExpandableControl::GetCaptionForFep
       
   999 // ---------------------------------------------------------
       
  1000 //
       
  1001 void CMsgExpandableControl::GetCaptionForFep( TDes& aCaption ) const
       
  1002     {
       
  1003     const TDesC* captionText = Caption().Text();
       
  1004     
       
  1005     const TInt maximumLength = aCaption.MaxLength();
       
  1006     
       
  1007     if ( captionText->Length() > maximumLength )
       
  1008         {
       
  1009         aCaption = captionText->Left( maximumLength );
       
  1010         }        
       
  1011     else
       
  1012         {
       
  1013         aCaption = *captionText;
       
  1014         }
       
  1015     }
       
  1016 //  End of File