messagingappbase/msgeditor/viewsrc/MsgAttachmentControl.cpp
changeset 0 72b543305e3a
child 66 fc3320e39880
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002 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:  MsgAttachmentControl implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ========== INCLUDE FILES ================================
       
    21 
       
    22 #include <barsread.h>                      // for TResourceReader
       
    23 #include <txtrich.h>                       // for CRichText
       
    24 
       
    25 #include <eikenv.h>                        // for CEikonEnv
       
    26 #include <eikappui.h>                      // for CEikAppUi
       
    27 #include <eikedwin.h>                      // for TClipboardFunc
       
    28 #include <eiklabel.h>
       
    29 
       
    30 #include <AknUtils.h>                      // for AknUtils
       
    31 #include <aknbutton.h>                     // for CAknButton
       
    32 
       
    33 #include <MsgAttachmentModel.h>
       
    34 #include <MsgAttachmentInfo.h>
       
    35 
       
    36 #include <gulicon.h>
       
    37 #include <AknsUtils.h>
       
    38 #include <AknsConstants.h>
       
    39 #include <aknlayoutscalable_apps.cdl.h>
       
    40 
       
    41 #include <data_caging_path_literals.hrh>
       
    42 #include <msgeditor.mbg>
       
    43 
       
    44 #ifdef RD_TACTILE_FEEDBACK
       
    45 #include <touchfeedback.h>
       
    46 #endif 
       
    47 
       
    48 #include "MsgAttachmentControl.h"             // for CMsgAttachmentControl
       
    49 #include "MsgExpandableControlEditor.h"       // for CMsgExpandableControlEditor
       
    50 #include "MsgBaseControlObserver.h"        // for MMsgBaseControlObserver
       
    51 #include "MsgEditorView.h"
       
    52 #include "MsgEditorPanic.h"                // for CMsgEditor panics
       
    53 #include "MsgEditorCommon.h"               // for KArabicSemicolon
       
    54 #include "MsgEditorCustomDraw.h"           // for CMsgEditorCustomDraw
       
    55 
       
    56 // ========== EXTERNAL DATA STRUCTURES =====================
       
    57 
       
    58 // ========== EXTERNAL FUNCTION PROTOTYPES =================
       
    59 
       
    60 // ========== CONSTANTS ====================================
       
    61 
       
    62 // Default color for EAknsCIQsnIconColorsCG13 group icons
       
    63 const TInt KDefaultAttachmentColor = 215; 
       
    64 
       
    65 // ========== MACROS =======================================
       
    66 
       
    67 // ========== LOCAL CONSTANTS AND MACROS ===================
       
    68 
       
    69 const TInt KAttachmentArrayGranularity = 10;
       
    70 
       
    71 _LIT( KAttachmentListSeparator, ", " );
       
    72 _LIT( KIconMbmFile, "msgeditor.mbm" );
       
    73 _LIT( KStripList, "\x000A\x000D\x2029\x2028\x0085" );
       
    74 
       
    75 const TText KZeroWidthJoiner = 0x200D;
       
    76 const TText KLRMarker = 0x200E;
       
    77 const TText KRLMarker = 0x200F;
       
    78 
       
    79 const TInt KScrollStartDelay = 1500000; // 1,5 s
       
    80 const TInt KScrollEndDelay = 500000;    // 0,5 s
       
    81 const TInt KScrollRestartDelay = 3000000; // 3 s.
       
    82 const TInt KScrollTickDelay = 135000; // 0,135s
       
    83 const TInt KScrollJumpAreaDivider = 15;
       
    84 
       
    85 // ========== MODULE DATA STRUCTURES =======================
       
    86 
       
    87 // ========== LOCAL FUNCTION PROTOTYPES ====================
       
    88 
       
    89 // ========== LOCAL FUNCTIONS ==============================
       
    90 
       
    91 // ========== MEMBER FUNCTIONS =============================
       
    92 
       
    93 
       
    94 // ---------------------------------------------------------
       
    95 // CMsgAttachmentControl::CMsgAttachmentControl
       
    96 //
       
    97 // Constructor.
       
    98 // ---------------------------------------------------------
       
    99 //
       
   100 CMsgAttachmentControl::CMsgAttachmentControl( 
       
   101                                     MMsgBaseControlObserver& aBaseControlObserver,
       
   102                                     CMsgEditorView& aView ) : 
       
   103     CMsgExpandableControl( aBaseControlObserver ),
       
   104     iScrollPos( EScrollPosBeginning )
       
   105     {
       
   106     iControlType = EMsgAttachmentControl;
       
   107     iControlId = EMsgComponentIdAttachment;
       
   108     
       
   109     SetMopParent( &aView );
       
   110     }
       
   111 
       
   112 // ---------------------------------------------------------
       
   113 // CMsgAttachmentControl::ConstructL
       
   114 //
       
   115 // 2nd phase constructor. After base class initialization creates
       
   116 // attachment array that holds the attachment name strings. Empty
       
   117 // caption control is also created for base class purposes. NOTE! This is 
       
   118 // something that would be good to get rid off. Initializes editor control
       
   119 // and sets itself as it's edwin event, edwin size event and
       
   120 // control event observer. Creates editor is set as readonly and cursor is
       
   121 // hidden. Focus must stop to this control when navigating. No formatting
       
   122 // is allowed. Label icon and if pen input (i.e. touch screen) is enabled
       
   123 // then also button are created. Initializes marquee scroll timer and
       
   124 // layout related parameters.
       
   125 // ---------------------------------------------------------
       
   126 //
       
   127 void CMsgAttachmentControl::ConstructL()
       
   128     {
       
   129     BaseConstructL();  // Sets margins only.
       
   130     
       
   131     iAttachmentArray = new( ELeave ) CDesCArrayFlat( KAttachmentArrayGranularity );
       
   132 
       
   133     // Create empty caption. (Needed by base class.)
       
   134     iCaption = new( ELeave ) CEikLabel;
       
   135 
       
   136     // Create editor.
       
   137     iEditor = new( ELeave ) CMsgExpandableControlEditor( this, 
       
   138                                                          iControlModeFlags, 
       
   139                                                          iBaseControlObserver );
       
   140     iEditor->SetControlType(iControlType);   
       
   141     iEditor->ConstructL();
       
   142     iEditor->SetObserver( this );
       
   143     iEditor->SetEdwinSizeObserver( this );
       
   144     iEditor->AddEdwinObserverL( this );
       
   145     iEditor->SetReadOnly( ETrue );
       
   146     iEditor->AddFlagToUserFlags( CEikEdwin::EAvkonDisableCursor );
       
   147     
       
   148     iControlModeFlags |= EMsgControlModeForceFocusStop;
       
   149     
       
   150     SetPlainTextMode( ETrue );
       
   151     
       
   152     iLabelIcon = CreateAttachmentIconsL();
       
   153     
       
   154 #ifdef RD_SCALABLE_UI_V2
       
   155     if ( AknLayoutUtils::PenEnabled() )
       
   156         {
       
   157         CreateButtonL();
       
   158         }
       
   159 #endif // RD_SCALABLE_UI_V2
       
   160     
       
   161     iScrollTimer = CPeriodic::NewL( EPriorityNormal );
       
   162     
       
   163     ResolveLayoutsL();
       
   164     }
       
   165 
       
   166 // ----------------------------------------------------------------------------
       
   167 // CMsgAttachmentControl::NewL
       
   168 // Symbian two phased constructor
       
   169 // ----------------------------------------------------------------------------
       
   170 //
       
   171 EXPORT_C CMsgAttachmentControl* CMsgAttachmentControl::NewL( 
       
   172                                                 MMsgBaseControlObserver& aBaseControlObserver,
       
   173                                                 CMsgEditorView& aView )
       
   174     {
       
   175     CMsgAttachmentControl* self = new( ELeave ) CMsgAttachmentControl( aBaseControlObserver,
       
   176                                                                        aView );
       
   177 
       
   178     CleanupStack::PushL( self );
       
   179     self->ConstructL();
       
   180     CleanupStack::Pop( self );
       
   181 
       
   182     return self;
       
   183     }
       
   184 
       
   185 // ---------------------------------------------------------
       
   186 // CMsgAttachmentControl::~CMsgAttachmentControl
       
   187 //
       
   188 // Destructor.
       
   189 // ---------------------------------------------------------
       
   190 //
       
   191 CMsgAttachmentControl::~CMsgAttachmentControl()
       
   192     {
       
   193     if ( iAttachmentArray )
       
   194         {
       
   195         iAttachmentArray->Reset();
       
   196         }
       
   197         
       
   198     delete iAttachmentArray;
       
   199     delete iLabelIcon;
       
   200     delete iScrollTimer;
       
   201     }
       
   202 
       
   203 // ---------------------------------------------------------
       
   204 // CMsgAttachmentControl::AppendAttachmentL
       
   205 //
       
   206 //
       
   207 // ---------------------------------------------------------
       
   208 //
       
   209 EXPORT_C void CMsgAttachmentControl::AppendAttachmentL( const TDesC& aName )
       
   210     {
       
   211     InsertAttachmentL( aName, Count() );
       
   212     }
       
   213 
       
   214 // ---------------------------------------------------------
       
   215 // CMsgAttachmentControl::InsertAttachmentL
       
   216 //
       
   217 //
       
   218 // ---------------------------------------------------------
       
   219 //
       
   220 EXPORT_C void CMsgAttachmentControl::InsertAttachmentL( const TDesC& aName, TInt aIndex )
       
   221     {
       
   222     AddToAttachmentArrayL( aName, aIndex );
       
   223     
       
   224     UpdateControlL();
       
   225     }
       
   226 
       
   227 // ---------------------------------------------------------
       
   228 // CMsgAttachmentControl::AddAttachmentL
       
   229 //
       
   230 //
       
   231 // ---------------------------------------------------------
       
   232 //
       
   233 EXPORT_C void CMsgAttachmentControl::AddAttachmentsL( const MDesCArray& aNames )
       
   234     {
       
   235     Reset();
       
   236     
       
   237     for ( TInt i = 0; i < aNames.MdcaCount(); i++ )
       
   238         {
       
   239         AddToAttachmentArrayL( aNames.MdcaPoint( i ), Count() );
       
   240         }
       
   241         
       
   242     UpdateControlL();
       
   243     }
       
   244 
       
   245 
       
   246 // ---------------------------------------------------------
       
   247 // CMsgAttachmentControl::AddAttachmentL
       
   248 //
       
   249 //
       
   250 // ---------------------------------------------------------
       
   251 //
       
   252 EXPORT_C void CMsgAttachmentControl::AddAttachmentsL( const CMsgAttachmentModel& aModel )
       
   253     {
       
   254     Reset();
       
   255     
       
   256     TParse* parser = new( ELeave ) TParse ;
       
   257     CleanupStack::PushL( parser );
       
   258     
       
   259     for ( TInt i = 0; i < aModel.NumberOfItems(); i++ )
       
   260         {
       
   261         parser->Set( aModel.AttachmentInfoAt( i ).FileName(),NULL, NULL );
       
   262         AddToAttachmentArrayL( parser->NameAndExt(), Count() );
       
   263         }
       
   264     
       
   265     CleanupStack::PopAndDestroy( parser ); 
       
   266     UpdateControlL();
       
   267     }
       
   268 
       
   269 // ---------------------------------------------------------
       
   270 // CMsgAttachmentControl::RemoveAttachmentL
       
   271 // ---------------------------------------------------------
       
   272 //
       
   273 EXPORT_C void CMsgAttachmentControl::RemoveAttachmentL( const TDesC& aName )
       
   274     {
       
   275     HBufC* convertedFileName = AknTextUtils::ConvertFileNameL( aName );
       
   276     CleanupStack::PushL( convertedFileName );
       
   277     
       
   278     TPtr convertedFileNamePtr = convertedFileName->Des();
       
   279     
       
   280     AknTextUtils::StripCharacters( convertedFileNamePtr, KAknStripListControlChars );
       
   281     
       
   282     TInt pos( KErrNotFound );
       
   283     if ( iAttachmentArray->Find( *convertedFileName, pos ) == 0 )
       
   284         {
       
   285         RemoveAttachmentL( pos );
       
   286         }
       
   287     
       
   288     CleanupStack::PopAndDestroy( convertedFileName );
       
   289     }
       
   290 
       
   291 // ---------------------------------------------------------
       
   292 // CMsgAttachmentControl::RemoveAttachmentL
       
   293 // ---------------------------------------------------------
       
   294 //
       
   295 EXPORT_C void CMsgAttachmentControl::RemoveAttachmentL( TInt aIndex )
       
   296     {
       
   297     iAttachmentArray->Delete( aIndex );
       
   298     UpdateControlL();
       
   299     }
       
   300 
       
   301 // ---------------------------------------------------------
       
   302 // CMsgAttachmentControl::Reset
       
   303 //
       
   304 // from CMsgBaseControl.
       
   305 // Same as above but non-leaving version.
       
   306 // ---------------------------------------------------------
       
   307 //
       
   308 EXPORT_C void CMsgAttachmentControl::Reset()
       
   309     {
       
   310     if ( iAttachmentArray )
       
   311         {
       
   312         iAttachmentArray->Reset();
       
   313         }
       
   314     if ( iEditor )
       
   315         {
       
   316         iEditor->Reset();
       
   317         }
       
   318     }
       
   319 
       
   320 
       
   321 // ---------------------------------------------------------
       
   322 // CMsgAttachmentControl::Count
       
   323 // ---------------------------------------------------------
       
   324 //
       
   325 EXPORT_C TInt CMsgAttachmentControl::Count() const
       
   326     {
       
   327     return iAttachmentArray->MdcaCount();
       
   328     }
       
   329 
       
   330 // ---------------------------------------------------------
       
   331 // CMsgAttachmentControl::Attachment
       
   332 // ---------------------------------------------------------
       
   333 //
       
   334 EXPORT_C TPtrC CMsgAttachmentControl::Attachment( TInt aIndex ) const
       
   335     {
       
   336     return iAttachmentArray->MdcaPoint( aIndex );
       
   337     }
       
   338 
       
   339 // ---------------------------------------------------------
       
   340 // CMsgAttachmentControl::ConstructFromResourceL
       
   341 //
       
   342 // Creates this control from resource.
       
   343 // ---------------------------------------------------------
       
   344 //
       
   345 void CMsgAttachmentControl::ConstructFromResourceL( TInt aResourceId )
       
   346     {
       
   347     TResourceReader reader;
       
   348     iCoeEnv->CreateResourceReaderLC( reader, aResourceId );
       
   349 
       
   350     // Read some information about control from resource.
       
   351     ReadControlPropertiesFromResourceL( reader );
       
   352     
       
   353     ConstructL();
       
   354     
       
   355     CleanupStack::PopAndDestroy();  // reader
       
   356     }
       
   357 
       
   358 // ---------------------------------------------------------
       
   359 // CMsgAttachmentControl::EditPermission
       
   360 //
       
   361 // Checks and returns control's edit permissions. Edit permissions are needed
       
   362 // to check in order to know whether some key press is allowed to pass
       
   363 // to the control or not.
       
   364 // ---------------------------------------------------------
       
   365 //
       
   366 TUint32 CMsgAttachmentControl::EditPermission() const
       
   367     {
       
   368     return CMsgBaseControl::EMsgEditNone;
       
   369     }
       
   370 
       
   371 // ---------------------------------------------------------
       
   372 // CMsgAttachmentControl::NotifyViewEvent
       
   373 //
       
   374 // Builds up text fields for the control i.e. reads verified recipients and
       
   375 // creates corresponding text fields for them.
       
   376 // ---------------------------------------------------------
       
   377 //
       
   378 void CMsgAttachmentControl::NotifyViewEvent( TMsgViewEvent aEvent, TInt aParam )
       
   379     {
       
   380     if ( IsReadOnly() )
       
   381         {
       
   382         aParam |= EMsgViewEventAutoHighlight;
       
   383         }
       
   384 
       
   385     if ( aEvent != EMsgViewEventSetCursorFirstPos &&
       
   386          aEvent != EMsgViewEventSetCursorLastPos )
       
   387         {
       
   388         CMsgExpandableControl::NotifyViewEvent( aEvent, aParam );
       
   389         }
       
   390     }
       
   391 
       
   392 
       
   393 // ---------------------------------------------------------
       
   394 // CMsgAttachmentControl::PrepareForReadOnly
       
   395 // ---------------------------------------------------------
       
   396 //
       
   397 void CMsgAttachmentControl::PrepareForReadOnly( TBool aReadOnly )
       
   398     {
       
   399     if ( aReadOnly )
       
   400         {
       
   401         TRAP_IGNORE( iEditor->SetHighlightStyleL( EEikEdwinHighlightLink ) );
       
   402         }
       
   403     }
       
   404 
       
   405 // ---------------------------------------------------------
       
   406 // CMsgAttachmentControl::CountComponentControls
       
   407 //
       
   408 // Returns a number of controls.
       
   409 // ---------------------------------------------------------
       
   410 //
       
   411 TInt CMsgAttachmentControl::CountComponentControls() const
       
   412     {
       
   413     TInt result( 1 );
       
   414     
       
   415     if ( iButton )
       
   416         {
       
   417         result++;
       
   418         }
       
   419         
       
   420     return result;
       
   421     }
       
   422 
       
   423 // ---------------------------------------------------------
       
   424 // CMsgAttachmentControl::ComponentControl
       
   425 //
       
   426 // Returns a control of index aIndex.
       
   427 // ---------------------------------------------------------
       
   428 //
       
   429 CCoeControl* CMsgAttachmentControl::ComponentControl( TInt aIndex ) const
       
   430     {
       
   431     CCoeControl* result = NULL;
       
   432     switch ( aIndex )
       
   433         {
       
   434         case 0:
       
   435             {
       
   436             result = iEditor;
       
   437             break;
       
   438             }
       
   439         case 1:
       
   440             {
       
   441             result = iButton;
       
   442             break;
       
   443             }
       
   444         default:
       
   445             {
       
   446             break;
       
   447             }
       
   448         }
       
   449         
       
   450     return result;
       
   451     }
       
   452 
       
   453 // ---------------------------------------------------------
       
   454 // CMsgAttachmentControl::OfferKeyEventL
       
   455 //
       
   456 // Handles key events. The most of the keys are passed to the control editor.
       
   457 // ---------------------------------------------------------
       
   458 //
       
   459 TKeyResponse CMsgAttachmentControl::OfferKeyEventL(
       
   460     const TKeyEvent& /*aKeyEvent*/, TEventCode /*aType*/ )
       
   461     {
       
   462     return EKeyWasNotConsumed;
       
   463     }
       
   464 
       
   465 // ---------------------------------------------------------
       
   466 // CMsgAttachmentControl::HandleResourceChange
       
   467 //
       
   468 // Handles resouce change events. Event are passed to the base
       
   469 // class and if layout has been switched new layouts are resolved
       
   470 // from LAF.
       
   471 // ---------------------------------------------------------
       
   472 //
       
   473 void CMsgAttachmentControl::HandleResourceChange( TInt aType )
       
   474     {
       
   475     TRAP_IGNORE( 
       
   476         {
       
   477         DoHandleResourceChangeBeforeL( aType );
       
   478     
       
   479         CMsgExpandableControl::HandleResourceChange( aType );
       
   480         
       
   481         DoHandleResourceChangeAfterL( aType );
       
   482         } );    
       
   483     }
       
   484 
       
   485 // ---------------------------------------------------------
       
   486 // CMsgAttachmentControl::HandlePointerEventL
       
   487 //
       
   488 // Pointer event handling is disabled on editor
       
   489 // ---------------------------------------------------------
       
   490 //
       
   491 void CMsgAttachmentControl::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   492     {
       
   493     if ( !iEditor->Rect().Contains( aPointerEvent.iPosition ) )
       
   494         {
       
   495         CMsgExpandableControl::HandlePointerEventL( aPointerEvent );
       
   496         }
       
   497 #ifdef RD_TACTILE_FEEDBACK 
       
   498     else if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   499         {
       
   500         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   501         if ( feedback )
       
   502             {
       
   503             feedback->InstantFeedback( this, ETouchFeedbackBasic );                        
       
   504             }                                     
       
   505         }
       
   506 #endif
       
   507     }
       
   508 
       
   509 // ---------------------------------------------------------
       
   510 // CMsgAttachmentControl::FocusChanged
       
   511 //
       
   512 // This is called when the focus of the control is changed.
       
   513 // ---------------------------------------------------------
       
   514 //
       
   515 void CMsgAttachmentControl::FocusChanged( TDrawNow aDrawNow )
       
   516     {
       
   517     CMsgExpandableControl::FocusChanged( aDrawNow );
       
   518         
       
   519     if ( IsReadOnly() )
       
   520         {
       
   521         TRAP_IGNORE( UpdateFocusL() );
       
   522         }
       
   523     
       
   524     if ( iAutomaticScrolling )
       
   525         {
       
   526         StopAutomaticScrolling();
       
   527         
       
   528         if ( IsFocused() )
       
   529             {
       
   530             StartAutomaticScrolling( KScrollStartDelay );
       
   531             }
       
   532         else
       
   533             {
       
   534             // Reset text to the beginning when focus is lost.
       
   535             iScrollPos = EScrollPosBeginning;
       
   536             TRAP_IGNORE( SetTextForEditorL( EFalse, ETrue ) );                
       
   537             
       
   538             // Reset the text view to it's original position.
       
   539             iEditor->TextView()->SetLeftTextMargin( 0 );
       
   540             }
       
   541         }
       
   542     }
       
   543 
       
   544 // ---------------------------------------------------------
       
   545 // CMsgAttachmentControl::Draw
       
   546 // Attachment icon is drawn to the line indicated by LAF x 
       
   547 // coordinate and controls current y coordinate. 
       
   548 // Attachment icon is also centered vertically to current 
       
   549 // control height.
       
   550 // ---------------------------------------------------------
       
   551 //
       
   552 void CMsgAttachmentControl::Draw( const TRect& /*aRect*/ ) const
       
   553     {
       
   554     if ( !iButton )
       
   555         {
       
   556         TPoint tlc( iIconLayout.Rect().iTl.iX, Position().iY );
       
   557         tlc.iY += ( Size().iHeight - iIconLayout.Rect().Size().iHeight ) / 2;
       
   558     
       
   559         SystemGc().BitBltMasked( tlc,
       
   560                                  iLabelIcon->Bitmap(), 
       
   561                                  iIconLayout.Rect().Size(),
       
   562                                  iLabelIcon->Mask(),
       
   563                                  EFalse );
       
   564         }
       
   565     }
       
   566 
       
   567 // ---------------------------------------------------------
       
   568 // CMsgAttachmentControl::ActivateL
       
   569 // ---------------------------------------------------------
       
   570 //
       
   571 void CMsgAttachmentControl::ActivateL()
       
   572     {
       
   573     CMsgExpandableControl::ActivateL();
       
   574     
       
   575     // Needs to be called after CEikEdwin::ActivateL as
       
   576     // panics if CEikEdwin::iTextView is not present
       
   577     iEditor->SetWordWrapL( EFalse );
       
   578     
       
   579     // Cursor is set to the beginning of text.
       
   580     iEditor->SetCursorPosL( 0, EFalse );
       
   581     
       
   582     if ( iEditor->TextView() )
       
   583         {
       
   584         const CFont* font = iEditorLayout.Font();
       
   585         TInt scrollJump( font->WidthZeroInPixels() );
       
   586         if ( scrollJump == 0 )
       
   587             {
       
   588             // Font gave us invalid scrollJump have to make
       
   589             // estimate according to scroll area.
       
   590             scrollJump = iEditorLayout.TextRect().Width() / KScrollJumpAreaDivider;
       
   591             }
       
   592         iEditor->TextView()->SetHorizontalScrollJump( scrollJump );
       
   593         }
       
   594     }
       
   595 
       
   596 // ---------------------------------------------------------
       
   597 // CMsgAttachmentControl::UpdateControlL
       
   598 // ---------------------------------------------------------
       
   599 //
       
   600 void CMsgAttachmentControl::UpdateControlL()
       
   601     {
       
   602     SetTextForEditorL( ETrue, ETrue );
       
   603     
       
   604     if ( iScrollTimer->IsActive() )
       
   605         {
       
   606         // Restart scrolling when attachment list is modified.
       
   607         iScrollPos = EScrollPosBeginning;
       
   608         StartAutomaticScrolling( KScrollStartDelay );        
       
   609         }
       
   610     
       
   611     DrawDeferred();
       
   612     iControlModeFlags |= EMsgControlModeModified;
       
   613     }
       
   614 
       
   615 
       
   616 // ---------------------------------------------------------
       
   617 // CMsgAttachmentControl::SetTextForEditorL
       
   618 // ---------------------------------------------------------
       
   619 //
       
   620 void CMsgAttachmentControl::SetTextForEditorL( TBool aContentChanged, TBool aClipText )
       
   621     {
       
   622     TInt count = iAttachmentArray->Count();
       
   623     TInt length = 0;
       
   624     
       
   625     for ( TInt i = 0; i < count; i++ )
       
   626         {
       
   627         length += iAttachmentArray->MdcaPoint( i ).Length();
       
   628         length += KAttachmentListSeparator().Length();
       
   629         }
       
   630 
       
   631     HBufC* buf = HBufC::NewLC( length );
       
   632     TPtr temp = buf->Des();
       
   633     
       
   634     for ( TInt j = 0; j < count; j++ )
       
   635         {
       
   636         temp.Append( iAttachmentArray->MdcaPoint( j ) );
       
   637         if ( j < count - 1 )
       
   638             {
       
   639             temp.Append( KAttachmentListSeparator );
       
   640             }
       
   641         }
       
   642         
       
   643     const CFont* font = iEditorLayout.Font();
       
   644 
       
   645     TInt clipWidth = 0;
       
   646     
       
   647     if ( iEditor->TextView() ) 
       
   648         {
       
   649         clipWidth = iEditor->TextView()->ViewRect().Width();
       
   650         }
       
   651     else
       
   652         {
       
   653         clipWidth = iEditorLayout.TextRect().Width();
       
   654         }
       
   655     
       
   656     TBool enableAutomaticScrolling( ETrue );
       
   657     if ( temp.Length() == 0 )
       
   658         {
       
   659         // Disable all processing if field is empty.
       
   660         enableAutomaticScrolling = EFalse;
       
   661         aContentChanged = EFalse;
       
   662         }
       
   663         
       
   664     if ( aContentChanged )
       
   665         {
       
   666         // Attachment array has been updated.
       
   667         TInt fits = font->TextCount( temp, clipWidth );
       
   668 
       
   669         if ( fits >= temp.Length() )
       
   670             {
       
   671             // All text fits to the field. No automatic scrolling.
       
   672             enableAutomaticScrolling = EFalse;
       
   673             }
       
   674         }
       
   675     
       
   676     if ( enableAutomaticScrolling )
       
   677         {
       
   678         EnableAutomaticScrolling();
       
   679         
       
   680         if ( aClipText )
       
   681             {
       
   682             ClipTextL( temp, clipWidth );
       
   683             }
       
   684         }
       
   685     else
       
   686         {
       
   687         DisableAutomaticScrolling();
       
   688         }
       
   689     
       
   690     // Replaces old text with new text.
       
   691     iEditor->SetTextL( buf );
       
   692 
       
   693     if ( IsActivated() && iEditor->CursorPos() != 0 )
       
   694         {
       
   695         // Cursor is set to the beginning of text.
       
   696         // Should not be called for non-activated control.
       
   697         iEditor->SetCursorPosL( 0, EFalse );
       
   698         }        
       
   699     
       
   700     CleanupStack::PopAndDestroy( buf );
       
   701     }
       
   702 
       
   703 // ---------------------------------------------------------
       
   704 // CMsgAttachmentControl::ResolveLayoutsL
       
   705 // 
       
   706 // ---------------------------------------------------------
       
   707 //
       
   708 void CMsgAttachmentControl::ResolveLayoutsL()
       
   709     {
       
   710     TAknLayoutRect msgTextPane;
       
   711     msgTextPane.LayoutRect( MsgEditorCommons::MsgDataPane(),
       
   712                             AknLayoutScalable_Apps::msg_text_pane( 0 ).LayoutLine() );
       
   713 
       
   714     TAknLayoutRect msgHeaderPane;
       
   715     msgHeaderPane.LayoutRect( msgTextPane.Rect(),
       
   716                               AknLayoutScalable_Apps::msg_header_pane().LayoutLine() );
       
   717     
       
   718     iIconLayout.LayoutRect( msgHeaderPane.Rect(),
       
   719                             AknLayoutScalable_Apps::msg_header_pane_g1().LayoutLine() );
       
   720     
       
   721     CMsgExpandableControl::ResolveLayoutsL();
       
   722         
       
   723     if ( iButton )
       
   724         {
       
   725         iButton->SetSize( iButton->Size() );
       
   726         }
       
   727     else
       
   728         {
       
   729         User::LeaveIfError( AknIconUtils::SetSize( iLabelIcon->Bitmap(), 
       
   730                                                    iIconLayout.Rect().Size() ) );
       
   731         }
       
   732      if ( iEditor->MsgEditorCustomDraw() )
       
   733         {
       
   734             iEditor->MsgEditorCustomDraw()->ResolveLayouts();
       
   735         }
       
   736     }
       
   737 
       
   738 // ---------------------------------------------------------
       
   739 // CMsgAttachmentControl::CreateAttachmentIconsL
       
   740 // ---------------------------------------------------------
       
   741 //
       
   742 CGulIcon* CMsgAttachmentControl::CreateAttachmentIconsL()
       
   743     {
       
   744     TParse fileParse;
       
   745     fileParse.Set( KIconMbmFile, &KDC_APP_BITMAP_DIR, NULL );
       
   746     
       
   747     CFbsBitmap* bitmap = NULL;
       
   748     CFbsBitmap* mask = NULL;
       
   749     
       
   750     AknsUtils::CreateColorIconLC( AknsUtils::SkinInstance(),
       
   751                                   KAknsIIDQgnIndiMceAttach,
       
   752                                   KAknsIIDQsnIconColors,
       
   753                                   EAknsCIQsnIconColorsCG13,
       
   754                                   bitmap, 
       
   755                                   mask,
       
   756                                   fileParse.FullName(), 
       
   757                                   EMbmMsgeditorQgn_indi_mce_attach,
       
   758                                   EMbmMsgeditorQgn_indi_mce_attach_mask,
       
   759                                   AKN_LAF_COLOR( KDefaultAttachmentColor ) ); 
       
   760     
       
   761     CGulIcon* result = CGulIcon::NewL( bitmap, mask ); // Ownership transferred
       
   762     CleanupStack::Pop( 2 ); // bitmap, mask
       
   763     
       
   764     return result;
       
   765     }
       
   766 
       
   767 // ---------------------------------------------------------
       
   768 // CMsgAttachmentControl::CreateButtonL
       
   769 // ---------------------------------------------------------
       
   770 //
       
   771 #ifdef RD_SCALABLE_UI_V2
       
   772 void CMsgAttachmentControl::CreateButtonL()
       
   773     {
       
   774     delete iButton;
       
   775     iButton = NULL;
       
   776     
       
   777     CGulIcon* buttonIcon = CGulIcon::NewL( iLabelIcon->Bitmap(), iLabelIcon->Mask() );
       
   778     buttonIcon->SetBitmapsOwnedExternally( ETrue ); // bitmaps owned by iLabelIcon
       
   779     
       
   780     CleanupStack::PushL( buttonIcon );
       
   781     
       
   782     iButton = CAknButton::NewL( buttonIcon,
       
   783                                 NULL,
       
   784                                 NULL,
       
   785                                 NULL,
       
   786                                 KNullDesC,
       
   787                                 KNullDesC,
       
   788                                 KAknButtonSizeFitText,
       
   789                                 0 );
       
   790         
       
   791     CleanupStack::Pop( buttonIcon ); // buttonIcon owned by iButton
       
   792     
       
   793     iButton->SetIconScaleMode( EAspectRatioPreserved );
       
   794     
       
   795     iButton->SetObserver( this );
       
   796     
       
   797     if ( DrawableWindow() )
       
   798         {
       
   799         iButton->SetContainerWindowL( Window() );
       
   800         iButton->ActivateL();
       
   801         }
       
   802     }
       
   803 #else
       
   804 void CMsgAttachmentControl::CreateButtonL()
       
   805     {
       
   806     }
       
   807 #endif // RD_SCALABLE_UI_V2
       
   808 
       
   809 
       
   810 // ---------------------------------------------------------
       
   811 // CMsgAttachmentControl::DoScrollTextL
       
   812 // ---------------------------------------------------------
       
   813 //
       
   814 TInt CMsgAttachmentControl::DoScrollTextL( TAny* aObject )
       
   815     {
       
   816     // cast, and call non-static function
       
   817     CMsgAttachmentControl* control = static_cast<CMsgAttachmentControl*>( aObject );
       
   818     TRAPD( error ,control->ScrollTextL() );
       
   819     if ( error != KErrNone )
       
   820         {
       
   821         control->StopAutomaticScrolling();
       
   822         User::Leave( error );
       
   823         }
       
   824     return KErrNone;
       
   825     }
       
   826 
       
   827 // ---------------------------------------------------------
       
   828 // CMsgAttachmentControl::ScrollTextL
       
   829 // ---------------------------------------------------------
       
   830 //
       
   831 void CMsgAttachmentControl::ScrollTextL()
       
   832     {
       
   833     TBool scrollText( ETrue );
       
   834     if ( iScrollPos == EScrollPosBeginning )
       
   835         {
       
   836         SetTextForEditorL( EFalse, EFalse );
       
   837         }
       
   838     else if ( iScrollPos == EScrollPosEnd )
       
   839         {
       
   840         // Indicates that text has been scrolled to the end and should be restarted.
       
   841         SetTextForEditorL( EFalse, ETrue );
       
   842         iScrollPos = EScrollPosBeginning;
       
   843         scrollText = EFalse;
       
   844         
       
   845         // Reset the text view to it's original position.
       
   846         iEditor->TextView()->SetLeftTextMargin( 0 );
       
   847         DrawNow();
       
   848         
       
   849         StartAutomaticScrolling( KScrollRestartDelay );
       
   850         }
       
   851     
       
   852     if ( scrollText )
       
   853         {
       
   854         TInt scrolledPixels = iEditor->TextView()->ScrollDisplayL( TCursorPosition::EFRight );
       
   855         if ( scrolledPixels == 0 )
       
   856             {
       
   857             // Indicates that text has been scrolled to the end. 
       
   858             iScrollPos = EScrollPosEnd;
       
   859             StartAutomaticScrolling( KScrollEndDelay ); 
       
   860             }
       
   861         else
       
   862             {
       
   863             iScrollPos = EScrollPosOther;
       
   864             }
       
   865         }
       
   866     }
       
   867 
       
   868 // ---------------------------------------------------------
       
   869 // CMsgAttachmentControl::DisableAutomaticScrolling
       
   870 // ---------------------------------------------------------
       
   871 //
       
   872 void CMsgAttachmentControl::DisableAutomaticScrolling()
       
   873     {
       
   874     iAutomaticScrolling = EFalse;    
       
   875     StopAutomaticScrolling();
       
   876     }
       
   877 
       
   878 // ---------------------------------------------------------
       
   879 // CMsgAttachmentControl::EnableAutomaticScrolling
       
   880 // ---------------------------------------------------------
       
   881 //
       
   882 void CMsgAttachmentControl::EnableAutomaticScrolling()
       
   883     {
       
   884     iAutomaticScrolling = ETrue;
       
   885     
       
   886     if ( !iScrollTimer->IsActive() && 
       
   887          IsFocused() )
       
   888         {
       
   889         StartAutomaticScrolling( KScrollStartDelay );
       
   890         }
       
   891     }
       
   892 
       
   893 
       
   894 // ---------------------------------------------------------
       
   895 // CMsgAttachmentControl::StartAutomaticScrolling
       
   896 // ---------------------------------------------------------
       
   897 //
       
   898 void CMsgAttachmentControl::StartAutomaticScrolling( TInt aStartDelay )
       
   899     {
       
   900     StopAutomaticScrolling();
       
   901     iScrollTimer->Start( aStartDelay,
       
   902                          KScrollTickDelay,
       
   903                          TCallBack( DoScrollTextL, this ) );
       
   904     }
       
   905         
       
   906 // ---------------------------------------------------------
       
   907 // CMsgAttachmentControl::StopAutomaticScrolling
       
   908 // ---------------------------------------------------------
       
   909 //
       
   910 void CMsgAttachmentControl::StopAutomaticScrolling()
       
   911     {
       
   912     iScrollTimer->Cancel();
       
   913     }
       
   914 
       
   915 // ---------------------------------------------------------
       
   916 // CMsgAttachmentControl::ClipTextL
       
   917 // ---------------------------------------------------------
       
   918 //
       
   919 void CMsgAttachmentControl::ClipTextL( TPtr aText, TInt aClipWidth )
       
   920     {
       
   921     const CFont* font = iEditorLayout.Font();
       
   922     
       
   923     TInt fits = font->TextCount( aText, aClipWidth );
       
   924         
       
   925     if ( fits < aText.Length() )
       
   926         {
       
   927         // Clipping is actually done only if text is at the beginning.
       
   928         TInt ellipsisWidth = font->CharWidthInPixels( KEllipsis );
       
   929 
       
   930         fits = font->TextCount( aText, aClipWidth - ellipsisWidth );
       
   931         
       
   932         // Work out the text directionality before the truncation point.
       
   933         // First put the text in reverse order and then call
       
   934         // TBidiText::TextDirectionality. This effectively tells the
       
   935         // directionality of the last strongly directional character
       
   936         // in the text.
       
   937         HBufC* temp = aText.Left( fits ).AllocL();
       
   938         TPtr tempPtr = temp->Des();
       
   939 
       
   940         TInt i = 0;
       
   941         TInt j = tempPtr.Length() - 1;
       
   942         while ( i < j )
       
   943             {
       
   944             TText t = tempPtr[i];
       
   945             tempPtr[i++] = tempPtr[j];
       
   946             tempPtr[j--] = t;
       
   947             }
       
   948         
       
   949         TBidiText::TDirectionality dir = TBidiText::TextDirectionality( tempPtr );
       
   950 
       
   951         delete temp;
       
   952 
       
   953         TText dirMarker = ( dir == TBidiText::ERightToLeft ) ? KRLMarker : 
       
   954                                                                KLRMarker;
       
   955         
       
   956         // Insert zero width joiner if necessary to get the correct glyph form
       
   957         // before truncation.
       
   958         TText lastChar = aText[fits - 1];
       
   959         TText next = aText[fits];
       
   960         
       
   961         TInt ellipsisPos = fits;
       
   962         
       
   963         if ( CFont::CharactersJoin( lastChar, KZeroWidthJoiner ) &&
       
   964              CFont::CharactersJoin( lastChar, next ) )
       
   965             {
       
   966             aText[fits] = KZeroWidthJoiner;
       
   967             ellipsisPos++;
       
   968             }
       
   969             
       
   970         aText.SetMax();
       
   971         
       
   972         aText[ellipsisPos] = KEllipsis;    
       
   973 
       
   974         // Inserting direction marker after the ellipsis ensures that
       
   975         // the ellipsis is shown on the correct side of the text
       
   976         // before it.
       
   977         aText[ellipsisPos + 1] = dirMarker;
       
   978 
       
   979         aText.SetLength( ellipsisPos + 2 );
       
   980         }
       
   981     }
       
   982 
       
   983 // ---------------------------------------------------------
       
   984 // CMsgAttachmentControl::UpdateFocusL
       
   985 // ---------------------------------------------------------
       
   986 //
       
   987 void CMsgAttachmentControl::UpdateFocusL()
       
   988     {
       
   989     TCharFormat charFormat;
       
   990     TCharFormatMask applyMask;
       
   991 
       
   992     iEditor->RichText()->GetCharFormat( charFormat,
       
   993                                         applyMask,
       
   994                                         0,
       
   995                                         iEditor->TextLength() );
       
   996             
       
   997     if ( !IsFocused() )
       
   998         {
       
   999         TRgb textColor( KRgbBlack );
       
  1000         AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), 
       
  1001                                    textColor, 
       
  1002                                    KAknsIIDQsnTextColors, 
       
  1003                                    EAknsCIQsnTextColorsCG6 );
       
  1004                                    
       
  1005         charFormat.iFontPresentation.iTextColor = textColor;
       
  1006         applyMask.SetAttrib( EAttColor );               
       
  1007         
       
  1008         charFormat.iFontPresentation.iHighlightStyle = TFontPresentation::EFontHighlightNone;
       
  1009         applyMask.SetAttrib( EAttFontHighlightStyle );
       
  1010         }
       
  1011     else
       
  1012         {
       
  1013         TRgb textColor( KRgbWhite );
       
  1014         AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), 
       
  1015                                    textColor, 
       
  1016                                    KAknsIIDQsnHighlightColors, 
       
  1017                                    EAknsCIQsnTextColorsCG3 );
       
  1018                                    
       
  1019         charFormat.iFontPresentation.iTextColor = textColor;
       
  1020         applyMask.SetAttrib( EAttColor );               
       
  1021            
       
  1022         TRgb highlightColor( KRgbBlue );
       
  1023         AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), 
       
  1024                                    highlightColor, 
       
  1025                                    KAknsIIDQsnHighlightColors, 
       
  1026                                    EAknsCIQsnHighlightColorsCG1 );
       
  1027                                    
       
  1028         charFormat.iFontPresentation.iHighlightColor = highlightColor;
       
  1029         applyMask.SetAttrib( EAttFontHighlightColor );
       
  1030 
       
  1031         charFormat.iFontPresentation.iHighlightStyle = TFontPresentation::EFontHighlightNormal;
       
  1032         applyMask.SetAttrib( EAttFontHighlightStyle );
       
  1033         }
       
  1034     
       
  1035     iEditor->RichText()->ApplyCharFormatL( charFormat,
       
  1036                                            applyMask,
       
  1037                                            0,
       
  1038                                            iEditor->TextLength() );    
       
  1039     }
       
  1040 
       
  1041 // ---------------------------------------------------------
       
  1042 // CMsgAttachmentControl::DoHandleResourceChangeBeforeL
       
  1043 //
       
  1044 // Contains functionality that base class handle resource change 
       
  1045 // is depending on to be completed before it can be executed properly.
       
  1046 // ---------------------------------------------------------
       
  1047 //
       
  1048 void CMsgAttachmentControl::DoHandleResourceChangeBeforeL( TInt aType )
       
  1049     {
       
  1050     switch( aType )
       
  1051         {
       
  1052         case KEikDynamicLayoutVariantSwitch:
       
  1053             {
       
  1054 #ifdef RD_SCALABLE_UI_V2
       
  1055             if ( AknLayoutUtils::PenEnabled() )
       
  1056                 {
       
  1057                 if ( !iButton )
       
  1058                     {
       
  1059                     CreateButtonL();
       
  1060                     }
       
  1061                 }
       
  1062             else
       
  1063                 {
       
  1064                 delete iButton;
       
  1065                 iButton = NULL;
       
  1066                 }
       
  1067 #endif // RD_SCALABLE_UI_V2
       
  1068             break;
       
  1069             }
       
  1070         default:
       
  1071             {
       
  1072             break;
       
  1073             }
       
  1074         }
       
  1075     }
       
  1076 
       
  1077 // ---------------------------------------------------------
       
  1078 // CMsgAttachmentControl::DoHandleResourceChangeAfterL
       
  1079 //
       
  1080 // Contains functionality that is dependant of base class handle
       
  1081 // resource change to complete before these can be executed properly.
       
  1082 // ---------------------------------------------------------
       
  1083 //
       
  1084 void CMsgAttachmentControl::DoHandleResourceChangeAfterL( TInt aType )
       
  1085     {
       
  1086     switch( aType )
       
  1087         {
       
  1088         case KEikDynamicLayoutVariantSwitch:
       
  1089             {
       
  1090             StopAutomaticScrolling();
       
  1091             iScrollPos = EScrollPosBeginning;
       
  1092             SetTextForEditorL( EFalse, ETrue );  
       
  1093             
       
  1094             break;
       
  1095             }
       
  1096         case KAknsMessageSkinChange:
       
  1097             {
       
  1098             CGulIcon* icon = CreateAttachmentIconsL();
       
  1099             CleanupStack::PushL( icon );
       
  1100             
       
  1101             if ( iButton )
       
  1102                 {
       
  1103                 CGulIcon* buttonIcon = CGulIcon::NewL( icon->Bitmap(), icon->Mask() );
       
  1104                 buttonIcon->SetBitmapsOwnedExternally( ETrue ); // bitmaps owned by iLabelIcon
       
  1105     
       
  1106                 iButton->State()->SetIcon( buttonIcon ); // buttonIcon ownership transferred
       
  1107                 }
       
  1108             
       
  1109             // Make the change here as button will take the old size from
       
  1110             // old icons that must be still valid when setting to button icon.
       
  1111             delete iLabelIcon;
       
  1112             iLabelIcon = icon;
       
  1113             
       
  1114             CleanupStack::Pop( icon );
       
  1115             
       
  1116             ResolveLayoutsL();
       
  1117             break;
       
  1118             }
       
  1119         default:
       
  1120             {
       
  1121             break;
       
  1122             }
       
  1123         }
       
  1124     }
       
  1125 
       
  1126 // ---------------------------------------------------------
       
  1127 // CMsgAttachmentControl::AddToAttachmentArrayL
       
  1128 // ---------------------------------------------------------
       
  1129 //
       
  1130 void CMsgAttachmentControl::AddToAttachmentArrayL( const TDesC& aName, TInt aIndex )
       
  1131     {
       
  1132     HBufC* convertedFileName = 
       
  1133                 AknTextUtils::ConvertFileNameL( aName );
       
  1134     CleanupStack::PushL( convertedFileName );
       
  1135     
       
  1136     TPtr convertedFileNamePtr = convertedFileName->Des();
       
  1137     
       
  1138     AknTextUtils::StripCharacters( convertedFileNamePtr, KStripList );
       
  1139     
       
  1140     iAttachmentArray->InsertL( aIndex, *convertedFileName );
       
  1141     
       
  1142     CleanupStack::PopAndDestroy( convertedFileName );
       
  1143     }
       
  1144 
       
  1145 // ---------------------------------------------------------
       
  1146 // CMsgAttachmentControl::LayoutButton
       
  1147 // ---------------------------------------------------------
       
  1148 //    
       
  1149 void CMsgAttachmentControl::LayoutButton()
       
  1150     {
       
  1151 #ifdef RD_SCALABLE_UI_V2
       
  1152     CMsgExpandableControl::LayoutButton();
       
  1153     
       
  1154     if ( iButton )
       
  1155         {
       
  1156         TMargins8 margins;
       
  1157         TRect buttonRect = iButtonLayout.Rect();
       
  1158         TRect iconRect = iIconLayout.Rect();
       
  1159         margins.iTop = iconRect.iTl.iY - buttonRect.iTl.iY;
       
  1160         margins.iBottom = buttonRect.iBr.iY - iconRect.iBr.iY;
       
  1161         margins.iLeft = iconRect.iTl.iX - buttonRect.iTl.iX;
       
  1162         margins.iRight = buttonRect.iBr.iX - iconRect.iBr.iX;
       
  1163         
       
  1164         iButton->SetMargins( margins );
       
  1165         }
       
  1166 #endif // RD_SCALABLE_UI_V2
       
  1167     }
       
  1168 
       
  1169 
       
  1170 //  End of File