messagingappbase/msgeditor/viewsrc/MsgExpandableTextEditorControl.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2007 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:  MsgExpandableTextEditorControl implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ========== INCLUDE FILES ================================
       
    21 
       
    22 #include <eikenv.h>                        // for CEikonEnv
       
    23 #include <eikedwin.h>                      // for TClipboardFunc
       
    24 #include <txtrich.h>                       // for CRichText
       
    25 #include <AknUtils.h>                      // for AknUtils
       
    26 #include <aknenv.h>                        // for CAknEnv
       
    27 #include <AknDef.h>
       
    28 
       
    29 
       
    30 #include "MsgExpandableTextEditorControl.h"
       
    31 #include "MsgEditorCommon.h"               //
       
    32 #include "MsgExpandableControlEditor.h"    // for CMsgExpandableControlEditor
       
    33 #include "MsgBaseControlObserver.h"        // for MMsgBaseControlObserver
       
    34 #include "MsgEditorPanic.h"                // for CMsgEditor panics
       
    35 #include "MsgEditorLogging.h"
       
    36 
       
    37 // ========== EXTERNAL DATA STRUCTURES =====================
       
    38 
       
    39 // ========== EXTERNAL FUNCTION PROTOTYPES =================
       
    40 
       
    41 // ========== CONSTANTS ====================================
       
    42 
       
    43 // ========== MACROS =======================================
       
    44 
       
    45 // ========== LOCAL CONSTANTS AND MACROS ===================
       
    46 const TInt KCursorPosNotSet = -1;
       
    47 
       
    48 // ========== MODULE DATA STRUCTURES =======================
       
    49 
       
    50 // ========== LOCAL FUNCTION PROTOTYPES ====================
       
    51 
       
    52 // ========== LOCAL FUNCTIONS ==============================
       
    53 
       
    54 // ========== MEMBER FUNCTIONS =============================
       
    55 
       
    56 // ---------------------------------------------------------
       
    57 // CMsgExpandableTextEditorControl::CMsgExpandableTextEditorControl
       
    58 //
       
    59 // Constructor.
       
    60 // ---------------------------------------------------------
       
    61 //
       
    62 EXPORT_C CMsgExpandableTextEditorControl::CMsgExpandableTextEditorControl() :
       
    63     iCursorPos( KCursorPosNotSet )
       
    64     {
       
    65     SetComponentsToInheritVisibility( ETrue );
       
    66     }
       
    67 
       
    68 // ---------------------------------------------------------
       
    69 // CMsgExpandableControl::CMsgExpandableControl
       
    70 //
       
    71 // Constructor.
       
    72 // ---------------------------------------------------------
       
    73 //
       
    74 EXPORT_C CMsgExpandableTextEditorControl::CMsgExpandableTextEditorControl( MMsgBaseControlObserver& aBaseControlObserver ) :
       
    75     CMsgBaseControl( aBaseControlObserver ),
       
    76     iCursorPos( KCursorPosNotSet )
       
    77     {
       
    78     SetComponentsToInheritVisibility( ETrue );
       
    79     }
       
    80 
       
    81 // ---------------------------------------------------------
       
    82 // CMsgExpandableTextEditorControl::~CMsgExpandableTextEditorControl
       
    83 //
       
    84 // Destructor.
       
    85 // ---------------------------------------------------------
       
    86 //
       
    87 EXPORT_C CMsgExpandableTextEditorControl::~CMsgExpandableTextEditorControl()
       
    88     {
       
    89     }
       
    90 
       
    91 // ---------------------------------------------------------
       
    92 // CMsgExpandableTextEditorControl::SetPlainTextMode
       
    93 //
       
    94 // Sets the plain text mode on or off.
       
    95 // ---------------------------------------------------------
       
    96 //
       
    97 EXPORT_C void CMsgExpandableTextEditorControl::SetPlainTextMode( TBool aMode )
       
    98     {
       
    99     if ( aMode )
       
   100         {
       
   101         iControlModeFlags |= EMsgControlModePlainTextMode;
       
   102         }
       
   103     else
       
   104         {
       
   105         iControlModeFlags &= ~EMsgControlModePlainTextMode;
       
   106         }
       
   107 
       
   108     iEditor->SetAllowPictures( !( iControlModeFlags & EMsgControlModePlainTextMode ) );
       
   109     }
       
   110 
       
   111 // ---------------------------------------------------------
       
   112 // CMsgExpandableControl::IsPlainTextMode
       
   113 //
       
   114 // Checks if the plain text mode is on and returns ETrue if it is.
       
   115 // ---------------------------------------------------------
       
   116 //
       
   117 EXPORT_C TBool CMsgExpandableTextEditorControl::IsPlainTextMode() const
       
   118     {
       
   119     return iControlModeFlags & EMsgControlModePlainTextMode;
       
   120     }
       
   121 
       
   122 // ---------------------------------------------------------
       
   123 // CMsgExpandableTextEditorControl::TextContent
       
   124 //
       
   125 // Returns a reference to text content of the editor.
       
   126 // ---------------------------------------------------------
       
   127 //
       
   128 EXPORT_C CRichText& CMsgExpandableTextEditorControl::TextContent() const
       
   129     {
       
   130     return *iEditor->RichText();
       
   131     }
       
   132 
       
   133 // ---------------------------------------------------------
       
   134 // CMsgExpandableTextEditorControl::CopyDocumentContentL
       
   135 //
       
   136 // Copies aInText to aOutText.
       
   137 // ---------------------------------------------------------
       
   138 //
       
   139 EXPORT_C void CMsgExpandableTextEditorControl::CopyDocumentContentL( CGlobalText& aInText,
       
   140                                                                      CGlobalText& aOutText )
       
   141     {
       
   142     iEditor->CopyDocumentContentL( aInText, aOutText );
       
   143     iControlModeFlags |= EMsgControlModeModified;
       
   144     }
       
   145 
       
   146 // ---------------------------------------------------------
       
   147 // CMsgExpandableTextEditorControl::SetMaxNumberOfChars
       
   148 //
       
   149 // Sets maximun number of characters.
       
   150 // ---------------------------------------------------------
       
   151 //
       
   152 EXPORT_C void CMsgExpandableTextEditorControl::SetMaxNumberOfChars( TInt aMaxNumberOfChars )
       
   153     {
       
   154     iEditor->SetMaxNumberOfChars( aMaxNumberOfChars );
       
   155     }
       
   156 
       
   157 // ---------------------------------------------------------
       
   158 // CMsgExpandableTextEditorControl::SetCursorPosL
       
   159 // ---------------------------------------------------------
       
   160 //
       
   161 EXPORT_C void CMsgExpandableTextEditorControl::SetCursorPosL( TInt aCursorPos )
       
   162     {
       
   163     if ( iEditor &&
       
   164          IsActivated() &&
       
   165          ( iEditor->CursorPos() != aCursorPos || 
       
   166            !iEditor->IsCursorVisibleL() ) )
       
   167         {
       
   168         iEditor->SetCursorPosL( aCursorPos, EFalse );
       
   169         iBaseControlObserver->HandleBaseControlEventRequestL( this, 
       
   170                                                               EMsgEnsureCorrectFormPosition, 
       
   171                                                               0 );            
       
   172         }
       
   173     iCursorPos = aCursorPos;
       
   174     }
       
   175 
       
   176 // ---------------------------------------------------------
       
   177 // CMsgExpandableTextEditorControl::ActivateL
       
   178 // ---------------------------------------------------------
       
   179 //
       
   180 EXPORT_C void CMsgExpandableTextEditorControl::ActivateL()
       
   181     {
       
   182     CMsgBaseControl::ActivateL();
       
   183     
       
   184     if ( iCursorPos != KCursorPosNotSet )
       
   185         {
       
   186         SetCursorPosL( iCursorPos );
       
   187         }
       
   188     }
       
   189 
       
   190 // ---------------------------------------------------------
       
   191 // CMsgExpandableTextEditorControl::ScrollL
       
   192 //
       
   193 // Tries to scroll the given amount of pixels. Restrict scroll
       
   194 // to top of lines is switched off to allow better scrolling of
       
   195 // text view. Otherwise scrolling would be limited to top of 
       
   196 // the text lines. Margin pixels are scrolled "away" when control reaches
       
   197 // the end.
       
   198 // ---------------------------------------------------------
       
   199 //
       
   200 #ifdef RD_SCALABLE_UI_V2
       
   201 EXPORT_C TInt CMsgExpandableTextEditorControl::ScrollL( TInt aPixelsToScroll, TMsgScrollDirection aDirection )
       
   202     {
       
   203     TInt pixelsToScroll( 0 );
       
   204     
       
   205     CTextLayout* textLayout = iEditor->TextLayout();
       
   206     
       
   207     if ( aDirection == EMsgScrollDown )
       
   208         {
       
   209         // Negative pixels means scrolling down.
       
   210         pixelsToScroll = -aPixelsToScroll;
       
   211         }
       
   212     else
       
   213         {
       
   214         // Positive pixels means scrolling up.
       
   215         pixelsToScroll = aPixelsToScroll;
       
   216         }
       
   217     
       
   218     if ( pixelsToScroll != 0 )
       
   219         {
       
   220         iEditor->TextView()->ScrollDisplayPixelsL( pixelsToScroll );
       
   221                 
       
   222         if ( Abs( pixelsToScroll ) % iLineHeight != 0 )
       
   223             {
       
   224             pixelsToScroll = Abs( pixelsToScroll ) - ( Size().iHeight - iEditor->Size().iHeight );
       
   225             }
       
   226 
       
   227         }
       
   228     
       
   229     return Abs( pixelsToScroll );
       
   230     }
       
   231 #else
       
   232 EXPORT_C TInt CMsgExpandableTextEditorControl::ScrollL( TInt /*aPixelsToScroll*/, TMsgScrollDirection /*aDirection*/ )
       
   233     {
       
   234     return 0;
       
   235     }
       
   236 #endif // RD_SCALABLE_UI_V2
       
   237 
       
   238 // ---------------------------------------------------------
       
   239 // CMsgExpandableTextEditorControl::CurrentLineRect
       
   240 //
       
   241 // Returns the current control rect.
       
   242 // ---------------------------------------------------------
       
   243 //
       
   244 EXPORT_C TRect CMsgExpandableTextEditorControl::CurrentLineRect()
       
   245     {
       
   246     TRect lineRect( 0, 0, 0, 0 );
       
   247     TRAPD( ret, lineRect = iEditor->CurrentLineRectL() );
       
   248     if ( ret != KErrNone )
       
   249         {
       
   250         return lineRect;
       
   251         }
       
   252 
       
   253     TRect ctrlRect( Rect() );
       
   254 
       
   255     lineRect.iTl.iX = ctrlRect.iTl.iX;
       
   256     lineRect.iBr.iX = ctrlRect.iBr.iX;
       
   257     // "lineRect" is relative to "ctrlRect" -> Move needed
       
   258     lineRect.Move( TPoint( 0, iPosition.iY  ) );
       
   259 
       
   260     // "lineRect" should never be outside the "ctrlRect"
       
   261     // There seems to be a bug in Edwin when layouting is
       
   262     // changed from "full" to "partial". In this case the
       
   263     // "lineRect" might get outside "ctrlRect". This
       
   264     // causes false alarm and unwanted scrolling in
       
   265     // CMsgEditorView::EnsureCorrectFormPosition.
       
   266     // -> Has to make sure lineRect won't get outside ctrlRect
       
   267 
       
   268     if ( lineRect.iBr.iY > ctrlRect.iBr.iY )
       
   269         {
       
   270         lineRect.Move( TPoint( 0, ctrlRect.iBr.iY - lineRect.iBr.iY ) );
       
   271         }
       
   272 
       
   273     return lineRect;
       
   274     }
       
   275 
       
   276 // ---------------------------------------------------------
       
   277 // CMsgExpandableTextEditorControl::SetBaseControlObserver
       
   278 //
       
   279 // Sets base control observer.
       
   280 // ---------------------------------------------------------
       
   281 //
       
   282 EXPORT_C void CMsgExpandableTextEditorControl::SetBaseControlObserver( MMsgBaseControlObserver& aBaseControlObserver )
       
   283     {
       
   284     CMsgBaseControl::SetBaseControlObserver( aBaseControlObserver );
       
   285     iEditor->SetBaseControlObserver( aBaseControlObserver );
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------
       
   289 // CMsgExpandableTextEditorControl::ClipboardL
       
   290 //
       
   291 // Handles clipboard operation.
       
   292 // ---------------------------------------------------------
       
   293 //
       
   294 EXPORT_C void CMsgExpandableTextEditorControl::ClipboardL( TMsgClipboardFunc /*aFunc*/ )
       
   295     {
       
   296     // changed to do nothing because
       
   297     // CMsgExpandableControlEditor::Ccpu???? functions handle
       
   298     // clipboard operations now.
       
   299     }
       
   300 // ---------------------------------------------------------
       
   301 // CMsgExpandableTextEditorControl::EditL
       
   302 //
       
   303 // Handles editing operation.
       
   304 // ---------------------------------------------------------
       
   305 //
       
   306 EXPORT_C void CMsgExpandableTextEditorControl::EditL( TMsgEditFunc aFunc )
       
   307     {
       
   308     TUint32 editPermission = EditPermission();
       
   309 
       
   310     switch ( aFunc )
       
   311         {
       
   312         case EMsgUndo:
       
   313             {
       
   314             if ( editPermission & EMsgEditUndo )
       
   315                 {
       
   316                 iEditor->UndoL();
       
   317                 }
       
   318             break;
       
   319             }
       
   320         case EMsgSelectAll:
       
   321             {
       
   322             if ( editPermission & EMsgEditSelectAll )
       
   323                 {
       
   324                 iEditor->SelectAllL();
       
   325                 HandleControlEventL( this, MCoeControlObserver::EEventStateChanged );
       
   326                 }
       
   327             break;
       
   328             }
       
   329         default:
       
   330             {
       
   331             __ASSERT_DEBUG( EFalse, Panic( EMsgIncorrectEditFunction ) );
       
   332             break;
       
   333             }
       
   334         }
       
   335     }
       
   336 
       
   337 // ---------------------------------------------------------
       
   338 // CMsgExpandableTextEditorControl::EditPermission
       
   339 //
       
   340 // Returns edit permission flags.
       
   341 // ---------------------------------------------------------
       
   342 //
       
   343 EXPORT_C TUint32 CMsgExpandableTextEditorControl::EditPermission() const
       
   344     {
       
   345     return iEditor->CheckEditPermission();
       
   346     }
       
   347 
       
   348 // ---------------------------------------------------------
       
   349 // CMsgExpandableTextEditorControl::IsCursorLocation
       
   350 //
       
   351 // Checks if the cursor location is on the topmost or downmost position
       
   352 // depending on aLocation and returns ETrue if it is.
       
   353 // ---------------------------------------------------------
       
   354 //
       
   355 EXPORT_C TBool CMsgExpandableTextEditorControl::IsCursorLocation( TMsgCursorLocation aLocation ) const
       
   356     {
       
   357     switch ( aLocation )
       
   358         {
       
   359         case EMsgTop:
       
   360             {
       
   361             return iEditor->CursorInFirstLine();
       
   362             }
       
   363         case EMsgBottom:
       
   364             {
       
   365             return iEditor->CursorInLastLine();
       
   366             }
       
   367         default:
       
   368             {
       
   369             return EFalse;
       
   370             }
       
   371         }
       
   372     }
       
   373 
       
   374 
       
   375 // CMsgExpandableTextEditorControl::VirtualHeight
       
   376 //
       
   377 // Returns approximate height of the control.
       
   378 // ---------------------------------------------------------
       
   379 //
       
   380 EXPORT_C TInt CMsgExpandableTextEditorControl::VirtualHeight()
       
   381     {
       
   382     return iEditor->VirtualHeight();
       
   383     }
       
   384 
       
   385 // ---------------------------------------------------------
       
   386 // CMsgExpandableTextEditorControl::VirtualVisibleTop
       
   387 //
       
   388 // Returns a topmost visible text position. Queries the visible top
       
   389 // from editor and adds control top position differences (= top margin ) 
       
   390 // into it if control is not visible.
       
   391 // ---------------------------------------------------------
       
   392 //
       
   393 EXPORT_C TInt CMsgExpandableTextEditorControl::VirtualVisibleTop()
       
   394     {
       
   395     return iEditor->VirtualVisibleTop();
       
   396     }
       
   397 
       
   398 // ---------------------------------------------------------
       
   399 // CMsgExpandableTextEditorControl::HandleControlEventL
       
   400 // 
       
   401 // Handles state change event from text editor. Checks whether form 
       
   402 // updating is needed. This is needed atleast when subject field
       
   403 // is visible at the last row of the view and word is typed using T9 
       
   404 // so that line is changed in the middle of it. Without this check
       
   405 // the view is not updated correctly.
       
   406 // ---------------------------------------------------------
       
   407 //
       
   408 EXPORT_C void CMsgExpandableTextEditorControl::HandleControlEventL( CCoeControl* aControl, 
       
   409                                                                     TCoeEvent aEventType )
       
   410     {
       
   411     if ( aControl == iEditor &&
       
   412          aEventType == MCoeControlObserver::EEventStateChanged )
       
   413         {
       
   414         iBaseControlObserver->HandleBaseControlEventRequestL( this, 
       
   415                                                               EMsgEnsureCorrectFormPosition, 
       
   416                                                               0 );
       
   417         iControlModeFlags |= EMsgControlModeModified;
       
   418         }
       
   419     }
       
   420 
       
   421 // ---------------------------------------------------------
       
   422 // CMsgExpandableTextEditorControl::HandleEdwinSizeEventL
       
   423 //
       
   424 // Handles expandable text editor size event. These event are send only when
       
   425 // the editor height changes. First desirable heigh is limited to maximum
       
   426 // body height. This is needed as edwin will report values larger than 
       
   427 // maximum height. After this a change delta between current and desired 
       
   428 // heights is calculated. This is rounded to the next full baseline. 
       
   429 // If editor height is wanted to reduce and there is still unshown content
       
   430 // then the content is scrolled downward so that it becomes visible. In this
       
   431 // case the editor or control height is not changed. If editor height is 
       
   432 // wanted to increase or all the content is current shown then
       
   433 // control and editor heights are changed. If body max height flag
       
   434 // is specified for control then the control height is always set to maximum.
       
   435 // After heights have been changed base control observer (CMsgEditorView)
       
   436 // is notified.
       
   437 // ---------------------------------------------------------
       
   438 //
       
   439 EXPORT_C TBool CMsgExpandableTextEditorControl::HandleEdwinSizeEventL( CEikEdwin* /*aEdwin*/,
       
   440                                                                        TEdwinSizeEvent aEventType,
       
   441                                                                        TSize aDesirableEdwinSize )
       
   442     {
       
   443     if ( aEventType == EEventSizeChanging )
       
   444         {
       
   445         MEBLOGGER_ENTERFN("CMsgExpandableTextEditorControl::HandleEdwinSizeEventL");
       
   446         
       
   447         aDesirableEdwinSize.iHeight = Min( aDesirableEdwinSize.iHeight, iMaxBodyHeight );
       
   448         
       
   449         TInt delta = aDesirableEdwinSize.iHeight - iEditor->Size().iHeight;
       
   450         MsgEditorCommons::RoundToNextLine( delta, iLineHeight );
       
   451         
       
   452         if ( delta < 0 && 
       
   453              iEditor->VirtualHeight() > iMaxBodyHeight )
       
   454             {
       
   455             ScrollL( delta, EMsgScrollDown );
       
   456             iBaseControlObserver->HandleBaseControlEventRequestL( this, 
       
   457                                                                   EMsgUpdateScrollbar, 
       
   458                                                                   delta );
       
   459             }        
       
   460         else if ( delta ||
       
   461                   iControlModeFlags & EMsgControlModeForceSizeUpdate )
       
   462             {
       
   463             if ( iControlModeFlags & EMsgControlModeBodyMaxHeight )
       
   464                 {
       
   465                 aDesirableEdwinSize.iHeight = iEditor->MaximumHeight();
       
   466                 }            
       
   467             
       
   468             // Performs the real size change if height has really changed
       
   469             // or if forced size change is set.
       
   470             iSize.iHeight = aDesirableEdwinSize.iHeight;
       
   471             MsgEditorCommons::RoundToNextLine( iSize.iHeight, iLineHeight );
       
   472             
       
   473             if ( delta != 0 )
       
   474                 {
       
   475                 iEditor->SetAndGetSizeL( aDesirableEdwinSize );
       
   476                 }
       
   477 
       
   478             iBaseControlObserver->HandleBaseControlEventRequestL( this, 
       
   479                                                                   EMsgHeightChanged, 
       
   480                                                                   delta );
       
   481             }
       
   482 
       
   483         MEBLOGGER_LEAVEFN("CMsgExpandableTextEditorControl::HandleEdwinSizeEventL");
       
   484 
       
   485         if ( delta < 0 )
       
   486             { 
       
   487             return ETrue;
       
   488             }
       
   489         }
       
   490 
       
   491     return EFalse;
       
   492     }
       
   493 
       
   494 // ---------------------------------------------------------
       
   495 // CMsgExpandableTextEditorControl::HandleEdwinEventL
       
   496 //
       
   497 // Handles events from expandable text editor. Navigation and format
       
   498 // change events are handled.
       
   499 // ---------------------------------------------------------
       
   500 //
       
   501 EXPORT_C void CMsgExpandableTextEditorControl::HandleEdwinEventL( CEikEdwin* aEdwin, 
       
   502                                                                   TEdwinEvent aEventType)
       
   503     {
       
   504     if ( aEventType == MEikEdwinObserver::EEventNavigation && aEdwin->TextView() )
       
   505         {
       
   506         // When cursor is in beginning of text and left key is pressed,
       
   507         // FEP places cursor to the end of text. This scrolls end of text
       
   508         // to be visible. With pen support this needs to be handled always since
       
   509         // select & drag scrolling might change the text position so that form updating
       
   510         // is needed.
       
   511         iBaseControlObserver->HandleBaseControlEventRequestL( this, 
       
   512                                                               EMsgEnsureCorrectFormPosition, 
       
   513                                                               0 );
       
   514         }
       
   515     else if ( aEventType == MEikEdwinObserver::EEventFormatChanged )
       
   516         {
       
   517         iBaseControlObserver->HandleBaseControlEventRequestL( this, 
       
   518                                                               EMsgEnsureCorrectFormPosition, 
       
   519                                                               0 );
       
   520         }
       
   521     }
       
   522 
       
   523 
       
   524 //  End of File