LCOV - code coverage report
Current view: top level - editeng/source/editeng - impedit2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1047 2278 46.0 %
Date: 2012-08-25 Functions: 71 113 62.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 972 4013 24.2 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <vcl/wrkwin.hxx>
      31                 :            : #include <vcl/dialog.hxx>
      32                 :            : #include <vcl/msgbox.hxx>
      33                 :            : #include <vcl/svapp.hxx>
      34                 :            : 
      35                 :            : #include <editeng/lspcitem.hxx>
      36                 :            : #include <editeng/flditem.hxx>
      37                 :            : #include <impedit.hxx>
      38                 :            : #include <editeng/editeng.hxx>
      39                 :            : #include <editeng/editview.hxx>
      40                 :            : #include <editdbg.hxx>
      41                 :            : #include <eerdll2.hxx>
      42                 :            : #include <editeng/eerdll.hxx>
      43                 :            : #include <edtspell.hxx>
      44                 :            : #include <eeobj.hxx>
      45                 :            : #include <editeng/txtrange.hxx>
      46                 :            : #include <svl/urlbmk.hxx>
      47                 :            : #include <svtools/colorcfg.hxx>
      48                 :            : #include <svl/ctloptions.hxx>
      49                 :            : #include <editeng/acorrcfg.hxx>
      50                 :            : #include <editeng/fhgtitem.hxx>
      51                 :            : #include <editeng/lrspitem.hxx>
      52                 :            : #include <editeng/ulspitem.hxx>
      53                 :            : #include <editeng/wghtitem.hxx>
      54                 :            : #include <editeng/postitem.hxx>
      55                 :            : #include <editeng/udlnitem.hxx>
      56                 :            : #include <editeng/adjitem.hxx>
      57                 :            : #include <editeng/scripttypeitem.hxx>
      58                 :            : #include <editeng/frmdiritem.hxx>
      59                 :            : #include <editeng/fontitem.hxx>
      60                 :            : #include <editeng/justifyitem.hxx>
      61                 :            : #include <vcl/cmdevt.h>
      62                 :            : 
      63                 :            : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
      64                 :            : #include <com/sun/star/i18n/WordType.hpp>
      65                 :            : #include <com/sun/star/i18n/ScriptType.hpp>
      66                 :            : #include <com/sun/star/lang/Locale.hpp>
      67                 :            : #include <com/sun/star/text/CharacterCompressionType.hpp>
      68                 :            : #include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
      69                 :            : 
      70                 :            : #include <comphelper/processfactory.hxx>
      71                 :            : 
      72                 :            : #include <sot/formats.hxx>
      73                 :            : 
      74                 :            : #include <unicode/ubidi.h>
      75                 :            : 
      76                 :            : #include <boost/scoped_ptr.hpp>
      77                 :            : 
      78                 :            : using namespace ::com::sun::star;
      79                 :            : 
      80                 :      18403 : sal_uInt16 lcl_CalcExtraSpace( ParaPortion*, const SvxLineSpacingItem& rLSItem )
      81                 :            : {
      82                 :      18403 :     sal_uInt16 nExtra = 0;
      83         [ +  + ]:      18403 :     if ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
      84                 :            :     {
      85                 :        194 :         nExtra = rLSItem.GetInterLineSpace();
      86                 :            :     }
      87                 :            : 
      88                 :      18403 :     return nExtra;
      89                 :            : }
      90                 :            : 
      91                 :      30636 : ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) :
      92                 :            :     aPaperSize( 0x7FFFFFFF, 0x7FFFFFFF ),
      93                 :            :     aMinAutoPaperSize( 0x0, 0x0 ),
      94                 :            :     aMaxAutoPaperSize( 0x7FFFFFFF, 0x7FFFFFFF ),
      95                 :            :     aEditDoc( pItemPool ),
      96                 :            :     aWordDelimiters( RTL_CONSTASCII_USTRINGPARAM( "  .,;:-'`'?!_=\"{}()[]\0xFF" ) ),
      97                 :            :     aGroupChars( RTL_CONSTASCII_USTRINGPARAM( "{}()[]" ) ),
      98                 :            :     bKernAsianPunctuation(false),
      99                 :            :     bAddExtLeading(false),
     100                 :            :     bIsFormatting(false),
     101                 :            :     bFormatted(false),
     102                 :            :     bInSelection(false),
     103                 :            :     bIsInUndo(false),
     104                 :            :     bUpdate(true),
     105                 :            :     bUndoEnabled(true),
     106                 :            :     bOwnerOfRefDev(false),
     107                 :            :     bDowning(false),
     108                 :            :     bUseAutoColor(true),
     109                 :            :     bForceAutoColor(false),
     110                 :            :     bCallParaInsertedOrDeleted(false),
     111                 :            :     bImpConvertFirstCall(false),
     112                 :            :     bFirstWordCapitalization(true),
     113 [ +  - ][ +  - ]:      30636 :     mbLastTryMerge(false)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     114                 :            : {
     115                 :      30636 :     pEditEngine         = pEE;
     116                 :      30636 :     pRefDev             = NULL;
     117                 :      30636 :     pVirtDev            = NULL;
     118                 :      30636 :     pEmptyItemSet       = NULL;
     119                 :      30636 :     pActiveView         = NULL;
     120                 :      30636 :     pSpellInfo          = NULL;
     121                 :      30636 :     pConvInfo           = NULL;
     122                 :      30636 :     pTextObjectPool     = NULL;
     123                 :      30636 :     mpIMEInfos          = NULL;
     124                 :      30636 :     pStylePool          = NULL;
     125                 :      30636 :     pUndoManager        = NULL;
     126                 :      30636 :     pUndoMarkSelection  = NULL;
     127                 :      30636 :     pTextRanger         = NULL;
     128                 :      30636 :     pColorConfig        = NULL;
     129                 :      30636 :     pCTLOptions         = NULL;
     130                 :            : 
     131                 :      30636 :     nCurTextHeight      = 0;
     132                 :      30636 :     nCurTextHeightNTP   = 0;
     133                 :      30636 :     nBlockNotifications = 0;
     134                 :      30636 :     nBigTextObjectStart = 20;
     135                 :            : 
     136                 :      30636 :     nStretchX           = 100;
     137                 :      30636 :     nStretchY           = 100;
     138                 :            : 
     139                 :      30636 :     eDefLanguage        = LANGUAGE_DONTKNOW;
     140                 :      30636 :     maBackgroundColor   = COL_AUTO;
     141                 :            : 
     142                 :      30636 :     nAsianCompressionMode = text::CharacterCompressionType::NONE;
     143                 :            : 
     144                 :      30636 :     eDefaultHorizontalTextDirection = EE_HTEXTDIR_DEFAULT;
     145                 :            : 
     146                 :            : 
     147                 :      30636 :     aStatus.GetControlWord() =  EE_CNTRL_USECHARATTRIBS | EE_CNTRL_DOIDLEFORMAT |
     148                 :            :                                 EE_CNTRL_PASTESPECIAL | EE_CNTRL_UNDOATTRIBS |
     149                 :            :                                 EE_CNTRL_ALLOWBIGOBJS | EE_CNTRL_RTFSTYLESHEETS |
     150                 :      30636 :                                 EE_CNTRL_FORMAT100;
     151                 :            : 
     152                 :      30636 :     aSelEngine.SetFunctionSet( &aSelFuncSet );
     153                 :            : 
     154         [ +  - ]:      30636 :     aStatusTimer.SetTimeout( 200 );
     155         [ +  - ]:      30636 :     aStatusTimer.SetTimeoutHdl( LINK( this, ImpEditEngine, StatusTimerHdl ) );
     156                 :            : 
     157         [ +  - ]:      30636 :     aIdleFormatter.SetTimeout( 5 );
     158         [ +  - ]:      30636 :     aIdleFormatter.SetTimeoutHdl( LINK( this, ImpEditEngine, IdleFormatHdl ) );
     159                 :            : 
     160         [ +  - ]:      30636 :     aOnlineSpellTimer.SetTimeout( 100 );
     161         [ +  - ]:      30636 :     aOnlineSpellTimer.SetTimeoutHdl( LINK( this, ImpEditEngine, OnlineSpellHdl ) );
     162                 :            : 
     163 [ +  - ][ +  - ]:      30636 :     pRefDev             = EE_DLL().GetGlobalData()->GetStdRefDevice();
     164                 :            : 
     165                 :            :     // Access data already from here on!
     166         [ +  - ]:      30636 :     SetRefDevice( pRefDev );
     167         [ +  - ]:      30636 :     InitDoc( sal_False );
     168                 :            : 
     169                 :      30636 :     bCallParaInsertedOrDeleted = true;
     170                 :            : 
     171         [ +  - ]:      30636 :     aEditDoc.SetModifyHdl( LINK( this, ImpEditEngine, DocModified ) );
     172                 :      30636 : }
     173                 :            : 
     174 [ +  - ][ +  - ]:      30388 : ImpEditEngine::~ImpEditEngine()
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     175                 :            : {
     176         [ +  - ]:      30388 :     aStatusTimer.Stop();
     177         [ +  - ]:      30388 :     aOnlineSpellTimer.Stop();
     178         [ +  - ]:      30388 :     aIdleFormatter.Stop();
     179                 :            : 
     180                 :            :     // Destroying templates may otherwise cause unnecessary formatting,
     181                 :            :     // when a parent template is destroyed.
     182                 :            :     // And this after the destruction of the data!
     183                 :      30388 :     bDowning = true;
     184         [ +  - ]:      30388 :     SetUpdateMode( sal_False );
     185                 :            : 
     186 [ +  + ][ +  - ]:      30388 :     delete pVirtDev;
     187 [ +  + ][ +  - ]:      30388 :     delete pEmptyItemSet;
     188 [ +  + ][ +  - ]:      30388 :     delete pUndoManager;
     189 [ -  + ][ #  # ]:      30388 :     delete pTextRanger;
     190 [ -  + ][ #  # ]:      30388 :     delete mpIMEInfos;
     191 [ +  + ][ +  - ]:      30388 :     delete pColorConfig;
     192 [ +  + ][ +  - ]:      30388 :     delete pCTLOptions;
     193         [ +  + ]:      30388 :     if ( bOwnerOfRefDev )
     194 [ +  - ][ +  - ]:       4996 :         delete pRefDev;
     195         [ -  + ]:      30388 :     delete pSpellInfo;
     196         [ -  + ]:      60776 : }
     197                 :            : 
     198                 :      62186 : void ImpEditEngine::SetRefDevice( OutputDevice* pRef )
     199                 :            : {
     200         [ +  + ]:      62186 :     if ( bOwnerOfRefDev )
     201         [ +  - ]:       4228 :         delete pRefDev;
     202                 :            : 
     203                 :      62186 :     pRefDev = pRef;
     204                 :      62186 :     bOwnerOfRefDev = false;
     205                 :            : 
     206         [ +  + ]:      62186 :     if ( !pRef )
     207                 :      15533 :         pRefDev = EE_DLL().GetGlobalData()->GetStdRefDevice();
     208                 :            : 
     209         [ +  - ]:      62186 :     nOnePixelInRef = (sal_uInt16)pRefDev->PixelToLogic( Size( 1, 0 ) ).Width();
     210                 :            : 
     211         [ +  + ]:      62186 :     if ( IsFormatted() )
     212                 :            :     {
     213                 :      27215 :         FormatFullDoc();
     214                 :      27215 :         UpdateViews( (EditView*) 0);
     215                 :            :     }
     216                 :      62186 : }
     217                 :            : 
     218                 :      18602 : void ImpEditEngine::SetRefMapMode( const MapMode& rMapMode )
     219                 :            : {
     220         [ +  + ]:      18602 :     if ( GetRefDevice()->GetMapMode() == rMapMode )
     221                 :      18602 :         return;
     222                 :            : 
     223                 :            :     // When RefDev == GlobalRefDev => create own!
     224 [ +  - ][ +  + ]:       9254 :     if ( !bOwnerOfRefDev && ( pRefDev == EE_DLL().GetGlobalData()->GetStdRefDevice() ) )
                 [ +  + ]
     225                 :            :     {
     226         [ +  - ]:       9228 :         pRefDev = new VirtualDevice;
     227         [ +  - ]:       9228 :         pRefDev->SetMapMode( MAP_TWIP );
     228                 :       9228 :         SetRefDevice( pRefDev );
     229                 :       9228 :         bOwnerOfRefDev = true;
     230                 :            :     }
     231                 :       9254 :     pRefDev->SetMapMode( rMapMode );
     232         [ +  - ]:       9254 :     nOnePixelInRef = (sal_uInt16)pRefDev->PixelToLogic( Size( 1, 0 ) ).Width();
     233         [ +  + ]:       9254 :     if ( IsFormatted() )
     234                 :            :     {
     235                 :       7012 :         FormatFullDoc();
     236                 :       7012 :         UpdateViews( (EditView*) 0);
     237                 :            :     }
     238                 :            : }
     239                 :            : 
     240                 :     309596 : void ImpEditEngine::InitDoc(bool bKeepParaAttribs)
     241                 :            : {
     242                 :     309596 :     sal_uInt16 nParas = aEditDoc.Count();
     243 [ +  + ][ +  + ]:     455894 :     for ( sal_uInt16 n = bKeepParaAttribs ? 1 : 0; n < nParas; n++ )
     244                 :            :     {
     245         [ +  + ]:     146298 :         if ( aEditDoc[n]->GetStyleSheet() )
     246                 :      19276 :             EndListening( *aEditDoc[n]->GetStyleSheet(), sal_False );
     247                 :            :     }
     248                 :            : 
     249         [ +  + ]:     309596 :     if ( bKeepParaAttribs )
     250                 :     143029 :         aEditDoc.RemoveText();
     251                 :            :     else
     252                 :     166567 :         aEditDoc.Clear();
     253                 :            : 
     254                 :     309596 :     GetParaPortions().Reset();
     255                 :            : 
     256         [ +  - ]:     309596 :     ParaPortion* pIniPortion = new ParaPortion( aEditDoc[0] );
     257                 :     309596 :     GetParaPortions().Insert(0, pIniPortion);
     258                 :            : 
     259                 :     309596 :     bFormatted = false;
     260                 :            : 
     261         [ +  + ]:     309596 :     if ( IsCallParaInsertedOrDeleted() )
     262                 :            :     {
     263                 :     278960 :         GetEditEnginePtr()->ParagraphDeleted( EE_PARA_ALL );
     264                 :     278960 :         GetEditEnginePtr()->ParagraphInserted( 0 );
     265                 :            :     }
     266                 :            : 
     267         [ +  + ]:     309596 :     if ( GetStatus().DoOnlineSpelling() )
     268                 :      28215 :         aEditDoc.GetObject( 0 )->CreateWrongList();
     269                 :     309596 : }
     270                 :            : 
     271                 :          0 : EditPaM ImpEditEngine::DeleteSelected( EditSelection aSel )
     272                 :            : {
     273                 :          0 :     EditPaM aPaM ( ImpDeleteSelection( aSel ) );
     274                 :          0 :     return aPaM;
     275                 :            : }
     276                 :            : 
     277                 :       3911 : XubString ImpEditEngine::GetSelected( const EditSelection& rSel, const LineEnd eEnd  ) const
     278                 :            : {
     279         [ +  - ]:       3911 :     XubString aText;
     280 [ +  - ][ +  + ]:       3911 :     if ( !rSel.HasRange() )
     281                 :            :         return aText;
     282                 :            : 
     283 [ +  - ][ +  - ]:       3584 :     String aSep = EditDoc::GetSepStr( eEnd );
     284                 :            : 
     285         [ +  - ]:       3584 :     EditSelection aSel( rSel );
     286         [ +  - ]:       3584 :     aSel.Adjust( aEditDoc );
     287                 :            : 
     288         [ +  - ]:       3584 :     ContentNode* pStartNode = aSel.Min().GetNode();
     289         [ +  - ]:       3584 :     ContentNode* pEndNode = aSel.Max().GetNode();
     290         [ +  - ]:       3584 :     sal_uInt16 nStartNode = aEditDoc.GetPos( pStartNode );
     291         [ +  - ]:       3584 :     sal_uInt16 nEndNode = aEditDoc.GetPos( pEndNode );
     292                 :            : 
     293                 :            :     OSL_ENSURE( nStartNode <= nEndNode, "Selection not sorted ?" );
     294                 :            : 
     295                 :            :     // iterate over the paragraphs ...
     296         [ +  + ]:       7221 :     for ( sal_uInt16 nNode = nStartNode; nNode <= nEndNode; nNode++ )
     297                 :            :     {
     298                 :            :         OSL_ENSURE( aEditDoc.GetObject( nNode ), "Node not found: GetSelected" );
     299         [ +  - ]:       3637 :         const ContentNode* pNode = aEditDoc.GetObject( nNode );
     300                 :            : 
     301                 :       3637 :         xub_StrLen nStartPos = 0;
     302         [ +  - ]:       3637 :         xub_StrLen nEndPos = pNode->Len();
     303         [ +  + ]:       3637 :         if ( nNode == nStartNode )
     304                 :       3584 :             nStartPos = aSel.Min().GetIndex();
     305         [ +  + ]:       3637 :         if ( nNode == nEndNode ) // can also be == nStart!
     306                 :       3584 :             nEndPos = aSel.Max().GetIndex();
     307                 :            : 
     308 [ +  - ][ +  - ]:       3637 :         aText += aEditDoc.GetParaAsString( pNode, nStartPos, nEndPos );
                 [ +  - ]
     309         [ +  + ]:       3637 :         if ( nNode < nEndNode )
     310         [ +  - ]:         53 :             aText += aSep;
     311                 :            :     }
     312         [ +  - ]:       3911 :     return aText;
     313                 :            : }
     314                 :            : 
     315                 :          0 : sal_Bool ImpEditEngine::MouseButtonDown( const MouseEvent& rMEvt, EditView* pView )
     316                 :            : {
     317         [ #  # ]:          0 :     GetSelEngine().SetCurView( pView );
     318         [ #  # ]:          0 :     SetActiveView( pView );
     319                 :            : 
     320         [ #  # ]:          0 :     if ( GetAutoCompleteText().Len() )
     321 [ #  # ][ #  # ]:          0 :         SetAutoCompleteText( String(), sal_True );
                 [ #  # ]
     322                 :            : 
     323         [ #  # ]:          0 :     GetSelEngine().SelMouseButtonDown( rMEvt );
     324                 :            :     // Special treatment
     325         [ #  # ]:          0 :     EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
     326         [ #  # ]:          0 :     if ( !rMEvt.IsShift() )
     327                 :            :     {
     328         [ #  # ]:          0 :         if ( rMEvt.GetClicks() == 2 )
     329                 :            :         {
     330                 :            :             // So that the SelectionEngine knows about the anchor.
     331         [ #  # ]:          0 :             aSelEngine.CursorPosChanging( sal_True, sal_False );
     332                 :            : 
     333         [ #  # ]:          0 :             EditSelection aNewSelection( SelectWord( aCurSel ) );
     334         [ #  # ]:          0 :             pView->pImpEditView->DrawSelection();
     335         [ #  # ]:          0 :             pView->pImpEditView->SetEditSelection( aNewSelection );
     336         [ #  # ]:          0 :             pView->pImpEditView->DrawSelection();
     337         [ #  # ]:          0 :             pView->ShowCursor( sal_True, sal_True );
     338                 :            :         }
     339         [ #  # ]:          0 :         else if ( rMEvt.GetClicks() == 3 )
     340                 :            :         {
     341                 :            :             // So that the SelectionEngine knows about the anchor.
     342         [ #  # ]:          0 :             aSelEngine.CursorPosChanging( sal_True, sal_False );
     343                 :            : 
     344         [ #  # ]:          0 :             EditSelection aNewSelection( aCurSel );
     345                 :          0 :             aNewSelection.Min().SetIndex( 0 );
     346 [ #  # ][ #  # ]:          0 :             aNewSelection.Max().SetIndex( aCurSel.Min().GetNode()->Len() );
     347         [ #  # ]:          0 :             pView->pImpEditView->DrawSelection();
     348         [ #  # ]:          0 :             pView->pImpEditView->SetEditSelection( aNewSelection );
     349         [ #  # ]:          0 :             pView->pImpEditView->DrawSelection();
     350         [ #  # ]:          0 :             pView->ShowCursor( sal_True, sal_True );
     351                 :            :         }
     352                 :            :     }
     353                 :          0 :     return sal_True;
     354                 :            : }
     355                 :            : 
     356                 :          0 : void ImpEditEngine::Command( const CommandEvent& rCEvt, EditView* pView )
     357                 :            : {
     358                 :          0 :     GetSelEngine().SetCurView( pView );
     359                 :          0 :     SetActiveView( pView );
     360         [ #  # ]:          0 :     if ( rCEvt.GetCommand() == COMMAND_VOICE )
     361                 :            :     {
     362                 :          0 :         const CommandVoiceData* pData = rCEvt.GetVoiceData();
     363         [ #  # ]:          0 :         if ( pData->GetType() == VOICECOMMANDTYPE_DICTATION )
     364                 :            :         {
     365                 :            :             // Turn functions into KeyEvent if no corresponding method to
     366                 :            :             // EditView/EditEngine so that Undo remains consistent.
     367                 :          0 :             SfxPoolItem* pNewAttr = NULL;
     368                 :            : 
     369   [ #  #  #  #  :          0 :             switch ( pData->GetCommand() )
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     370                 :            :             {
     371                 :            :                 case DICTATIONCOMMAND_UNKNOWN:
     372                 :            :                 {
     373                 :          0 :                     pView->InsertText( pData->GetText() );
     374                 :            :                 }
     375                 :          0 :                 break;
     376                 :            :                 case DICTATIONCOMMAND_NEWPARAGRAPH:
     377                 :            :                 {
     378 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RETURN, 0 ) ) );
     379                 :            :                 }
     380                 :          0 :                 break;
     381                 :            :                 case DICTATIONCOMMAND_NEWLINE:
     382                 :            :                 {
     383 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RETURN, KEY_SHIFT ) ) );
     384                 :            :                 }
     385                 :          0 :                 break;
     386                 :            :                 case DICTATIONCOMMAND_TAB:
     387                 :            :                 {
     388 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_TAB, 0 ) ) );
     389                 :            :                 }
     390                 :          0 :                 break;
     391                 :            :                 case DICTATIONCOMMAND_LEFT:
     392                 :            :                 {
     393 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1  ) ) );
     394                 :            :                 }
     395                 :          0 :                 break;
     396                 :            :                 case DICTATIONCOMMAND_RIGHT:
     397                 :            :                 {
     398 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RIGHT, KEY_MOD1  ) ) );
     399                 :            :                 }
     400                 :          0 :                 break;
     401                 :            :                 case DICTATIONCOMMAND_UP:
     402                 :            :                 {
     403 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_UP, 0 ) ) );
     404                 :            :                 }
     405                 :          0 :                 break;
     406                 :            :                 case DICTATIONCOMMAND_DOWN:
     407                 :            :                 {
     408 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_UP, 0 ) ) );
     409                 :            :                 }
     410                 :          0 :                 break;
     411                 :            :                 case DICTATIONCOMMAND_UNDO:
     412                 :            :                 {
     413                 :          0 :                     pView->Undo();
     414                 :            :                 }
     415                 :          0 :                 break;
     416                 :            :                 case DICTATIONCOMMAND_DEL:
     417                 :            :                 {
     418 [ #  # ][ #  # ]:          0 :                     pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1|KEY_SHIFT  ) ) );
     419                 :          0 :                     pView->DeleteSelected();
     420                 :            :                 }
     421                 :          0 :                 break;
     422                 :            :                 case DICTATIONCOMMAND_BOLD_ON:
     423                 :            :                 {
     424         [ #  # ]:          0 :                     pNewAttr = new SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT );
     425                 :            :                 }
     426                 :          0 :                 break;
     427                 :            :                 case DICTATIONCOMMAND_BOLD_OFF:
     428                 :            :                 {
     429         [ #  # ]:          0 :                     pNewAttr = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT );
     430                 :            :                 }
     431                 :          0 :                 break;
     432                 :            :                 case DICTATIONCOMMAND_ITALIC_ON:
     433                 :            :                 {
     434         [ #  # ]:          0 :                     pNewAttr = new SvxPostureItem( ITALIC_NORMAL, EE_CHAR_ITALIC );
     435                 :            :                 }
     436                 :          0 :                 break;
     437                 :            :                 case DICTATIONCOMMAND_ITALIC_OFF:
     438                 :            :                 {
     439         [ #  # ]:          0 :                     pNewAttr = new SvxPostureItem( ITALIC_NORMAL, EE_CHAR_ITALIC );
     440                 :            :                 }
     441                 :          0 :                 break;
     442                 :            :                 case DICTATIONCOMMAND_UNDERLINE_ON:
     443                 :            :                 {
     444         [ #  # ]:          0 :                     pNewAttr = new SvxUnderlineItem( UNDERLINE_SINGLE, EE_CHAR_UNDERLINE );
     445                 :            :                 }
     446                 :          0 :                 break;
     447                 :            :                 case DICTATIONCOMMAND_UNDERLINE_OFF:
     448                 :            :                 {
     449         [ #  # ]:          0 :                     pNewAttr = new SvxUnderlineItem( UNDERLINE_NONE, EE_CHAR_UNDERLINE );
     450                 :            :                 }
     451                 :          0 :                 break;
     452                 :            :             }
     453                 :            : 
     454         [ #  # ]:          0 :             if ( pNewAttr )
     455                 :            :             {
     456 [ #  # ][ #  # ]:          0 :                 SfxItemSet aSet( GetEmptyItemSet() );
     457         [ #  # ]:          0 :                 aSet.Put( *pNewAttr );
     458         [ #  # ]:          0 :                 pView->SetAttribs( aSet );
     459 [ #  # ][ #  # ]:          0 :                 delete pNewAttr;
                 [ #  # ]
     460                 :            :             }
     461                 :            :         }
     462                 :            :     }
     463         [ #  # ]:          0 :     else if ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT )
     464                 :            :     {
     465         [ #  # ]:          0 :         pView->DeleteSelected();
     466 [ #  # ][ #  # ]:          0 :         delete mpIMEInfos;
     467         [ #  # ]:          0 :         EditPaM aPaM = pView->GetImpEditView()->GetEditSelection().Max();
     468 [ #  # ][ #  # ]:          0 :         String aOldTextAfterStartPos = aPaM.GetNode()->Copy( aPaM.GetIndex() );
     469         [ #  # ]:          0 :         sal_uInt16 nMax = aOldTextAfterStartPos.Search( CH_FEATURE );
     470         [ #  # ]:          0 :         if ( nMax != STRING_NOTFOUND )  // don't overwrite features!
     471         [ #  # ]:          0 :             aOldTextAfterStartPos.Erase( nMax );
     472 [ #  # ][ #  # ]:          0 :         mpIMEInfos = new ImplIMEInfos( aPaM, aOldTextAfterStartPos );
     473         [ #  # ]:          0 :         mpIMEInfos->bWasCursorOverwrite = !pView->IsInsertMode();
     474 [ #  # ][ #  # ]:          0 :         UndoActionStart( EDITUNDO_INSERT );
     475                 :            :     }
     476         [ #  # ]:          0 :     else if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
     477                 :            :     {
     478                 :            :         OSL_ENSURE( mpIMEInfos, "COMMAND_ENDEXTTEXTINPUT => Kein Start ?" );
     479         [ #  # ]:          0 :         if( mpIMEInfos )
     480                 :            :         {
     481                 :            :             // #102812# convert quotes in IME text
     482                 :            :             // works on the last input character, this is escpecially in Korean text often done
     483                 :            :             // quotes that are inside of the string are not replaced!
     484                 :            :             // Borrowed from sw: edtwin.cxx
     485         [ #  # ]:          0 :             if ( mpIMEInfos->nLen )
     486                 :            :             {
     487         [ #  # ]:          0 :                 EditSelection aSel( mpIMEInfos->aPos );
     488                 :          0 :                 aSel.Min().GetIndex() += mpIMEInfos->nLen-1;
     489                 :          0 :                 aSel.Max().GetIndex() =
     490                 :          0 :                     aSel.Max().GetIndex() + mpIMEInfos->nLen;
     491                 :            :                 // #102812# convert quotes in IME text
     492                 :            :                 // works on the last input character, this is escpecially in Korean text often done
     493                 :            :                 // quotes that are inside of the string are not replaced!
     494 [ #  # ][ #  # ]:          0 :                 const sal_Unicode nCharCode = aSel.Min().GetNode()->GetChar( aSel.Min().GetIndex() );
     495 [ #  # ][ #  # ]:          0 :                 if ( ( GetStatus().DoAutoCorrect() ) && ( ( nCharCode == '\"' ) || ( nCharCode == '\'' ) ) )
         [ #  # ][ #  # ]
     496                 :            :                 {
     497 [ #  # ][ #  # ]:          0 :                     aSel = DeleteSelected( aSel );
                 [ #  # ]
     498 [ #  # ][ #  # ]:          0 :                     aSel = AutoCorrect( aSel, nCharCode, mpIMEInfos->bWasCursorOverwrite );
     499         [ #  # ]:          0 :                     pView->pImpEditView->SetEditSelection( aSel );
     500                 :            :                 }
     501                 :            :             }
     502                 :            : 
     503                 :          0 :             ParaPortion* pPortion = FindParaPortion( mpIMEInfos->aPos.GetNode() );
     504                 :          0 :             pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex(), 0 );
     505                 :            : 
     506                 :          0 :             sal_Bool bWasCursorOverwrite = mpIMEInfos->bWasCursorOverwrite;
     507                 :            : 
     508         [ #  # ]:          0 :             delete mpIMEInfos;
     509                 :          0 :             mpIMEInfos = NULL;
     510                 :            : 
     511                 :          0 :             FormatAndUpdate( pView );
     512                 :            : 
     513                 :          0 :             pView->SetInsertMode( !bWasCursorOverwrite );
     514                 :            :         }
     515                 :          0 :         UndoActionEnd( EDITUNDO_INSERT );
     516                 :            :     }
     517         [ #  # ]:          0 :     else if ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT )
     518                 :            :     {
     519                 :            :         OSL_ENSURE( mpIMEInfos, "COMMAND_EXTTEXTINPUT => No Start ?" );
     520         [ #  # ]:          0 :         if( mpIMEInfos )
     521                 :            :         {
     522         [ #  # ]:          0 :             const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
     523                 :            : 
     524         [ #  # ]:          0 :             if ( !pData->IsOnlyCursorChanged() )
     525                 :            :             {
     526         [ #  # ]:          0 :                 EditSelection aSel( mpIMEInfos->aPos );
     527                 :          0 :                 aSel.Max().GetIndex() =
     528                 :          0 :                     aSel.Max().GetIndex() + mpIMEInfos->nLen;
     529 [ #  # ][ #  # ]:          0 :                 aSel = DeleteSelected( aSel );
                 [ #  # ]
     530 [ #  # ][ #  # ]:          0 :                 aSel = ImpInsertText( aSel, pData->GetText() );
     531                 :            : 
     532         [ #  # ]:          0 :                 if ( mpIMEInfos->bWasCursorOverwrite )
     533                 :            :                 {
     534                 :          0 :                     sal_uInt16 nOldIMETextLen = mpIMEInfos->nLen;
     535                 :          0 :                     sal_uInt16 nNewIMETextLen = pData->GetText().Len();
     536                 :            : 
     537         [ #  # ]:          0 :                     if ( ( nOldIMETextLen > nNewIMETextLen ) &&
           [ #  #  #  # ]
     538                 :          0 :                          ( nNewIMETextLen < mpIMEInfos->aOldTextAfterStartPos.Len() ) )
     539                 :            :                     {
     540                 :            :                         // restore old characters
     541                 :          0 :                         sal_uInt16 nRestore = nOldIMETextLen - nNewIMETextLen;
     542         [ #  # ]:          0 :                         EditPaM aPaM( mpIMEInfos->aPos );
     543                 :          0 :                         aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
     544 [ #  # ][ #  # ]:          0 :                         ImpInsertText( aPaM, mpIMEInfos->aOldTextAfterStartPos.Copy( nNewIMETextLen, nRestore ) );
         [ #  # ][ #  # ]
     545                 :            :                     }
     546   [ #  #  #  # ]:          0 :                     else if ( ( nOldIMETextLen < nNewIMETextLen ) &&
                 [ #  # ]
     547                 :          0 :                               ( nOldIMETextLen < mpIMEInfos->aOldTextAfterStartPos.Len() ) )
     548                 :            :                     {
     549                 :            :                         // overwrite
     550                 :          0 :                         sal_uInt16 nOverwrite = nNewIMETextLen - nOldIMETextLen;
     551         [ #  # ]:          0 :                         if ( ( nOldIMETextLen + nOverwrite ) > mpIMEInfos->aOldTextAfterStartPos.Len() )
     552                 :          0 :                             nOverwrite = mpIMEInfos->aOldTextAfterStartPos.Len() - nOldIMETextLen;
     553                 :            :                         OSL_ENSURE( nOverwrite && (nOverwrite < 0xFF00), "IME Overwrite?!" );
     554         [ #  # ]:          0 :                         EditPaM aPaM( mpIMEInfos->aPos );
     555                 :          0 :                         aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
     556         [ #  # ]:          0 :                         EditSelection _aSel( aPaM );
     557                 :          0 :                         _aSel.Max().GetIndex() =
     558                 :          0 :                             _aSel.Max().GetIndex() + nOverwrite;
     559 [ #  # ][ #  # ]:          0 :                         DeleteSelected( _aSel );
     560                 :            :                     }
     561                 :            :                 }
     562         [ #  # ]:          0 :                 if ( pData->GetTextAttr() )
     563                 :            :                 {
     564         [ #  # ]:          0 :                     mpIMEInfos->CopyAttribs( pData->GetTextAttr(), pData->GetText().Len() );
     565                 :          0 :                     mpIMEInfos->bCursor = pData->IsCursorVisible();
     566                 :            :                 }
     567                 :            :                 else
     568                 :            :                 {
     569         [ #  # ]:          0 :                     mpIMEInfos->DestroyAttribs();
     570                 :          0 :                     mpIMEInfos->nLen = pData->GetText().Len();
     571                 :            :                 }
     572                 :            : 
     573 [ #  # ][ #  # ]:          0 :                 ParaPortion* pPortion = FindParaPortion( mpIMEInfos->aPos.GetNode() );
     574         [ #  # ]:          0 :                 pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex(), 0 );
     575         [ #  # ]:          0 :                 FormatAndUpdate( pView );
     576                 :            :             }
     577                 :            : 
     578 [ #  # ][ #  # ]:          0 :             EditSelection aNewSel = EditPaM( mpIMEInfos->aPos.GetNode(), mpIMEInfos->aPos.GetIndex()+pData->GetCursorPos() );
                 [ #  # ]
     579 [ #  # ][ #  # ]:          0 :             pView->SetSelection( CreateESel( aNewSel ) );
     580         [ #  # ]:          0 :             pView->SetInsertMode( !pData->IsCursorOverwrite() );
     581                 :            : 
     582         [ #  # ]:          0 :             if ( pData->IsCursorVisible() )
     583         [ #  # ]:          0 :                 pView->ShowCursor();
     584                 :            :             else
     585         [ #  # ]:          0 :                 pView->HideCursor();
     586                 :            :         }
     587                 :            :     }
     588         [ #  # ]:          0 :     else if ( rCEvt.GetCommand() == COMMAND_INPUTCONTEXTCHANGE )
     589                 :            :     {
     590                 :            :     }
     591         [ #  # ]:          0 :     else if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
     592                 :            :     {
     593 [ #  # ][ #  # ]:          0 :         if ( mpIMEInfos && mpIMEInfos->nLen )
     594                 :            :         {
     595         [ #  # ]:          0 :             EditPaM aPaM( pView->pImpEditView->GetEditSelection().Max() );
     596 [ #  # ][ #  # ]:          0 :             Rectangle aR1 = PaMtoEditCursor( aPaM, 0 );
     597                 :            : 
     598                 :          0 :             sal_uInt16 nInputEnd = mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen;
     599                 :            : 
     600         [ #  # ]:          0 :             if ( !IsFormatted() )
     601         [ #  # ]:          0 :                 FormatDoc();
     602                 :            : 
     603 [ #  # ][ #  # ]:          0 :             ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( GetEditDoc().GetPos( aPaM.GetNode() ) );
                 [ #  # ]
     604         [ #  # ]:          0 :             sal_uInt16 nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_True );
     605         [ #  # ]:          0 :             const EditLine* pLine = pParaPortion->GetLines()[nLine];
     606 [ #  # ][ #  # ]:          0 :             if ( pLine && ( nInputEnd > pLine->GetEnd() ) )
                 [ #  # ]
     607                 :          0 :                 nInputEnd = pLine->GetEnd();
     608 [ #  # ][ #  # ]:          0 :             Rectangle aR2 = PaMtoEditCursor( EditPaM( aPaM.GetNode(), nInputEnd ), GETCRSR_ENDOFLINE );
                 [ #  # ]
     609         [ #  # ]:          0 :             Rectangle aRect = pView->GetImpEditView()->GetWindowPos( aR1 );
     610 [ #  # ][ #  # ]:          0 :             pView->GetWindow()->SetCursorRect( &aRect, aR2.Left()-aR1.Right() );
     611                 :            :         }
     612                 :            :         else
     613                 :            :         {
     614                 :          0 :             pView->GetWindow()->SetCursorRect();
     615                 :            :         }
     616                 :            :     }
     617         [ #  # ]:          0 :     else if ( rCEvt.GetCommand() == COMMAND_SELECTIONCHANGE )
     618                 :            :     {
     619         [ #  # ]:          0 :         const CommandSelectionChangeData *pData = rCEvt.GetSelectionChangeData();
     620                 :            : 
     621         [ #  # ]:          0 :         ESelection aSelection = pView->GetSelection();
     622                 :          0 :         aSelection.Adjust();
     623                 :            : 
     624 [ #  # ][ #  # ]:          0 :         if( pView->HasSelection() )
     625                 :            :         {
     626                 :          0 :             aSelection.nEndPos = aSelection.nStartPos;
     627                 :          0 :             aSelection.nStartPos += pData->GetStart();
     628                 :          0 :             aSelection.nEndPos += pData->GetEnd();
     629                 :            :         }
     630                 :            :         else
     631                 :            :         {
     632                 :          0 :             aSelection.nStartPos = pData->GetStart();
     633                 :          0 :             aSelection.nEndPos = pData->GetEnd();
     634                 :            :         }
     635         [ #  # ]:          0 :         pView->SetSelection( aSelection );
     636                 :            :     }
     637         [ #  # ]:          0 :     else if ( rCEvt.GetCommand() == COMMAND_PREPARERECONVERSION )
     638                 :            :     {
     639         [ #  # ]:          0 :         if ( pView->HasSelection() )
     640                 :            :         {
     641         [ #  # ]:          0 :             ESelection aSelection = pView->GetSelection();
     642                 :          0 :             aSelection.Adjust();
     643                 :            : 
     644         [ #  # ]:          0 :             if ( aSelection.nStartPara != aSelection.nEndPara )
     645                 :            :             {
     646         [ #  # ]:          0 :                 xub_StrLen aParaLen = pEditEngine->GetTextLen( aSelection.nStartPara );
     647                 :          0 :                 aSelection.nEndPara = aSelection.nStartPara;
     648                 :          0 :                 aSelection.nEndPos = aParaLen;
     649         [ #  # ]:          0 :                 pView->SetSelection( aSelection );
     650                 :            :             }
     651                 :            :         }
     652                 :            :     }
     653                 :            : 
     654                 :          0 :     GetSelEngine().Command( rCEvt );
     655                 :          0 : }
     656                 :            : 
     657                 :          0 : sal_Bool ImpEditEngine::MouseButtonUp( const MouseEvent& rMEvt, EditView* pView )
     658                 :            : {
     659         [ #  # ]:          0 :     GetSelEngine().SetCurView( pView );
     660         [ #  # ]:          0 :     GetSelEngine().SelMouseButtonUp( rMEvt );
     661                 :          0 :     bInSelection = false;
     662                 :            :     // Special treatments
     663         [ #  # ]:          0 :     EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
     664 [ #  # ][ #  # ]:          0 :     if ( !aCurSel.HasRange() )
     665                 :            :     {
     666 [ #  # ][ #  # ]:          0 :         if ( ( rMEvt.GetClicks() == 1 ) && rMEvt.IsLeft() && !rMEvt.IsMod2() )
         [ #  # ][ #  # ]
     667                 :            :         {
     668         [ #  # ]:          0 :             const SvxFieldItem* pFld = pView->GetFieldUnderMousePointer();
     669         [ #  # ]:          0 :             if ( pFld )
     670                 :            :             {
     671         [ #  # ]:          0 :                 EditPaM aPaM( aCurSel.Max() );
     672 [ #  # ][ #  # ]:          0 :                 sal_uInt16 nPara = GetEditDoc().GetPos( aPaM.GetNode() );
     673         [ #  # ]:          0 :                 GetEditEnginePtr()->FieldClicked( *pFld, nPara, aPaM.GetIndex() );
     674                 :            :             }
     675                 :            :         }
     676                 :            :     }
     677                 :          0 :     return sal_True;
     678                 :            : }
     679                 :            : 
     680                 :          0 : sal_Bool ImpEditEngine::MouseMove( const MouseEvent& rMEvt, EditView* pView )
     681                 :            : {
     682                 :            :     // MouseMove is called directly after ShowQuickHelp()!
     683                 :          0 :     GetSelEngine().SetCurView( pView );
     684                 :          0 :     GetSelEngine().SelMouseMove( rMEvt );
     685                 :          0 :     return sal_True;
     686                 :            : }
     687                 :            : 
     688                 :         45 : EditPaM ImpEditEngine::InsertText(const EditSelection& aSel, const String& rStr)
     689                 :            : {
     690                 :         45 :     EditPaM aPaM = ImpInsertText( aSel, rStr );
     691                 :         45 :     return aPaM;
     692                 :            : }
     693                 :            : 
     694                 :     135931 : EditPaM ImpEditEngine::Clear()
     695                 :            : {
     696         [ +  - ]:     135931 :     InitDoc( sal_False );
     697                 :            : 
     698         [ +  - ]:     135931 :     EditPaM aPaM = aEditDoc.GetStartPaM();
     699         [ +  - ]:     135931 :     EditSelection aSel( aPaM );
     700                 :            : 
     701                 :     135931 :     nCurTextHeight = 0;
     702                 :     135931 :     nCurTextHeightNTP = 0;
     703                 :            : 
     704         [ +  - ]:     135931 :     ResetUndoManager();
     705                 :            : 
     706         [ -  + ]:     135931 :     for (size_t nView = aEditViews.size(); nView; )
     707                 :            :     {
     708                 :          0 :         EditView* pView = aEditViews[--nView];
     709                 :            :         DBG_CHKOBJ( pView, EditView, 0 );
     710         [ #  # ]:          0 :         pView->pImpEditView->SetEditSelection( aSel );
     711                 :            :     }
     712                 :            : 
     713                 :     135931 :     return aPaM;
     714                 :            : }
     715                 :            : 
     716                 :     143029 : EditPaM ImpEditEngine::RemoveText()
     717                 :            : {
     718         [ +  - ]:     143029 :     InitDoc( sal_True );
     719                 :            : 
     720         [ +  - ]:     143029 :     EditPaM aStartPaM = aEditDoc.GetStartPaM();
     721         [ +  - ]:     143029 :     EditSelection aEmptySel( aStartPaM, aStartPaM );
     722         [ +  + ]:     143126 :     for (size_t nView = 0; nView < aEditViews.size(); ++nView)
     723                 :            :     {
     724                 :         97 :         EditView* pView = aEditViews[nView];
     725                 :            :         DBG_CHKOBJ( pView, EditView, 0 );
     726         [ +  - ]:         97 :         pView->pImpEditView->SetEditSelection( aEmptySel );
     727                 :            :     }
     728         [ +  - ]:     143029 :     ResetUndoManager();
     729         [ +  - ]:     143029 :     return aEditDoc.GetStartPaM();
     730                 :            : }
     731                 :            : 
     732                 :            : 
     733                 :     143029 : void ImpEditEngine::SetText( const XubString& rText )
     734                 :            : {
     735                 :            :     // RemoveText deletes the undo list!
     736         [ +  - ]:     143029 :     EditPaM aStartPaM = RemoveText();
     737                 :     143029 :     sal_Bool bUndoCurrentlyEnabled = IsUndoEnabled();
     738                 :            :     // The text inserted manually can not be made reversable by the user
     739         [ +  - ]:     143029 :     EnableUndo( sal_False );
     740                 :            : 
     741         [ +  - ]:     143029 :     EditSelection aEmptySel( aStartPaM, aStartPaM );
     742         [ +  - ]:     143029 :     EditPaM aPaM = aStartPaM;
     743         [ +  + ]:     143029 :     if ( rText.Len() )
     744 [ +  - ][ +  - ]:       5456 :         aPaM = ImpInsertText( aEmptySel, rText );
     745                 :            : 
     746         [ +  + ]:     143126 :     for (size_t nView = 0; nView < aEditViews.size(); ++nView)
     747                 :            :     {
     748                 :         97 :         EditView* pView = aEditViews[nView];
     749                 :            :         DBG_CHKOBJ( pView, EditView, 0 );
     750 [ +  - ][ +  - ]:         97 :         pView->pImpEditView->SetEditSelection( EditSelection( aPaM, aPaM ) );
     751                 :            :         //  If no text then also no Format&Update
     752                 :            :         // => The text remains.
     753 [ +  + ][ -  + ]:         97 :         if ( !rText.Len() && GetUpdateMode() )
                 [ -  + ]
     754                 :            :         {
     755         [ #  # ]:          0 :             Rectangle aTmpRec( pView->GetOutputArea().TopLeft(),
     756         [ #  # ]:          0 :                                 Size( aPaperSize.Width(), nCurTextHeight ) );
     757 [ #  # ][ #  # ]:          0 :             aTmpRec.Intersection( pView->GetOutputArea() );
     758 [ #  # ][ #  # ]:          0 :             pView->GetWindow()->Invalidate( aTmpRec );
     759                 :            :         }
     760                 :            :     }
     761         [ +  + ]:     143029 :     if( !rText.Len() ) {    // otherwise it must be invalidated later, !bFormatted is enough.
     762                 :     137573 :         nCurTextHeight = 0;
     763                 :     137573 :         nCurTextHeightNTP = 0;
     764                 :            :     }
     765         [ +  - ]:     143029 :     EnableUndo( bUndoCurrentlyEnabled );
     766                 :            :     OSL_ENSURE( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "Undo after SetText?" );
     767                 :     143029 : }
     768                 :            : 
     769                 :            : 
     770                 :     517139 : const SfxItemSet& ImpEditEngine::GetEmptyItemSet()
     771                 :            : {
     772         [ +  + ]:     517139 :     if ( !pEmptyItemSet )
     773                 :            :     {
     774         [ +  - ]:       4931 :         pEmptyItemSet = new SfxItemSet( aEditDoc.GetItemPool(), EE_ITEMS_START, EE_ITEMS_END );
     775         [ +  + ]:     241619 :         for ( sal_uInt16 nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++)
     776                 :            :         {
     777                 :     236688 :             pEmptyItemSet->ClearItem( nWhich );
     778                 :            :         }
     779                 :            :     }
     780                 :     517139 :     return *pEmptyItemSet;
     781                 :            : }
     782                 :            : 
     783                 :            : //  ----------------------------------------------------------------------
     784                 :            : //  MISC
     785                 :            : //  ----------------------------------------------------------------------
     786                 :       3984 : void ImpEditEngine::CursorMoved( ContentNode* pPrevNode )
     787                 :            : {
     788                 :            :     // Delete empty attributes, but only if paragraph is not empty!
     789 [ +  + ][ +  + ]:       3984 :     if ( pPrevNode->GetCharAttribs().HasEmptyAttribs() && pPrevNode->Len() )
                 [ +  + ]
     790                 :         78 :         pPrevNode->GetCharAttribs().DeleteEmptyAttribs( aEditDoc.GetItemPool() );
     791                 :       3984 : }
     792                 :            : 
     793                 :     207180 : void ImpEditEngine::TextModified()
     794                 :            : {
     795                 :     207180 :     bFormatted = false;
     796                 :            : 
     797 [ +  - ][ +  + ]:     207180 :     if ( GetNotifyHdl().IsSet() )
     798                 :            :     {
     799                 :         55 :         EENotify aNotify( EE_NOTIFY_TEXTMODIFIED );
     800                 :         55 :         aNotify.pEditEngine = GetEditEnginePtr();
     801         [ +  - ]:         55 :         CallNotify( aNotify );
     802                 :            :     }
     803                 :     207180 : }
     804                 :            : 
     805                 :            : 
     806                 :     370425 : void ImpEditEngine::ParaAttribsChanged( ContentNode* pNode )
     807                 :            : {
     808                 :            :     OSL_ENSURE( pNode, "ParaAttribsChanged: Which one?" );
     809                 :            : 
     810                 :     370425 :     aEditDoc.SetModified( sal_True );
     811                 :     370425 :     bFormatted = false;
     812                 :            : 
     813                 :     370425 :     ParaPortion* pPortion = FindParaPortion( pNode );
     814                 :            :     OSL_ENSURE( pPortion, "ParaAttribsChanged: Portion?" );
     815                 :     370425 :     pPortion->MarkSelectionInvalid( 0, pNode->Len() );
     816                 :            : 
     817                 :     370425 :     sal_uInt16 nPara = aEditDoc.GetPos( pNode );
     818                 :     370425 :     pEditEngine->ParaAttribsChanged( nPara );
     819                 :            : 
     820                 :     370425 :     ParaPortion* pNextPortion = GetParaPortions().SafeGetObject( nPara+1 );
     821                 :            :     // => is formatted again anyway, if Invalid.
     822 [ +  + ][ +  + ]:     370425 :     if ( pNextPortion && !pNextPortion->IsInvalid() )
                 [ +  + ]
     823                 :        435 :         CalcHeight( pNextPortion );
     824                 :     370425 : }
     825                 :            : 
     826                 :            : //  ----------------------------------------------------------------------
     827                 :            : //  Cursor movements
     828                 :            : //  ----------------------------------------------------------------------
     829                 :            : 
     830                 :          0 : EditSelection ImpEditEngine::MoveCursor( const KeyEvent& rKeyEvent, EditView* pEditView )
     831                 :            : {
     832                 :            :     // Actually, only necessary for up/down, but whatever.
     833         [ #  # ]:          0 :     CheckIdleFormatter();
     834                 :            : 
     835         [ #  # ]:          0 :     EditPaM aPaM( pEditView->pImpEditView->GetEditSelection().Max() );
     836                 :            : 
     837         [ #  # ]:          0 :     EditPaM aOldPaM( aPaM );
     838                 :            : 
     839                 :          0 :     TextDirectionality eTextDirection = TextDirectionality_LeftToRight_TopToBottom;
     840         [ #  # ]:          0 :     if ( IsVertical() )
     841                 :          0 :         eTextDirection = TextDirectionality_TopToBottom_RightToLeft;
     842 [ #  # ][ #  # ]:          0 :     else if ( IsRightToLeft( GetEditDoc().GetPos( aPaM.GetNode() ) ) )
         [ #  # ][ #  # ]
     843                 :          0 :         eTextDirection = TextDirectionality_RightToLeft_TopToBottom;
     844                 :            : 
     845         [ #  # ]:          0 :     KeyEvent aTranslatedKeyEvent = rKeyEvent.LogicalTextDirectionality( eTextDirection );
     846                 :            : 
     847         [ #  # ]:          0 :     sal_Bool bCtrl = aTranslatedKeyEvent.GetKeyCode().IsMod1() ? sal_True : sal_False;
     848                 :          0 :     sal_uInt16 nCode = aTranslatedKeyEvent.GetKeyCode().GetCode();
     849                 :            : 
     850 [ #  # ][ #  # ]:          0 :     if ( DoVisualCursorTraveling( aPaM.GetNode() ) )
                 [ #  # ]
     851                 :            :     {
     852                 :            :         // Only for simple cursor movement...
     853 [ #  # ][ #  # ]:          0 :         if ( !bCtrl && ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ) )
                 [ #  # ]
     854                 :            :         {
     855 [ #  # ][ #  # ]:          0 :             aPaM = CursorVisualLeftRight( pEditView, aPaM, rKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL, rKeyEvent.GetKeyCode().GetCode() == KEY_LEFT );
                 [ #  # ]
     856                 :          0 :             nCode = 0;  // skip switch statement
     857                 :            :         }
     858                 :            :     }
     859                 :            : 
     860                 :          0 :     bool bKeyModifySelection = aTranslatedKeyEvent.GetKeyCode().IsShift();
     861   [ #  #  #  #  :          0 :     switch ( nCode )
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     862                 :            :     {
     863 [ #  # ][ #  # ]:          0 :         case KEY_UP:        aPaM = CursorUp( aPaM, pEditView );
     864                 :          0 :                             break;
     865 [ #  # ][ #  # ]:          0 :         case KEY_DOWN:      aPaM = CursorDown( aPaM, pEditView );
     866                 :          0 :                             break;
     867 [ #  # ][ #  # ]:          0 :         case KEY_LEFT:      aPaM = bCtrl ? WordLeft( aPaM ) : CursorLeft( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL );
         [ #  # ][ #  # ]
                 [ #  # ]
     868                 :          0 :                             break;
     869 [ #  # ][ #  # ]:          0 :         case KEY_RIGHT:     aPaM = bCtrl ? WordRight( aPaM ) : CursorRight( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL );
         [ #  # ][ #  # ]
                 [ #  # ]
     870                 :          0 :                             break;
     871 [ #  # ][ #  # ]:          0 :         case KEY_HOME:      aPaM = bCtrl ? CursorStartOfDoc() : CursorStartOfLine( aPaM );
         [ #  # ][ #  # ]
     872                 :          0 :                             break;
     873 [ #  # ][ #  # ]:          0 :         case KEY_END:       aPaM = bCtrl ? CursorEndOfDoc() : CursorEndOfLine( aPaM );
         [ #  # ][ #  # ]
     874                 :          0 :                             break;
     875 [ #  # ][ #  # ]:          0 :         case KEY_PAGEUP:    aPaM = bCtrl ? CursorStartOfDoc() : PageUp( aPaM, pEditView );
         [ #  # ][ #  # ]
     876                 :          0 :                             break;
     877 [ #  # ][ #  # ]:          0 :         case KEY_PAGEDOWN:  aPaM = bCtrl ? CursorEndOfDoc() : PageDown( aPaM, pEditView );
         [ #  # ][ #  # ]
     878                 :          0 :                             break;
     879                 :            :         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
     880 [ #  # ][ #  # ]:          0 :                             aPaM = CursorStartOfLine( aPaM );
     881                 :          0 :                             bKeyModifySelection = false;
     882                 :          0 :                             break;
     883                 :            :         case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
     884 [ #  # ][ #  # ]:          0 :                             aPaM = CursorEndOfLine( aPaM );
     885                 :          0 :                             bKeyModifySelection = false;
     886                 :          0 :                             break;
     887                 :            :         case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
     888 [ #  # ][ #  # ]:          0 :                             aPaM = WordLeft( aPaM );
     889                 :          0 :                             bKeyModifySelection = false;
     890                 :          0 :                             break;
     891                 :            :         case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
     892 [ #  # ][ #  # ]:          0 :                             aPaM = WordRight( aPaM );
     893                 :          0 :                             bKeyModifySelection = false;
     894                 :          0 :                             break;
     895                 :            :         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
     896 [ #  # ][ #  # ]:          0 :                             aPaM = CursorStartOfParagraph( aPaM );
     897 [ #  # ][ #  # ]:          0 :                             if( aPaM == aOldPaM )
     898                 :            :                             {
     899 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
     900 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorStartOfParagraph( aPaM );
     901                 :            :                             }
     902                 :          0 :                             bKeyModifySelection = false;
     903                 :          0 :                             break;
     904                 :            :         case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
     905 [ #  # ][ #  # ]:          0 :                             aPaM = CursorEndOfParagraph( aPaM );
     906 [ #  # ][ #  # ]:          0 :                             if( aPaM == aOldPaM )
     907                 :            :                             {
     908 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
     909 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorEndOfParagraph( aPaM );
     910                 :            :                             }
     911                 :          0 :                             bKeyModifySelection = false;
     912                 :          0 :                             break;
     913                 :            :         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
     914 [ #  # ][ #  # ]:          0 :                             aPaM = CursorStartOfDoc();
     915                 :          0 :                             bKeyModifySelection = false;
     916                 :          0 :                             break;
     917                 :            :         case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
     918 [ #  # ][ #  # ]:          0 :                             aPaM = CursorEndOfDoc();
     919                 :          0 :                             bKeyModifySelection = false;
     920                 :          0 :                             break;
     921                 :            :         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
     922 [ #  # ][ #  # ]:          0 :                             aPaM = CursorStartOfLine( aPaM );
     923                 :          0 :                             bKeyModifySelection = true;
     924                 :          0 :                             break;
     925                 :            :         case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
     926 [ #  # ][ #  # ]:          0 :                             aPaM = CursorEndOfLine( aPaM );
     927                 :          0 :                             bKeyModifySelection = true;
     928                 :          0 :                             break;
     929                 :            :         case com::sun::star::awt::Key::SELECT_BACKWARD:
     930 [ #  # ][ #  # ]:          0 :                             aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
     931                 :          0 :                             bKeyModifySelection = true;
     932                 :          0 :                             break;
     933                 :            :         case com::sun::star::awt::Key::SELECT_FORWARD:
     934 [ #  # ][ #  # ]:          0 :                             aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
     935                 :          0 :                             bKeyModifySelection = true;
     936                 :          0 :                             break;
     937                 :            :         case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
     938 [ #  # ][ #  # ]:          0 :                             aPaM = WordLeft( aPaM );
     939                 :          0 :                             bKeyModifySelection = true;
     940                 :          0 :                             break;
     941                 :            :         case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
     942 [ #  # ][ #  # ]:          0 :                             aPaM = WordRight( aPaM );
     943                 :          0 :                             bKeyModifySelection = true;
     944                 :          0 :                             break;
     945                 :            :         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
     946 [ #  # ][ #  # ]:          0 :                             aPaM = CursorStartOfParagraph( aPaM );
     947 [ #  # ][ #  # ]:          0 :                             if( aPaM == aOldPaM )
     948                 :            :                             {
     949 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
     950 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorStartOfParagraph( aPaM );
     951                 :            :                             }
     952                 :          0 :                             bKeyModifySelection = true;
     953                 :          0 :                             break;
     954                 :            :         case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
     955 [ #  # ][ #  # ]:          0 :                             aPaM = CursorEndOfParagraph( aPaM );
     956 [ #  # ][ #  # ]:          0 :                             if( aPaM == aOldPaM )
     957                 :            :                             {
     958 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
     959 [ #  # ][ #  # ]:          0 :                                 aPaM = CursorEndOfParagraph( aPaM );
     960                 :            :                             }
     961                 :          0 :                             bKeyModifySelection = true;
     962                 :          0 :                             break;
     963                 :            :         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
     964 [ #  # ][ #  # ]:          0 :                             aPaM = CursorStartOfDoc();
     965                 :          0 :                             bKeyModifySelection = true;
     966                 :          0 :                             break;
     967                 :            :         case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
     968 [ #  # ][ #  # ]:          0 :                             aPaM = CursorEndOfDoc();
     969                 :          0 :                             bKeyModifySelection = true;
     970                 :          0 :                             break;
     971                 :            :     }
     972                 :            : 
     973 [ #  # ][ #  # ]:          0 :     if ( aOldPaM != aPaM )
     974                 :            :     {
     975 [ #  # ][ #  # ]:          0 :         CursorMoved( aOldPaM.GetNode() );
     976 [ #  # ][ #  # ]:          0 :         if ( aStatus.NotifyCursorMovements() && ( aOldPaM.GetNode() != aPaM.GetNode() ) )
         [ #  # ][ #  # ]
                 [ #  # ]
     977                 :            :         {
     978                 :          0 :             aStatus.GetStatusWord() = aStatus.GetStatusWord() | EE_STAT_CRSRLEFTPARA;
     979 [ #  # ][ #  # ]:          0 :             aStatus.GetPrevParagraph() = aEditDoc.GetPos( aOldPaM.GetNode() );
     980                 :            :         }
     981                 :            :     }
     982                 :            :     else
     983                 :          0 :         aStatus.GetStatusWord() = aStatus.GetStatusWord() | EE_STAT_CRSRMOVEFAIL;
     984                 :            : 
     985                 :            :     // May cause, an CreateAnchor or deselection all
     986         [ #  # ]:          0 :     aSelEngine.SetCurView( pEditView );
     987         [ #  # ]:          0 :     aSelEngine.CursorPosChanging( bKeyModifySelection, aTranslatedKeyEvent.GetKeyCode().IsMod1() );
     988         [ #  # ]:          0 :     EditPaM aOldEnd( pEditView->pImpEditView->GetEditSelection().Max() );
     989         [ #  # ]:          0 :     pEditView->pImpEditView->GetEditSelection().Max() = aPaM;
     990         [ #  # ]:          0 :     if ( bKeyModifySelection )
     991                 :            :     {
     992                 :            :         // Then the selection is expanded ...
     993         [ #  # ]:          0 :         EditSelection aTmpNewSel( aOldEnd, aPaM );
     994 [ #  # ][ #  # ]:          0 :         pEditView->pImpEditView->DrawSelection( aTmpNewSel );
     995                 :            :     }
     996                 :            :     else
     997         [ #  # ]:          0 :         pEditView->pImpEditView->GetEditSelection().Min() = aPaM;
     998                 :            : 
     999         [ #  # ]:          0 :     return pEditView->pImpEditView->GetEditSelection();
    1000                 :            : }
    1001                 :            : 
    1002                 :          0 : EditPaM ImpEditEngine::CursorVisualStartEnd( EditView* pEditView, const EditPaM& rPaM, sal_Bool bStart )
    1003                 :            : {
    1004                 :          0 :     EditPaM aPaM( rPaM );
    1005                 :            : 
    1006                 :          0 :     sal_uInt16 nPara = GetEditDoc().GetPos( aPaM.GetNode() );
    1007                 :          0 :     ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1008                 :            : 
    1009                 :          0 :     sal_uInt16 nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
    1010                 :          0 :     const EditLine* pLine = pParaPortion->GetLines()[nLine];
    1011                 :          0 :     bool bEmptyLine = pLine->GetStart() == pLine->GetEnd();
    1012                 :            : 
    1013                 :          0 :     pEditView->pImpEditView->nExtraCursorFlags = 0;
    1014                 :            : 
    1015         [ #  # ]:          0 :     if ( !bEmptyLine )
    1016                 :            :     {
    1017 [ #  # ][ #  # ]:          0 :         String aLine(aPaM.GetNode()->GetString(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart());
                 [ #  # ]
    1018                 :            : 
    1019                 :          0 :         const sal_Unicode* pLineString = aLine.GetBuffer();
    1020                 :            : 
    1021                 :          0 :         UErrorCode nError = U_ZERO_ERROR;
    1022         [ #  # ]:          0 :         UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
    1023                 :            : 
    1024 [ #  # ][ #  # ]:          0 :         const UBiDiLevel  nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
    1025         [ #  # ]:          0 :         ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), aLine.Len(), nBidiLevel, NULL, &nError );   // UChar != sal_Unicode in MinGW
    1026                 :            : 
    1027         [ #  # ]:          0 :         sal_uInt16 nVisPos = bStart ? 0 : aLine.Len()-1;
    1028         [ #  # ]:          0 :         sal_uInt16 nLogPos = (sal_uInt16)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
    1029                 :            : 
    1030         [ #  # ]:          0 :         ubidi_close( pBidi );
    1031                 :            : 
    1032                 :          0 :         aPaM.GetIndex() = nLogPos + pLine->GetStart();
    1033                 :            : 
    1034                 :            :         sal_uInt16 nTmp;
    1035         [ #  # ]:          0 :         sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTmp, sal_True );
    1036         [ #  # ]:          0 :         const TextPortion* pTextPortion = pParaPortion->GetTextPortions()[nTextPortion];
    1037                 :          0 :         sal_uInt16 nRTLLevel = pTextPortion->GetRightToLeft();
    1038                 :          0 :         sal_Bool bPortionRTL = (nRTLLevel%2) ? sal_True : sal_False;
    1039                 :            : 
    1040         [ #  # ]:          0 :         if ( bStart )
    1041                 :            :         {
    1042                 :          0 :             pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 0 : 1 );
    1043                 :            :             // Maybe we must be *behind* the character
    1044 [ #  # ][ #  # ]:          0 :             if ( bPortionRTL && pEditView->IsInsertMode() )
         [ #  # ][ #  # ]
    1045                 :          0 :                 aPaM.GetIndex()++;
    1046                 :            :         }
    1047                 :            :         else
    1048                 :            :         {
    1049         [ #  # ]:          0 :             pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 1 : 0 );
    1050 [ #  # ][ #  # ]:          0 :             if ( !bPortionRTL && pEditView->IsInsertMode() )
         [ #  # ][ #  # ]
    1051                 :          0 :                 aPaM.GetIndex()++;
    1052         [ #  # ]:          0 :         }
    1053                 :            :     }
    1054                 :            : 
    1055                 :          0 :     return aPaM;
    1056                 :            : }
    1057                 :            : 
    1058                 :          0 : EditPaM ImpEditEngine::CursorVisualLeftRight( EditView* pEditView, const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode, sal_Bool bVisualToLeft )
    1059                 :            : {
    1060                 :          0 :     EditPaM aPaM( rPaM );
    1061                 :            : 
    1062                 :          0 :     sal_uInt16 nPara = GetEditDoc().GetPos( aPaM.GetNode() );
    1063                 :          0 :     ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1064                 :            : 
    1065                 :          0 :     sal_uInt16 nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
    1066                 :          0 :     const EditLine* pLine = pParaPortion->GetLines()[nLine];
    1067                 :          0 :     bool bEmptyLine = pLine->GetStart() == pLine->GetEnd();
    1068                 :            : 
    1069                 :          0 :     pEditView->pImpEditView->nExtraCursorFlags = 0;
    1070                 :            : 
    1071                 :          0 :     sal_Bool bParaRTL = IsRightToLeft( nPara );
    1072                 :            : 
    1073                 :          0 :     sal_Bool bDone = sal_False;
    1074                 :            : 
    1075         [ #  # ]:          0 :     if ( bEmptyLine )
    1076                 :            :     {
    1077         [ #  # ]:          0 :         if ( bVisualToLeft )
    1078                 :            :         {
    1079         [ #  # ]:          0 :             aPaM = CursorUp( aPaM, pEditView );
    1080         [ #  # ]:          0 :             if ( aPaM != rPaM )
    1081         [ #  # ]:          0 :                 aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_False );
    1082                 :            :         }
    1083                 :            :         else
    1084                 :            :         {
    1085         [ #  # ]:          0 :             aPaM = CursorDown( aPaM, pEditView );
    1086         [ #  # ]:          0 :             if ( aPaM != rPaM )
    1087         [ #  # ]:          0 :                 aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_True );
    1088                 :            :         }
    1089                 :            : 
    1090                 :          0 :         bDone = sal_True;
    1091                 :            :     }
    1092                 :            : 
    1093         [ #  # ]:          0 :     sal_Bool bLogicalBackward = bParaRTL ? !bVisualToLeft : bVisualToLeft;
    1094                 :            : 
    1095 [ #  # ][ #  # ]:          0 :     if ( !bDone && pEditView->IsInsertMode() )
                 [ #  # ]
    1096                 :            :     {
    1097                 :            :         // Check if we are within a portion and don't have overwrite mode, then it's easy...
    1098                 :            :         sal_uInt16 nPortionStart;
    1099         [ #  # ]:          0 :         sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, sal_False );
    1100         [ #  # ]:          0 :         const TextPortion* pTextPortion = pParaPortion->GetTextPortions()[nTextPortion];
    1101                 :            : 
    1102 [ #  # ][ #  # ]:          0 :         sal_Bool bPortionBoundary = ( aPaM.GetIndex() == nPortionStart ) || ( aPaM.GetIndex() == (nPortionStart+pTextPortion->GetLen()) );
    1103                 :          0 :         sal_uInt16 nRTLLevel = pTextPortion->GetRightToLeft();
    1104                 :            : 
    1105                 :            :         // Portion boundary doesn't matter if both have same RTL level
    1106                 :          0 :         sal_uInt16 nRTLLevelNextPortion = 0xFFFF;
    1107 [ #  # ][ #  # ]:          0 :         if ( bPortionBoundary && aPaM.GetIndex() && ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1108                 :            :         {
    1109                 :            :             sal_uInt16 nTmp;
    1110         [ #  # ]:          0 :             sal_uInt16 nNextTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex()+1, nTmp, bLogicalBackward ? sal_False : sal_True );
    1111         [ #  # ]:          0 :             const TextPortion* pNextTextPortion = pParaPortion->GetTextPortions()[nNextTextPortion];
    1112                 :          0 :             nRTLLevelNextPortion = pNextTextPortion->GetRightToLeft();
    1113                 :            :         }
    1114                 :            : 
    1115 [ #  # ][ #  # ]:          0 :         if ( !bPortionBoundary || ( nRTLLevel == nRTLLevelNextPortion ) )
    1116                 :            :         {
    1117 [ #  # ][ #  # ]:          0 :             if ( ( bVisualToLeft && !(nRTLLevel%2) ) || ( !bVisualToLeft && (nRTLLevel%2) ) )
         [ #  # ][ #  # ]
    1118                 :            :             {
    1119 [ #  # ][ #  # ]:          0 :                 aPaM = CursorLeft( aPaM, nCharacterIteratorMode );
    1120                 :          0 :                 pEditView->pImpEditView->SetCursorBidiLevel( 1 );
    1121                 :            :             }
    1122                 :            :             else
    1123                 :            :             {
    1124 [ #  # ][ #  # ]:          0 :                 aPaM = CursorRight( aPaM, nCharacterIteratorMode );
    1125                 :          0 :                 pEditView->pImpEditView->SetCursorBidiLevel( 0 );
    1126                 :            :             }
    1127                 :          0 :             bDone = sal_True;
    1128                 :            :         }
    1129                 :            :     }
    1130                 :            : 
    1131         [ #  # ]:          0 :     if ( !bDone )
    1132                 :            :     {
    1133                 :          0 :         sal_Bool bGotoStartOfNextLine = sal_False;
    1134                 :          0 :         sal_Bool bGotoEndOfPrevLine = sal_False;
    1135                 :            : 
    1136 [ #  # ][ #  # ]:          0 :         String aLine(aPaM.GetNode()->GetString(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart());
                 [ #  # ]
    1137                 :          0 :         sal_uInt16 nPosInLine = aPaM.GetIndex() - pLine->GetStart();
    1138                 :            : 
    1139                 :          0 :         const sal_Unicode* pLineString = aLine.GetBuffer();
    1140                 :            : 
    1141                 :          0 :         UErrorCode nError = U_ZERO_ERROR;
    1142         [ #  # ]:          0 :         UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
    1143                 :            : 
    1144 [ #  # ][ #  # ]:          0 :         const UBiDiLevel  nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
    1145         [ #  # ]:          0 :         ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), aLine.Len(), nBidiLevel, NULL, &nError );   // UChar != sal_Unicode in MinGW
    1146                 :            : 
    1147 [ #  # ][ #  # ]:          0 :         if ( !pEditView->IsInsertMode() )
    1148                 :            :         {
    1149                 :          0 :             sal_Bool bEndOfLine = nPosInLine == aLine.Len();
    1150 [ #  # ][ #  # ]:          0 :             sal_uInt16 nVisPos = (sal_uInt16)ubidi_getVisualIndex( pBidi, !bEndOfLine ? nPosInLine : nPosInLine-1, &nError );
    1151         [ #  # ]:          0 :             if ( bVisualToLeft )
    1152                 :            :             {
    1153                 :          0 :                 bGotoEndOfPrevLine = nVisPos == 0;
    1154         [ #  # ]:          0 :                 if ( !bEndOfLine )
    1155                 :          0 :                     nVisPos--;
    1156                 :            :             }
    1157                 :            :             else
    1158                 :            :             {
    1159                 :          0 :                 bGotoStartOfNextLine = nVisPos == (aLine.Len() - 1);
    1160         [ #  # ]:          0 :                 if ( !bEndOfLine )
    1161                 :          0 :                     nVisPos++;
    1162                 :            :             }
    1163                 :            : 
    1164 [ #  # ][ #  # ]:          0 :             if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
    1165                 :            :             {
    1166         [ #  # ]:          0 :                 sal_uInt16 nLogPos = (sal_uInt16)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
    1167                 :          0 :                 aPaM.GetIndex() = pLine->GetStart() + nLogPos;
    1168                 :          0 :                 pEditView->pImpEditView->SetCursorBidiLevel( 0 );
    1169                 :            :             }
    1170                 :            :         }
    1171                 :            :         else
    1172                 :            :         {
    1173                 :          0 :             sal_Bool bWasBehind = sal_False;
    1174 [ #  # ][ #  # ]:          0 :             sal_Bool bBeforePortion = !nPosInLine || pEditView->pImpEditView->GetCursorBidiLevel() == 1;
    1175 [ #  # ][ #  # ]:          0 :             if ( nPosInLine && ( !bBeforePortion ) ) // before the next portion
    1176                 :          0 :                 bWasBehind = sal_True;  // step one back, otherwise visual will be unusable when rtl portion follows.
    1177                 :            : 
    1178                 :            :             sal_uInt16 nPortionStart;
    1179         [ #  # ]:          0 :             sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, bBeforePortion );
    1180         [ #  # ]:          0 :             const TextPortion* pTextPortion = pParaPortion->GetTextPortions()[nTextPortion];
    1181                 :          0 :             sal_Bool bRTLPortion = (pTextPortion->GetRightToLeft() % 2) != 0;
    1182                 :            : 
    1183                 :            :             // -1: We are 'behind' the character
    1184 [ #  # ][ #  # ]:          0 :             long nVisPos = (long)ubidi_getVisualIndex( pBidi, bWasBehind ? nPosInLine-1 : nPosInLine, &nError );
    1185         [ #  # ]:          0 :             if ( bVisualToLeft )
    1186                 :            :             {
    1187 [ #  # ][ #  # ]:          0 :                 if ( !bWasBehind || bRTLPortion )
    1188                 :          0 :                     nVisPos--;
    1189                 :            :             }
    1190                 :            :             else
    1191                 :            :             {
    1192 [ #  # ][ #  # ]:          0 :                 if ( bWasBehind || bRTLPortion || bBeforePortion )
                 [ #  # ]
    1193                 :          0 :                     nVisPos++;
    1194                 :            :             }
    1195                 :            : 
    1196                 :          0 :             bGotoEndOfPrevLine = nVisPos < 0;
    1197                 :          0 :             bGotoStartOfNextLine = nVisPos >= aLine.Len();
    1198                 :            : 
    1199 [ #  # ][ #  # ]:          0 :             if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
    1200                 :            :             {
    1201         [ #  # ]:          0 :                 sal_uInt16 nLogPos = (sal_uInt16)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
    1202                 :            : 
    1203                 :          0 :                 aPaM.GetIndex() = pLine->GetStart() + nLogPos;
    1204                 :            : 
    1205                 :            :                 // RTL portion, stay visually on the left side.
    1206                 :            :                 sal_uInt16 _nPortionStart;
    1207                 :            :                 // sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, !bRTLPortion );
    1208         [ #  # ]:          0 :                 sal_uInt16 _nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), _nPortionStart, sal_True );
    1209         [ #  # ]:          0 :                 const TextPortion* _pTextPortion = pParaPortion->GetTextPortions()[_nTextPortion];
    1210 [ #  # ][ #  # ]:          0 :                 if ( bVisualToLeft && !bRTLPortion && ( _pTextPortion->GetRightToLeft() % 2 ) )
         [ #  # ][ #  # ]
    1211                 :          0 :                     aPaM.GetIndex()++;
    1212 [ #  # ][ #  # ]:          0 :                 else if ( !bVisualToLeft && bRTLPortion && ( bWasBehind || !(_pTextPortion->GetRightToLeft() % 2 )) )
         [ #  # ][ #  # ]
                 [ #  # ]
    1213                 :          0 :                     aPaM.GetIndex()++;
    1214                 :            : 
    1215                 :          0 :                 pEditView->pImpEditView->SetCursorBidiLevel( _nPortionStart );
    1216                 :            :             }
    1217                 :            :         }
    1218                 :            : 
    1219         [ #  # ]:          0 :         ubidi_close( pBidi );
    1220                 :            : 
    1221         [ #  # ]:          0 :         if ( bGotoEndOfPrevLine )
    1222                 :            :         {
    1223 [ #  # ][ #  # ]:          0 :             aPaM = CursorUp( aPaM, pEditView );
    1224 [ #  # ][ #  # ]:          0 :             if ( aPaM != rPaM )
    1225 [ #  # ][ #  # ]:          0 :                 aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_False );
    1226                 :            :         }
    1227         [ #  # ]:          0 :         else if ( bGotoStartOfNextLine )
    1228                 :            :         {
    1229 [ #  # ][ #  # ]:          0 :             aPaM = CursorDown( aPaM, pEditView );
    1230 [ #  # ][ #  # ]:          0 :             if ( aPaM != rPaM )
    1231 [ #  # ][ #  # ]:          0 :                 aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_True );
    1232         [ #  # ]:          0 :         }
    1233                 :            :     }
    1234                 :          0 :     return aPaM;
    1235                 :            : }
    1236                 :            : 
    1237                 :            : 
    1238                 :          0 : EditPaM ImpEditEngine::CursorLeft( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode )
    1239                 :            : {
    1240         [ #  # ]:          0 :     EditPaM aCurPaM( rPaM );
    1241         [ #  # ]:          0 :     EditPaM aNewPaM( aCurPaM );
    1242                 :            : 
    1243         [ #  # ]:          0 :     if ( aCurPaM.GetIndex() )
    1244                 :            :     {
    1245                 :          0 :         sal_Int32 nCount = 1;
    1246         [ #  # ]:          0 :         uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1247                 :            :          aNewPaM.SetIndex(
    1248         [ #  # ]:          0 :              (sal_uInt16)_xBI->previousCharacters(
    1249 [ #  # ][ #  # ]:          0 :                  aNewPaM.GetNode()->GetString(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount));
         [ #  # ][ #  # ]
                 [ #  # ]
    1250                 :            :     }
    1251                 :            :     else
    1252                 :            :     {
    1253         [ #  # ]:          0 :         ContentNode* pNode = aCurPaM.GetNode();
    1254         [ #  # ]:          0 :         pNode = GetPrevVisNode( pNode );
    1255         [ #  # ]:          0 :         if ( pNode )
    1256                 :            :         {
    1257         [ #  # ]:          0 :             aNewPaM.SetNode( pNode );
    1258         [ #  # ]:          0 :             aNewPaM.SetIndex( pNode->Len() );
    1259                 :            :         }
    1260                 :            :     }
    1261                 :            : 
    1262                 :          0 :     return aNewPaM;
    1263                 :            : }
    1264                 :            : 
    1265                 :          0 : EditPaM ImpEditEngine::CursorRight( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode )
    1266                 :            : {
    1267         [ #  # ]:          0 :     EditPaM aCurPaM( rPaM );
    1268         [ #  # ]:          0 :     EditPaM aNewPaM( aCurPaM );
    1269                 :            : 
    1270 [ #  # ][ #  # ]:          0 :     if ( aCurPaM.GetIndex() < aCurPaM.GetNode()->Len() )
                 [ #  # ]
    1271                 :            :     {
    1272         [ #  # ]:          0 :         uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1273                 :          0 :         sal_Int32 nCount = 1;
    1274                 :            :         aNewPaM.SetIndex(
    1275         [ #  # ]:          0 :             (sal_uInt16)_xBI->nextCharacters(
    1276 [ #  # ][ #  # ]:          0 :                 aNewPaM.GetNode()->GetString(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount));
         [ #  # ][ #  # ]
                 [ #  # ]
    1277                 :            :     }
    1278                 :            :     else
    1279                 :            :     {
    1280         [ #  # ]:          0 :         ContentNode* pNode = aCurPaM.GetNode();
    1281         [ #  # ]:          0 :         pNode = GetNextVisNode( pNode );
    1282         [ #  # ]:          0 :         if ( pNode )
    1283                 :            :         {
    1284         [ #  # ]:          0 :             aNewPaM.SetNode( pNode );
    1285                 :          0 :             aNewPaM.SetIndex( 0 );
    1286                 :            :         }
    1287                 :            :     }
    1288                 :            : 
    1289                 :          0 :     return aNewPaM;
    1290                 :            : }
    1291                 :            : 
    1292                 :          0 : EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, EditView* pView )
    1293                 :            : {
    1294                 :            :     OSL_ENSURE( pView, "No View - No Cursor Movement!" );
    1295                 :            : 
    1296                 :          0 :     const ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
    1297                 :            :     OSL_ENSURE( pPPortion, "No matching portion found: CursorUp ");
    1298                 :          0 :     sal_uInt16 nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
    1299                 :          0 :     const EditLine* pLine = pPPortion->GetLines()[nLine];
    1300                 :            : 
    1301                 :            :     long nX;
    1302         [ #  # ]:          0 :     if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
    1303                 :            :     {
    1304                 :          0 :         nX = GetXPos( pPPortion, pLine, rPaM.GetIndex() );
    1305                 :          0 :         pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
    1306                 :            :     }
    1307                 :            :     else
    1308                 :          0 :         nX = pView->pImpEditView->nTravelXPos;
    1309                 :            : 
    1310                 :          0 :     EditPaM aNewPaM( rPaM );
    1311         [ #  # ]:          0 :     if ( nLine )    // same paragraph
    1312                 :            :     {
    1313                 :          0 :         const EditLine* pPrevLine = pPPortion->GetLines()[nLine-1];
    1314                 :          0 :         aNewPaM.SetIndex( GetChar( pPPortion, pPrevLine, nX ) );
    1315                 :            :         // If a previous automatically wrapped line, and one has to be exactly
    1316                 :            :         // at the end of this line, the cursor lands on the current line at the
    1317                 :            :         // beginning. See Problem: Last character of an automatically wrapped
    1318                 :            :         // Row = cursor
    1319 [ #  # ][ #  # ]:          0 :         if ( aNewPaM.GetIndex() && ( aNewPaM.GetIndex() == pLine->GetStart() ) )
                 [ #  # ]
    1320         [ #  # ]:          0 :             aNewPaM = CursorLeft( aNewPaM );
    1321                 :            :     }
    1322                 :            :     else    // previous paragraph
    1323                 :            :     {
    1324                 :          0 :         const ParaPortion* pPrevPortion = GetPrevVisPortion( pPPortion );
    1325         [ #  # ]:          0 :         if ( pPrevPortion )
    1326                 :            :         {
    1327                 :          0 :             pLine = pPrevPortion->GetLines()[pPrevPortion->GetLines().Count()-1];
    1328                 :            :             OSL_ENSURE( pLine, "Line in front not found: CursorUp" );
    1329                 :          0 :             aNewPaM.SetNode( pPrevPortion->GetNode() );
    1330                 :          0 :             aNewPaM.SetIndex( GetChar( pPrevPortion, pLine, nX+nOnePixelInRef ) );
    1331                 :            :         }
    1332                 :            :     }
    1333                 :            : 
    1334                 :          0 :     return aNewPaM;
    1335                 :            : }
    1336                 :            : 
    1337                 :          0 : EditPaM ImpEditEngine::CursorDown( const EditPaM& rPaM, EditView* pView )
    1338                 :            : {
    1339                 :            :     OSL_ENSURE( pView, "No View - No Cursor Movement!" );
    1340                 :            : 
    1341                 :          0 :     const ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
    1342                 :            :     OSL_ENSURE( pPPortion, "No matching portion found: CursorDown" );
    1343                 :          0 :     sal_uInt16 nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
    1344                 :            : 
    1345                 :            :     long nX;
    1346         [ #  # ]:          0 :     if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
    1347                 :            :     {
    1348                 :          0 :         const EditLine* pLine = pPPortion->GetLines()[nLine];
    1349                 :          0 :         nX = GetXPos( pPPortion, pLine, rPaM.GetIndex() );
    1350                 :          0 :         pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
    1351                 :            :     }
    1352                 :            :     else
    1353                 :          0 :         nX = pView->pImpEditView->nTravelXPos;
    1354                 :            : 
    1355                 :          0 :     EditPaM aNewPaM( rPaM );
    1356         [ #  # ]:          0 :     if ( nLine < pPPortion->GetLines().Count()-1 )
    1357                 :            :     {
    1358                 :          0 :         const EditLine* pNextLine = pPPortion->GetLines()[nLine+1];
    1359                 :          0 :         aNewPaM.SetIndex( GetChar( pPPortion, pNextLine, nX ) );
    1360                 :            :         // Special treatment, see CursorUp ...
    1361 [ #  # ][ #  # ]:          0 :         if ( ( aNewPaM.GetIndex() == pNextLine->GetEnd() ) && ( aNewPaM.GetIndex() > pNextLine->GetStart() ) && ( aNewPaM.GetIndex() < pPPortion->GetNode()->Len() ) )
         [ #  # ][ #  # ]
    1362         [ #  # ]:          0 :             aNewPaM = CursorLeft( aNewPaM );
    1363                 :            :     }
    1364                 :            :     else    // next paragraph
    1365                 :            :     {
    1366                 :          0 :         const ParaPortion* pNextPortion = GetNextVisPortion( pPPortion );
    1367         [ #  # ]:          0 :         if ( pNextPortion )
    1368                 :            :         {
    1369                 :          0 :             const EditLine* pLine = pNextPortion->GetLines()[0];
    1370                 :            :             OSL_ENSURE( pLine, "Line in front not found: CursorUp" );
    1371                 :          0 :             aNewPaM.SetNode( pNextPortion->GetNode() );
    1372                 :            :             // Never at the very end when several lines, because then a line
    1373                 :            :             // below the cursor appears.
    1374                 :          0 :             aNewPaM.SetIndex( GetChar( pNextPortion, pLine, nX+nOnePixelInRef ) );
    1375 [ #  # ][ #  # ]:          0 :             if ( ( aNewPaM.GetIndex() == pLine->GetEnd() ) && ( aNewPaM.GetIndex() > pLine->GetStart() ) && ( pNextPortion->GetLines().Count() > 1 ) )
         [ #  # ][ #  # ]
    1376         [ #  # ]:          0 :                 aNewPaM = CursorLeft( aNewPaM );
    1377                 :            :         }
    1378                 :            :     }
    1379                 :            : 
    1380                 :          0 :     return aNewPaM;
    1381                 :            : }
    1382                 :            : 
    1383                 :          0 : EditPaM ImpEditEngine::CursorStartOfLine( const EditPaM& rPaM )
    1384                 :            : {
    1385                 :          0 :     const ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
    1386                 :            :     OSL_ENSURE( pCurPortion, "No Portion for the PaM ?" );
    1387                 :          0 :     sal_uInt16 nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
    1388                 :          0 :     const EditLine* pLine = pCurPortion->GetLines()[nLine];
    1389                 :            :     OSL_ENSURE( pLine, "Current line not found ?!" );
    1390                 :            : 
    1391                 :          0 :     EditPaM aNewPaM( rPaM );
    1392                 :          0 :     aNewPaM.SetIndex( pLine->GetStart() );
    1393                 :          0 :     return aNewPaM;
    1394                 :            : }
    1395                 :            : 
    1396                 :          0 : EditPaM ImpEditEngine::CursorEndOfLine( const EditPaM& rPaM )
    1397                 :            : {
    1398                 :          0 :     const ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
    1399                 :            :     OSL_ENSURE( pCurPortion, "No Portion for the PaM ?" );
    1400                 :          0 :     sal_uInt16 nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
    1401                 :          0 :     const EditLine* pLine = pCurPortion->GetLines()[nLine];
    1402                 :            :     OSL_ENSURE( pLine, "Current line not found ?!" );
    1403                 :            : 
    1404                 :          0 :     EditPaM aNewPaM( rPaM );
    1405                 :          0 :     aNewPaM.SetIndex( pLine->GetEnd() );
    1406         [ #  # ]:          0 :     if ( pLine->GetEnd() > pLine->GetStart() )
    1407                 :            :     {
    1408         [ #  # ]:          0 :         if ( aNewPaM.GetNode()->IsFeature( aNewPaM.GetIndex() - 1 ) )
    1409                 :            :         {
    1410                 :            :             // When a soft break, be in front of it!
    1411                 :          0 :             const EditCharAttrib* pNextFeature = aNewPaM.GetNode()->GetCharAttribs().FindFeature( aNewPaM.GetIndex()-1 );
    1412 [ #  # ][ #  # ]:          0 :             if ( pNextFeature && ( pNextFeature->GetItem()->Which() == EE_FEATURE_LINEBR ) )
                 [ #  # ]
    1413         [ #  # ]:          0 :                 aNewPaM = CursorLeft( aNewPaM );
    1414                 :            :         }
    1415 [ #  # ][ #  # ]:          0 :         else if ( ( aNewPaM.GetNode()->GetChar( aNewPaM.GetIndex() - 1 ) == ' ' ) && ( aNewPaM.GetIndex() != aNewPaM.GetNode()->Len() ) )
                 [ #  # ]
    1416                 :            :         {
    1417                 :            :             // For a Blank in an auto wrapped line, it makes sense, to stand
    1418                 :            :             // in front of it, since the user wants to be after the word.
    1419                 :            :             // If this is changed, special treatment for Pos1 to End!
    1420         [ #  # ]:          0 :             aNewPaM = CursorLeft( aNewPaM );
    1421                 :            :         }
    1422                 :            :     }
    1423                 :          0 :     return aNewPaM;
    1424                 :            : }
    1425                 :            : 
    1426                 :          0 : EditPaM ImpEditEngine::CursorStartOfParagraph( const EditPaM& rPaM )
    1427                 :            : {
    1428                 :          0 :     EditPaM aPaM(rPaM);
    1429                 :          0 :     aPaM.SetIndex(0);
    1430                 :          0 :     return aPaM;
    1431                 :            : }
    1432                 :            : 
    1433                 :          0 : EditPaM ImpEditEngine::CursorEndOfParagraph( const EditPaM& rPaM )
    1434                 :            : {
    1435                 :          0 :     EditPaM aPaM(rPaM);
    1436                 :          0 :     aPaM.SetIndex(rPaM.GetNode()->Len());
    1437                 :          0 :     return aPaM;
    1438                 :            : }
    1439                 :            : 
    1440                 :          0 : EditPaM ImpEditEngine::CursorStartOfDoc()
    1441                 :            : {
    1442                 :          0 :     EditPaM aPaM( aEditDoc.GetObject( 0 ), 0 );
    1443                 :          0 :     return aPaM;
    1444                 :            : }
    1445                 :            : 
    1446                 :          0 : EditPaM ImpEditEngine::CursorEndOfDoc()
    1447                 :            : {
    1448                 :          0 :     ContentNode* pLastNode = aEditDoc.GetObject( aEditDoc.Count()-1 );
    1449                 :          0 :     ParaPortion* pLastPortion = GetParaPortions().SafeGetObject( aEditDoc.Count()-1 );
    1450                 :            :     OSL_ENSURE( pLastNode && pLastPortion, "CursorEndOfDoc: Node or Portion not found" );
    1451                 :            : 
    1452         [ #  # ]:          0 :     if ( !pLastPortion->IsVisible() )
    1453                 :            :     {
    1454                 :          0 :         pLastNode = GetPrevVisNode( pLastPortion->GetNode() );
    1455                 :            :         OSL_ENSURE( pLastNode, "Kein sichtbarer Absatz?" );
    1456         [ #  # ]:          0 :         if ( !pLastNode )
    1457                 :          0 :             pLastNode = aEditDoc.GetObject( aEditDoc.Count()-1 );
    1458                 :            :     }
    1459                 :            : 
    1460                 :          0 :     EditPaM aPaM( pLastNode, pLastNode->Len() );
    1461                 :          0 :     return aPaM;
    1462                 :            : }
    1463                 :            : 
    1464                 :          0 : EditPaM ImpEditEngine::PageUp( const EditPaM& rPaM, EditView* pView )
    1465                 :            : {
    1466 [ #  # ][ #  # ]:          0 :     Rectangle aRec = PaMtoEditCursor( rPaM );
    1467                 :          0 :     Point aTopLeft = aRec.TopLeft();
    1468 [ #  # ][ #  # ]:          0 :     aTopLeft.Y() -= pView->GetVisArea().GetHeight() *9/10;
    1469                 :          0 :     aTopLeft.X() += nOnePixelInRef;
    1470         [ #  # ]:          0 :     if ( aTopLeft.Y() < 0 )
    1471                 :            :     {
    1472                 :          0 :         aTopLeft.Y() = 0;
    1473                 :            :     }
    1474         [ #  # ]:          0 :     return GetPaM( aTopLeft );
    1475                 :            : }
    1476                 :            : 
    1477                 :          0 : EditPaM ImpEditEngine::PageDown( const EditPaM& rPaM, EditView* pView )
    1478                 :            : {
    1479 [ #  # ][ #  # ]:          0 :     Rectangle aRec = PaMtoEditCursor( rPaM );
    1480         [ #  # ]:          0 :     Point aBottomRight = aRec.BottomRight();
    1481 [ #  # ][ #  # ]:          0 :     aBottomRight.Y() += pView->GetVisArea().GetHeight() *9/10;
    1482                 :          0 :     aBottomRight.X() += nOnePixelInRef;
    1483                 :          0 :     long nHeight = GetTextHeight();
    1484         [ #  # ]:          0 :     if ( aBottomRight.Y() > nHeight )
    1485                 :            :     {
    1486                 :          0 :         aBottomRight.Y() = nHeight-2;
    1487                 :            :     }
    1488         [ #  # ]:          0 :     return GetPaM( aBottomRight );
    1489                 :            : }
    1490                 :            : 
    1491                 :          0 : EditPaM ImpEditEngine::WordLeft( const EditPaM& rPaM, sal_Int16 nWordType )
    1492                 :            : {
    1493                 :          0 :     sal_uInt16 nCurrentPos = rPaM.GetIndex();
    1494                 :          0 :     EditPaM aNewPaM( rPaM );
    1495         [ #  # ]:          0 :     if ( nCurrentPos == 0 )
    1496                 :            :     {
    1497                 :            :         // Previous paragraph...
    1498                 :          0 :         sal_uInt16 nCurPara = aEditDoc.GetPos( aNewPaM.GetNode() );
    1499                 :          0 :         ContentNode* pPrevNode = aEditDoc.GetObject( --nCurPara );
    1500         [ #  # ]:          0 :         if ( pPrevNode )
    1501                 :            :         {
    1502                 :          0 :             aNewPaM.SetNode( pPrevNode );
    1503                 :          0 :             aNewPaM.SetIndex( pPrevNode->Len() );
    1504                 :            :         }
    1505                 :            :     }
    1506                 :            :     else
    1507                 :            :     {
    1508                 :            :         // we need to increase the position by 1 when retrieving the locale
    1509                 :            :         // since the attribute for the char left to the cursor position is returned
    1510         [ #  # ]:          0 :         EditPaM aTmpPaM( aNewPaM );
    1511 [ #  # ][ #  # ]:          0 :         xub_StrLen nMax = rPaM.GetNode()->Len();
    1512         [ #  # ]:          0 :         if ( aTmpPaM.GetIndex() < nMax )
    1513                 :          0 :             aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
    1514         [ #  # ]:          0 :         lang::Locale aLocale( GetLocale( aTmpPaM ) );
    1515                 :            : 
    1516         [ #  # ]:          0 :         uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1517                 :            :         i18n::Boundary aBoundary =
    1518 [ #  # ][ #  # ]:          0 :             _xBI->getWordBoundary(aNewPaM.GetNode()->GetString(), nCurrentPos, aLocale, nWordType, true);
         [ #  # ][ #  # ]
                 [ #  # ]
    1519         [ #  # ]:          0 :         if ( aBoundary.startPos >= nCurrentPos )
    1520         [ #  # ]:          0 :             aBoundary = _xBI->previousWord(
    1521 [ #  # ][ #  # ]:          0 :                 aNewPaM.GetNode()->GetString(), nCurrentPos, aLocale, nWordType);
         [ #  # ][ #  # ]
    1522         [ #  # ]:          0 :         aNewPaM.SetIndex( ( aBoundary.startPos != (-1) ) ? (sal_uInt16)aBoundary.startPos : 0 );
    1523                 :            :     }
    1524                 :            : 
    1525                 :          0 :     return aNewPaM;
    1526                 :            : }
    1527                 :            : 
    1528                 :       3311 : EditPaM ImpEditEngine::WordRight( const EditPaM& rPaM, sal_Int16 nWordType )
    1529                 :            : {
    1530                 :       3311 :     xub_StrLen nMax = rPaM.GetNode()->Len();
    1531                 :       3311 :     EditPaM aNewPaM( rPaM );
    1532         [ +  + ]:       3311 :     if ( aNewPaM.GetIndex() < nMax )
    1533                 :            :     {
    1534                 :            :         // we need to increase the position by 1 when retrieving the locale
    1535                 :            :         // since the attribute for the char left to the cursor position is returned
    1536         [ +  - ]:        816 :         EditPaM aTmpPaM( aNewPaM );
    1537                 :        816 :         aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
    1538         [ +  - ]:        816 :         lang::Locale aLocale( GetLocale( aTmpPaM ) );
    1539                 :            : 
    1540         [ +  - ]:        816 :         uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1541         [ +  - ]:        816 :         i18n::Boundary aBoundary = _xBI->nextWord(
    1542 [ +  - ][ +  - ]:        816 :             aNewPaM.GetNode()->GetString(), aNewPaM.GetIndex(), aLocale, nWordType);
         [ +  - ][ +  - ]
    1543                 :        816 :         aNewPaM.SetIndex( (sal_uInt16)aBoundary.startPos );
    1544                 :            :     }
    1545                 :            :     // not 'else', maybe the index reached nMax now...
    1546         [ +  + ]:       3311 :     if ( aNewPaM.GetIndex() >= nMax )
    1547                 :            :     {
    1548                 :            :         // Next paragraph ...
    1549                 :       2538 :         sal_uInt16 nCurPara = aEditDoc.GetPos( aNewPaM.GetNode() );
    1550                 :       2538 :         ContentNode* pNextNode = aEditDoc.GetObject( ++nCurPara );
    1551         [ +  + ]:       2538 :         if ( pNextNode )
    1552                 :            :         {
    1553                 :         34 :             aNewPaM.SetNode( pNextNode );
    1554                 :         34 :             aNewPaM.SetIndex( 0 );
    1555                 :            :         }
    1556                 :            :     }
    1557                 :       3311 :     return aNewPaM;
    1558                 :            : }
    1559                 :            : 
    1560                 :          0 : EditPaM ImpEditEngine::StartOfWord( const EditPaM& rPaM, sal_Int16 nWordType )
    1561                 :            : {
    1562         [ #  # ]:          0 :     EditPaM aNewPaM( rPaM );
    1563                 :            : 
    1564                 :            :     // we need to increase the position by 1 when retrieving the locale
    1565                 :            :     // since the attribute for the char left to the cursor position is returned
    1566         [ #  # ]:          0 :     EditPaM aTmpPaM( aNewPaM );
    1567 [ #  # ][ #  # ]:          0 :     xub_StrLen nMax = rPaM.GetNode()->Len();
    1568         [ #  # ]:          0 :     if ( aTmpPaM.GetIndex() < nMax )
    1569                 :          0 :         aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
    1570         [ #  # ]:          0 :     lang::Locale aLocale( GetLocale( aTmpPaM ) );
    1571                 :            : 
    1572         [ #  # ]:          0 :     uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1573         [ #  # ]:          0 :     i18n::Boundary aBoundary = _xBI->getWordBoundary(
    1574 [ #  # ][ #  # ]:          0 :         rPaM.GetNode()->GetString(), rPaM.GetIndex(), aLocale, nWordType, true);
         [ #  # ][ #  # ]
    1575                 :            : 
    1576                 :          0 :     aNewPaM.SetIndex( (sal_uInt16)aBoundary.startPos );
    1577                 :          0 :     return aNewPaM;
    1578                 :            : }
    1579                 :            : 
    1580                 :          0 : EditPaM ImpEditEngine::EndOfWord( const EditPaM& rPaM, sal_Int16 nWordType )
    1581                 :            : {
    1582         [ #  # ]:          0 :     EditPaM aNewPaM( rPaM );
    1583                 :            : 
    1584                 :            :     // we need to increase the position by 1 when retrieving the locale
    1585                 :            :     // since the attribute for the char left to the cursor position is returned
    1586         [ #  # ]:          0 :     EditPaM aTmpPaM( aNewPaM );
    1587 [ #  # ][ #  # ]:          0 :     xub_StrLen nMax = rPaM.GetNode()->Len();
    1588         [ #  # ]:          0 :     if ( aTmpPaM.GetIndex() < nMax )
    1589                 :          0 :         aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
    1590         [ #  # ]:          0 :     lang::Locale aLocale( GetLocale( aTmpPaM ) );
    1591                 :            : 
    1592         [ #  # ]:          0 :     uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1593         [ #  # ]:          0 :     i18n::Boundary aBoundary = _xBI->getWordBoundary(
    1594 [ #  # ][ #  # ]:          0 :         rPaM.GetNode()->GetString(), rPaM.GetIndex(), aLocale, nWordType, true);
         [ #  # ][ #  # ]
    1595                 :            : 
    1596                 :          0 :     aNewPaM.SetIndex( (sal_uInt16)aBoundary.endPos );
    1597                 :          0 :     return aNewPaM;
    1598                 :            : }
    1599                 :            : 
    1600                 :       7771 : EditSelection ImpEditEngine::SelectWord( const EditSelection& rCurSel, sal_Int16 nWordType, sal_Bool bAcceptStartOfWord )
    1601                 :            : {
    1602         [ +  - ]:       7771 :     EditSelection aNewSel( rCurSel );
    1603         [ +  - ]:       7771 :     EditPaM aPaM( rCurSel.Max() );
    1604                 :            : 
    1605                 :            :     // we need to increase the position by 1 when retrieving the locale
    1606                 :            :     // since the attribute for the char left to the cursor position is returned
    1607         [ +  - ]:       7771 :     EditPaM aTmpPaM( aPaM );
    1608 [ +  - ][ +  - ]:       7771 :     xub_StrLen nMax = aPaM.GetNode()->Len();
    1609         [ +  + ]:       7771 :     if ( aTmpPaM.GetIndex() < nMax )
    1610                 :       3424 :         aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
    1611         [ +  - ]:       7771 :     lang::Locale aLocale( GetLocale( aTmpPaM ) );
    1612                 :            : 
    1613         [ +  - ]:       7771 :     uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1614         [ +  - ]:       7771 :     sal_Int16 nType = _xBI->getWordType(
    1615 [ +  - ][ +  - ]:       7771 :         aPaM.GetNode()->GetString(), aPaM.GetIndex(), aLocale);
         [ +  - ][ +  - ]
    1616                 :            : 
    1617         [ +  - ]:       7771 :     if ( nType == i18n::WordType::ANY_WORD )
    1618                 :            :     {
    1619         [ +  - ]:       7771 :         i18n::Boundary aBoundary = _xBI->getWordBoundary(
    1620 [ +  - ][ +  - ]:       7771 :             aPaM.GetNode()->GetString(), aPaM.GetIndex(), aLocale, nWordType, true);
         [ +  - ][ +  - ]
    1621                 :            : 
    1622                 :            :         // don't select when curser at end of word
    1623   [ +  -  +  + ]:      14465 :         if ( ( aBoundary.endPos > aPaM.GetIndex() ) &&
                 [ +  + ]
           [ +  +  +  + ]
    1624                 :       6694 :              ( ( aBoundary.startPos < aPaM.GetIndex() ) || ( bAcceptStartOfWord && ( aBoundary.startPos == aPaM.GetIndex() ) ) ) )
    1625                 :            :         {
    1626                 :       3370 :             aNewSel.Min().SetIndex( (sal_uInt16)aBoundary.startPos );
    1627                 :       7771 :             aNewSel.Max().SetIndex( (sal_uInt16)aBoundary.endPos );
    1628                 :            :         }
    1629                 :            :     }
    1630                 :            : 
    1631                 :       7771 :     return aNewSel;
    1632                 :            : }
    1633                 :            : 
    1634                 :          0 : EditSelection ImpEditEngine::SelectSentence( const EditSelection& rCurSel )
    1635                 :            :     const
    1636                 :            : {
    1637         [ #  # ]:          0 :     uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1638                 :          0 :     const EditPaM& rPaM = rCurSel.Min();
    1639         [ #  # ]:          0 :     const ContentNode* pNode = rPaM.GetNode();
    1640                 :            :     // #i50710# line breaks are marked with 0x01 - the break iterator prefers 0x0a for that
    1641 [ #  # ][ #  # ]:          0 :     String sParagraph = pNode->GetString();
    1642         [ #  # ]:          0 :     sParagraph.SearchAndReplaceAll(0x01,0x0a);
    1643                 :            :     //return Null if search starts at the beginning of the string
    1644 [ #  # ][ #  # ]:          0 :     sal_Int32 nStart = rPaM.GetIndex() ? _xBI->beginOfSentence( sParagraph, rPaM.GetIndex(), GetLocale( rPaM ) ) : 0;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
    1645                 :            : 
    1646         [ #  # ]:          0 :     sal_Int32 nEnd = _xBI->endOfSentence(
    1647 [ #  # ][ #  # ]:          0 :         pNode->GetString(), rPaM.GetIndex(), GetLocale(rPaM));
         [ #  # ][ #  # ]
    1648                 :            : 
    1649         [ #  # ]:          0 :     EditSelection aNewSel( rCurSel );
    1650                 :            :     OSL_ENSURE(pNode->Len() ? (nStart < pNode->Len()) : (nStart == 0), "sentence start index out of range");
    1651                 :            :     OSL_ENSURE(nEnd <= pNode->Len(), "sentence end index out of range");
    1652                 :          0 :     aNewSel.Min().SetIndex( (sal_uInt16)nStart );
    1653                 :          0 :     aNewSel.Max().SetIndex( (sal_uInt16)nEnd );
    1654         [ #  # ]:          0 :     return aNewSel;
    1655                 :            : }
    1656                 :            : 
    1657                 :          0 : sal_Bool ImpEditEngine::IsInputSequenceCheckingRequired( sal_Unicode nChar, const EditSelection& rCurSel ) const
    1658                 :            : {
    1659         [ #  # ]:          0 :     uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1660         [ #  # ]:          0 :     if (!pCTLOptions)
    1661 [ #  # ][ #  # ]:          0 :         pCTLOptions = new SvtCTLOptions;
    1662                 :            : 
    1663                 :            :     // get the index that really is first
    1664                 :          0 :     sal_uInt16 nFirstPos = rCurSel.Min().GetIndex();
    1665                 :          0 :     sal_uInt16 nMaxPos   = rCurSel.Max().GetIndex();
    1666         [ #  # ]:          0 :     if (nMaxPos < nFirstPos)
    1667                 :          0 :         nFirstPos = nMaxPos;
    1668                 :            : 
    1669                 :            :     sal_Bool bIsSequenceChecking =
    1670         [ #  # ]:          0 :         pCTLOptions->IsCTLFontEnabled() &&
    1671         [ #  # ]:          0 :         pCTLOptions->IsCTLSequenceChecking() &&
    1672                 :            :         nFirstPos != 0 && /* first char needs not to be checked */
    1673 [ #  # ][ #  # ]:          0 :         _xBI.is() && i18n::ScriptType::COMPLEX == _xBI->getScriptType( rtl::OUString( nChar ), 0 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1674                 :            : 
    1675                 :          0 :     return bIsSequenceChecking;
    1676                 :            : }
    1677                 :            : 
    1678                 :       1177 :  bool lcl_HasStrongLTR ( const String& rTxt, xub_StrLen nStart, xub_StrLen nEnd )
    1679                 :            :  {
    1680         [ +  - ]:       1177 :      for ( xub_StrLen nCharIdx = nStart; nCharIdx < nEnd; ++nCharIdx )
    1681                 :            :      {
    1682                 :       1177 :          const UCharDirection nCharDir = u_charDirection ( rTxt.GetChar ( nCharIdx ));
    1683 [ #  # ][ #  # ]:       1177 :          if ( nCharDir == U_LEFT_TO_RIGHT ||
                 [ -  + ]
    1684                 :            :               nCharDir == U_LEFT_TO_RIGHT_EMBEDDING ||
    1685                 :            :               nCharDir == U_LEFT_TO_RIGHT_OVERRIDE )
    1686                 :       1177 :              return true;
    1687                 :            :      }
    1688                 :       1177 :      return false;
    1689                 :            :  }
    1690                 :            : 
    1691                 :            : 
    1692                 :            : 
    1693                 :     194477 : void ImpEditEngine::InitScriptTypes( sal_uInt16 nPara )
    1694                 :            : {
    1695                 :     194477 :     ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1696                 :     194477 :     ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
    1697                 :     194477 :     rTypes.clear();
    1698                 :            : 
    1699                 :     194477 :     ContentNode* pNode = pParaPortion->GetNode();
    1700         [ +  + ]:     194477 :     if ( pNode->Len() )
    1701                 :            :     {
    1702         [ +  - ]:     174733 :         uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    1703                 :            : 
    1704 [ +  - ][ +  - ]:     174733 :         String aText = pNode->GetString();
    1705                 :            : 
    1706                 :            :         // To handle fields put the character from the field in the string,
    1707                 :            :         // because endOfScript( ... ) will skip the CH_FEATURE, because this is WEAK
    1708         [ +  - ]:     174733 :         const EditCharAttrib* pField = pNode->GetCharAttribs().FindNextAttrib( EE_FEATURE_FIELD, 0 );
    1709         [ +  + ]:     185833 :         while ( pField )
    1710                 :            :         {
    1711         [ +  - ]:      11100 :             rtl::OUString aFldText = static_cast<const EditCharAttribField*>(pField)->GetFieldValue();
    1712         [ +  + ]:      11100 :             if ( !aFldText.isEmpty() )
    1713                 :            :             {
    1714         [ +  - ]:       3408 :                 aText.SetChar( pField->GetStart(), aFldText.getStr()[0] );
    1715 [ +  - ][ +  - ]:       3408 :                 short nFldScriptType = _xBI->getScriptType( aFldText, 0 );
    1716                 :            : 
    1717         [ +  + ]:      21840 :                 for ( sal_uInt16 nCharInField = 1; nCharInField < aFldText.getLength(); nCharInField++ )
    1718                 :            :                 {
    1719 [ +  - ][ +  - ]:      18432 :                     short nTmpType = _xBI->getScriptType( aFldText, nCharInField );
    1720                 :            : 
    1721                 :            :                     // First char from field wins...
    1722         [ -  + ]:      18432 :                     if ( nFldScriptType == i18n::ScriptType::WEAK )
    1723                 :            :                     {
    1724                 :          0 :                         nFldScriptType = nTmpType;
    1725         [ #  # ]:          0 :                         aText.SetChar( pField->GetStart(), aFldText.getStr()[nCharInField] );
    1726                 :            :                     }
    1727                 :            : 
    1728                 :            :                     // ...  but if the first one is LATIN, and there are CJK or CTL chars too,
    1729                 :            :                     // we prefer that ScripType because we need an other font.
    1730 [ +  - ][ -  + ]:      18432 :                     if ( ( nTmpType == i18n::ScriptType::ASIAN ) || ( nTmpType == i18n::ScriptType::COMPLEX ) )
    1731                 :            :                     {
    1732         [ #  # ]:          0 :                         aText.SetChar( pField->GetStart(), aFldText.getStr()[nCharInField] );
    1733                 :          0 :                         break;
    1734                 :            :                     }
    1735                 :            :                 }
    1736                 :            :             }
    1737                 :            :             // #112831# Last Field might go from 0xffff to 0x0000
    1738 [ +  - ][ +  - ]:      11100 :             pField = pField->GetEnd() ? pNode->GetCharAttribs().FindNextAttrib( EE_FEATURE_FIELD, pField->GetEnd() ) : NULL;
    1739                 :      11100 :         }
    1740                 :            : 
    1741         [ +  - ]:     174733 :         ::rtl::OUString aOUText( aText );
    1742                 :     174733 :         sal_uInt16 nTextLen = (sal_uInt16)aOUText.getLength();
    1743                 :            : 
    1744                 :     174733 :         sal_Int32 nPos = 0;
    1745 [ +  - ][ +  - ]:     174733 :         short nScriptType = _xBI->getScriptType( aOUText, nPos );
    1746         [ +  - ]:     174733 :         rTypes.push_back( ScriptTypePosInfo( nScriptType, (sal_uInt16)nPos, nTextLen ) );
    1747 [ +  - ][ +  - ]:     174733 :         nPos = _xBI->endOfScript( aOUText, nPos, nScriptType );
    1748 [ +  - ][ +  + ]:     176613 :         while ( ( nPos != (-1) ) && ( nPos < nTextLen ) )
                 [ +  + ]
    1749                 :            :         {
    1750         [ +  - ]:       1880 :             rTypes.back().nEndPos = (sal_uInt16)nPos;
    1751                 :            : 
    1752 [ +  - ][ +  - ]:       1880 :             nScriptType = _xBI->getScriptType( aOUText, nPos );
    1753 [ +  - ][ +  - ]:       1880 :             long nEndPos = _xBI->endOfScript( aOUText, nPos, nScriptType );
    1754                 :            : 
    1755 [ +  - ][ +  - ]:       1880 :             if ( ( nScriptType == i18n::ScriptType::WEAK ) || ( nScriptType == rTypes.back().nScriptType ) )
         [ -  + ][ -  + ]
    1756                 :            :             {
    1757                 :            :                 // Expand last ScriptTypePosInfo, don't create weak or unecessary portions
    1758         [ #  # ]:          0 :                 rTypes.back().nEndPos = (sal_uInt16)nEndPos;
    1759                 :            :             }
    1760                 :            :             else
    1761                 :            :             {
    1762 [ +  - ][ +  - ]:       1880 :                 if ( _xBI->getScriptType( aOUText, nPos - 1 ) == i18n::ScriptType::WEAK )
                 [ +  - ]
    1763                 :            :                 {
    1764 [ +  - ][ +  - ]:       1880 :                     switch ( u_charType(aOUText.iterateCodePoints(&nPos, 0) ) ) {
                 [ -  + ]
    1765                 :            :                     case U_NON_SPACING_MARK:
    1766                 :            :                     case U_ENCLOSING_MARK:
    1767                 :            :                     case U_COMBINING_SPACING_MARK:
    1768                 :          0 :                         --nPos;
    1769         [ #  # ]:          0 :                         rTypes.back().nEndPos--;
    1770                 :       1880 :                         break;
    1771                 :            :                     }
    1772                 :            :                 }
    1773         [ +  - ]:       1880 :                 rTypes.push_back( ScriptTypePosInfo( nScriptType, (sal_uInt16)nPos, nTextLen ) );
    1774                 :            :             }
    1775                 :            : 
    1776                 :       1880 :             nPos = nEndPos;
    1777                 :            :         }
    1778                 :            : 
    1779 [ +  - ][ +  + ]:     174733 :         if ( rTypes[0].nScriptType == i18n::ScriptType::WEAK )
    1780 [ +  - ][ +  + ]:       4508 :             rTypes[0].nScriptType = ( rTypes.size() > 1 ) ? rTypes[1].nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
         [ +  - ][ +  - ]
    1781                 :            : 
    1782                 :            :         // create writing direction information:
    1783         [ +  - ]:     174733 :         if ( pParaPortion->aWritingDirectionInfos.empty() )
    1784         [ +  - ]:     174733 :             InitWritingDirections( nPara );
    1785                 :            : 
    1786                 :            :         // i89825: Use CTL font for numbers embedded into an RTL run:
    1787                 :     174733 :         WritingDirectionInfos& rDirInfos = pParaPortion->aWritingDirectionInfos;
    1788         [ +  + ]:     349466 :         for ( size_t n = 0; n < rDirInfos.size(); ++n )
    1789                 :            :         {
    1790         [ +  - ]:     174733 :             const xub_StrLen nStart = rDirInfos[n].nStartPos;
    1791         [ +  - ]:     174733 :             const xub_StrLen nEnd   = rDirInfos[n].nEndPos;
    1792         [ +  - ]:     174733 :             const sal_uInt8 nCurrDirType = rDirInfos[n].nType;
    1793                 :            : 
    1794 [ +  - ][ +  + ]:     175910 :             if ( nCurrDirType % 2 == UBIDI_RTL  || // text in RTL run
         [ -  + ][ -  + ]
    1795         [ +  - ]:       1177 :                 ( nCurrDirType > UBIDI_LTR && !lcl_HasStrongLTR( aText, nStart, nEnd ) ) ) // non-strong text in embedded LTR run
    1796                 :            :             {
    1797                 :          0 :                 size_t nIdx = 0;
    1798                 :            : 
    1799                 :            :                 // Skip entries in ScriptArray which are not inside the RTL run:
    1800 [ #  # ][ #  # ]:          0 :                 while ( nIdx < rTypes.size() && rTypes[nIdx].nStartPos < nStart )
         [ #  # ][ #  # ]
    1801                 :          0 :                     ++nIdx;
    1802                 :            : 
    1803                 :            :                 // Remove any entries *inside* the current run:
    1804 [ #  # ][ #  # ]:          0 :                 while ( nIdx < rTypes.size() && rTypes[nIdx].nEndPos <= nEnd )
         [ #  # ][ #  # ]
    1805 [ #  # ][ #  # ]:          0 :                     rTypes.erase( rTypes.begin()+nIdx );
    1806                 :            : 
    1807                 :            :                 // special case:
    1808 [ #  # ][ #  # ]:          0 :                 if(nIdx < rTypes.size() && rTypes[nIdx].nStartPos < nStart && rTypes[nIdx].nEndPos > nEnd)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1809                 :            :                 {
    1810 [ #  # ][ #  # ]:          0 :                     rTypes.insert( rTypes.begin()+nIdx, ScriptTypePosInfo( rTypes[nIdx].nScriptType, (sal_uInt16)nEnd, rTypes[nIdx].nEndPos ) );
         [ #  # ][ #  # ]
    1811         [ #  # ]:          0 :                     rTypes[nIdx].nEndPos = nStart;
    1812                 :            :                 }
    1813                 :            : 
    1814         [ #  # ]:          0 :                 if( nIdx )
    1815         [ #  # ]:          0 :                     rTypes[nIdx - 1].nEndPos = nStart;
    1816                 :            : 
    1817 [ #  # ][ #  # ]:          0 :                 rTypes.insert( rTypes.begin()+nIdx, ScriptTypePosInfo( i18n::ScriptType::COMPLEX, (sal_uInt16)nStart, (sal_uInt16)nEnd) );
    1818                 :          0 :                 ++nIdx;
    1819                 :            : 
    1820         [ #  # ]:          0 :                 if( nIdx < rTypes.size() )
    1821         [ #  # ]:          0 :                     rTypes[nIdx].nStartPos = nEnd;
    1822                 :            :             }
    1823         [ +  - ]:     174733 :         }
    1824                 :            :     }
    1825                 :     194477 : }
    1826                 :            : 
    1827                 :     904251 : sal_uInt16 ImpEditEngine::GetScriptType( const EditPaM& rPaM, sal_uInt16* pEndPos ) const
    1828                 :            : {
    1829                 :     904251 :     sal_uInt16 nScriptType = 0;
    1830                 :            : 
    1831         [ -  + ]:     904251 :     if ( pEndPos )
    1832                 :          0 :         *pEndPos = rPaM.GetNode()->Len();
    1833                 :            : 
    1834         [ +  + ]:     904251 :     if ( rPaM.GetNode()->Len() )
    1835                 :            :     {
    1836                 :     685215 :         sal_uInt16 nPara = GetEditDoc().GetPos( rPaM.GetNode() );
    1837                 :     685215 :         const ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1838         [ +  + ]:     685215 :         if ( pParaPortion->aScriptInfos.empty() )
    1839                 :         12 :             ((ImpEditEngine*)this)->InitScriptTypes( nPara );
    1840                 :            : 
    1841                 :     685215 :         const ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
    1842                 :     685215 :         sal_uInt16 nPos = rPaM.GetIndex();
    1843         [ +  + ]:    1372218 :         for ( size_t n = 0; n < rTypes.size(); n++ )
    1844                 :            :         {
    1845 [ +  - ][ +  + ]:     687003 :             if ( ( rTypes[n].nStartPos <= nPos ) && ( rTypes[n].nEndPos >= nPos ) )
                 [ +  + ]
    1846                 :            :                {
    1847                 :     685213 :                 nScriptType = rTypes[n].nScriptType;
    1848         [ -  + ]:     685213 :                 if( pEndPos )
    1849                 :          0 :                     *pEndPos = rTypes[n].nEndPos;
    1850                 :     685213 :                 break;
    1851                 :            :             }
    1852                 :            :         }
    1853                 :            :     }
    1854         [ +  + ]:     904251 :     return nScriptType ? nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
    1855                 :            : }
    1856                 :            : 
    1857                 :      65838 : sal_uInt16 ImpEditEngine::GetScriptType( const EditSelection& rSel ) const
    1858                 :            : {
    1859         [ +  - ]:      65838 :     EditSelection aSel( rSel );
    1860         [ +  - ]:      65838 :     aSel.Adjust( aEditDoc );
    1861                 :            : 
    1862                 :      65838 :     short nScriptType = 0;
    1863                 :            : 
    1864 [ +  - ][ +  - ]:      65838 :      sal_uInt16 nStartPara = GetEditDoc().GetPos( aSel.Min().GetNode() );
    1865 [ +  - ][ +  - ]:      65838 :      sal_uInt16 nEndPara = GetEditDoc().GetPos( aSel.Max().GetNode() );
    1866                 :            : 
    1867         [ +  + ]:     137713 :     for ( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
    1868                 :            :     {
    1869         [ +  - ]:      71875 :         const ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1870         [ +  + ]:      71875 :         if ( pParaPortion->aScriptInfos.empty() )
    1871         [ +  - ]:      66533 :             ((ImpEditEngine*)this)->InitScriptTypes( nPara );
    1872                 :            : 
    1873                 :      71875 :         const ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
    1874                 :            : 
    1875                 :            :         // find the first(!) script type position that holds the
    1876                 :            :         // complete selection. Thus it will work for selections as
    1877                 :            :         // well as with just moving the cursor from char to char.
    1878         [ +  + ]:      71875 :         sal_uInt16 nS = ( nPara == nStartPara ) ? aSel.Min().GetIndex() : 0;
    1879 [ +  + ][ +  - ]:      71875 :         sal_uInt16 nE = ( nPara == nEndPara ) ? aSel.Max().GetIndex() : pParaPortion->GetNode()->Len();
    1880         [ +  + ]:      75887 :         for ( size_t n = 0; n < rTypes.size(); n++ )
    1881                 :            :         {
    1882 [ +  - ][ +  + ]:      68421 :             if (rTypes[n].nStartPos <= nS  &&  nE <= rTypes[n].nEndPos)
         [ +  - ][ +  + ]
                 [ +  + ]
    1883                 :            :                {
    1884 [ +  - ][ +  - ]:      64409 :                 if ( rTypes[n].nScriptType != i18n::ScriptType::WEAK )
    1885                 :            :                 {
    1886 [ +  - ][ +  - ]:      64409 :                     nScriptType |= GetItemScriptType ( rTypes[n].nScriptType );
    1887                 :            :                 }
    1888                 :            :                 else
    1889                 :            :                 {
    1890 [ #  # ][ #  # ]:          0 :                     if ( !nScriptType && n )
    1891                 :            :                     {
    1892                 :            :                         // #93548# When starting with WEAK, use prev ScriptType...
    1893         [ #  # ]:          0 :                         nScriptType = rTypes[n-1].nScriptType;
    1894                 :            :                     }
    1895                 :            :                 }
    1896                 :      64409 :                 break;
    1897                 :            :             }
    1898                 :            :         }
    1899                 :            :     }
    1900 [ +  + ][ +  - ]:      65838 :     return nScriptType ? nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
    1901                 :            : }
    1902                 :            : 
    1903                 :        182 : sal_Bool ImpEditEngine::IsScriptChange( const EditPaM& rPaM ) const
    1904                 :            : {
    1905                 :        182 :     bool bScriptChange = false;
    1906                 :            : 
    1907         [ +  - ]:        182 :     if ( rPaM.GetNode()->Len() )
    1908                 :            :     {
    1909                 :        182 :         sal_uInt16 nPara = GetEditDoc().GetPos( rPaM.GetNode() );
    1910                 :        182 :         const ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1911         [ -  + ]:        182 :         if ( pParaPortion->aScriptInfos.empty() )
    1912                 :          0 :             ((ImpEditEngine*)this)->InitScriptTypes( nPara );
    1913                 :            : 
    1914                 :        182 :         const ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
    1915                 :        182 :         sal_uInt16 nPos = rPaM.GetIndex();
    1916         [ +  + ]:        412 :         for ( size_t n = 0; n < rTypes.size(); n++ )
    1917                 :            :         {
    1918         [ +  + ]:        230 :             if ( rTypes[n].nStartPos == nPos )
    1919                 :            :                {
    1920                 :         66 :                 bScriptChange = true;
    1921                 :         66 :                 break;
    1922                 :            :             }
    1923                 :            :         }
    1924                 :            :     }
    1925                 :        182 :     return bScriptChange;
    1926                 :            : }
    1927                 :            : 
    1928                 :     322697 : sal_Bool ImpEditEngine::HasScriptType( sal_uInt16 nPara, sal_uInt16 nType ) const
    1929                 :            : {
    1930                 :     322697 :     bool bTypeFound = false;
    1931                 :            : 
    1932                 :     322697 :     const ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1933         [ +  + ]:     322697 :     if ( pParaPortion->aScriptInfos.empty() )
    1934                 :     127932 :         ((ImpEditEngine*)this)->InitScriptTypes( nPara );
    1935                 :            : 
    1936                 :     322697 :     const ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
    1937 [ +  + ][ +  - ]:     631905 :     for ( size_t n = rTypes.size(); n && !bTypeFound; )
                 [ +  + ]
    1938                 :            :     {
    1939         [ -  + ]:     309208 :         if ( rTypes[--n].nScriptType == nType )
    1940                 :          0 :                 bTypeFound = true;
    1941                 :            :     }
    1942                 :     322697 :     return bTypeFound;
    1943                 :            : }
    1944                 :            : 
    1945                 :     174733 : void ImpEditEngine::InitWritingDirections( sal_uInt16 nPara )
    1946                 :            : {
    1947                 :     174733 :     ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    1948                 :     174733 :     WritingDirectionInfos& rInfos = pParaPortion->aWritingDirectionInfos;
    1949                 :     174733 :     rInfos.clear();
    1950                 :            : 
    1951                 :     174733 :     sal_Bool bCTL = sal_False;
    1952                 :     174733 :     ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
    1953         [ +  + ]:     351346 :     for ( size_t n = 0; n < rTypes.size(); n++ )
    1954                 :            :     {
    1955         [ -  + ]:     176613 :         if ( rTypes[n].nScriptType == i18n::ScriptType::COMPLEX )
    1956                 :            :            {
    1957                 :          0 :             bCTL = sal_True;
    1958                 :          0 :             break;
    1959                 :            :         }
    1960                 :            :     }
    1961                 :            : 
    1962         [ +  + ]:     174733 :     const UBiDiLevel nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
    1963 [ +  - ][ +  + ]:     174733 :     if ( ( bCTL || ( nBidiLevel == 1 /*RTL*/ ) ) && pParaPortion->GetNode()->Len() )
         [ +  - ][ +  + ]
    1964                 :            :     {
    1965                 :            : 
    1966 [ +  - ][ +  - ]:       1177 :         String aText = pParaPortion->GetNode()->GetString();
    1967                 :            : 
    1968                 :            :         //
    1969                 :            :         // Bidi functions from icu 2.0
    1970                 :            :         //
    1971                 :       1177 :         UErrorCode nError = U_ZERO_ERROR;
    1972         [ +  - ]:       1177 :         UBiDi* pBidi = ubidi_openSized( aText.Len(), 0, &nError );
    1973                 :       1177 :         nError = U_ZERO_ERROR;
    1974                 :            : 
    1975         [ +  - ]:       1177 :         ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(aText.GetBuffer()), aText.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
    1976                 :       1177 :         nError = U_ZERO_ERROR;
    1977                 :            : 
    1978         [ +  - ]:       1177 :         size_t nCount = ubidi_countRuns( pBidi, &nError );
    1979                 :            : 
    1980                 :       1177 :         int32_t nStart = 0;
    1981                 :            :         int32_t nEnd;
    1982                 :            :         UBiDiLevel nCurrDir;
    1983                 :            : 
    1984         [ +  + ]:       2354 :         for ( size_t nIdx = 0; nIdx < nCount; ++nIdx )
    1985                 :            :         {
    1986         [ +  - ]:       1177 :             ubidi_getLogicalRun( pBidi, nStart, &nEnd, &nCurrDir );
    1987         [ +  - ]:       1177 :             rInfos.push_back( WritingDirectionInfo( nCurrDir, (sal_uInt16)nStart, (sal_uInt16)nEnd ) );
    1988                 :       1177 :             nStart = nEnd;
    1989                 :            :         }
    1990                 :            : 
    1991 [ +  - ][ +  - ]:       1177 :         ubidi_close( pBidi );
    1992                 :            :     }
    1993                 :            : 
    1994                 :            :     // No infos mean no CTL and default dir is L2R...
    1995         [ +  + ]:     174733 :     if ( rInfos.empty() )
    1996         [ +  - ]:     173556 :         rInfos.push_back( WritingDirectionInfo( 0, 0, (sal_uInt16)pParaPortion->GetNode()->Len() ) );
    1997                 :            : 
    1998                 :     174733 : }
    1999                 :            : 
    2000                 :     964676 : sal_Bool ImpEditEngine::IsRightToLeft( sal_uInt16 nPara ) const
    2001                 :            : {
    2002                 :     964676 :     sal_Bool bR2L = sal_False;
    2003                 :     964676 :     const SvxFrameDirectionItem* pFrameDirItem = NULL;
    2004                 :            : 
    2005         [ +  - ]:     964676 :     if ( !IsVertical() )
    2006                 :            :     {
    2007                 :     964676 :         bR2L = GetDefaultHorizontalTextDirection() == EE_HTEXTDIR_R2L;
    2008                 :     964676 :         pFrameDirItem = &(const SvxFrameDirectionItem&)GetParaAttrib( nPara, EE_PARA_WRITINGDIR );
    2009         [ +  + ]:     964676 :         if ( pFrameDirItem->GetValue() == FRMDIR_ENVIRONMENT )
    2010                 :            :         {
    2011                 :            :             // #103045# if DefaultHorizontalTextDirection is set, use that value, otherwise pool default.
    2012         [ +  + ]:     498875 :             if ( GetDefaultHorizontalTextDirection() != EE_HTEXTDIR_DEFAULT )
    2013                 :            :             {
    2014                 :      12031 :                 pFrameDirItem = NULL; // bR2L allready set to default horizontal text direction
    2015                 :            :             }
    2016                 :            :             else
    2017                 :            :             {
    2018                 :            :                 // Use pool default
    2019                 :     486844 :                 pFrameDirItem = &(const SvxFrameDirectionItem&)((ImpEditEngine*)this)->GetEmptyItemSet().Get( EE_PARA_WRITINGDIR );
    2020                 :            :             }
    2021                 :            :         }
    2022                 :            :     }
    2023                 :            : 
    2024         [ +  + ]:     964676 :     if ( pFrameDirItem )
    2025                 :     952645 :         bR2L = pFrameDirItem->GetValue() == FRMDIR_HORI_RIGHT_TOP;
    2026                 :            : 
    2027                 :     964676 :     return bR2L;
    2028                 :            : }
    2029                 :            : 
    2030                 :       1040 : sal_Bool ImpEditEngine::HasDifferentRTLLevels( const ContentNode* pNode )
    2031                 :            : {
    2032                 :       1040 :     sal_uInt16 nPara = GetEditDoc().GetPos( (ContentNode*)pNode );
    2033                 :       1040 :     ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    2034                 :            : 
    2035                 :       1040 :     sal_Bool bHasDifferentRTLLevels = sal_False;
    2036                 :            : 
    2037         [ -  + ]:       1040 :     sal_uInt16 nRTLLevel = IsRightToLeft( nPara ) ? 1 : 0;
    2038         [ +  + ]:       2080 :     for ( sal_uInt16 n = 0; n < pParaPortion->GetTextPortions().Count(); n++ )
    2039                 :            :     {
    2040                 :       1040 :         const TextPortion* pTextPortion = pParaPortion->GetTextPortions()[n];
    2041         [ -  + ]:       1040 :         if ( pTextPortion->GetRightToLeft() != nRTLLevel )
    2042                 :            :         {
    2043                 :          0 :             bHasDifferentRTLLevels = sal_True;
    2044                 :          0 :             break;
    2045                 :            :         }
    2046                 :            :     }
    2047                 :       1040 :     return bHasDifferentRTLLevels;
    2048                 :            : }
    2049                 :            : 
    2050                 :            : 
    2051                 :     227991 : sal_uInt8 ImpEditEngine::GetRightToLeft( sal_uInt16 nPara, sal_uInt16 nPos, sal_uInt16* pStart, sal_uInt16* pEnd )
    2052                 :            : {
    2053                 :     227991 :     sal_uInt8 nRightToLeft = 0;
    2054                 :            : 
    2055                 :     227991 :     ContentNode* pNode = aEditDoc.GetObject( nPara );
    2056 [ +  + ][ +  + ]:     227991 :     if ( pNode && pNode->Len() )
                 [ +  - ]
    2057                 :            :     {
    2058                 :     226565 :         ParaPortion* pParaPortion = GetParaPortions().SafeGetObject( nPara );
    2059         [ -  + ]:     226565 :         if ( pParaPortion->aWritingDirectionInfos.empty() )
    2060                 :          0 :             InitWritingDirections( nPara );
    2061                 :            : 
    2062                 :     226565 :         WritingDirectionInfos& rDirInfos = pParaPortion->aWritingDirectionInfos;
    2063         [ +  + ]:     453130 :         for ( size_t n = 0; n < rDirInfos.size(); n++ )
    2064                 :            :         {
    2065 [ +  - ][ +  + ]:     226565 :             if ( ( rDirInfos[n].nStartPos <= nPos ) && ( rDirInfos[n].nEndPos >= nPos ) )
                 [ +  + ]
    2066                 :            :                {
    2067                 :     226563 :                 nRightToLeft = rDirInfos[n].nType;
    2068         [ -  + ]:     226563 :                 if ( pStart )
    2069                 :          0 :                     *pStart = rDirInfos[n].nStartPos;
    2070         [ -  + ]:     226563 :                 if ( pEnd )
    2071                 :          0 :                     *pEnd = rDirInfos[n].nEndPos;
    2072                 :     226563 :                 break;
    2073                 :            :             }
    2074                 :            :         }
    2075                 :            :     }
    2076                 :     227991 :     return nRightToLeft;
    2077                 :            : }
    2078                 :            : 
    2079                 :     441605 : SvxAdjust ImpEditEngine::GetJustification( sal_uInt16 nPara ) const
    2080                 :            : {
    2081                 :     441605 :     SvxAdjust eJustification = SVX_ADJUST_LEFT;
    2082                 :            : 
    2083         [ +  - ]:     441605 :     if ( !aStatus.IsOutliner() )
    2084                 :            :     {
    2085                 :     441605 :         eJustification = ((const SvxAdjustItem&) GetParaAttrib( nPara, EE_PARA_JUST )).GetAdjust();
    2086                 :            : 
    2087         [ +  + ]:     441605 :         if ( IsRightToLeft( nPara ) )
    2088                 :            :         {
    2089         [ +  + ]:       1910 :             if ( eJustification == SVX_ADJUST_LEFT )
    2090                 :        273 :                 eJustification = SVX_ADJUST_RIGHT;
    2091         [ +  - ]:       1637 :             else if ( eJustification == SVX_ADJUST_RIGHT )
    2092                 :       1637 :                 eJustification = SVX_ADJUST_LEFT;
    2093                 :            :         }
    2094                 :            :     }
    2095                 :     441605 :     return eJustification;
    2096                 :            : }
    2097                 :            : 
    2098                 :        325 : SvxCellJustifyMethod ImpEditEngine::GetJustifyMethod( sal_uInt16 nPara ) const
    2099                 :            : {
    2100                 :            :     const SvxJustifyMethodItem& rItem = static_cast<const SvxJustifyMethodItem&>(
    2101                 :        325 :         GetParaAttrib(nPara, EE_PARA_JUST_METHOD));
    2102                 :        325 :     return static_cast<SvxCellJustifyMethod>(rItem.GetEnumValue());
    2103                 :            : }
    2104                 :            : 
    2105                 :      16003 : SvxCellVerJustify ImpEditEngine::GetVerJustification( sal_uInt16 nPara ) const
    2106                 :            : {
    2107                 :            :     const SvxVerJustifyItem& rItem = static_cast<const SvxVerJustifyItem&>(
    2108                 :      16003 :         GetParaAttrib(nPara, EE_PARA_VER_JUST));
    2109                 :      16003 :     return static_cast<SvxCellVerJustify>(rItem.GetEnumValue());
    2110                 :            : }
    2111                 :            : 
    2112                 :            : //  ----------------------------------------------------------------------
    2113                 :            : //  Text changes
    2114                 :            : //  ----------------------------------------------------------------------
    2115                 :            : 
    2116                 :       1848 : void ImpEditEngine::ImpRemoveChars( const EditPaM& rPaM, sal_uInt16 nChars, EditUndoRemoveChars* pCurUndo )
    2117                 :            : {
    2118 [ +  + ][ +  - ]:       1848 :     if ( IsUndoEnabled() && !IsInUndo() )
                 [ +  + ]
    2119                 :            :     {
    2120 [ +  - ][ +  - ]:        152 :         XubString aStr( rPaM.GetNode()->Copy( rPaM.GetIndex(), nChars ) );
    2121                 :            : 
    2122                 :            :         // Check whether attributes are deleted or changed:
    2123                 :        152 :         sal_uInt16 nStart = rPaM.GetIndex();
    2124                 :        152 :         sal_uInt16 nEnd = nStart + nChars;
    2125 [ +  - ][ +  - ]:        152 :         const CharAttribList::AttribsType& rAttribs = rPaM.GetNode()->GetCharAttribs().GetAttribs();
    2126         [ -  + ]:        152 :         for (size_t i = 0, n = rAttribs.size(); i < n; ++i)
    2127                 :            :         {
    2128         [ #  # ]:          0 :             const EditCharAttrib& rAttr = rAttribs[i];
    2129 [ #  # ][ #  # ]:          0 :             if (rAttr.GetEnd() >= nStart && rAttr.GetStart() < nEnd)
                 [ #  # ]
    2130                 :            :             {
    2131         [ #  # ]:          0 :                 EditSelection aSel( rPaM );
    2132                 :          0 :                 aSel.Max().GetIndex() = aSel.Max().GetIndex() + nChars;
    2133 [ #  # ][ #  # ]:          0 :                 EditUndoSetAttribs* pAttrUndo = CreateAttribUndo( aSel, GetEmptyItemSet() );
                 [ #  # ]
    2134         [ #  # ]:          0 :                 InsertUndo( pAttrUndo );
    2135                 :            :                 break;  // for
    2136                 :            :             }
    2137                 :            :         }
    2138 [ -  + ][ #  # ]:        152 :         if ( pCurUndo && ( CreateEditPaM( pCurUndo->GetEPaM() ) == rPaM ) )
         [ #  # ][ #  # ]
                 [ -  + ]
           [ -  +  #  # ]
    2139         [ #  # ]:          0 :             pCurUndo->GetStr() += aStr;
    2140                 :            :         else
    2141 [ +  - ][ +  - ]:        152 :             InsertUndo(new EditUndoRemoveChars(pEditEngine, CreateEPaM(rPaM), aStr));
         [ +  - ][ +  - ]
                 [ +  - ]
    2142                 :            :     }
    2143                 :            : 
    2144         [ +  - ]:       1848 :     aEditDoc.RemoveChars( rPaM, nChars );
    2145                 :       1848 :     TextModified();
    2146                 :       1848 : }
    2147                 :            : 
    2148                 :          0 : EditSelection ImpEditEngine::ImpMoveParagraphs( Range aOldPositions, sal_uInt16 nNewPos )
    2149                 :            : {
    2150                 :          0 :     aOldPositions.Justify();
    2151 [ #  # ][ #  # ]:          0 :     sal_Bool bValidAction = ( (long)nNewPos < aOldPositions.Min() ) || ( (long)nNewPos > aOldPositions.Max() );
    2152                 :            :     OSL_ENSURE( bValidAction, "Move in itself?" );
    2153                 :            :     OSL_ENSURE( aOldPositions.Max() <= (long)GetParaPortions().Count(), "totally over it: MoveParagraphs" );
    2154                 :            : 
    2155         [ #  # ]:          0 :     EditSelection aSelection;
    2156                 :            : 
    2157         [ #  # ]:          0 :     if ( !bValidAction )
    2158                 :            :     {
    2159 [ #  # ][ #  # ]:          0 :         aSelection = aEditDoc.GetStartPaM();
    2160                 :            :         return aSelection;
    2161                 :            :     }
    2162                 :            : 
    2163         [ #  # ]:          0 :     size_t nParaCount = GetParaPortions().Count();
    2164                 :            : 
    2165         [ #  # ]:          0 :     if ( nNewPos >= nParaCount )
    2166                 :          0 :         nNewPos = nParaCount;
    2167                 :            : 
    2168                 :            :     // Height may change when moving first or last Paragraph
    2169                 :          0 :     ParaPortion* pRecalc1 = NULL;
    2170                 :          0 :     ParaPortion* pRecalc2 = NULL;
    2171                 :          0 :     ParaPortion* pRecalc3 = NULL;
    2172                 :          0 :     ParaPortion* pRecalc4 = NULL;
    2173                 :            : 
    2174         [ #  # ]:          0 :     if ( nNewPos == 0 ) // Move to Start
    2175                 :            :     {
    2176         [ #  # ]:          0 :         pRecalc1 = GetParaPortions()[0];
    2177         [ #  # ]:          0 :         pRecalc2 = GetParaPortions()[aOldPositions.Min()];
    2178                 :            : 
    2179                 :            :     }
    2180         [ #  # ]:          0 :     else if ( nNewPos == nParaCount )
    2181                 :            :     {
    2182         [ #  # ]:          0 :         pRecalc1 = GetParaPortions()[nParaCount-1];
    2183         [ #  # ]:          0 :         pRecalc2 = GetParaPortions()[aOldPositions.Max()];
    2184                 :            :     }
    2185                 :            : 
    2186         [ #  # ]:          0 :     if ( aOldPositions.Min() == 0 ) // Move from Start
    2187                 :            :     {
    2188         [ #  # ]:          0 :         pRecalc3 = GetParaPortions()[0];
    2189         [ #  # ]:          0 :         pRecalc4 = GetParaPortions()[aOldPositions.Max()+1];
    2190                 :            :     }
    2191         [ #  # ]:          0 :     else if ( (sal_uInt16)aOldPositions.Max() == (nParaCount-1) )
    2192                 :            :     {
    2193         [ #  # ]:          0 :         pRecalc3 = GetParaPortions()[aOldPositions.Max()];
    2194         [ #  # ]:          0 :         pRecalc4 = GetParaPortions()[aOldPositions.Min()-1];
    2195                 :            :     }
    2196                 :            : 
    2197                 :          0 :     MoveParagraphsInfo aMoveParagraphsInfo( sal::static_int_cast< sal_uInt16 >(aOldPositions.Min()), sal::static_int_cast< sal_uInt16 >(aOldPositions.Max()), nNewPos );
    2198         [ #  # ]:          0 :     aBeginMovingParagraphsHdl.Call( &aMoveParagraphsInfo );
    2199                 :            : 
    2200 [ #  # ][ #  # ]:          0 :     if ( IsUndoEnabled() && !IsInUndo())
                 [ #  # ]
    2201 [ #  # ][ #  # ]:          0 :         InsertUndo(new EditUndoMoveParagraphs(pEditEngine, aOldPositions, nNewPos));
                 [ #  # ]
    2202                 :            : 
    2203                 :            :     // do not lose sight of the Position !
    2204         [ #  # ]:          0 :     ParaPortion* pDestPortion = GetParaPortions().SafeGetObject( nNewPos );
    2205                 :            : 
    2206         [ #  # ]:          0 :     ParaPortionList aTmpPortionList;
    2207         [ #  # ]:          0 :     for (sal_uInt16 i = (sal_uInt16)aOldPositions.Min(); i <= (sal_uInt16)aOldPositions.Max(); i++  )
    2208                 :            :     {
    2209                 :            :         // always aOldPositions.Min(), since Remove().
    2210         [ #  # ]:          0 :         ParaPortion* pTmpPortion = GetParaPortions().Release(aOldPositions.Min());
    2211         [ #  # ]:          0 :         aEditDoc.Release( (sal_uInt16)aOldPositions.Min() );
    2212         [ #  # ]:          0 :         aTmpPortionList.Append(pTmpPortion);
    2213                 :            :     }
    2214                 :            : 
    2215 [ #  # ][ #  # ]:          0 :     sal_uInt16 nRealNewPos = pDestPortion ? GetParaPortions().GetPos( pDestPortion ) : GetParaPortions().Count();
                 [ #  # ]
    2216                 :            :     OSL_ENSURE( nRealNewPos != USHRT_MAX, "ImpMoveParagraphs: Invalid Position!" );
    2217                 :            : 
    2218 [ #  # ][ #  # ]:          0 :     for (size_t i = 0; i < aTmpPortionList.Count(); ++i)
    2219                 :            :     {
    2220         [ #  # ]:          0 :         ParaPortion* pTmpPortion = aTmpPortionList[i];
    2221         [ #  # ]:          0 :         if ( i == 0 )
    2222         [ #  # ]:          0 :             aSelection.Min().SetNode( pTmpPortion->GetNode() );
    2223                 :            : 
    2224         [ #  # ]:          0 :         aSelection.Max().SetNode( pTmpPortion->GetNode() );
    2225         [ #  # ]:          0 :         aSelection.Max().SetIndex( pTmpPortion->GetNode()->Len() );
    2226                 :            : 
    2227                 :          0 :         ContentNode* pN = pTmpPortion->GetNode();
    2228         [ #  # ]:          0 :         aEditDoc.Insert(nRealNewPos+i, pN);
    2229                 :            : 
    2230         [ #  # ]:          0 :         GetParaPortions().Insert(nRealNewPos+i, pTmpPortion);
    2231                 :            :     }
    2232                 :            : 
    2233         [ #  # ]:          0 :     aEndMovingParagraphsHdl.Call( &aMoveParagraphsInfo );
    2234                 :            : 
    2235 [ #  # ][ #  # ]:          0 :     if ( GetNotifyHdl().IsSet() )
    2236                 :            :     {
    2237                 :          0 :         EENotify aNotify( EE_NOTIFY_PARAGRAPHSMOVED );
    2238                 :          0 :         aNotify.pEditEngine = GetEditEnginePtr();
    2239                 :          0 :         aNotify.nParagraph = nNewPos;
    2240                 :          0 :         aNotify.nParam1 = sal::static_int_cast< sal_uInt16 >(aOldPositions.Min());
    2241                 :          0 :         aNotify.nParam2 = sal::static_int_cast< sal_uInt16 >(aOldPositions.Max());
    2242         [ #  # ]:          0 :         CallNotify( aNotify );
    2243                 :            :     }
    2244                 :            : 
    2245         [ #  # ]:          0 :     aEditDoc.SetModified( sal_True );
    2246                 :            : 
    2247         [ #  # ]:          0 :     if ( pRecalc1 )
    2248         [ #  # ]:          0 :         CalcHeight( pRecalc1 );
    2249         [ #  # ]:          0 :     if ( pRecalc2 )
    2250         [ #  # ]:          0 :         CalcHeight( pRecalc2 );
    2251         [ #  # ]:          0 :     if ( pRecalc3 )
    2252         [ #  # ]:          0 :         CalcHeight( pRecalc3 );
    2253         [ #  # ]:          0 :     if ( pRecalc4 )
    2254         [ #  # ]:          0 :         CalcHeight( pRecalc4 );
    2255                 :            : 
    2256 [ #  # ][ #  # ]:          0 :     while( aTmpPortionList.Count() > 0 )
    2257 [ #  # ][ #  # ]:          0 :         aTmpPortionList.Release( aTmpPortionList.Count() - 1 );
    2258                 :            : 
    2259                 :            : #if OSL_DEBUG_LEVEL > 2
    2260                 :            :     GetParaPortions().DbgCheck(aEditDoc);
    2261                 :            : #endif
    2262         [ #  # ]:          0 :     return aSelection;
    2263                 :            : }
    2264                 :            : 
    2265                 :            : 
    2266                 :        810 : EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* pLeft, ContentNode* pRight, sal_Bool bBackward )
    2267                 :            : {
    2268                 :            :     OSL_ENSURE( pLeft != pRight, "Join together the same paragraph ?" );
    2269                 :            :     OSL_ENSURE( aEditDoc.GetPos( pLeft ) != USHRT_MAX, "Inserted node not found (1)" );
    2270                 :            :     OSL_ENSURE( aEditDoc.GetPos( pRight ) != USHRT_MAX, "Inserted node not found (2)" );
    2271                 :            : 
    2272                 :        810 :     sal_uInt16 nParagraphTobeDeleted = aEditDoc.GetPos( pRight );
    2273                 :        810 :     DeletedNodeInfo* pInf = new DeletedNodeInfo( (sal_uLong)pRight, nParagraphTobeDeleted );
    2274                 :        810 :     aDeletedNodes.push_back(pInf);
    2275                 :            : 
    2276                 :        810 :     GetEditEnginePtr()->ParagraphConnected( aEditDoc.GetPos( pLeft ), aEditDoc.GetPos( pRight ) );
    2277                 :            : 
    2278 [ +  - ][ +  + ]:        810 :     if ( IsUndoEnabled() && !IsInUndo() )
                 [ +  + ]
    2279                 :            :     {
    2280                 :            :         InsertUndo( new EditUndoConnectParas(pEditEngine,
    2281                 :         22 :             aEditDoc.GetPos( pLeft ), pLeft->Len(),
    2282                 :         44 :             pLeft->GetContentAttribs().GetItems(), pRight->GetContentAttribs().GetItems(),
    2283         [ +  - ]:         44 :             pLeft->GetStyleSheet(), pRight->GetStyleSheet(), bBackward ) );
    2284                 :            :     }
    2285                 :            : 
    2286         [ -  + ]:        810 :     if ( bBackward )
    2287                 :            :     {
    2288                 :          0 :         pLeft->SetStyleSheet( pRight->GetStyleSheet(), sal_True );
    2289                 :          0 :         pLeft->GetContentAttribs().GetItems().Set( pRight->GetContentAttribs().GetItems() );
    2290                 :          0 :         pLeft->GetCharAttribs().GetDefFont() = pRight->GetCharAttribs().GetDefFont();
    2291                 :            :     }
    2292                 :            : 
    2293                 :        810 :     ParaAttribsChanged( pLeft );
    2294                 :            : 
    2295                 :            :     // First search for Portions since pRight is gone after ConnectParagraphs.
    2296                 :        810 :     ParaPortion* pLeftPortion = FindParaPortion( pLeft );
    2297                 :            :     OSL_ENSURE( pLeftPortion, "Blind Portion in ImpConnectParagraphs(1)" );
    2298                 :            : 
    2299         [ -  + ]:        810 :     if ( GetStatus().DoOnlineSpelling() )
    2300                 :            :     {
    2301                 :          0 :         xub_StrLen nEnd = pLeft->Len();
    2302         [ #  # ]:          0 :         xub_StrLen nInv = nEnd ? nEnd-1 : nEnd;
    2303                 :          0 :         pLeft->GetWrongList()->ClearWrongs( nInv, 0xFFFF, pLeft );  // Possibly remove one
    2304                 :          0 :         pLeft->GetWrongList()->MarkInvalid( nInv, nEnd+1 );
    2305                 :            :         // Take over misspelled words
    2306                 :          0 :         WrongList* pRWrongs = pRight->GetWrongList();
    2307 [ #  # ][ #  # ]:          0 :         for (WrongList::iterator i = pRWrongs->begin(); i < pRWrongs->end(); ++i)
         [ #  # ][ #  # ]
    2308                 :            :         {
    2309         [ #  # ]:          0 :             if (i->nStart != 0)   // Not a subsequent
    2310                 :            :             {
    2311                 :          0 :                 i->nStart = i->nStart + nEnd;
    2312                 :          0 :                 i->nEnd = i->nEnd + nEnd;
    2313         [ #  # ]:          0 :                 pLeft->GetWrongList()->push_back(*i);
    2314                 :            :             }
    2315                 :            :         }
    2316                 :            :     }
    2317                 :            : 
    2318         [ +  - ]:        810 :     if ( IsCallParaInsertedOrDeleted() )
    2319                 :        810 :         GetEditEnginePtr()->ParagraphDeleted( nParagraphTobeDeleted );
    2320                 :            : 
    2321                 :        810 :     EditPaM aPaM = aEditDoc.ConnectParagraphs( pLeft, pRight );
    2322                 :        810 :     GetParaPortions().Remove( nParagraphTobeDeleted );
    2323                 :            : 
    2324                 :        810 :     pLeftPortion->MarkSelectionInvalid( aPaM.GetIndex(), pLeft->Len() );
    2325                 :            : 
    2326                 :            :     // the right node is deleted by EditDoc:ConnectParagraphs().
    2327         [ -  + ]:        810 :     if ( GetTextRanger() )
    2328                 :            :     {
    2329                 :            :         // By joining together the two, the left is although reformatted,
    2330                 :            :         // however if its height does not change then the formatting receives
    2331                 :            :         // the change of the total text hight too late...
    2332         [ #  # ]:          0 :         for ( sal_uInt16 n = nParagraphTobeDeleted; n < GetParaPortions().Count(); n++ )
    2333                 :            :         {
    2334                 :          0 :             ParaPortion* pPP = GetParaPortions()[n];
    2335                 :          0 :             pPP->MarkSelectionInvalid( 0, pPP->GetNode()->Len() );
    2336                 :          0 :             pPP->GetLines().Reset();
    2337                 :            :         }
    2338                 :            :     }
    2339                 :            : 
    2340                 :        810 :     TextModified();
    2341                 :            : 
    2342                 :        810 :     return aPaM;
    2343                 :            : }
    2344                 :            : 
    2345                 :          0 : EditPaM ImpEditEngine::DeleteLeftOrRight( const EditSelection& rSel, sal_uInt8 nMode, sal_uInt8 nDelMode )
    2346                 :            : {
    2347                 :            :     OSL_ENSURE( !EditSelection( rSel ).DbgIsBuggy( aEditDoc ), "Index out of range in DeleteLeftOrRight" );
    2348                 :            : 
    2349 [ #  # ][ #  # ]:          0 :     if ( rSel.HasRange() )  // only then Delete Selection
    2350         [ #  # ]:          0 :         return ImpDeleteSelection( rSel );
    2351                 :            : 
    2352         [ #  # ]:          0 :     EditPaM aCurPos( rSel.Max() );
    2353         [ #  # ]:          0 :     EditPaM aDelStart( aCurPos );
    2354         [ #  # ]:          0 :     EditPaM aDelEnd( aCurPos );
    2355         [ #  # ]:          0 :     if ( nMode == DEL_LEFT )
    2356                 :            :     {
    2357         [ #  # ]:          0 :         if ( nDelMode == DELMODE_SIMPLE )
    2358                 :            :         {
    2359 [ #  # ][ #  # ]:          0 :             aDelStart = CursorLeft( aCurPos, i18n::CharacterIteratorMode::SKIPCHARACTER );
    2360                 :            :         }
    2361         [ #  # ]:          0 :         else if ( nDelMode == DELMODE_RESTOFWORD )
    2362                 :            :         {
    2363 [ #  # ][ #  # ]:          0 :             aDelStart = StartOfWord( aCurPos );
    2364         [ #  # ]:          0 :             if ( aDelStart.GetIndex() == aCurPos.GetIndex() )
    2365 [ #  # ][ #  # ]:          0 :                 aDelStart = WordLeft( aCurPos );
    2366                 :            :         }
    2367                 :            :         else    // DELMODE_RESTOFCONTENT
    2368                 :            :         {
    2369                 :          0 :             aDelStart.SetIndex( 0 );
    2370 [ #  # ][ #  # ]:          0 :             if ( aDelStart == aCurPos )
    2371                 :            :             {
    2372                 :            :                 // Complete paragraph previous
    2373 [ #  # ][ #  # ]:          0 :                 ContentNode* pPrev = GetPrevVisNode( aCurPos.GetNode() );
    2374         [ #  # ]:          0 :                 if ( pPrev )
    2375 [ #  # ][ #  # ]:          0 :                     aDelStart = EditPaM( pPrev, 0 );
    2376                 :            :             }
    2377                 :            :         }
    2378                 :            :     }
    2379                 :            :     else
    2380                 :            :     {
    2381         [ #  # ]:          0 :         if ( nDelMode == DELMODE_SIMPLE )
    2382                 :            :         {
    2383 [ #  # ][ #  # ]:          0 :             aDelEnd = CursorRight( aCurPos );
    2384                 :            :         }
    2385         [ #  # ]:          0 :         else if ( nDelMode == DELMODE_RESTOFWORD )
    2386                 :            :         {
    2387 [ #  # ][ #  # ]:          0 :             aDelEnd = EndOfWord( aCurPos );
    2388         [ #  # ]:          0 :             if (aDelEnd.GetIndex() == aCurPos.GetIndex())
    2389                 :            :             {
    2390 [ #  # ][ #  # ]:          0 :                 xub_StrLen nLen = aCurPos.GetNode()->Len();
    2391                 :            :                 // end of para?
    2392         [ #  # ]:          0 :                 if (aDelEnd.GetIndex() == nLen)
    2393 [ #  # ][ #  # ]:          0 :                     aDelEnd = WordLeft( aCurPos );
    2394                 :            :                 else // there's still sth to delete on the right
    2395                 :            :                 {
    2396 [ #  # ][ #  # ]:          0 :                     aDelEnd = EndOfWord( WordRight( aCurPos ) );
                 [ #  # ]
    2397                 :            :                     // if there'n no next word...
    2398         [ #  # ]:          0 :                     if (aDelEnd.GetIndex() == nLen )
    2399                 :          0 :                         aDelEnd.SetIndex( nLen );
    2400                 :            :                 }
    2401                 :            :             }
    2402                 :            :         }
    2403                 :            :         else    // DELMODE_RESTOFCONTENT
    2404                 :            :         {
    2405 [ #  # ][ #  # ]:          0 :             aDelEnd.SetIndex( aCurPos.GetNode()->Len() );
    2406 [ #  # ][ #  # ]:          0 :             if ( aDelEnd == aCurPos )
    2407                 :            :             {
    2408                 :            :                 // Complete paragraph next
    2409 [ #  # ][ #  # ]:          0 :                 ContentNode* pNext = GetNextVisNode( aCurPos.GetNode() );
    2410         [ #  # ]:          0 :                 if ( pNext )
    2411 [ #  # ][ #  # ]:          0 :                     aDelEnd = EditPaM( pNext, pNext->Len() );
                 [ #  # ]
    2412                 :            :             }
    2413                 :            :         }
    2414                 :            :     }
    2415                 :            : 
    2416                 :            :     // ConnectParagraphs  not enoguh for different Nodes when
    2417                 :            :     // DELMODE_RESTOFCONTENT.
    2418 [ #  # ][ #  # ]:          0 :     if ( ( nDelMode == DELMODE_RESTOFCONTENT ) || ( aDelStart.GetNode() == aDelEnd.GetNode() ) )
         [ #  # ][ #  # ]
                 [ #  # ]
    2419 [ #  # ][ #  # ]:          0 :         return ImpDeleteSelection( EditSelection( aDelStart, aDelEnd ) );
    2420                 :            : 
    2421                 :            :     // Decide now if to delete selection (RESTOFCONTENTS)
    2422                 :            :     sal_Bool bSpecialBackward = ( ( nMode == DEL_LEFT ) && ( nDelMode == DELMODE_SIMPLE ) )
    2423 [ #  # ][ #  # ]:          0 :                                 ? sal_True : sal_False;
    2424         [ #  # ]:          0 :     if ( aStatus.IsAnyOutliner() )
    2425                 :          0 :         bSpecialBackward = sal_False;
    2426                 :            : 
    2427 [ #  # ][ #  # ]:          0 :     return ImpConnectParagraphs( aDelStart.GetNode(), aDelEnd.GetNode(), bSpecialBackward );
                 [ #  # ]
    2428                 :            : }
    2429                 :            : 
    2430                 :       1101 : EditPaM ImpEditEngine::ImpDeleteSelection(const EditSelection& rCurSel)
    2431                 :            : {
    2432 [ +  - ][ +  + ]:       1101 :     if ( !rCurSel.HasRange() )
    2433         [ +  - ]:         63 :         return rCurSel.Min();
    2434                 :            : 
    2435         [ +  - ]:       1038 :     EditSelection aCurSel(rCurSel);
    2436         [ +  - ]:       1038 :     aCurSel.Adjust( aEditDoc );
    2437         [ +  - ]:       1038 :     EditPaM aStartPaM(aCurSel.Min());
    2438         [ +  - ]:       1038 :     EditPaM aEndPaM(aCurSel.Max());
    2439                 :            : 
    2440 [ +  - ][ +  - ]:       1038 :     CursorMoved( aStartPaM.GetNode() ); // only so that newly set Attributes dissapear...
    2441 [ +  - ][ +  - ]:       1038 :     CursorMoved( aEndPaM.GetNode() );   // only so that newly set Attributes dissapear...
    2442                 :            : 
    2443                 :            :     OSL_ENSURE( aStartPaM.GetIndex() <= aStartPaM.GetNode()->Len(), "Index out of range in ImpDeleteSelection" );
    2444                 :            :     OSL_ENSURE( aEndPaM.GetIndex() <= aEndPaM.GetNode()->Len(), "Index out of range in ImpDeleteSelection" );
    2445                 :            : 
    2446 [ +  - ][ +  - ]:       1038 :     sal_uInt16 nStartNode = aEditDoc.GetPos( aStartPaM.GetNode() );
    2447 [ +  - ][ +  - ]:       1038 :     sal_uInt16 nEndNode = aEditDoc.GetPos( aEndPaM.GetNode() );
    2448                 :            : 
    2449                 :            :     OSL_ENSURE( nEndNode != USHRT_MAX, "Start > End ?!" );
    2450                 :            :     OSL_ENSURE( nStartNode <= nEndNode, "Start > End ?!" );
    2451                 :            : 
    2452                 :            :     // Remove all nodes in between ....
    2453         [ +  + ]:       1050 :     for ( sal_uLong z = nStartNode+1; z < nEndNode; z++ )
    2454                 :            :     {
    2455                 :            :         // Always nStartNode+1, due to Remove()!
    2456         [ +  - ]:         12 :         ImpRemoveParagraph( nStartNode+1 );
    2457                 :            :     }
    2458                 :            : 
    2459 [ +  - ][ +  - ]:       1038 :     if ( aStartPaM.GetNode() != aEndPaM.GetNode() )
                 [ +  + ]
    2460                 :            :     {
    2461                 :            :         // The Rest of the StartNodes...
    2462                 :            :         sal_uInt16 nChars;
    2463 [ +  - ][ +  - ]:        810 :         nChars = aStartPaM.GetNode()->Len() - aStartPaM.GetIndex();
    2464         [ +  - ]:        810 :         ImpRemoveChars( aStartPaM, nChars );
    2465 [ +  - ][ +  - ]:        810 :         ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
    2466                 :            :         OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(3)" );
    2467 [ +  - ][ +  - ]:        810 :         pPortion->MarkSelectionInvalid( aStartPaM.GetIndex(), aStartPaM.GetNode()->Len() );
                 [ +  - ]
    2468                 :            : 
    2469                 :            :         // The beginning of the EndNodes....
    2470                 :        810 :         nChars = aEndPaM.GetIndex();
    2471                 :        810 :         aEndPaM.SetIndex( 0 );
    2472         [ +  - ]:        810 :         ImpRemoveChars( aEndPaM, nChars );
    2473 [ +  - ][ +  - ]:        810 :         pPortion = FindParaPortion( aEndPaM.GetNode() );
    2474                 :            :         OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(4)" );
    2475 [ +  - ][ +  - ]:        810 :         pPortion->MarkSelectionInvalid( 0, aEndPaM.GetNode()->Len() );
                 [ +  - ]
    2476                 :            :         // Join together....
    2477 [ +  - ][ +  - ]:        810 :         aStartPaM = ImpConnectParagraphs( aStartPaM.GetNode(), aEndPaM.GetNode() );
         [ +  - ][ +  - ]
    2478                 :            :     }
    2479                 :            :     else
    2480                 :            :     {
    2481                 :            :         sal_uInt16 nChars;
    2482                 :        228 :         nChars = aEndPaM.GetIndex() - aStartPaM.GetIndex();
    2483         [ +  - ]:        228 :         ImpRemoveChars( aStartPaM, nChars );
    2484 [ +  - ][ +  - ]:        228 :         ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
    2485                 :            :         OSL_ENSURE( pPortion, "Blind Portion in ImpDeleteSelection(5)" );
    2486         [ +  - ]:        228 :         pPortion->MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - aEndPaM.GetIndex() );
    2487                 :            :     }
    2488                 :            : 
    2489         [ +  - ]:       1038 :     UpdateSelections();
    2490         [ +  - ]:       1038 :     TextModified();
    2491         [ +  - ]:       1101 :     return aStartPaM;
    2492                 :            : }
    2493                 :            : 
    2494                 :         12 : void ImpEditEngine::ImpRemoveParagraph( sal_uInt16 nPara )
    2495                 :            : {
    2496                 :         12 :     ContentNode* pNode = aEditDoc.GetObject( nPara );
    2497                 :         12 :     ContentNode* pNextNode = aEditDoc.GetObject( nPara+1 );
    2498                 :            : 
    2499                 :            :     OSL_ENSURE( pNode, "Blind Node in ImpRemoveParagraph" );
    2500                 :            : 
    2501                 :         12 :     DeletedNodeInfo* pInf = new DeletedNodeInfo( (sal_uLong)pNode, nPara );
    2502                 :         12 :     aDeletedNodes.push_back(pInf);
    2503                 :            : 
    2504                 :            :     // The node is managed by the undo and possibly destroyed!
    2505                 :         12 :     aEditDoc.Release( nPara );
    2506                 :         12 :     GetParaPortions().Remove( nPara );
    2507                 :            : 
    2508         [ +  - ]:         12 :     if ( IsCallParaInsertedOrDeleted() )
    2509                 :            :     {
    2510                 :         12 :         GetEditEnginePtr()->ParagraphDeleted( nPara );
    2511                 :            :     }
    2512                 :            : 
    2513                 :            :     // Extra-Space may be determined again in the following. For
    2514                 :            :     // ParaAttribsChanged the paragraph is unfortunately formatted again,
    2515                 :            :     // however this method should not be time critical!
    2516         [ +  - ]:         12 :     if ( pNextNode )
    2517                 :         12 :         ParaAttribsChanged( pNextNode );
    2518                 :            : 
    2519 [ +  - ][ +  - ]:         12 :     if ( IsUndoEnabled() && !IsInUndo() )
                 [ +  - ]
    2520         [ +  - ]:         12 :         InsertUndo(new EditUndoDelContent(pEditEngine, pNode, nPara));
    2521                 :            :     else
    2522                 :            :     {
    2523                 :          0 :         aEditDoc.RemoveItemsFromPool(*pNode);
    2524         [ #  # ]:          0 :         if ( pNode->GetStyleSheet() )
    2525                 :          0 :             EndListening( *pNode->GetStyleSheet(), sal_False );
    2526         [ #  # ]:          0 :         delete pNode;
    2527                 :            :     }
    2528                 :         12 : }
    2529                 :            : 
    2530                 :          0 : EditPaM ImpEditEngine::AutoCorrect( const EditSelection& rCurSel, xub_Unicode c,
    2531                 :            :                                     sal_Bool bOverwrite, Window* pFrameWin )
    2532                 :            : {
    2533         [ #  # ]:          0 :     EditSelection aSel( rCurSel );
    2534         [ #  # ]:          0 :     SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
    2535         [ #  # ]:          0 :     if ( pAutoCorrect )
    2536                 :            :     {
    2537 [ #  # ][ #  # ]:          0 :         if ( aSel.HasRange() )
    2538 [ #  # ][ #  # ]:          0 :             aSel = ImpDeleteSelection( rCurSel );
    2539                 :            : 
    2540                 :            :         // #i78661 allow application to turn off capitalization of
    2541                 :            :         // start sentence explicitly.
    2542                 :            :         // (This is done by setting IsFirstWordCapitalization to sal_False.)
    2543                 :          0 :         sal_Bool bOldCptlSttSntnc = pAutoCorrect->IsAutoCorrFlag( CptlSttSntnc );
    2544         [ #  # ]:          0 :         if (!IsFirstWordCapitalization())
    2545                 :            :         {
    2546         [ #  # ]:          0 :             ESelection aESel( CreateESel(aSel) );
    2547         [ #  # ]:          0 :             EditSelection aFirstWordSel;
    2548         [ #  # ]:          0 :             EditSelection aSecondWordSel;
    2549         [ #  # ]:          0 :             if (aESel.nEndPara == 0)    // is this the first para?
    2550                 :            :             {
    2551                 :            :                 // select first word...
    2552                 :            :                 // start by checking if para starts with word.
    2553 [ #  # ][ #  # ]:          0 :                 aFirstWordSel = SelectWord( CreateSel(ESelection()) );
                 [ #  # ]
    2554 [ #  # ][ #  # ]:          0 :                 if (aFirstWordSel.Min().GetIndex() == 0 && aFirstWordSel.Max().GetIndex() == 0)
                 [ #  # ]
    2555                 :            :                 {
    2556                 :            :                     // para does not start with word -> select next/first word
    2557         [ #  # ]:          0 :                     EditPaM aRightWord( WordRight( aFirstWordSel.Max(), 1 ) );
    2558 [ #  # ][ #  # ]:          0 :                     aFirstWordSel = SelectWord( EditSelection( aRightWord ) );
                 [ #  # ]
    2559                 :            :                 }
    2560                 :            : 
    2561                 :            :                 // select second word
    2562                 :            :                 // (sometimes aSel mightnot point to the end of the first word
    2563                 :            :                 // but to some following char like '.'. ':', ...
    2564                 :            :                 // In those cases we need aSecondWordSel to see if aSel
    2565                 :            :                 // will actually effect the first word.)
    2566         [ #  # ]:          0 :                 EditPaM aRight2Word( WordRight( aFirstWordSel.Max(), 1 ) );
    2567 [ #  # ][ #  # ]:          0 :                 aSecondWordSel = SelectWord( EditSelection( aRight2Word ) );
                 [ #  # ]
    2568                 :            :             }
    2569                 :            :             sal_Bool bIsFirstWordInFirstPara = aESel.nEndPara == 0 &&
    2570                 :          0 :                     aFirstWordSel.Max().GetIndex() <= aSel.Max().GetIndex() &&
    2571   [ #  #  #  # ]:          0 :                     aSel.Max().GetIndex() <= aSecondWordSel.Min().GetIndex();
                 [ #  # ]
    2572                 :            : 
    2573         [ #  # ]:          0 :             if (bIsFirstWordInFirstPara)
    2574         [ #  # ]:          0 :                 pAutoCorrect->SetAutoCorrFlag( CptlSttSntnc, IsFirstWordCapitalization() );
    2575                 :            :         }
    2576                 :            : 
    2577         [ #  # ]:          0 :         ContentNode* pNode = aSel.Max().GetNode();
    2578                 :          0 :         sal_uInt16 nIndex = aSel.Max().GetIndex();
    2579         [ #  # ]:          0 :         EdtAutoCorrDoc aAuto(pEditEngine, pNode, nIndex, c);
    2580                 :            :         pAutoCorrect->AutoCorrect(
    2581 [ #  # ][ #  # ]:          0 :             aAuto, pNode->GetString(), nIndex, c, !bOverwrite, pFrameWin );
    2582                 :          0 :         aSel.Max().SetIndex( aAuto.GetCursor() );
    2583                 :            : 
    2584                 :            :         // #i78661 since the SvxAutoCorrect object used here is
    2585                 :            :         // shared we need to reset the value to it's original state.
    2586 [ #  # ][ #  # ]:          0 :         pAutoCorrect->SetAutoCorrFlag( CptlSttSntnc, bOldCptlSttSntnc );
    2587                 :            :     }
    2588         [ #  # ]:          0 :     return aSel.Max();
    2589                 :            : }
    2590                 :            : 
    2591                 :            : 
    2592                 :          0 : EditPaM ImpEditEngine::InsertText( const EditSelection& rCurSel,
    2593                 :            :         xub_Unicode c, sal_Bool bOverwrite, sal_Bool bIsUserInput )
    2594                 :            : {
    2595                 :            :     OSL_ENSURE( c != '\t', "Tab for InsertText ?" );
    2596                 :            :     OSL_ENSURE( c != '\n', "Word wrapping for InsertText ?");
    2597                 :            : 
    2598         [ #  # ]:          0 :     EditPaM aPaM( rCurSel.Min() );
    2599                 :            : 
    2600                 :            :     sal_Bool bDoOverwrite = ( bOverwrite &&
    2601 [ #  # ][ #  # ]:          0 :             ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) ) ? sal_True : sal_False;
         [ #  # ][ #  # ]
    2602                 :            : 
    2603 [ #  # ][ #  # ]:          0 :     sal_Bool bUndoAction = ( rCurSel.HasRange() || bDoOverwrite );
                 [ #  # ]
    2604                 :            : 
    2605         [ #  # ]:          0 :     if ( bUndoAction )
    2606         [ #  # ]:          0 :         UndoActionStart( EDITUNDO_INSERT );
    2607                 :            : 
    2608 [ #  # ][ #  # ]:          0 :     if ( rCurSel.HasRange() )
    2609                 :            :     {
    2610 [ #  # ][ #  # ]:          0 :         aPaM = ImpDeleteSelection( rCurSel );
    2611                 :            :     }
    2612         [ #  # ]:          0 :     else if ( bDoOverwrite )
    2613                 :            :     {
    2614                 :            :         // If selected, then do not also overwrite a character!
    2615         [ #  # ]:          0 :         EditSelection aTmpSel( aPaM );
    2616                 :          0 :         aTmpSel.Max().GetIndex()++;
    2617                 :            :         OSL_ENSURE( !aTmpSel.DbgIsBuggy( aEditDoc ), "Overwrite: Wrong selection! ");
    2618         [ #  # ]:          0 :         ImpDeleteSelection( aTmpSel );
    2619                 :            :     }
    2620                 :            : 
    2621 [ #  # ][ #  # ]:          0 :     if ( aPaM.GetNode()->Len() < MAXCHARSINPARA )
                 [ #  # ]
    2622                 :            :     {
    2623 [ #  # ][ #  # ]:          0 :         if (bIsUserInput && IsInputSequenceCheckingRequired( c, rCurSel ))
         [ #  # ][ #  # ]
    2624                 :            :         {
    2625         [ #  # ]:          0 :             uno::Reference < i18n::XExtendedInputSequenceChecker > _xISC( ImplGetInputSequenceChecker() );
    2626         [ #  # ]:          0 :             if (!pCTLOptions)
    2627 [ #  # ][ #  # ]:          0 :                 pCTLOptions = new SvtCTLOptions;
    2628                 :            : 
    2629 [ #  # ][ #  # ]:          0 :             if (_xISC.is() || pCTLOptions)
                 [ #  # ]
    2630                 :            :             {
    2631                 :          0 :                 xub_StrLen nTmpPos = aPaM.GetIndex();
    2632         [ #  # ]:          0 :                 sal_Int16 nCheckMode = pCTLOptions->IsCTLSequenceCheckingRestricted() ?
    2633         [ #  # ]:          0 :                         i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
    2634                 :            : 
    2635                 :            :                 // the text that needs to be checked is only the one
    2636                 :            :                 // before the current cursor position
    2637 [ #  # ][ #  # ]:          0 :                 rtl::OUString aOldText( aPaM.GetNode()->Copy(0, nTmpPos) );
         [ #  # ][ #  # ]
    2638                 :          0 :                 rtl::OUString aNewText( aOldText );
    2639 [ #  # ][ #  # ]:          0 :                 if (pCTLOptions->IsCTLSequenceCheckingTypeAndReplace())
    2640                 :            :                 {
    2641 [ #  # ][ #  # ]:          0 :                     /*const xub_StrLen nPrevPos = static_cast< xub_StrLen >*/( _xISC->correctInputSequence( aNewText, nTmpPos - 1, c, nCheckMode ) );
    2642                 :            : 
    2643                 :            :                     // find position of first character that has changed
    2644                 :          0 :                     sal_Int32 nOldLen = aOldText.getLength();
    2645                 :          0 :                     sal_Int32 nNewLen = aNewText.getLength();
    2646                 :          0 :                     const sal_Unicode *pOldTxt = aOldText.getStr();
    2647                 :          0 :                     const sal_Unicode *pNewTxt = aNewText.getStr();
    2648                 :          0 :                     sal_Int32 nChgPos = 0;
    2649 [ #  # ][ #  # ]:          0 :                     while ( nChgPos < nOldLen && nChgPos < nNewLen &&
         [ #  # ][ #  # ]
    2650                 :          0 :                             pOldTxt[nChgPos] == pNewTxt[nChgPos] )
    2651                 :          0 :                         ++nChgPos;
    2652                 :            : 
    2653         [ #  # ]:          0 :                     String aChgText( aNewText.copy( nChgPos ) );
    2654                 :            : 
    2655                 :            :                     // select text from first pos to be changed to current pos
    2656 [ #  # ][ #  # ]:          0 :                     EditSelection aSel( EditPaM( aPaM.GetNode(), (sal_uInt16) nChgPos ), aPaM );
                 [ #  # ]
    2657                 :            : 
    2658         [ #  # ]:          0 :                     if (aChgText.Len())
    2659         [ #  # ]:          0 :                         return InsertText( aSel, aChgText ); // implicitly handles undo
    2660                 :            :                     else
    2661 [ #  # ][ #  # ]:          0 :                         return aPaM;
    2662                 :            :                 }
    2663                 :            :                 else
    2664                 :            :                 {
    2665                 :            :                     // should the character be ignored (i.e. not get inserted) ?
    2666 [ #  # ][ #  # ]:          0 :                     if (!_xISC->checkInputSequence( aOldText, nTmpPos - 1, c, nCheckMode ))
                 [ #  # ]
    2667         [ #  # ]:          0 :                         return aPaM;    // nothing to be done -> no need for undo
    2668 [ #  # ][ #  # ]:          0 :                 }
    2669         [ #  # ]:          0 :             }
    2670                 :            : 
    2671                 :            :             // at this point now we will insert the character 'normally' some lines below...
    2672                 :            :         }
    2673                 :            : 
    2674 [ #  # ][ #  # ]:          0 :         if ( IsUndoEnabled() && !IsInUndo() )
                 [ #  # ]
    2675                 :            :         {
    2676 [ #  # ][ #  # ]:          0 :             EditUndoInsertChars* pNewUndo = new EditUndoInsertChars(pEditEngine, CreateEPaM(aPaM), rtl::OUString(c));
         [ #  # ][ #  # ]
                 [ #  # ]
    2677 [ #  # ][ #  # ]:          0 :             sal_Bool bTryMerge = ( !bDoOverwrite && ( c != ' ' ) ) ? sal_True : sal_False;
    2678         [ #  # ]:          0 :             InsertUndo( pNewUndo, bTryMerge );
    2679                 :            :         }
    2680                 :            : 
    2681 [ #  # ][ #  # ]:          0 :         aEditDoc.InsertText( (const EditPaM&)aPaM, rtl::OUString(c) );
         [ #  # ][ #  # ]
    2682 [ #  # ][ #  # ]:          0 :         ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
    2683                 :            :         OSL_ENSURE( pPortion, "Blind Portion in InsertText" );
    2684         [ #  # ]:          0 :         pPortion->MarkInvalid( aPaM.GetIndex(), 1 );
    2685                 :          0 :         aPaM.GetIndex()++;   // does not do EditDoc-Method anymore
    2686                 :            :     }
    2687                 :            : 
    2688         [ #  # ]:          0 :     TextModified();
    2689                 :            : 
    2690         [ #  # ]:          0 :     if ( bUndoAction )
    2691         [ #  # ]:          0 :         UndoActionEnd( EDITUNDO_INSERT );
    2692                 :            : 
    2693         [ #  # ]:          0 :     return aPaM;
    2694                 :            : }
    2695                 :            : 
    2696                 :      54623 : EditPaM ImpEditEngine::ImpInsertText(const EditSelection& aCurSel, const String& rStr)
    2697                 :            : {
    2698         [ +  - ]:      54623 :     UndoActionStart( EDITUNDO_INSERT );
    2699                 :            : 
    2700         [ +  - ]:      54623 :     EditPaM aPaM;
    2701 [ +  - ][ +  + ]:      54623 :     if ( aCurSel.HasRange() )
    2702 [ +  - ][ +  - ]:        544 :         aPaM = ImpDeleteSelection( aCurSel );
    2703                 :            :     else
    2704         [ +  - ]:      54079 :         aPaM = aCurSel.Max();
    2705                 :            : 
    2706         [ +  - ]:      54623 :     EditPaM aCurPaM( aPaM );    // for the Invalidate
    2707                 :            : 
    2708                 :            :     // get word boundaries in order to clear possible WrongList entries
    2709                 :            :     // and invalidate all the necessary text (everything after and including the
    2710                 :            :     // start of the word)
    2711                 :            :     // #i107201# do the expensive SelectWord call only if online spelling is active
    2712         [ +  - ]:      54623 :     EditSelection aCurWord;
    2713         [ +  + ]:      54623 :     if ( GetStatus().DoOnlineSpelling() )
    2714 [ +  - ][ +  - ]:       4302 :         aCurWord = SelectWord( aCurPaM, i18n::WordType::DICTIONARY_WORD );
                 [ +  - ]
    2715                 :            : 
    2716 [ +  - ][ +  - ]:      54623 :     XubString aText(convertLineEnd(rStr, LINEEND_LF));
                 [ +  - ]
    2717         [ +  - ]:      54623 :     SfxVoidItem aTabItem( EE_FEATURE_TAB );
    2718                 :            : 
    2719                 :            :     // Converts to linesep = \n
    2720                 :            :     // Token LINE_SEP query,
    2721                 :            :     // since the MAC-Compiler makes something else from \n !
    2722                 :            : 
    2723                 :            :     // fdo#39869 The loop run variable must be capable to hold STRLEN_MAX+1,
    2724                 :            :     // that with STRING32 would be SAL_MAX_INT32+1 but with 16-bit is 0xFFFF+1
    2725                 :      54623 :     sal_uInt32 nStart = 0;
    2726         [ +  + ]:      85908 :     while ( nStart < aText.Len() )
    2727                 :            :     {
    2728         [ +  - ]:      31285 :         sal_uInt32 nEnd = aText.Search( LINE_SEP, static_cast<xub_StrLen>(nStart) );
    2729         [ +  + ]:      31285 :         if ( nEnd == STRING_NOTFOUND )
    2730                 :      29963 :             nEnd = aText.Len(); // not dereference!
    2731                 :            : 
    2732                 :            :         // Start == End => empty line
    2733         [ +  + ]:      31285 :         if ( nEnd > nStart )
    2734                 :            :         {
    2735         [ +  - ]:      30379 :             XubString aLine( aText, nStart, static_cast<xub_StrLen>(nEnd-nStart) );
    2736 [ +  - ][ +  - ]:      30379 :             xub_StrLen nChars = aPaM.GetNode()->Len() + aLine.Len();
    2737         [ -  + ]:      30379 :             if ( nChars > MAXCHARSINPARA )
    2738                 :            :             {
    2739 [ #  # ][ #  # ]:          0 :                 xub_StrLen nMaxNewChars = MAXCHARSINPARA-aPaM.GetNode()->Len();
    2740                 :          0 :                 nEnd -= ( aLine.Len() - nMaxNewChars ); // Then the characters end up in the next paragraph.
    2741         [ #  # ]:          0 :                 aLine.Erase( nMaxNewChars );            // Delete the Rest...
    2742                 :            :             }
    2743 [ +  + ][ +  - ]:      30379 :             if ( IsUndoEnabled() && !IsInUndo() )
                 [ +  + ]
    2744 [ +  - ][ +  - ]:      23058 :                 InsertUndo(new EditUndoInsertChars(pEditEngine, CreateEPaM(aPaM), aLine));
         [ +  - ][ +  - ]
    2745                 :            :             // Tabs ?
    2746 [ +  - ][ +  - ]:      30379 :             if ( aLine.Search( '\t' ) == STRING_NOTFOUND )
    2747 [ +  - ][ +  - ]:      30379 :                 aPaM = aEditDoc.InsertText( aPaM, aLine );
                 [ +  - ]
    2748                 :            :             else
    2749                 :            :             {
    2750                 :          0 :                 sal_uInt32 nStart2 = 0;
    2751         [ #  # ]:          0 :                 while ( nStart2 < aLine.Len() )
    2752                 :            :                 {
    2753         [ #  # ]:          0 :                     sal_uInt32 nEnd2 = aLine.Search( '\t', static_cast<xub_StrLen>(nStart2) );
    2754         [ #  # ]:          0 :                     if ( nEnd2 == STRING_NOTFOUND )
    2755                 :          0 :                         nEnd2 = aLine.Len();    // not dereference!
    2756                 :            : 
    2757         [ #  # ]:          0 :                     if ( nEnd2 > nStart2 )
    2758                 :            :                         aPaM = aEditDoc.InsertText( aPaM, XubString( aLine,
    2759                 :            :                                     static_cast<xub_StrLen>(nStart2),
    2760 [ #  # ][ #  # ]:          0 :                                     static_cast<xub_StrLen>(nEnd2-nStart2) ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    2761         [ #  # ]:          0 :                     if ( nEnd2 < aLine.Len() )
    2762                 :            :                     {
    2763 [ #  # ][ #  # ]:          0 :                         aPaM = aEditDoc.InsertFeature( aPaM, aTabItem );
                 [ #  # ]
    2764                 :            :                     }
    2765                 :          0 :                     nStart2 = nEnd2+1;
    2766                 :            :                 }
    2767                 :            :             }
    2768 [ +  - ][ +  - ]:      30379 :             ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
    2769                 :            :             OSL_ENSURE( pPortion, "Blind Portion in InsertText" );
    2770                 :            : 
    2771         [ +  + ]:      30379 :             if ( GetStatus().DoOnlineSpelling() )
    2772                 :            :             {
    2773                 :            :                 // now remove the Wrongs (red spell check marks) from both words...
    2774         [ +  - ]:       4023 :                 WrongList *pWrongs = aCurPaM.GetNode()->GetWrongList();
    2775 [ +  - ][ -  + ]:       4023 :                 if (pWrongs && !pWrongs->empty())
         [ -  + ][ +  - ]
    2776 [ #  # ][ #  # ]:          0 :                     pWrongs->ClearWrongs( aCurWord.Min().GetIndex(), aPaM.GetIndex(), aPaM.GetNode() );
    2777                 :            :                 // ... and mark both words as 'to be checked again'
    2778         [ +  - ]:       4023 :                 pPortion->MarkInvalid( aCurWord.Min().GetIndex(), aLine.Len() );
    2779                 :            :             }
    2780                 :            :             else
    2781 [ +  - ][ +  - ]:      30379 :                 pPortion->MarkInvalid( aCurPaM.GetIndex(), aLine.Len() );
    2782                 :            :         }
    2783         [ +  + ]:      31285 :         if ( nEnd < aText.Len() )
    2784 [ +  - ][ +  - ]:       1322 :             aPaM = ImpInsertParaBreak( aPaM );
    2785                 :            : 
    2786                 :      31285 :         nStart = nEnd+1;
    2787                 :            :     }
    2788                 :            : 
    2789         [ +  - ]:      54623 :     UndoActionEnd( EDITUNDO_INSERT );
    2790                 :            : 
    2791         [ +  - ]:      54623 :     TextModified();
    2792 [ +  - ][ +  - ]:      54623 :     return aPaM;
    2793                 :            : }
    2794                 :            : 
    2795                 :     142005 : EditPaM ImpEditEngine::ImpFastInsertText( EditPaM aPaM, const XubString& rStr )
    2796                 :            : {
    2797                 :            :     OSL_ENSURE( rStr.Search( 0x0A ) == STRING_NOTFOUND, "FastInsertText: Newline not allowed! ");
    2798                 :            :     OSL_ENSURE( rStr.Search( 0x0D ) == STRING_NOTFOUND, "FastInsertText: Newline not allowed! ");
    2799                 :            :     OSL_ENSURE( rStr.Search( '\t' ) == STRING_NOTFOUND, "FastInsertText: Newline not allowed! ");
    2800                 :            : 
    2801         [ +  - ]:     142005 :     if ( ( aPaM.GetNode()->Len() + rStr.Len() ) < MAXCHARSINPARA )
    2802                 :            :     {
    2803 [ -  + ][ #  # ]:     142005 :         if ( IsUndoEnabled() && !IsInUndo() )
                 [ -  + ]
    2804 [ #  # ][ #  # ]:          0 :             InsertUndo(new EditUndoInsertChars(pEditEngine, CreateEPaM(aPaM), rStr));
                 [ #  # ]
    2805                 :            : 
    2806 [ +  - ][ +  - ]:     142005 :         aPaM = aEditDoc.InsertText( aPaM, rStr );
    2807                 :     142005 :         TextModified();
    2808                 :            :     }
    2809                 :            :     else
    2810                 :            :     {
    2811 [ #  # ][ #  # ]:          0 :         aPaM = ImpInsertText( aPaM, rStr );
    2812                 :            :     }
    2813                 :            : 
    2814                 :     142005 :     return aPaM;
    2815                 :            : }
    2816                 :            : 
    2817                 :       5024 : EditPaM ImpEditEngine::ImpInsertFeature(const EditSelection& rCurSel, const SfxPoolItem& rItem)
    2818                 :            : {
    2819                 :       5024 :     EditPaM aPaM;
    2820         [ +  + ]:       5024 :     if ( rCurSel.HasRange() )
    2821         [ +  - ]:        106 :         aPaM = ImpDeleteSelection( rCurSel );
    2822                 :            :     else
    2823                 :       4918 :         aPaM = rCurSel.Max();
    2824                 :            : 
    2825         [ -  + ]:       5024 :     if ( aPaM.GetIndex() >= 0xfffe )
    2826                 :          0 :         return aPaM;
    2827                 :            : 
    2828 [ +  + ][ +  - ]:       5024 :     if ( IsUndoEnabled() && !IsInUndo() )
                 [ +  + ]
    2829 [ +  - ][ +  - ]:       3390 :         InsertUndo(new EditUndoInsertFeature(pEditEngine, CreateEPaM(aPaM), rItem));
                 [ +  - ]
    2830 [ +  - ][ +  - ]:       5024 :     aPaM = aEditDoc.InsertFeature( aPaM, rItem );
    2831                 :            : 
    2832                 :       5024 :     ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
    2833                 :            :     OSL_ENSURE( pPortion, "Blind Portion in InsertFeature" );
    2834                 :       5024 :     pPortion->MarkInvalid( aPaM.GetIndex()-1, 1 );
    2835                 :            : 
    2836                 :       5024 :     TextModified();
    2837                 :            : 
    2838                 :       5024 :     return aPaM;
    2839                 :            : }
    2840                 :            : 
    2841                 :         18 : EditPaM ImpEditEngine::ImpInsertParaBreak( const EditSelection& rCurSel, bool bKeepEndingAttribs )
    2842                 :            : {
    2843         [ +  - ]:         18 :     EditPaM aPaM;
    2844 [ +  - ][ -  + ]:         18 :     if ( rCurSel.HasRange() )
    2845 [ #  # ][ #  # ]:          0 :         aPaM = ImpDeleteSelection( rCurSel );
    2846                 :            :     else
    2847         [ +  - ]:         18 :         aPaM = rCurSel.Max();
    2848                 :            : 
    2849         [ +  - ]:         18 :     return ImpInsertParaBreak( aPaM, bKeepEndingAttribs );
    2850                 :            : }
    2851                 :            : 
    2852                 :       1832 : EditPaM ImpEditEngine::ImpInsertParaBreak( EditPaM& rPaM, bool bKeepEndingAttribs )
    2853                 :            : {
    2854 [ +  - ][ -  + ]:       1832 :     if ( aEditDoc.Count() >= 0xFFFE )
    2855                 :            :     {
    2856                 :            :         OSL_FAIL( "Can't process more than 64K paragraphs!" );
    2857         [ #  # ]:          0 :         return rPaM;
    2858                 :            :     }
    2859                 :            : 
    2860 [ +  + ][ +  - ]:       1832 :     if ( IsUndoEnabled() && !IsInUndo() )
                 [ +  + ]
    2861 [ +  - ][ +  - ]:        526 :         InsertUndo(new EditUndoSplitPara(pEditEngine, aEditDoc.GetPos(rPaM.GetNode()), rPaM.GetIndex()));
         [ +  - ][ +  - ]
                 [ +  - ]
    2862                 :            : 
    2863 [ +  - ][ +  - ]:       1832 :     EditPaM aPaM( aEditDoc.InsertParaBreak( rPaM, bKeepEndingAttribs ) );
    2864                 :            : 
    2865         [ +  + ]:       1832 :     if ( GetStatus().DoOnlineSpelling() )
    2866                 :            :     {
    2867 [ +  - ][ +  - ]:        408 :         xub_StrLen nEnd = rPaM.GetNode()->Len();
    2868 [ +  - ][ +  - ]:        408 :         aPaM.GetNode()->CreateWrongList();
    2869         [ +  - ]:        408 :         WrongList* pLWrongs = rPaM.GetNode()->GetWrongList();
    2870         [ +  - ]:        408 :         WrongList* pRWrongs = aPaM.GetNode()->GetWrongList();
    2871                 :            :         // take over misspelled words:
    2872 [ +  - ][ +  - ]:        408 :         for(WrongList::iterator i = pLWrongs->begin(); i < pLWrongs->end(); ++i)
         [ -  + ][ +  - ]
    2873                 :            :         {
    2874                 :            :             // Correct only if really a word gets overlapped in the process of
    2875                 :            :             // Spell checking
    2876         [ #  # ]:          0 :             if (i->nStart > nEnd)
    2877                 :            :             {
    2878         [ #  # ]:          0 :                 pRWrongs->push_back(*i);
    2879         [ #  # ]:          0 :                 WrongRange& rRWrong = pRWrongs->back();
    2880                 :          0 :                 rRWrong.nStart = rRWrong.nStart - nEnd;
    2881                 :          0 :                 rRWrong.nEnd = rRWrong.nEnd - nEnd;
    2882                 :            :             }
    2883 [ #  # ][ #  # ]:          0 :             else if (i->nStart < nEnd && i->nEnd > nEnd)
                 [ #  # ]
    2884                 :          0 :                 i->nEnd = nEnd;
    2885                 :            :         }
    2886         [ +  - ]:        408 :         sal_uInt16 nInv = nEnd ? nEnd-1 : nEnd;
    2887         [ +  - ]:        408 :         if ( nEnd )
    2888         [ +  - ]:        408 :             pLWrongs->MarkInvalid( nInv, nEnd );
    2889                 :            :         else
    2890         [ #  # ]:          0 :             pLWrongs->SetValid();
    2891         [ +  - ]:        408 :         pRWrongs->SetValid(); // otherwise 0 - 0xFFFF
    2892         [ +  - ]:        408 :         pRWrongs->MarkInvalid( 0, 1 );  // Only test the first word
    2893                 :            :     }
    2894                 :            : 
    2895 [ +  - ][ +  - ]:       1832 :     ParaPortion* pPortion = FindParaPortion( rPaM.GetNode() );
    2896                 :            :     OSL_ENSURE( pPortion, "Blind Portion in ImpInsertParaBreak" );
    2897         [ +  - ]:       1832 :     pPortion->MarkInvalid( rPaM.GetIndex(), 0 );
    2898                 :            : 
    2899                 :            :     // Optimization: Do not place unnecessarily many getPos to Listen!
    2900                 :            :     // Here, as in undo, but also in all other methods.
    2901         [ +  - ]:       1832 :     sal_uInt16 nPos = GetParaPortions().GetPos( pPortion );
    2902 [ +  - ][ +  - ]:       1832 :     ParaPortion* pNewPortion = new ParaPortion( aPaM.GetNode() );
                 [ +  - ]
    2903         [ +  - ]:       1832 :     GetParaPortions().Insert(nPos+1, pNewPortion);
    2904         [ +  - ]:       1832 :     ParaAttribsChanged( pNewPortion->GetNode() );
    2905         [ +  - ]:       1832 :     if ( IsCallParaInsertedOrDeleted() )
    2906         [ +  - ]:       1832 :         GetEditEnginePtr()->ParagraphInserted( nPos+1 );
    2907                 :            : 
    2908 [ +  - ][ +  - ]:       1832 :     CursorMoved( rPaM.GetNode() );  // if empty Attributes have emerged.
    2909         [ +  - ]:       1832 :     TextModified();
    2910         [ +  - ]:       1832 :     return aPaM;
    2911                 :            : }
    2912                 :            : 
    2913                 :       9660 : EditPaM ImpEditEngine::ImpFastInsertParagraph( sal_uInt16 nPara )
    2914                 :            : {
    2915 [ -  + ][ #  # ]:       9660 :     if ( IsUndoEnabled() && !IsInUndo() )
                 [ -  + ]
    2916                 :            :     {
    2917         [ #  # ]:          0 :         if ( nPara )
    2918                 :            :         {
    2919                 :            :             OSL_ENSURE( aEditDoc.GetObject( nPara-1 ), "FastInsertParagraph: Prev does not exist" );
    2920         [ #  # ]:          0 :             InsertUndo(new EditUndoSplitPara(pEditEngine, nPara-1, aEditDoc.GetObject( nPara-1 )->Len()));
    2921                 :            :         }
    2922                 :            :         else
    2923         [ #  # ]:          0 :             InsertUndo(new EditUndoSplitPara(pEditEngine, 0, 0));
    2924                 :            :     }
    2925                 :            : 
    2926         [ +  - ]:       9660 :     ContentNode* pNode = new ContentNode( aEditDoc.GetItemPool() );
    2927                 :            :     // If flat mode, then later no Font is set:
    2928                 :       9660 :     pNode->GetCharAttribs().GetDefFont() = aEditDoc.GetDefFont();
    2929                 :            : 
    2930         [ +  + ]:       9660 :     if ( GetStatus().DoOnlineSpelling() )
    2931                 :       6321 :         pNode->CreateWrongList();
    2932                 :            : 
    2933                 :       9660 :     aEditDoc.Insert(nPara, pNode);
    2934                 :            : 
    2935         [ +  - ]:       9660 :     ParaPortion* pNewPortion = new ParaPortion( pNode );
    2936                 :       9660 :     GetParaPortions().Insert(nPara, pNewPortion);
    2937         [ +  - ]:       9660 :     if ( IsCallParaInsertedOrDeleted() )
    2938                 :       9660 :         GetEditEnginePtr()->ParagraphInserted( nPara );
    2939                 :            : 
    2940                 :       9660 :     return EditPaM( pNode, 0 );
    2941                 :            : }
    2942                 :            : 
    2943                 :          0 : EditPaM ImpEditEngine::InsertParaBreak( EditSelection aCurSel )
    2944                 :            : {
    2945                 :          0 :     EditPaM aPaM( ImpInsertParaBreak( aCurSel ) );
    2946         [ #  # ]:          0 :     if ( aStatus.DoAutoIndenting() )
    2947                 :            :     {
    2948 [ #  # ][ #  # ]:          0 :         sal_uInt16 nPara = aEditDoc.GetPos( aPaM.GetNode() );
    2949                 :            :         OSL_ENSURE( nPara > 0, "AutoIndenting: Error!" );
    2950         [ #  # ]:          0 :         XubString aPrevParaText( GetEditDoc().GetParaAsString( nPara-1 ) );
    2951                 :          0 :         sal_uInt16 n = 0;
    2952   [ #  #  #  #  :          0 :         while ( ( n < aPrevParaText.Len() ) &&
           #  # ][ #  # ]
    2953                 :          0 :                 ( ( aPrevParaText.GetChar(n) == ' ' ) || ( aPrevParaText.GetChar(n) == '\t' ) ) )
    2954                 :            :         {
    2955         [ #  # ]:          0 :             if ( aPrevParaText.GetChar(n) == '\t' )
    2956 [ #  # ][ #  # ]:          0 :                 aPaM = ImpInsertFeature( aPaM, SfxVoidItem( EE_FEATURE_TAB ) );
         [ #  # ][ #  # ]
                 [ #  # ]
    2957                 :            :             else
    2958 [ #  # ][ #  # ]:          0 :                 aPaM = ImpInsertText( aPaM, rtl::OUString(aPrevParaText.GetChar(n)) );
         [ #  # ][ #  # ]
                 [ #  # ]
    2959                 :          0 :             n++;
    2960         [ #  # ]:          0 :         }
    2961                 :            : 
    2962                 :            :     }
    2963                 :          0 :     return aPaM;
    2964                 :            : }
    2965                 :            : 
    2966                 :          0 : EditPaM ImpEditEngine::InsertTab( EditSelection aCurSel )
    2967                 :            : {
    2968         [ #  # ]:          0 :     EditPaM aPaM( ImpInsertFeature( aCurSel, SfxVoidItem( EE_FEATURE_TAB ) ) );
    2969                 :          0 :     return aPaM;
    2970                 :            : }
    2971                 :            : 
    2972                 :          0 : EditPaM ImpEditEngine::InsertField(const EditSelection& rCurSel, const SvxFieldItem& rFld)
    2973                 :            : {
    2974                 :          0 :     return ImpInsertFeature(rCurSel, rFld);
    2975                 :            : }
    2976                 :            : 
    2977                 :       3805 : sal_Bool ImpEditEngine::UpdateFields()
    2978                 :            : {
    2979                 :       3805 :     bool bChanges = false;
    2980                 :       3805 :     sal_uInt16 nParas = GetEditDoc().Count();
    2981         [ +  + ]:       7611 :     for ( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
    2982                 :            :     {
    2983                 :       3806 :         bool bChangesInPara = false;
    2984                 :       3806 :         ContentNode* pNode = GetEditDoc().GetObject( nPara );
    2985                 :            :         OSL_ENSURE( pNode, "NULL-Pointer in Doc" );
    2986                 :       3806 :         CharAttribList::AttribsType& rAttribs = pNode->GetCharAttribs().GetAttribs();
    2987         [ +  + ]:      11461 :         for (size_t nAttr = 0; nAttr < rAttribs.size(); ++nAttr)
    2988                 :            :         {
    2989                 :       7655 :             EditCharAttrib& rAttr = rAttribs[nAttr];
    2990         [ +  + ]:       7655 :             if (rAttr.Which() == EE_FEATURE_FIELD)
    2991                 :            :             {
    2992                 :       3895 :                 EditCharAttribField& rField = static_cast<EditCharAttribField&>(rAttr);
    2993 [ +  - ][ +  - ]:       3895 :                 boost::scoped_ptr<EditCharAttribField> pCurrent(new EditCharAttribField(rField));
    2994         [ +  - ]:       3895 :                 rField.Reset();
    2995                 :            : 
    2996         [ +  + ]:       3895 :                 if ( aStatus.MarkFields() )
    2997 [ +  - ][ +  - ]:        133 :                     rField.GetFldColor() = new Color( GetColorConfig().GetColorValue( svtools::WRITERFIELDSHADINGS ).nColor );
                 [ +  - ]
    2998                 :            : 
    2999                 :            :                 rtl::OUString aFldValue =
    3000                 :       3895 :                     GetEditEnginePtr()->CalcFieldValue(
    3001                 :       3895 :                         static_cast<const SvxFieldItem&>(*rField.GetItem()),
    3002 [ +  - ][ +  - ]:       7790 :                         nPara, rField.GetStart(), rField.GetTxtColor(), rField.GetFldColor());
                 [ +  - ]
    3003                 :            : 
    3004         [ +  - ]:       3895 :                 rField.SetFieldValue(aFldValue);
    3005 [ +  - ][ +  + ]:       3895 :                 if (rField != *pCurrent)
    3006                 :            :                 {
    3007                 :       3508 :                     bChanges = true;
    3008                 :       3508 :                     bChangesInPara = true;
    3009         [ +  - ]:       3895 :                 }
    3010                 :            :             }
    3011                 :            :         }
    3012         [ +  + ]:       3806 :         if ( bChangesInPara )
    3013                 :            :         {
    3014                 :            :             // If possible be more precise when invalidate.
    3015                 :       3420 :             ParaPortion* pPortion = GetParaPortions()[nPara];
    3016                 :            :             OSL_ENSURE( pPortion, "NULL-Pointer in Doc" );
    3017                 :       3420 :             pPortion->MarkSelectionInvalid( 0, pNode->Len() );
    3018                 :            :         }
    3019                 :            :     }
    3020                 :       3805 :     return bChanges;
    3021                 :            : }
    3022                 :            : 
    3023                 :         13 : EditPaM ImpEditEngine::InsertLineBreak(const EditSelection& aCurSel)
    3024                 :            : {
    3025         [ +  - ]:         13 :     EditPaM aPaM( ImpInsertFeature( aCurSel, SfxVoidItem( EE_FEATURE_LINEBR ) ) );
    3026                 :         13 :     return aPaM;
    3027                 :            : }
    3028                 :            : 
    3029                 :            : //  ----------------------------------------------------------------------
    3030                 :            : //  Helper functions
    3031                 :            : //  ----------------------------------------------------------------------
    3032                 :       1124 : Rectangle ImpEditEngine::PaMtoEditCursor( EditPaM aPaM, sal_uInt16 nFlags )
    3033                 :            : {
    3034                 :            :     OSL_ENSURE( GetUpdateMode(), "Must not be reached when Update=FALSE: PaMtoEditCursor" );
    3035                 :            : 
    3036                 :       1124 :     Rectangle aEditCursor;
    3037                 :       1124 :     long nY = 0;
    3038         [ +  - ]:       1124 :     for ( sal_uInt16 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
    3039                 :            :     {
    3040                 :       1124 :         ParaPortion* pPortion = GetParaPortions()[nPortion];
    3041                 :       1124 :         ContentNode* pNode = pPortion->GetNode();
    3042                 :            :         OSL_ENSURE( pNode, "Invalid Node in Portion!" );
    3043         [ -  + ]:       1124 :         if ( pNode != aPaM.GetNode() )
    3044                 :            :         {
    3045                 :          0 :             nY += pPortion->GetHeight();
    3046                 :            :         }
    3047                 :            :         else
    3048                 :            :         {
    3049                 :       1124 :             aEditCursor = GetEditCursor( pPortion, aPaM.GetIndex(), nFlags );
    3050                 :       1124 :             aEditCursor.Top() += nY;
    3051                 :       1124 :             aEditCursor.Bottom() += nY;
    3052                 :       1124 :             return aEditCursor;
    3053                 :            :         }
    3054                 :            :     }
    3055                 :            :     OSL_FAIL( "Portion not found!" );
    3056                 :       1124 :     return aEditCursor;
    3057                 :            : }
    3058                 :            : 
    3059                 :         22 : EditPaM ImpEditEngine::GetPaM( Point aDocPos, sal_Bool bSmart )
    3060                 :            : {
    3061                 :            :     OSL_ENSURE( GetUpdateMode(), "Must not be reached when Update=FALSE: GetPaM" );
    3062                 :            : 
    3063                 :         22 :     long nY = 0;
    3064                 :            :     long nTmpHeight;
    3065                 :         22 :     EditPaM aPaM;
    3066                 :            :     sal_uInt16 nPortion;
    3067         [ +  - ]:         22 :     for ( nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
    3068                 :            :     {
    3069                 :         22 :         ParaPortion* pPortion = GetParaPortions()[nPortion];
    3070                 :         22 :         nTmpHeight = pPortion->GetHeight();     // should also be correct for !bVisible!
    3071                 :         22 :         nY += nTmpHeight;
    3072         [ +  - ]:         22 :         if ( nY > aDocPos.Y() )
    3073                 :            :         {
    3074                 :         22 :             nY -= nTmpHeight;
    3075                 :         22 :             aDocPos.Y() -= nY;
    3076                 :            :             // Skip invisible Portions:
    3077 [ +  - ][ -  + ]:         22 :             while ( pPortion && !pPortion->IsVisible() )
                 [ -  + ]
    3078                 :            :             {
    3079                 :          0 :                 nPortion++;
    3080                 :          0 :                 pPortion = GetParaPortions().SafeGetObject( nPortion );
    3081                 :            :             }
    3082                 :            :             OSL_ENSURE( pPortion, "No visible paragraph found: GetPaM" );
    3083         [ +  - ]:         22 :             aPaM = GetPaM( pPortion, aDocPos, bSmart );
    3084                 :         22 :             return aPaM;
    3085                 :            : 
    3086                 :            :         }
    3087                 :            :     }
    3088                 :            :     // Then search for the last visible:
    3089                 :          0 :     nPortion = GetParaPortions().Count()-1;
    3090 [ #  # ][ #  # ]:          0 :     while ( nPortion && !GetParaPortions()[nPortion]->IsVisible() )
                 [ #  # ]
    3091                 :          0 :         nPortion--;
    3092                 :            : 
    3093                 :            :     OSL_ENSURE( GetParaPortions()[nPortion]->IsVisible(), "No visible paragraph found: GetPaM" );
    3094                 :          0 :     aPaM.SetNode( GetParaPortions()[nPortion]->GetNode() );
    3095                 :          0 :     aPaM.SetIndex( GetParaPortions()[nPortion]->GetNode()->Len() );
    3096                 :         22 :     return aPaM;
    3097                 :            : }
    3098                 :            : 
    3099                 :     163412 : sal_uInt32 ImpEditEngine::GetTextHeight() const
    3100                 :            : {
    3101                 :            :     OSL_ENSURE( GetUpdateMode(), "Should not be used for Update=FALSE: GetTextHeight" );
    3102                 :            :     OSL_ENSURE( IsFormatted() || IsFormatting(), "GetTextHeight: Not formatted" );
    3103                 :     163412 :     return nCurTextHeight;
    3104                 :            : }
    3105                 :            : 
    3106                 :      86220 : sal_uInt32 ImpEditEngine::CalcTextWidth( sal_Bool bIgnoreExtraSpace )
    3107                 :            : {
    3108                 :            :     // If still not formatted and not in the process.
    3109                 :            :     // Will be brought in the formatting for AutoPageSize.
    3110 [ +  + ][ -  + ]:      86220 :     if ( !IsFormatted() && !IsFormatting() )
                 [ -  + ]
    3111                 :          0 :         FormatDoc();
    3112                 :            : 
    3113                 :            :     EditLine* pLine;
    3114                 :            : 
    3115                 :      86220 :     long nMaxWidth = 0;
    3116                 :      86220 :     long nCurWidth = 0;
    3117                 :            : 
    3118                 :            :     // --------------------------------------------------
    3119                 :            :     // Over all the paragraphs ...
    3120                 :            :     // --------------------------------------------------
    3121                 :      86220 :     sal_uInt16 nParas = GetParaPortions().Count();
    3122         [ +  + ]:     176696 :     for ( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
    3123                 :            :     {
    3124                 :      90476 :         ParaPortion* pPortion = GetParaPortions()[nPara];
    3125         [ +  - ]:      90476 :         if ( pPortion->IsVisible() )
    3126                 :            :         {
    3127                 :      90476 :             const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pPortion->GetNode() );
    3128                 :      90476 :             sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( pPortion->GetNode() );
    3129                 :            : 
    3130                 :            :             // --------------------------------------------------
    3131                 :            :             // On the lines of the paragraph ...
    3132                 :            :             // --------------------------------------------------
    3133                 :      90476 :             sal_uLong nLines = pPortion->GetLines().Count();
    3134         [ +  + ]:     184487 :             for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
    3135                 :            :             {
    3136                 :      94011 :                 pLine = pPortion->GetLines()[nLine];
    3137                 :            :                 OSL_ENSURE( pLine, "NULL-Pointer in the line iterator in CalcWidth" );
    3138                 :            :                 // nCurWidth = pLine->GetStartPosX();
    3139                 :            :                 // For Center- or Right- alignment it depends on the paper
    3140                 :            :                 // width, here not prefered. I general, it is best not leave it
    3141                 :            :                 // to StartPosX, also the right indents have to be taken into
    3142                 :            :                 // account!
    3143                 :      94011 :                 nCurWidth = GetXValue( rLRItem.GetTxtLeft() + nSpaceBeforeAndMinLabelWidth );
    3144         [ +  + ]:      94011 :                 if ( nLine == 0 )
    3145                 :            :                 {
    3146                 :      90476 :                     long nFI = GetXValue( rLRItem.GetTxtFirstLineOfst() );
    3147                 :      90476 :                     nCurWidth -= nFI;
    3148         [ +  + ]:      90476 :                     if ( pPortion->GetBulletX() > nCurWidth )
    3149                 :            :                     {
    3150                 :          4 :                         nCurWidth += nFI;   // LI?
    3151         [ -  + ]:          4 :                         if ( pPortion->GetBulletX() > nCurWidth )
    3152                 :          0 :                             nCurWidth = pPortion->GetBulletX();
    3153                 :            :                     }
    3154                 :            :                 }
    3155                 :      94011 :                 nCurWidth += GetXValue( rLRItem.GetRight() );
    3156                 :      94011 :                 nCurWidth += CalcLineWidth( pPortion, pLine, bIgnoreExtraSpace );
    3157         [ +  + ]:      94011 :                 if ( nCurWidth > nMaxWidth )
    3158                 :            :                 {
    3159                 :      74102 :                     nMaxWidth = nCurWidth;
    3160                 :            :                 }
    3161                 :            :             }
    3162                 :            :         }
    3163                 :            :     }
    3164         [ -  + ]:      86220 :     if ( nMaxWidth < 0 )
    3165                 :          0 :         nMaxWidth = 0;
    3166                 :            : 
    3167                 :      86220 :     nMaxWidth++; // widen it, because in CreateLines for >= is wrapped.
    3168                 :      86220 :     return (sal_uInt32)nMaxWidth;
    3169                 :            : }
    3170                 :            : 
    3171                 :      94011 : sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, sal_Bool bIgnoreExtraSpace )
    3172                 :            : {
    3173                 :      94011 :     sal_uInt16 nPara = GetEditDoc().GetPos( pPortion->GetNode() );
    3174                 :            : 
    3175                 :            :     // #114278# Saving both layout mode and language (since I'm
    3176                 :            :     // potentially changing both)
    3177                 :      94011 :     GetRefDevice()->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
    3178                 :            : 
    3179                 :      94011 :     ImplInitLayoutMode( GetRefDevice(), nPara, 0xFFFF );
    3180                 :            : 
    3181                 :      94011 :     SvxAdjust eJustification = GetJustification( nPara );
    3182                 :            : 
    3183                 :            :     // Calculation of the width without the Indents ...
    3184                 :      94011 :     sal_uInt32 nWidth = 0;
    3185                 :      94011 :     sal_uInt16 nPos = pLine->GetStart();
    3186         [ +  + ]:     188134 :     for ( sal_uInt16 nTP = pLine->GetStartPortion(); nTP <= pLine->GetEndPortion(); nTP++ )
    3187                 :            :     {
    3188                 :      94123 :         const TextPortion* pTextPortion = pPortion->GetTextPortions()[nTP];
    3189      [ +  +  + ]:      94123 :         switch ( pTextPortion->GetKind() )
    3190                 :            :         {
    3191                 :            :             case PORTIONKIND_FIELD:
    3192                 :            :             case PORTIONKIND_HYPHENATOR:
    3193                 :            :             case PORTIONKIND_TAB:
    3194                 :            :             {
    3195                 :       1042 :                 nWidth += pTextPortion->GetSize().Width();
    3196                 :            :             }
    3197                 :       1042 :             break;
    3198                 :            :             case PORTIONKIND_TEXT:
    3199                 :            :             {
    3200 [ +  + ][ -  + ]:      93075 :                 if ( ( eJustification != SVX_ADJUST_BLOCK ) || ( !bIgnoreExtraSpace ) )
    3201                 :            :                 {
    3202                 :      92955 :                     nWidth += pTextPortion->GetSize().Width();
    3203                 :            :                 }
    3204                 :            :                 else
    3205                 :            :                 {
    3206         [ +  - ]:        120 :                     SvxFont aTmpFont( pPortion->GetNode()->GetCharAttribs().GetDefFont() );
    3207         [ +  - ]:        120 :                     SeekCursor( pPortion->GetNode(), nPos+1, aTmpFont );
    3208         [ +  - ]:        120 :                     aTmpFont.SetPhysFont( GetRefDevice() );
    3209         [ +  - ]:        120 :                     ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
    3210 [ +  - ][ +  - ]:        120 :                     nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), pPortion->GetNode()->GetString(), nPos, pTextPortion->GetLen(), NULL ).Width();
                 [ +  - ]
    3211                 :            :                 }
    3212                 :            :             }
    3213                 :      93075 :             break;
    3214                 :            :         }
    3215                 :      94123 :         nPos = nPos + pTextPortion->GetLen();
    3216                 :            :     }
    3217                 :            : 
    3218                 :      94011 :     GetRefDevice()->Pop();
    3219                 :            : 
    3220                 :      94011 :     return nWidth;
    3221                 :            : }
    3222                 :            : 
    3223                 :         62 : sal_uInt32 ImpEditEngine::GetTextHeightNTP() const
    3224                 :            : {
    3225                 :            :     DBG_ASSERT( GetUpdateMode(), "Should not be used for Update=FALSE: GetTextHeight" );
    3226                 :            :     DBG_ASSERT( IsFormatted() || IsFormatting(), "GetTextHeight: Not formatted" );
    3227                 :         62 :     return nCurTextHeightNTP;
    3228                 :            : }
    3229                 :            : 
    3230                 :     332033 : sal_uInt32 ImpEditEngine::CalcTextHeight( sal_uInt32* pHeightNTP )
    3231                 :            : {
    3232                 :            :     OSL_ENSURE( GetUpdateMode(), "Should not be used when Update=FALSE: CalcTextHeight" );
    3233                 :     332033 :     sal_uInt32 nY = 0;
    3234                 :            :     sal_uInt32 nPH;
    3235                 :     332033 :     sal_uInt32 nEmptyHeight = 0;
    3236         [ +  + ]:     674413 :     for ( sal_uInt16 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ ) {
    3237                 :     342380 :         ParaPortion* pPortion = GetParaPortions()[nPortion];
    3238                 :     342380 :         nPH = pPortion->GetHeight();
    3239                 :     342380 :         nY += nPH;
    3240         [ +  - ]:     342380 :         if( pHeightNTP ) {
    3241         [ +  + ]:     342380 :             if ( pPortion->IsEmpty() )
    3242                 :     227441 :                 nEmptyHeight += nPH;
    3243                 :            :             else
    3244                 :     114939 :                 nEmptyHeight = 0;
    3245                 :            :         }
    3246                 :            :     }
    3247                 :            : 
    3248         [ +  - ]:     332033 :     if ( pHeightNTP )
    3249                 :     332033 :         *pHeightNTP = nY - nEmptyHeight;
    3250                 :            : 
    3251                 :     332033 :     return nY;
    3252                 :            : }
    3253                 :            : 
    3254                 :          0 : sal_uInt16 ImpEditEngine::GetLineCount( sal_uInt16 nParagraph ) const
    3255                 :            : {
    3256                 :            :     OSL_ENSURE( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
    3257                 :          0 :     const ParaPortion* pPPortion = GetParaPortions().SafeGetObject( nParagraph );
    3258                 :            :     OSL_ENSURE( pPPortion, "Paragraph not found: GetLineCount" );
    3259         [ #  # ]:          0 :     if ( pPPortion )
    3260                 :          0 :         return pPPortion->GetLines().Count();
    3261                 :            : 
    3262                 :          0 :     return 0xFFFF;
    3263                 :            : }
    3264                 :            : 
    3265                 :          0 : xub_StrLen ImpEditEngine::GetLineLen( sal_uInt16 nParagraph, sal_uInt16 nLine ) const
    3266                 :            : {
    3267                 :            :     OSL_ENSURE( nParagraph < GetParaPortions().Count(), "GetLineLen: Out of range" );
    3268                 :          0 :     const ParaPortion* pPPortion = GetParaPortions().SafeGetObject( nParagraph );
    3269                 :            :     OSL_ENSURE( pPPortion, "Paragraph not found: GetLineLen" );
    3270 [ #  # ][ #  # ]:          0 :     if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
                 [ #  # ]
    3271                 :            :     {
    3272                 :          0 :         const EditLine* pLine = pPPortion->GetLines()[nLine];
    3273                 :            :         OSL_ENSURE( pLine, "Line not found: GetLineHeight" );
    3274                 :          0 :         return pLine->GetLen();
    3275                 :            :     }
    3276                 :            : 
    3277                 :          0 :     return 0xFFFF;
    3278                 :            : }
    3279                 :            : 
    3280                 :          0 : void ImpEditEngine::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt16 nParagraph, sal_uInt16 nLine ) const
    3281                 :            : {
    3282                 :            :     OSL_ENSURE( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
    3283                 :          0 :     const ParaPortion* pPPortion = GetParaPortions().SafeGetObject( nParagraph );
    3284                 :            :     OSL_ENSURE( pPPortion, "Paragraph not found: GetLineBoundaries" );
    3285                 :          0 :     rStart = rEnd = 0xFFFF;     // default values in case of error
    3286 [ #  # ][ #  # ]:          0 :     if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
                 [ #  # ]
    3287                 :            :     {
    3288                 :          0 :         const EditLine* pLine = pPPortion->GetLines()[nLine];
    3289                 :            :         OSL_ENSURE( pLine, "Line not found: GetLineBoundaries" );
    3290                 :          0 :         rStart = pLine->GetStart();
    3291                 :          0 :         rEnd   = pLine->GetEnd();
    3292                 :            :     }
    3293                 :          0 : }
    3294                 :            : 
    3295                 :          0 : sal_uInt16 ImpEditEngine::GetLineNumberAtIndex( sal_uInt16 nPara, sal_uInt16 nIndex ) const
    3296                 :            : {
    3297                 :          0 :     sal_uInt16 nLineNo = 0xFFFF;
    3298                 :          0 :     const ContentNode* pNode = GetEditDoc().GetObject( nPara );
    3299                 :            :     OSL_ENSURE( pNode, "GetLineNumberAtIndex: invalid paragraph index" );
    3300         [ #  # ]:          0 :     if (pNode)
    3301                 :            :     {
    3302                 :            :         // we explicitly allow for the index to point at the character right behind the text
    3303                 :          0 :         const bool bValidIndex = /*0 <= nIndex &&*/ nIndex <= pNode->Len();
    3304                 :            :         OSL_ENSURE( bValidIndex, "GetLineNumberAtIndex: invalid index" );
    3305                 :          0 :         const sal_uInt16 nLineCount = GetLineCount( nPara );
    3306         [ #  # ]:          0 :         if (nIndex == pNode->Len())
    3307         [ #  # ]:          0 :             nLineNo = nLineCount > 0 ? nLineCount - 1 : 0;
    3308         [ #  # ]:          0 :         else if (bValidIndex)   // nIndex < pNode->Len()
    3309                 :            :         {
    3310                 :          0 :             sal_uInt16 nStart = USHRT_MAX, nEnd = USHRT_MAX;
    3311 [ #  # ][ #  # ]:          0 :             for (sal_uInt16 i = 0;  i < nLineCount && nLineNo == 0xFFFF;  ++i)
                 [ #  # ]
    3312                 :            :             {
    3313         [ #  # ]:          0 :                 GetLineBoundaries( nStart, nEnd, nPara, i );
    3314 [ #  # ][ #  # ]:          0 :                 if (nStart <= nIndex && nIndex < nEnd)
    3315                 :          0 :                     nLineNo = i;
    3316                 :            :             }
    3317                 :            :         }
    3318                 :            :     }
    3319                 :          0 :     return nLineNo;
    3320                 :            : }
    3321                 :            : 
    3322                 :          0 : sal_uInt16 ImpEditEngine::GetLineHeight( sal_uInt16 nParagraph, sal_uInt16 nLine )
    3323                 :            : {
    3324                 :            :     OSL_ENSURE( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
    3325                 :          0 :     ParaPortion* pPPortion = GetParaPortions().SafeGetObject( nParagraph );
    3326                 :            :     OSL_ENSURE( pPPortion, "Paragraph not found: GetLineHeight" );
    3327 [ #  # ][ #  # ]:          0 :     if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
                 [ #  # ]
    3328                 :            :     {
    3329                 :          0 :         const EditLine* pLine = pPPortion->GetLines()[nLine];
    3330                 :            :         OSL_ENSURE( pLine, "Paragraph not found: GetLineHeight" );
    3331                 :          0 :         return pLine->GetHeight();
    3332                 :            :     }
    3333                 :            : 
    3334                 :          0 :     return 0xFFFF;
    3335                 :            : }
    3336                 :            : 
    3337                 :        203 : sal_uInt32 ImpEditEngine::GetParaHeight( sal_uInt16 nParagraph )
    3338                 :            : {
    3339                 :        203 :     sal_uInt32 nHeight = 0;
    3340                 :            : 
    3341                 :        203 :     ParaPortion* pPPortion = GetParaPortions().SafeGetObject( nParagraph );
    3342                 :            :     OSL_ENSURE( pPPortion, "Paragraph not found: GetParaHeight" );
    3343                 :            : 
    3344         [ +  - ]:        203 :     if ( pPPortion )
    3345                 :        203 :         nHeight = pPPortion->GetHeight();
    3346                 :            : 
    3347                 :        203 :     return nHeight;
    3348                 :            : }
    3349                 :            : 
    3350                 :       1038 : void ImpEditEngine::UpdateSelections()
    3351                 :            : {
    3352                 :            :     // Check whether one of the selections is at a deleted node...
    3353                 :            :     // If the node is valid, the index has yet to be examined!
    3354         [ -  + ]:       1038 :     for (size_t nView = 0; nView < aEditViews.size(); ++nView)
    3355                 :            :     {
    3356                 :          0 :         EditView* pView = aEditViews[nView];
    3357                 :            :         DBG_CHKOBJ( pView, EditView, 0 );
    3358         [ #  # ]:          0 :         EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
    3359                 :          0 :         bool bChanged = false;
    3360         [ #  # ]:          0 :         for (size_t i = 0, n = aDeletedNodes.size(); i < n; ++i)
    3361                 :            :         {
    3362         [ #  # ]:          0 :             const DeletedNodeInfo& rInf = aDeletedNodes[i];
    3363         [ #  # ]:          0 :             if ( ( ( sal_uLong )(aCurSel.Min().GetNode()) == rInf.GetInvalidAdress() ) ||
           [ #  #  #  # ]
                 [ #  # ]
    3364         [ #  # ]:          0 :                  ( ( sal_uLong )(aCurSel.Max().GetNode()) == rInf.GetInvalidAdress() ) )
    3365                 :            :             {
    3366                 :            :                 // Use ParaPortions, as now also hidden paragraphs have to be
    3367                 :            :                 // taken into account!
    3368                 :          0 :                 sal_uInt16 nPara = rInf.GetPosition();
    3369         [ #  # ]:          0 :                 ParaPortion* pPPortion = GetParaPortions().SafeGetObject( nPara );
    3370         [ #  # ]:          0 :                 if ( !pPPortion ) // Last paragraph
    3371                 :            :                 {
    3372         [ #  # ]:          0 :                     nPara = GetParaPortions().Count()-1;
    3373         [ #  # ]:          0 :                     pPPortion = GetParaPortions()[nPara];
    3374                 :            :                 }
    3375                 :            :                 OSL_ENSURE( pPPortion, "Empty Document in UpdateSelections ?" );
    3376                 :            :                 // Do not end up from a hidden paragraph:
    3377                 :          0 :                 sal_uInt16 nCurPara = nPara;
    3378         [ #  # ]:          0 :                 sal_uInt16 nLastPara = GetParaPortions().Count()-1;
    3379 [ #  # ][ #  # ]:          0 :                 while ( nPara <= nLastPara && !GetParaPortions()[nPara]->IsVisible() )
         [ #  # ][ #  # ]
    3380                 :          0 :                     nPara++;
    3381         [ #  # ]:          0 :                 if ( nPara > nLastPara ) // then also backwards ...
    3382                 :            :                 {
    3383                 :          0 :                     nPara = nCurPara;
    3384 [ #  # ][ #  # ]:          0 :                     while ( nPara && !GetParaPortions()[nPara]->IsVisible() )
         [ #  # ][ #  # ]
    3385                 :          0 :                         nPara--;
    3386                 :            :                 }
    3387                 :            :                 OSL_ENSURE( GetParaPortions()[nPara]->IsVisible(), "No visible paragraph found: UpdateSelections" );
    3388                 :            : 
    3389         [ #  # ]:          0 :                 ParaPortion* pParaPortion = GetParaPortions()[nPara];
    3390 [ #  # ][ #  # ]:          0 :                 EditSelection aTmpSelection( EditPaM( pParaPortion->GetNode(), 0 ) );
    3391         [ #  # ]:          0 :                 pView->pImpEditView->SetEditSelection( aTmpSelection );
    3392                 :          0 :                 bChanged=sal_True;
    3393                 :            :                 break;  // for loop
    3394                 :            :             }
    3395                 :            :         }
    3396         [ #  # ]:          0 :         if ( !bChanged )
    3397                 :            :         {
    3398                 :            :             // Check Index if node shrunk.
    3399 [ #  # ][ #  # ]:          0 :             if ( aCurSel.Min().GetIndex() > aCurSel.Min().GetNode()->Len() )
                 [ #  # ]
    3400                 :            :             {
    3401 [ #  # ][ #  # ]:          0 :                 aCurSel.Min().GetIndex() = aCurSel.Min().GetNode()->Len();
    3402         [ #  # ]:          0 :                 pView->pImpEditView->SetEditSelection( aCurSel );
    3403                 :            :             }
    3404 [ #  # ][ #  # ]:          0 :             if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
                 [ #  # ]
    3405                 :            :             {
    3406 [ #  # ][ #  # ]:          0 :                 aCurSel.Max().GetIndex() = aCurSel.Max().GetNode()->Len();
    3407         [ #  # ]:          0 :                 pView->pImpEditView->SetEditSelection( aCurSel );
    3408                 :            :             }
    3409                 :            :         }
    3410                 :            :     }
    3411                 :            : 
    3412                 :       1038 :     aDeletedNodes.clear();
    3413                 :       1038 : }
    3414                 :            : 
    3415                 :      36717 : EditSelection ImpEditEngine::ConvertSelection(
    3416                 :            :     sal_uInt16 nStartPara, sal_uInt16 nStartPos, sal_uInt16 nEndPara, sal_uInt16 nEndPos )
    3417                 :            : {
    3418                 :      36717 :     EditSelection aNewSelection;
    3419                 :            : 
    3420                 :            :     // Start...
    3421                 :      36717 :     ContentNode* pNode = aEditDoc.GetObject( nStartPara );
    3422                 :      36717 :     sal_uInt16 nIndex = nStartPos;
    3423         [ -  + ]:      36717 :     if ( !pNode )
    3424                 :            :     {
    3425                 :          0 :         pNode = aEditDoc[ aEditDoc.Count()-1 ];
    3426                 :          0 :         nIndex = pNode->Len();
    3427                 :            :     }
    3428         [ -  + ]:      36717 :     else if ( nIndex > pNode->Len() )
    3429                 :          0 :         nIndex = pNode->Len();
    3430                 :            : 
    3431                 :      36717 :     aNewSelection.Min().SetNode( pNode );
    3432                 :      36717 :     aNewSelection.Min().SetIndex( nIndex );
    3433                 :            : 
    3434                 :            :     // End...
    3435                 :      36717 :     pNode = aEditDoc.GetObject( nEndPara );
    3436                 :      36717 :     nIndex = nEndPos;
    3437         [ +  + ]:      36717 :     if ( !pNode )
    3438                 :            :     {
    3439                 :        293 :         pNode = aEditDoc[ aEditDoc.Count()-1 ];
    3440                 :        293 :         nIndex = pNode->Len();
    3441                 :            :     }
    3442         [ +  + ]:      36424 :     else if ( nIndex > pNode->Len() )
    3443                 :        162 :         nIndex = pNode->Len();
    3444                 :            : 
    3445                 :      36717 :     aNewSelection.Max().SetNode( pNode );
    3446                 :      36717 :     aNewSelection.Max().SetIndex( nIndex );
    3447                 :            : 
    3448                 :      36717 :     return aNewSelection;
    3449                 :            : }
    3450                 :            : 
    3451                 :        371 : void ImpEditEngine::SetActiveView( EditView* pView )
    3452                 :            : {
    3453                 :            :     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    3454                 :            :     // Actually, now bHasVisSel and HideSelection would be necessary     !!!
    3455                 :            : 
    3456         [ -  + ]:        371 :     if ( pView == pActiveView )
    3457                 :        371 :         return;
    3458                 :            : 
    3459 [ +  + ][ -  + ]:        371 :     if ( pActiveView && pActiveView->HasSelection() )
                 [ -  + ]
    3460                 :          0 :         pActiveView->pImpEditView->DrawSelection();
    3461                 :            : 
    3462                 :        371 :     pActiveView = pView;
    3463                 :            : 
    3464 [ +  + ][ -  + ]:        371 :     if ( pActiveView && pActiveView->HasSelection() )
                 [ -  + ]
    3465                 :          0 :         pActiveView->pImpEditView->DrawSelection();
    3466                 :            : 
    3467                 :            :     //  NN: Quick fix for #78668#:
    3468                 :            :     //  When editing of a cell in Calc is ended, the edit engine is not deleted,
    3469                 :            :     //  only the edit views are removed. If mpIMEInfos is still set in that case,
    3470                 :            :     //  mpIMEInfos->aPos points to an invalid selection.
    3471                 :            :     //  -> reset mpIMEInfos now
    3472                 :            :     //  (probably something like this is necessary whenever the content is modified
    3473                 :            :     //  from the outside)
    3474                 :            : 
    3475 [ +  + ][ -  + ]:        371 :     if ( !pView && mpIMEInfos )
    3476                 :            :     {
    3477         [ #  # ]:          0 :         delete mpIMEInfos;
    3478                 :          0 :         mpIMEInfos = NULL;
    3479                 :            :     }
    3480                 :            : }
    3481                 :            : 
    3482                 :          0 : uno::Reference< datatransfer::XTransferable > ImpEditEngine::CreateTransferable( const EditSelection& rSelection )
    3483                 :            : {
    3484         [ #  # ]:          0 :     EditSelection aSelection( rSelection );
    3485         [ #  # ]:          0 :     aSelection.Adjust( GetEditDoc() );
    3486                 :            : 
    3487         [ #  # ]:          0 :     EditDataObject* pDataObj = new EditDataObject;
    3488                 :          0 :     uno::Reference< datatransfer::XTransferable > xDataObj;
    3489         [ #  # ]:          0 :     xDataObj = pDataObj;
    3490                 :            : 
    3491 [ #  # ][ #  # ]:          0 :     XubString aText(convertLineEnd(GetSelected(aSelection), GetSystemLineEnd())); // System specific
         [ #  # ][ #  # ]
                 [ #  # ]
    3492         [ #  # ]:          0 :     pDataObj->GetString() = aText;
    3493                 :            : 
    3494         [ #  # ]:          0 :     SvxFontItem::EnableStoreUnicodeNames( sal_True );
    3495 [ #  # ][ #  # ]:          0 :     WriteBin( pDataObj->GetStream(), aSelection, sal_True );
    3496         [ #  # ]:          0 :     pDataObj->GetStream().Seek( 0 );
    3497         [ #  # ]:          0 :     SvxFontItem::EnableStoreUnicodeNames( sal_False );
    3498                 :            : 
    3499 [ #  # ][ #  # ]:          0 :     ((ImpEditEngine*)this)->WriteRTF( pDataObj->GetRTFStream(), aSelection );
    3500         [ #  # ]:          0 :     pDataObj->GetRTFStream().Seek( 0 );
    3501                 :            : 
    3502 [ #  # ][ #  # ]:          0 :     if ( ( aSelection.Min().GetNode() == aSelection.Max().GetNode() )
           [ #  #  #  # ]
                 [ #  # ]
    3503                 :          0 :             && ( aSelection.Max().GetIndex() == (aSelection.Min().GetIndex()+1) ) )
    3504                 :            :     {
    3505         [ #  # ]:          0 :         const EditCharAttrib* pAttr = aSelection.Min().GetNode()->GetCharAttribs().
    3506         [ #  # ]:          0 :             FindFeature( aSelection.Min().GetIndex() );
    3507   [ #  #  #  #  :          0 :         if ( pAttr &&
           #  # ][ #  # ]
    3508                 :          0 :             ( pAttr->GetStart() == aSelection.Min().GetIndex() ) &&
    3509                 :          0 :             ( pAttr->Which() == EE_FEATURE_FIELD ) )
    3510                 :            :         {
    3511                 :          0 :             const SvxFieldItem* pField = (const SvxFieldItem*)pAttr->GetItem();
    3512                 :          0 :             const SvxFieldData* pFld = pField->GetField();
    3513 [ #  # ][ #  # ]:          0 :             if ( pFld && pFld->ISA( SvxURLField ) )
         [ #  # ][ #  # ]
                 [ #  # ]
    3514                 :            :             {
    3515                 :            :                 // Office-Bookmark
    3516         [ #  # ]:          0 :                 String aURL( ((const SvxURLField*)pFld)->GetURL() );
    3517         [ #  # ]:          0 :                 String aTxt( ((const SvxURLField*)pFld)->GetRepresentation() );
    3518 [ #  # ][ #  # ]:          0 :                 pDataObj->GetURL() = aURL;
                 [ #  # ]
    3519                 :            :             }
    3520                 :            :         }
    3521                 :            :     }
    3522                 :            : 
    3523         [ #  # ]:          0 :     return xDataObj;
    3524                 :            : }
    3525                 :            : 
    3526                 :          0 : EditSelection ImpEditEngine::InsertText( uno::Reference< datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, sal_Bool bUseSpecial )
    3527                 :            : {
    3528                 :          0 :     EditSelection aNewSelection( rPaM );
    3529                 :            : 
    3530         [ #  # ]:          0 :     if ( rxDataObj.is() )
    3531                 :            :     {
    3532                 :          0 :         datatransfer::DataFlavor aFlavor;
    3533                 :          0 :         sal_Bool bDone = sal_False;
    3534                 :            : 
    3535         [ #  # ]:          0 :         if ( bUseSpecial )
    3536                 :            :         {
    3537                 :            :             // BIN
    3538         [ #  # ]:          0 :             SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EDITENGINE, aFlavor );
    3539 [ #  # ][ #  # ]:          0 :             if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
                 [ #  # ]
    3540                 :            :             {
    3541                 :            :                 try
    3542                 :            :                 {
    3543 [ #  # ][ #  # ]:          0 :                     uno::Any aData = rxDataObj->getTransferData( aFlavor );
    3544         [ #  # ]:          0 :                     uno::Sequence< sal_Int8 > aSeq;
    3545         [ #  # ]:          0 :                     aData >>= aSeq;
    3546                 :            :                     {
    3547 [ #  # ][ #  # ]:          0 :                         SvMemoryStream aBinStream( aSeq.getArray(), aSeq.getLength(), STREAM_READ );
    3548 [ #  # ][ #  # ]:          0 :                         aNewSelection = Read( aBinStream, rBaseURL, EE_FORMAT_BIN, rPaM );
         [ #  # ][ #  # ]
    3549                 :            :                     }
    3550 [ #  # ][ #  # ]:          0 :                     bDone = sal_True;
    3551                 :            :                 }
    3552         [ #  # ]:          0 :                 catch( const ::com::sun::star::uno::Exception& )
    3553                 :            :                 {
    3554                 :            :                 }
    3555                 :            :             }
    3556                 :            : 
    3557         [ #  # ]:          0 :             if ( !bDone )
    3558                 :            :             {
    3559                 :            :                 // RTF
    3560         [ #  # ]:          0 :                 SotExchange::GetFormatDataFlavor( SOT_FORMAT_RTF, aFlavor );
    3561 [ #  # ][ #  # ]:          0 :                 if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
                 [ #  # ]
    3562                 :            :                 {
    3563                 :            :                     try
    3564                 :            :                     {
    3565 [ #  # ][ #  # ]:          0 :                         uno::Any aData = rxDataObj->getTransferData( aFlavor );
    3566         [ #  # ]:          0 :                         uno::Sequence< sal_Int8 > aSeq;
    3567         [ #  # ]:          0 :                         aData >>= aSeq;
    3568                 :            :                         {
    3569 [ #  # ][ #  # ]:          0 :                             SvMemoryStream aRTFStream( aSeq.getArray(), aSeq.getLength(), STREAM_READ );
    3570 [ #  # ][ #  # ]:          0 :                             aNewSelection = Read( aRTFStream, rBaseURL, EE_FORMAT_RTF, rPaM );
         [ #  # ][ #  # ]
    3571                 :            :                         }
    3572 [ #  # ][ #  # ]:          0 :                         bDone = sal_True;
    3573                 :            :                     }
    3574         [ #  # ]:          0 :                     catch( const ::com::sun::star::uno::Exception& )
    3575                 :            :                     {
    3576                 :            :                     }
    3577                 :            :                 }
    3578                 :            :             }
    3579                 :            :             if ( !bDone )
    3580                 :            :             {
    3581                 :            :                 // XML ?
    3582                 :            :                 // Currently, there is nothing like "The" XML format, StarOffice doesn't offer plain XML in Clipboard...
    3583                 :            :             }
    3584                 :            :         }
    3585         [ #  # ]:          0 :         if ( !bDone )
    3586                 :            :         {
    3587         [ #  # ]:          0 :             SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
    3588 [ #  # ][ #  # ]:          0 :             if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
                 [ #  # ]
    3589                 :            :             {
    3590                 :            :                 try
    3591                 :            :                 {
    3592 [ #  # ][ #  # ]:          0 :                     uno::Any aData = rxDataObj->getTransferData( aFlavor );
    3593                 :          0 :                     ::rtl::OUString aText;
    3594                 :          0 :                     aData >>= aText;
    3595 [ #  # ][ #  # ]:          0 :                     aNewSelection = ImpInsertText( rPaM, aText );
         [ #  # ][ #  # ]
                 [ #  # ]
    3596                 :          0 :                        bDone = sal_True;
    3597                 :            :                 }
    3598         [ #  # ]:          0 :                 catch( ... )
    3599                 :            :                 {
    3600                 :            :                     ; // #i9286# can happen, even if isDataFlavorSupported returns true...
    3601                 :            :                 }
    3602                 :            :             }
    3603                 :          0 :         }
    3604                 :            :     }
    3605                 :            : 
    3606                 :          0 :     return aNewSelection;
    3607                 :            : }
    3608                 :            : 
    3609                 :     314936 : Range ImpEditEngine::GetInvalidYOffsets( ParaPortion* pPortion )
    3610                 :            : {
    3611                 :     314936 :     Range aRange( 0, 0 );
    3612                 :            : 
    3613         [ +  - ]:     314936 :     if ( pPortion->IsVisible() )
    3614                 :            :     {
    3615                 :     314936 :         const SvxULSpaceItem& rULSpace = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
    3616                 :     314936 :         const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
    3617                 :     314936 :         sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
    3618         [ +  + ]:     314936 :                             ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
    3619                 :            : 
    3620                 :            :         // only from the top ...
    3621                 :     314936 :         sal_uInt16 nFirstInvalid = 0xFFFF;
    3622                 :            :         sal_uInt16 nLine;
    3623         [ +  - ]:     314936 :         for ( nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
    3624                 :            :         {
    3625                 :     314936 :             const EditLine* pL = pPortion->GetLines()[nLine];
    3626         [ +  - ]:     314936 :             if ( pL->IsInvalid() )
    3627                 :            :             {
    3628                 :     314936 :                 nFirstInvalid = nLine;
    3629                 :     314936 :                 break;
    3630                 :            :             }
    3631 [ #  # ][ #  # ]:          0 :             if ( nLine && !aStatus.IsOutliner() )   // not the first line
                 [ #  # ]
    3632                 :          0 :                 aRange.Min() += nSBL;
    3633                 :          0 :             aRange.Min() += pL->GetHeight();
    3634                 :            :         }
    3635                 :            :         OSL_ENSURE( nFirstInvalid != 0xFFFF, "No invalid line found in GetInvalidYOffset(1)" );
    3636                 :            : 
    3637                 :            : 
    3638                 :            :         // Syndicate and more ...
    3639                 :     314936 :         aRange.Max() = aRange.Min();
    3640                 :     314936 :         aRange.Max() += pPortion->GetFirstLineOffset();
    3641         [ -  + ]:     314936 :         if ( nFirstInvalid != 0 )   // Only if the first line is invalid
    3642                 :          0 :             aRange.Min() = aRange.Max();
    3643                 :            : 
    3644                 :     314936 :         sal_uInt16 nLastInvalid = pPortion->GetLines().Count()-1;
    3645         [ +  + ]:     721080 :         for ( nLine = nFirstInvalid; nLine < pPortion->GetLines().Count(); nLine++ )
    3646                 :            :         {
    3647                 :     406144 :             const EditLine* pL = pPortion->GetLines()[nLine];
    3648         [ -  + ]:     406144 :             if ( pL->IsValid() )
    3649                 :            :             {
    3650                 :          0 :                 nLastInvalid = nLine;
    3651                 :          0 :                 break;
    3652                 :            :             }
    3653                 :            : 
    3654 [ +  + ][ +  - ]:     406144 :             if ( nLine && !aStatus.IsOutliner() )
                 [ +  + ]
    3655                 :      91208 :                 aRange.Max() += nSBL;
    3656                 :     406144 :             aRange.Max() += pL->GetHeight();
    3657                 :            :         }
    3658                 :            : 
    3659         [ +  + ]:     315473 :         if( ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP ) && rLSItem.GetPropLineSpace() &&
           [ +  -  +  + ]
                 [ +  + ]
    3660                 :        537 :             ( rLSItem.GetPropLineSpace() < 100 ) )
    3661                 :            :         {
    3662                 :        270 :             const EditLine* pL = pPortion->GetLines()[nFirstInvalid];
    3663                 :        270 :             long n = pL->GetTxtHeight() * ( 100 - rLSItem.GetPropLineSpace() );
    3664                 :        270 :             n /= 100;
    3665                 :        270 :             aRange.Min() -= n;
    3666                 :        270 :             aRange.Max() += n;
    3667                 :            :         }
    3668                 :            : 
    3669 [ +  - ][ +  - ]:     314936 :         if ( ( nLastInvalid == pPortion->GetLines().Count()-1 ) && ( !aStatus.IsOutliner() ) )
                 [ +  - ]
    3670                 :     314936 :             aRange.Max() += GetYValue( rULSpace.GetLower() );
    3671                 :            :     }
    3672                 :     314936 :     return aRange;
    3673                 :            : }
    3674                 :            : 
    3675                 :         22 : EditPaM ImpEditEngine::GetPaM( ParaPortion* pPortion, Point aDocPos, sal_Bool bSmart )
    3676                 :            : {
    3677                 :            :     OSL_ENSURE( pPortion->IsVisible(), "Why GetPaM() for an invisible paragraph?" );
    3678                 :            :     OSL_ENSURE( IsFormatted(), "GetPaM: Not formatted" );
    3679                 :            : 
    3680                 :         22 :     sal_uInt16 nCurIndex = 0;
    3681                 :         22 :     EditPaM aPaM;
    3682                 :         22 :     aPaM.SetNode( pPortion->GetNode() );
    3683                 :            : 
    3684                 :         22 :     const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
    3685                 :         22 :     sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
    3686         [ -  + ]:         22 :                         ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
    3687                 :            : 
    3688                 :         22 :     long nY = pPortion->GetFirstLineOffset();
    3689                 :            : 
    3690                 :            :     OSL_ENSURE( pPortion->GetLines().Count(), "Empty ParaPortion in GetPaM!" );
    3691                 :            : 
    3692                 :         22 :     const EditLine* pLine = NULL;
    3693         [ +  - ]:         22 :     for ( sal_uInt16 nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
    3694                 :            :     {
    3695                 :         22 :         const EditLine* pTmpLine = pPortion->GetLines()[nLine];
    3696                 :         22 :         nY += pTmpLine->GetHeight();
    3697         [ +  - ]:         22 :         if ( !aStatus.IsOutliner() )
    3698                 :         22 :             nY += nSBL;
    3699         [ +  - ]:         22 :         if ( nY > aDocPos.Y() )
    3700                 :            :         {
    3701                 :         22 :             pLine = pTmpLine;
    3702                 :         22 :             break;                  // correct Y-position is not of interest
    3703                 :            :         }
    3704                 :            : 
    3705                 :          0 :         nCurIndex = nCurIndex + pTmpLine->GetLen();
    3706                 :            :     }
    3707                 :            : 
    3708         [ -  + ]:         22 :     if ( !pLine ) // may happen only in the range of SA!
    3709                 :            :     {
    3710                 :            : #if OSL_DEBUG_LEVEL > 0
    3711                 :            :         const SvxULSpaceItem& rULSpace =(const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
    3712                 :            :         OSL_ENSURE( nY+GetYValue( rULSpace.GetLower() ) >= aDocPos.Y() , "Index in no line, GetPaM ?" );
    3713                 :            : #endif
    3714                 :          0 :         aPaM.SetIndex( pPortion->GetNode()->Len() );
    3715                 :          0 :         return aPaM;
    3716                 :            :     }
    3717                 :            : 
    3718                 :            :     // If no line found, only just X-Position => Index
    3719                 :         22 :     nCurIndex = GetChar( pPortion, pLine, aDocPos.X(), bSmart );
    3720                 :         22 :     aPaM.SetIndex( nCurIndex );
    3721                 :            : 
    3722   [ -  +  #  # ]:         22 :     if ( nCurIndex && ( nCurIndex == pLine->GetEnd() ) &&
         [ -  + ][ +  + ]
    3723                 :          0 :          ( pLine != pPortion->GetLines()[pPortion->GetLines().Count()-1] ) )
    3724                 :            :     {
    3725         [ #  # ]:          0 :         aPaM = CursorLeft( aPaM, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL );
    3726                 :            :     }
    3727                 :            : 
    3728                 :         22 :     return aPaM;
    3729                 :            : }
    3730                 :            : 
    3731                 :         22 : sal_uInt16 ImpEditEngine::GetChar(
    3732                 :            :     const ParaPortion* pParaPortion, const EditLine* pLine, long nXPos, bool bSmart)
    3733                 :            : {
    3734                 :            :     OSL_ENSURE( pLine, "No line received: GetChar" );
    3735                 :            : 
    3736                 :         22 :     sal_uInt16 nChar = 0xFFFF;
    3737                 :         22 :     sal_uInt16 nCurIndex = pLine->GetStart();
    3738                 :            : 
    3739                 :            : 
    3740                 :            :     // Search best matching portion with GetPortionXOffset()
    3741         [ +  + ]:         44 :     for ( sal_uInt16 i = pLine->GetStartPortion(); i <= pLine->GetEndPortion(); i++ )
    3742                 :            :     {
    3743                 :         22 :         const TextPortion* pPortion = pParaPortion->GetTextPortions()[i];
    3744                 :         22 :         long nXLeft = GetPortionXOffset( pParaPortion, pLine, i );
    3745                 :         22 :         long nXRight = nXLeft + pPortion->GetSize().Width();
    3746 [ +  - ][ +  + ]:         22 :         if ( ( nXLeft <= nXPos ) && ( nXRight >= nXPos ) )
    3747                 :            :         {
    3748                 :         20 :              nChar = nCurIndex;
    3749                 :            : 
    3750                 :            :             // Search within Portion...
    3751                 :            : 
    3752                 :            :             // Don't search within special portions...
    3753         [ -  + ]:         20 :             if ( pPortion->GetKind() != PORTIONKIND_TEXT )
    3754                 :            :             {
    3755                 :            :                 // ...but check on which side
    3756         [ #  # ]:          0 :                 if ( bSmart )
    3757                 :            :                 {
    3758                 :          0 :                     long nLeftDiff = nXPos-nXLeft;
    3759                 :          0 :                     long nRightDiff = nXRight-nXPos;
    3760         [ #  # ]:          0 :                     if ( nRightDiff < nLeftDiff )
    3761                 :          0 :                         nChar++;
    3762                 :            :                 }
    3763                 :            :             }
    3764                 :            :             else
    3765                 :            :             {
    3766                 :         20 :                 sal_uInt16 nMax = pPortion->GetLen();
    3767                 :         20 :                 sal_uInt16 nOffset = 0xFFFF;
    3768                 :         20 :                 sal_uInt16 nTmpCurIndex = nChar - pLine->GetStart();
    3769                 :            : 
    3770                 :         20 :                 long nXInPortion = nXPos - nXLeft;
    3771         [ -  + ]:         20 :                 if ( pPortion->IsRightToLeft() )
    3772                 :          0 :                     nXInPortion = nXRight - nXPos;
    3773                 :            : 
    3774                 :            :                 // Search in Array...
    3775         [ +  - ]:         56 :                 for ( sal_uInt16 x = 0; x < nMax; x++ )
    3776                 :            :                 {
    3777                 :         56 :                     long nTmpPosMax = pLine->GetCharPosArray()[nTmpCurIndex+x];
    3778         [ +  + ]:         56 :                     if ( nTmpPosMax > nXInPortion )
    3779                 :            :                     {
    3780                 :            :                         // Check whether this or the previous...
    3781         [ +  + ]:         20 :                         long nTmpPosMin = x ? pLine->GetCharPosArray()[nTmpCurIndex+x-1] : 0;
    3782                 :         20 :                         long nDiffLeft = nXInPortion - nTmpPosMin;
    3783                 :         20 :                         long nDiffRight = nTmpPosMax - nXInPortion;
    3784                 :            :                         OSL_ENSURE( nDiffLeft >= 0, "DiffLeft negative" );
    3785                 :            :                         OSL_ENSURE( nDiffRight >= 0, "DiffRight negative" );
    3786 [ -  + ][ #  # ]:         20 :                         nOffset = ( bSmart && ( nDiffRight < nDiffLeft ) ) ? x+1 : x;
    3787                 :            :                         // I18N: If there are character position with the length of 0,
    3788                 :            :                         // they belong to the same character, we can not use this position as an index.
    3789                 :            :                         // Skip all 0-positions, cheaper than using XBreakIterator:
    3790         [ +  - ]:         20 :                         if ( nOffset < nMax )
    3791                 :            :                         {
    3792                 :         20 :                             const long nX = pLine->GetCharPosArray()[nOffset];
    3793 [ +  + ][ -  + ]:         20 :                             while ( ( (nOffset+1) < nMax ) && ( pLine->GetCharPosArray()[nOffset+1] == nX ) )
                 [ -  + ]
    3794                 :          0 :                                 nOffset++;
    3795                 :            :                         }
    3796                 :         20 :                         break;
    3797                 :            :                     }
    3798                 :            :                 }
    3799                 :            : 
    3800                 :            :                 // There should not be any inaccuracies when using the
    3801                 :            :                 // CharPosArray! Maybe for kerning?
    3802                 :            :                 // 0xFFF happens for example for Outline-Font when at the very end.
    3803         [ -  + ]:         20 :                 if ( nOffset == 0xFFFF )
    3804                 :          0 :                     nOffset = nMax;
    3805                 :            : 
    3806                 :            :                 OSL_ENSURE( nOffset <= nMax, "nOffset > nMax" );
    3807                 :            : 
    3808                 :         20 :                 nChar = nChar + nOffset;
    3809                 :            : 
    3810                 :            :                 // Check if index is within a cell:
    3811 [ +  + ][ +  - ]:         20 :                 if ( nChar && ( nChar < pParaPortion->GetNode()->Len() ) )
                 [ +  + ]
    3812                 :            :                 {
    3813         [ +  - ]:         14 :                     EditPaM aPaM( pParaPortion->GetNode(), nChar+1 );
    3814         [ +  - ]:         14 :                     sal_uInt16 nScriptType = GetScriptType( aPaM );
    3815         [ -  + ]:         14 :                     if ( nScriptType == i18n::ScriptType::COMPLEX )
    3816                 :            :                     {
    3817         [ #  # ]:          0 :                         uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
    3818                 :          0 :                         sal_Int32 nCount = 1;
    3819         [ #  # ]:          0 :                         lang::Locale aLocale = GetLocale( aPaM );
    3820         [ #  # ]:          0 :                         sal_uInt16 nRight = (sal_uInt16)_xBI->nextCharacters(
    3821 [ #  # ][ #  # ]:          0 :                             pParaPortion->GetNode()->GetString(), nChar, aLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, nCount, nCount );
                 [ #  # ]
    3822         [ #  # ]:          0 :                         sal_uInt16 nLeft = (sal_uInt16)_xBI->previousCharacters(
    3823 [ #  # ][ #  # ]:          0 :                             pParaPortion->GetNode()->GetString(), nRight, aLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, nCount, nCount );
                 [ #  # ]
    3824 [ #  # ][ #  # ]:          0 :                         if ( ( nLeft != nChar ) && ( nRight != nChar ) )
    3825                 :            :                         {
    3826         [ #  # ]:          0 :                             nChar = ( Abs( nRight - nChar ) < Abs( nLeft - nChar ) ) ? nRight : nLeft;
    3827                 :         14 :                         }
    3828                 :            :                     }
    3829                 :            :                 }
    3830                 :            :             }
    3831                 :            :         }
    3832                 :            : 
    3833                 :         22 :         nCurIndex = nCurIndex + pPortion->GetLen();
    3834                 :            :     }
    3835                 :            : 
    3836         [ +  + ]:         22 :     if ( nChar == 0xFFFF )
    3837                 :            :     {
    3838         [ +  - ]:          2 :         nChar = ( nXPos <= pLine->GetStartPosX() ) ? pLine->GetStart() : pLine->GetEnd();
    3839                 :            :     }
    3840                 :            : 
    3841                 :         22 :     return nChar;
    3842                 :            : }
    3843                 :            : 
    3844                 :          8 : Range ImpEditEngine::GetLineXPosStartEnd( const ParaPortion* pParaPortion, const EditLine* pLine ) const
    3845                 :            : {
    3846                 :          8 :     Range aLineXPosStartEnd;
    3847                 :            : 
    3848                 :          8 :     sal_uInt16 nPara = GetEditDoc().GetPos( pParaPortion->GetNode() );
    3849         [ +  - ]:          8 :     if ( !IsRightToLeft( nPara ) )
    3850                 :            :     {
    3851                 :          8 :         aLineXPosStartEnd.Min() = pLine->GetStartPosX();
    3852                 :          8 :         aLineXPosStartEnd.Max() = pLine->GetStartPosX() + pLine->GetTextWidth();
    3853                 :            :     }
    3854                 :            :     else
    3855                 :            :     {
    3856                 :          0 :         aLineXPosStartEnd.Min() = GetPaperSize().Width() - ( pLine->GetStartPosX() + pLine->GetTextWidth() );
    3857                 :          0 :         aLineXPosStartEnd.Max() = GetPaperSize().Width() - pLine->GetStartPosX();
    3858                 :            :     }
    3859                 :            : 
    3860                 :            : 
    3861                 :          8 :     return aLineXPosStartEnd;
    3862                 :            : }
    3863                 :            : 
    3864                 :      22293 : long ImpEditEngine::GetPortionXOffset(
    3865                 :            :     const ParaPortion* pParaPortion, const EditLine* pLine, sal_uInt16 nTextPortion) const
    3866                 :            : {
    3867                 :      22293 :     long nX = pLine->GetStartPosX();
    3868                 :            : 
    3869         [ +  + ]:      22446 :     for ( sal_uInt16 i = pLine->GetStartPortion(); i < nTextPortion; i++ )
    3870                 :            :     {
    3871                 :        153 :         const TextPortion* pPortion = pParaPortion->GetTextPortions()[i];
    3872         [ +  - ]:        153 :         switch ( pPortion->GetKind() )
    3873                 :            :         {
    3874                 :            :             case PORTIONKIND_FIELD:
    3875                 :            :             case PORTIONKIND_TEXT:
    3876                 :            :             case PORTIONKIND_HYPHENATOR:
    3877                 :            :             case PORTIONKIND_TAB:
    3878                 :            :             {
    3879                 :        153 :                 nX += pPortion->GetSize().Width();
    3880                 :            :             }
    3881                 :        153 :             break;
    3882                 :            :         }
    3883                 :            :     }
    3884                 :            : 
    3885                 :      22293 :     sal_uInt16 nPara = GetEditDoc().GetPos( pParaPortion->GetNode() );
    3886                 :      22293 :     sal_Bool bR2LPara = IsRightToLeft( nPara );
    3887                 :            : 
    3888                 :      22293 :     const TextPortion* pDestPortion = pParaPortion->GetTextPortions()[nTextPortion];
    3889         [ +  - ]:      22293 :     if ( pDestPortion->GetKind() != PORTIONKIND_TAB )
    3890                 :            :     {
    3891 [ +  + ][ -  + ]:      22293 :         if ( !bR2LPara && pDestPortion->GetRightToLeft() )
                 [ -  + ]
    3892                 :            :         {
    3893                 :            :             // Portions behind must be added, visual before this portion
    3894                 :          0 :             sal_uInt16 nTmpPortion = nTextPortion+1;
    3895         [ #  # ]:          0 :             while ( nTmpPortion <= pLine->GetEndPortion() )
    3896                 :            :             {
    3897                 :          0 :                 const TextPortion* pNextTextPortion = pParaPortion->GetTextPortions()[nTmpPortion];
    3898 [ #  # ][ #  # ]:          0 :                 if ( pNextTextPortion->GetRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
                 [ #  # ]
    3899                 :          0 :                     nX += pNextTextPortion->GetSize().Width();
    3900                 :            :                 else
    3901                 :          0 :                     break;
    3902                 :          0 :                 nTmpPortion++;
    3903                 :            :             }
    3904                 :            :             // Portions before must be removed, visual behind this portion
    3905                 :          0 :             nTmpPortion = nTextPortion;
    3906         [ #  # ]:          0 :             while ( nTmpPortion > pLine->GetStartPortion() )
    3907                 :            :             {
    3908                 :          0 :                 --nTmpPortion;
    3909                 :          0 :                 const TextPortion* pPrevTextPortion = pParaPortion->GetTextPortions()[nTmpPortion];
    3910 [ #  # ][ #  # ]:          0 :                 if ( pPrevTextPortion->GetRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
                 [ #  # ]
    3911                 :          0 :                     nX -= pPrevTextPortion->GetSize().Width();
    3912                 :            :                 else
    3913                 :          0 :                     break;
    3914                 :            :             }
    3915                 :            :         }
    3916 [ +  + ][ +  - ]:      22293 :         else if ( bR2LPara && !pDestPortion->IsRightToLeft() )
                 [ +  + ]
    3917                 :            :         {
    3918                 :            :             // Portions behind must be removed, visual behind this portion
    3919                 :        798 :             sal_uInt16 nTmpPortion = nTextPortion+1;
    3920         [ +  + ]:        838 :             while ( nTmpPortion <= pLine->GetEndPortion() )
    3921                 :            :             {
    3922                 :         40 :                 const TextPortion* pNextTextPortion = pParaPortion->GetTextPortions()[nTmpPortion];
    3923 [ +  - ][ +  - ]:         40 :                 if ( !pNextTextPortion->IsRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
                 [ +  - ]
    3924                 :         40 :                     nX += pNextTextPortion->GetSize().Width();
    3925                 :            :                 else
    3926                 :          0 :                     break;
    3927                 :         40 :                 nTmpPortion++;
    3928                 :            :             }
    3929                 :            :             // Portions before must be added, visual before this portion
    3930                 :        798 :             nTmpPortion = nTextPortion;
    3931         [ +  + ]:        838 :             while ( nTmpPortion > pLine->GetStartPortion() )
    3932                 :            :             {
    3933                 :         40 :                 --nTmpPortion;
    3934                 :         40 :                 const TextPortion* pPrevTextPortion = pParaPortion->GetTextPortions()[nTmpPortion];
    3935 [ +  - ][ +  - ]:         40 :                 if ( !pPrevTextPortion->IsRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
                 [ +  - ]
    3936                 :         40 :                     nX -= pPrevTextPortion->GetSize().Width();
    3937                 :            :                 else
    3938                 :          0 :                     break;
    3939                 :            :             }
    3940                 :            :         }
    3941                 :            :     }
    3942         [ +  + ]:      22293 :     if ( bR2LPara )
    3943                 :            :     {
    3944                 :            :         // Switch X postions...
    3945                 :            :         OSL_ENSURE( GetTextRanger() || GetPaperSize().Width(), "GetPortionXOffset - paper size?!" );
    3946                 :            :         OSL_ENSURE( GetTextRanger() || (nX <= GetPaperSize().Width()), "GetPortionXOffset - position out of paper size!" );
    3947                 :        798 :         nX = GetPaperSize().Width() - nX;
    3948                 :        798 :         nX -= pDestPortion->GetSize().Width();
    3949                 :            :     }
    3950                 :            : 
    3951                 :      22293 :     return nX;
    3952                 :            : }
    3953                 :            : 
    3954                 :       1116 : long ImpEditEngine::GetXPos(
    3955                 :            :     const ParaPortion* pParaPortion, const EditLine* pLine, sal_uInt16 nIndex, bool bPreferPortionStart) const
    3956                 :            : {
    3957                 :            :     OSL_ENSURE( pLine, "No line received: GetXPos" );
    3958                 :            :     OSL_ENSURE( ( nIndex >= pLine->GetStart() ) && ( nIndex <= pLine->GetEnd() ) , "GetXPos has to be called properly!" );
    3959                 :            : 
    3960                 :       1116 :     sal_Bool bDoPreferPortionStart = bPreferPortionStart;
    3961                 :            :     // Assure that the portion belongs to this line:
    3962         [ +  + ]:       1116 :     if ( nIndex == pLine->GetStart() )
    3963                 :        949 :         bDoPreferPortionStart = sal_True;
    3964         [ +  + ]:        167 :     else if ( nIndex == pLine->GetEnd() )
    3965                 :        103 :         bDoPreferPortionStart = sal_False;
    3966                 :            : 
    3967                 :       1116 :     sal_uInt16 nTextPortionStart = 0;
    3968         [ +  - ]:       1116 :     sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( nIndex, nTextPortionStart, bDoPreferPortionStart );
    3969                 :            : 
    3970                 :            :     OSL_ENSURE( ( nTextPortion >= pLine->GetStartPortion() ) && ( nTextPortion <= pLine->GetEndPortion() ), "GetXPos: Portion not in current line! " );
    3971                 :            : 
    3972         [ +  - ]:       1116 :     const TextPortion* pPortion = pParaPortion->GetTextPortions()[nTextPortion];
    3973                 :            : 
    3974         [ +  - ]:       1116 :     long nX = GetPortionXOffset( pParaPortion, pLine, nTextPortion );
    3975                 :            : 
    3976                 :            :     // calc text width, portion size may include CJK/CTL spacing...
    3977                 :            :     // But the array migh not be init yet, if using text ranger this method is called within CreateLines()...
    3978                 :       1116 :     long nPortionTextWidth = pPortion->GetSize().Width();
    3979 [ +  + ][ +  - ]:       1116 :     if ( ( pPortion->GetKind() == PORTIONKIND_TEXT ) && pPortion->GetLen() && !GetTextRanger() )
         [ +  + ][ +  - ]
    3980 [ +  - ][ +  - ]:        284 :         nPortionTextWidth = pLine->GetCharPosArray()[nTextPortionStart + pPortion->GetLen() - 1 - pLine->GetStart()];
    3981                 :            : 
    3982         [ +  + ]:       1116 :     if ( nTextPortionStart != nIndex )
    3983                 :            :     {
    3984                 :            :         // Search within portion...
    3985         [ +  + ]:        167 :         if ( nIndex == ( nTextPortionStart + pPortion->GetLen() ) )
    3986                 :            :         {
    3987                 :            :             // End of Portion
    3988         [ -  + ]:        103 :             if ( pPortion->GetKind() == PORTIONKIND_TAB )
    3989                 :            :             {
    3990 [ #  # ][ #  # ]:          0 :                 if ( static_cast<size_t>(nTextPortion+1) < pParaPortion->GetTextPortions().Count() )
    3991                 :            :                 {
    3992         [ #  # ]:          0 :                     const TextPortion* pNextPortion = pParaPortion->GetTextPortions()[nTextPortion+1];
    3993         [ #  # ]:          0 :                     if ( pNextPortion->GetKind() != PORTIONKIND_TAB )
    3994                 :            :                     {
    3995         [ #  # ]:          0 :                         if ( !bPreferPortionStart )
    3996         [ #  # ]:          0 :                             nX = GetXPos( pParaPortion, pLine, nIndex, sal_True );
    3997 [ #  # ][ #  # ]:          0 :                         else if ( !IsRightToLeft( GetEditDoc().GetPos( pParaPortion->GetNode() ) ) )
                 [ #  # ]
    3998                 :          0 :                             nX += nPortionTextWidth;
    3999                 :            :                     }
    4000                 :            :                 }
    4001 [ #  # ][ #  # ]:          0 :                 else if ( !IsRightToLeft( GetEditDoc().GetPos( pParaPortion->GetNode() ) ) )
                 [ #  # ]
    4002                 :            :                 {
    4003                 :          0 :                     nX += nPortionTextWidth;
    4004                 :            :                 }
    4005                 :            :             }
    4006         [ +  - ]:        103 :             else if ( !pPortion->IsRightToLeft() )
    4007                 :            :             {
    4008                 :        103 :                 nX += nPortionTextWidth;
    4009                 :            :             }
    4010                 :            :         }
    4011         [ +  - ]:         64 :         else if ( pPortion->GetKind() == PORTIONKIND_TEXT )
    4012                 :            :         {
    4013                 :            :             OSL_ENSURE( nIndex != pLine->GetStart(), "Strange behavior in new GetXPos()" );
    4014                 :            :             OSL_ENSURE( pLine && pLine->GetCharPosArray().size(), "svx::ImpEditEngine::GetXPos(), portion in an empty line?" );
    4015                 :            : 
    4016 [ +  - ][ +  - ]:         64 :             if( pLine->GetCharPosArray().size() )
    4017                 :            :             {
    4018                 :         64 :                 sal_uInt16 nPos = nIndex - 1 - pLine->GetStart();
    4019 [ -  + ][ +  - ]:         64 :                 if( nPos >= pLine->GetCharPosArray().size() )
    4020                 :            :                 {
    4021         [ #  # ]:          0 :                     nPos = pLine->GetCharPosArray().size()-1;
    4022                 :            :                     OSL_FAIL("svx::ImpEditEngine::GetXPos(), index out of range!");
    4023                 :            :                 }
    4024                 :            : 
    4025                 :            :                 // old code restored see #i112788 (which leaves #i74188 unfixed again)
    4026 [ +  - ][ +  - ]:         64 :                 long nPosInPortion = pLine->GetCharPosArray()[nPos];
    4027                 :            : 
    4028         [ +  - ]:         64 :                 if ( !pPortion->IsRightToLeft() )
    4029                 :            :                 {
    4030                 :         64 :                     nX += nPosInPortion;
    4031                 :            :                 }
    4032                 :            :                 else
    4033                 :            :                 {
    4034                 :          0 :                     nX += nPortionTextWidth - nPosInPortion;
    4035                 :            :                 }
    4036                 :            : 
    4037 [ -  + ][ #  # ]:         64 :                 if ( pPortion->GetExtraInfos() && pPortion->GetExtraInfos()->bCompressed )
                 [ -  + ]
    4038                 :            :                 {
    4039                 :          0 :                     nX += pPortion->GetExtraInfos()->nPortionOffsetX;
    4040         [ #  # ]:          0 :                     if ( pPortion->GetExtraInfos()->nAsianCompressionTypes & CHAR_PUNCTUATIONRIGHT )
    4041                 :            :                     {
    4042 [ #  # ][ #  # ]:          0 :                         sal_uInt8 nType = GetCharTypeForCompression( pParaPortion->GetNode()->GetChar( nIndex ) );
    4043         [ #  # ]:          0 :                         if ( nType == CHAR_PUNCTUATIONRIGHT )
    4044                 :            :                         {
    4045                 :          0 :                             sal_uInt16 n = nIndex - nTextPortionStart;
    4046                 :          0 :                             const sal_Int32* pDXArray = NULL;
    4047 [ #  # ][ #  # ]:          0 :                             if (!pLine->GetCharPosArray().empty())
    4048 [ #  # ][ #  # ]:          0 :                                 pDXArray = &pLine->GetCharPosArray()[0]+( nTextPortionStart-pLine->GetStart() );
    4049         [ #  # ]:          0 :                             sal_Int32 nCharWidth = ( ( (n+1) < pPortion->GetLen() ) ? pDXArray[n] : pPortion->GetSize().Width() )
    4050 [ #  # ][ #  # ]:          0 :                                                             - ( n ? pDXArray[n-1] : 0 );
    4051         [ #  # ]:          0 :                             if ( (n+1) < pPortion->GetLen() )
    4052                 :            :                             {
    4053                 :            :                                 // smaller, when char behind is CHAR_PUNCTUATIONRIGHT also
    4054 [ #  # ][ #  # ]:          0 :                                 nType = GetCharTypeForCompression( pParaPortion->GetNode()->GetChar( nIndex+1 ) );
    4055         [ #  # ]:          0 :                                 if ( nType == CHAR_PUNCTUATIONRIGHT )
    4056                 :            :                                 {
    4057         [ #  # ]:          0 :                                     sal_Int32 nNextCharWidth = ( ( (n+2) < pPortion->GetLen() ) ? pDXArray[n+1] : pPortion->GetSize().Width() )
    4058         [ #  # ]:          0 :                                                                     - pDXArray[n];
    4059                 :          0 :                                     sal_Int32 nCompressed = nNextCharWidth/2;
    4060                 :          0 :                                     nCompressed *= pPortion->GetExtraInfos()->nMaxCompression100thPercent;
    4061                 :          0 :                                     nCompressed /= 10000;
    4062                 :          0 :                                     nCharWidth += nCompressed;
    4063                 :            :                                 }
    4064                 :            :                             }
    4065                 :            :                             else
    4066                 :            :                             {
    4067                 :          0 :                                 nCharWidth *= 2;    // last char pos to portion end is only compressed size
    4068                 :            :                             }
    4069                 :          0 :                             nX += nCharWidth/2; // 50% compression
    4070                 :            :                         }
    4071                 :            :                     }
    4072                 :            :                 }
    4073                 :            :             }
    4074                 :            :         }
    4075                 :            :     }
    4076                 :            :     else // if ( nIndex == pLine->GetStart() )
    4077                 :            :     {
    4078         [ -  + ]:        949 :         if ( pPortion->IsRightToLeft() )
    4079                 :            :         {
    4080                 :          0 :             nX += nPortionTextWidth;
    4081                 :            :         }
    4082                 :            :     }
    4083                 :            : 
    4084                 :       1116 :     return nX;
    4085                 :            : }
    4086                 :            : 
    4087                 :     325016 : void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
    4088                 :            : {
    4089                 :     325016 :     pPortion->nHeight = 0;
    4090                 :     325016 :     pPortion->nFirstLineOffset = 0;
    4091                 :            : 
    4092         [ +  - ]:     325016 :     if ( pPortion->IsVisible() )
    4093                 :            :     {
    4094                 :            :         OSL_ENSURE( pPortion->GetLines().Count(), "Paragraph with no lines in ParaPortion::CalcHeight" );
    4095         [ +  + ]:     744262 :         for (size_t nLine = 0; nLine < pPortion->GetLines().Count(); ++nLine)
    4096                 :     419246 :             pPortion->nHeight += pPortion->GetLines()[nLine]->GetHeight();
    4097                 :            : 
    4098         [ +  - ]:     325016 :         if ( !aStatus.IsOutliner() )
    4099                 :            :         {
    4100                 :     325016 :             const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
    4101                 :     325016 :             const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
    4102         [ +  + ]:     325016 :             sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX ) ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
    4103                 :            : 
    4104         [ +  + ]:     325016 :             if ( nSBL )
    4105                 :            :             {
    4106         [ +  + ]:        173 :                 if ( pPortion->GetLines().Count() > 1 )
    4107                 :         70 :                     pPortion->nHeight += ( pPortion->GetLines().Count() - 1 ) * nSBL;
    4108         [ -  + ]:        173 :                 if ( aStatus.ULSpaceSummation() )
    4109                 :          0 :                     pPortion->nHeight += nSBL;
    4110                 :            :             }
    4111                 :            : 
    4112                 :     325016 :             sal_uInt16 nPortion = GetParaPortions().GetPos( pPortion );
    4113 [ -  + ][ +  + ]:     325016 :             if ( nPortion || aStatus.ULSpaceFirstParagraph() )
                 [ +  + ]
    4114                 :            :             {
    4115                 :       9575 :                 sal_uInt16 nUpper = GetYValue( rULItem.GetUpper() );
    4116                 :       9575 :                 pPortion->nHeight += nUpper;
    4117                 :       9575 :                 pPortion->nFirstLineOffset = nUpper;
    4118                 :            :             }
    4119                 :            : 
    4120         [ +  + ]:     325016 :             if ( ( nPortion != (GetParaPortions().Count()-1) ) )
    4121                 :            :             {
    4122                 :       9753 :                 pPortion->nHeight += GetYValue( rULItem.GetLower() );   // not in the last
    4123                 :            :             }
    4124                 :            : 
    4125                 :            : 
    4126 [ +  + ][ +  + ]:     325016 :             if ( nPortion && !aStatus.ULSpaceSummation() )
                 [ +  + ]
    4127                 :            :             {
    4128                 :       9419 :                 ParaPortion* pPrev = GetParaPortions().SafeGetObject( nPortion-1 );
    4129                 :       9419 :                 const SvxULSpaceItem& rPrevULItem = (const SvxULSpaceItem&)pPrev->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
    4130                 :       9419 :                 const SvxLineSpacingItem& rPrevLSItem = (const SvxLineSpacingItem&)pPrev->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
    4131                 :            : 
    4132                 :            :                 // In realation between WinWord6/Writer3:
    4133                 :            :                 // With a proportional line spacing the paragraph spacing is
    4134                 :            :                 // also manipulated.
    4135                 :            :                 // Only Writer3: Do not add up, but minimum distance.
    4136                 :            : 
    4137                 :            :                 // check if distance by LineSpacing > Upper:
    4138                 :       9419 :                 sal_uInt16 nExtraSpace = GetYValue( lcl_CalcExtraSpace( pPortion, rLSItem ) );
    4139         [ +  + ]:       9419 :                 if ( nExtraSpace > pPortion->nFirstLineOffset )
    4140                 :            :                 {
    4141                 :            :                     // Paragraph becomes 'bigger':
    4142                 :         92 :                     pPortion->nHeight += ( nExtraSpace - pPortion->nFirstLineOffset );
    4143                 :         92 :                     pPortion->nFirstLineOffset = nExtraSpace;
    4144                 :            :                 }
    4145                 :            : 
    4146                 :            :                 // Determine nFirstLineOffset now f(pNode) => now f(pNode, pPrev):
    4147                 :       9419 :                 sal_uInt16 nPrevLower = GetYValue( rPrevULItem.GetLower() );
    4148                 :            : 
    4149                 :            :                 // This PrevLower is still in the height of PrevPortion ...
    4150         [ +  + ]:       9419 :                 if ( nPrevLower > pPortion->nFirstLineOffset )
    4151                 :            :                 {
    4152                 :            :                     // Paragraph is 'small':
    4153                 :       2976 :                     pPortion->nHeight -= pPortion->nFirstLineOffset;
    4154                 :       2976 :                     pPortion->nFirstLineOffset = 0;
    4155                 :            :                 }
    4156         [ +  + ]:       6443 :                 else if ( nPrevLower )
    4157                 :            :                 {
    4158                 :            :                     // Paragraph becomes 'somewhat smaller':
    4159                 :        372 :                     pPortion->nHeight -= nPrevLower;
    4160                 :            :                     pPortion->nFirstLineOffset =
    4161                 :        372 :                         pPortion->nFirstLineOffset - nPrevLower;
    4162                 :            :                 }
    4163                 :            :                 // I find it not so good, but Writer3 feature:
    4164                 :            :                 // Check if distance by LineSpacing > Lower: this value is not
    4165                 :            :                 // stuck in the height of PrevPortion.
    4166         [ +  + ]:       9419 :                 if ( !pPrev->IsInvalid() )
    4167                 :            :                 {
    4168                 :       8984 :                     nExtraSpace = GetYValue( lcl_CalcExtraSpace( pPrev, rPrevLSItem ) );
    4169         [ +  + ]:       8984 :                     if ( nExtraSpace > nPrevLower )
    4170                 :            :                     {
    4171                 :        102 :                         sal_uInt16 nMoreLower = nExtraSpace - nPrevLower;
    4172                 :            :                         // Paragraph becomes 'bigger', 'grows' downwards:
    4173         [ +  + ]:        102 :                         if ( nMoreLower > pPortion->nFirstLineOffset )
    4174                 :            :                         {
    4175                 :         18 :                             pPortion->nHeight += ( nMoreLower - pPortion->nFirstLineOffset );
    4176                 :         18 :                             pPortion->nFirstLineOffset = nMoreLower;
    4177                 :            :                         }
    4178                 :            :                     }
    4179                 :            :                 }
    4180                 :            :             }
    4181                 :            :         }
    4182                 :            :     }
    4183                 :     325016 : }
    4184                 :            : 
    4185                 :       1124 : Rectangle ImpEditEngine::GetEditCursor( ParaPortion* pPortion, sal_uInt16 nIndex, sal_uInt16 nFlags )
    4186                 :            : {
    4187                 :            :     OSL_ENSURE( pPortion->IsVisible(), "Why GetEditCursor() for an invisible paragraph?" );
    4188                 :            :     OSL_ENSURE( IsFormatted() || GetTextRanger(), "GetEditCursor: Not formatted" );
    4189                 :            : 
    4190                 :            :     /*
    4191                 :            :      GETCRSR_ENDOFLINE: If after the last character of a wrapped line, remaining
    4192                 :            :      at the end of the line, not the beginning of the next one.
    4193                 :            :      Purpose:   - END => really after the last character
    4194                 :            :                 - Selection....
    4195                 :            :     */
    4196                 :            : 
    4197                 :       1124 :     long nY = pPortion->GetFirstLineOffset();
    4198                 :            : 
    4199                 :       1124 :     const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
    4200                 :       1124 :     sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
    4201         [ -  + ]:       1124 :                         ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
    4202                 :            : 
    4203                 :       1124 :     sal_uInt16 nCurIndex = 0;
    4204                 :            :     OSL_ENSURE( pPortion->GetLines().Count(), "Empty ParaPortion in GetEditCursor!" );
    4205                 :       1124 :     const EditLine* pLine = NULL;
    4206         [ +  + ]:       1124 :     sal_Bool bEOL = ( nFlags & GETCRSR_ENDOFLINE ) ? sal_True : sal_False;
    4207         [ +  + ]:       1227 :     for ( sal_uInt16 nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
    4208                 :            :     {
    4209                 :       1124 :         const EditLine* pTmpLine = pPortion->GetLines()[nLine];
    4210 [ +  + ][ +  + ]:       1124 :         if ( ( pTmpLine->GetStart() == nIndex ) || ( pTmpLine->IsIn( nIndex, bEOL ) ) )
                 [ +  + ]
    4211                 :            :         {
    4212                 :       1021 :             pLine = pTmpLine;
    4213                 :       1021 :             break;
    4214                 :            :         }
    4215                 :            : 
    4216                 :        103 :         nCurIndex = nCurIndex + pTmpLine->GetLen();
    4217                 :        103 :         nY += pTmpLine->GetHeight();
    4218         [ +  - ]:        103 :         if ( !aStatus.IsOutliner() )
    4219                 :        103 :             nY += nSBL;
    4220                 :            :     }
    4221         [ +  + ]:       1124 :     if ( !pLine )
    4222                 :            :     {
    4223                 :            :         // Cursor at the End of the paragraph.
    4224                 :            :         OSL_ENSURE( nIndex == nCurIndex, "Index dead wrong in GetEditCursor!" );
    4225                 :            : 
    4226                 :        103 :         pLine = pPortion->GetLines()[pPortion->GetLines().Count()-1];
    4227                 :        103 :         nY -= pLine->GetHeight();
    4228         [ +  - ]:        103 :         if ( !aStatus.IsOutliner() )
    4229                 :        103 :             nY -= nSBL;
    4230                 :        103 :         nCurIndex = nCurIndex - pLine->GetLen();
    4231                 :            :     }
    4232                 :            : 
    4233                 :       1124 :     Rectangle aEditCursor;
    4234                 :            : 
    4235                 :       1124 :     aEditCursor.Top() = nY;
    4236                 :       1124 :     nY += pLine->GetHeight();
    4237                 :       1124 :     aEditCursor.Bottom() = nY-1;
    4238                 :            : 
    4239                 :            :     // Search within the line...
    4240                 :            :     long nX;
    4241                 :            : 
    4242 [ -  + ][ -  + ]:       1124 :     if ( ( nIndex == pLine->GetStart() ) && ( nFlags & GETCRSR_STARTOFLINE ) )
                 [ +  + ]
    4243                 :            :     {
    4244         [ #  # ]:          0 :         Range aXRange = GetLineXPosStartEnd( pPortion, pLine );
    4245 [ #  # ][ #  # ]:          0 :         nX = !IsRightToLeft( GetEditDoc().GetPos( pPortion->GetNode() ) ) ? aXRange.Min() : aXRange.Max();
                 [ #  # ]
    4246                 :            :     }
    4247 [ +  + ][ +  + ]:       1124 :     else if ( ( nIndex == pLine->GetEnd() ) && ( nFlags & GETCRSR_ENDOFLINE ) )
                 [ +  + ]
    4248                 :            :     {
    4249         [ +  - ]:          8 :         Range aXRange = GetLineXPosStartEnd( pPortion, pLine );
    4250 [ +  - ][ +  - ]:          8 :         nX = !IsRightToLeft( GetEditDoc().GetPos( pPortion->GetNode() ) ) ? aXRange.Max() : aXRange.Min();
                 [ +  - ]
    4251                 :            :     }
    4252                 :            :     else
    4253                 :            :     {
    4254                 :       1116 :         nX = GetXPos( pPortion, pLine, nIndex, ( nFlags & GETCRSR_PREFERPORTIONSTART ) ? sal_True : sal_False );
    4255                 :            :     }
    4256                 :            : 
    4257                 :       1124 :     aEditCursor.Left() = aEditCursor.Right() = nX;
    4258                 :            : 
    4259         [ +  - ]:       1124 :     if ( nFlags & GETCRSR_TXTONLY )
    4260                 :       1124 :         aEditCursor.Top() = aEditCursor.Bottom() - pLine->GetTxtHeight() + 1;
    4261                 :            :     else
    4262                 :          0 :         aEditCursor.Top() = aEditCursor.Bottom() - Min( pLine->GetTxtHeight(), pLine->GetHeight() ) + 1;
    4263                 :            : 
    4264                 :       1124 :     return aEditCursor;
    4265                 :            : }
    4266                 :            : 
    4267                 :     530884 : void ImpEditEngine::SetValidPaperSize( const Size& rNewSz )
    4268                 :            : {
    4269                 :     530884 :     aPaperSize = rNewSz;
    4270                 :            : 
    4271         [ +  + ]:     530884 :     long nMinWidth = aStatus.AutoPageWidth() ? aMinAutoPaperSize.Width() : 0;
    4272         [ +  + ]:     530884 :     long nMaxWidth = aStatus.AutoPageWidth() ? aMaxAutoPaperSize.Width() : 0x7FFFFFFF;
    4273         [ +  + ]:     530884 :     long nMinHeight = aStatus.AutoPageHeight() ? aMinAutoPaperSize.Height() : 0;
    4274         [ +  + ]:     530884 :     long nMaxHeight = aStatus.AutoPageHeight() ? aMaxAutoPaperSize.Height() : 0x7FFFFFFF;
    4275                 :            : 
    4276                 :            :     // Minimum/Maximum width:
    4277         [ +  + ]:     530884 :     if ( aPaperSize.Width() < nMinWidth )
    4278                 :       6444 :         aPaperSize.Width() = nMinWidth;
    4279         [ +  + ]:     524440 :     else if ( aPaperSize.Width() > nMaxWidth )
    4280                 :        480 :         aPaperSize.Width() = nMaxWidth;
    4281                 :            : 
    4282                 :            :     // Minimum/Maximum height:
    4283         [ -  + ]:     530884 :     if ( aPaperSize.Height() < nMinHeight )
    4284                 :          0 :         aPaperSize.Height() = nMinHeight;
    4285         [ +  + ]:     530884 :     else if ( aPaperSize.Height() > nMaxHeight )
    4286                 :       9746 :         aPaperSize.Height() = nMaxHeight;
    4287                 :     530884 : }
    4288                 :            : 
    4289                 :          0 : void ImpEditEngine::IndentBlock( EditView* pEditView, sal_Bool bRight )
    4290                 :            : {
    4291         [ #  # ]:          0 :     ESelection aESel( CreateESel( pEditView->pImpEditView->GetEditSelection() ) );
    4292                 :          0 :     aESel.Adjust();
    4293                 :            : 
    4294                 :            :     // Only if more selected Paragraphs ...
    4295         [ #  # ]:          0 :     if ( aESel.nEndPara > aESel.nStartPara )
    4296                 :            :     {
    4297                 :          0 :         ESelection aNewSel = aESel;
    4298                 :          0 :         aNewSel.nStartPos = 0;
    4299                 :          0 :         aNewSel.nEndPos = 0xFFFF;
    4300                 :            : 
    4301         [ #  # ]:          0 :         if ( aESel.nEndPos == 0 )
    4302                 :            :         {
    4303                 :          0 :             aESel.nEndPara--;       // then not this paragraph ...
    4304                 :          0 :             aNewSel.nEndPos = 0;
    4305                 :            :         }
    4306                 :            : 
    4307         [ #  # ]:          0 :         pEditView->pImpEditView->DrawSelection();
    4308                 :            :         pEditView->pImpEditView->SetEditSelection(
    4309 [ #  # ][ #  # ]:          0 :                         pEditView->pImpEditView->GetEditSelection().Max() );
    4310 [ #  # ][ #  # ]:          0 :         UndoActionStart( bRight ? EDITUNDO_INDENTBLOCK : EDITUNDO_UNINDENTBLOCK );
    4311                 :            : 
    4312         [ #  # ]:          0 :         for ( sal_uInt16 nPara = aESel.nStartPara; nPara <= aESel.nEndPara; nPara++ )
    4313                 :            :         {
    4314         [ #  # ]:          0 :             ContentNode* pNode = GetEditDoc().GetObject( nPara );
    4315         [ #  # ]:          0 :             if ( bRight )
    4316                 :            :             {
    4317                 :            :                 // Insert Tabs
    4318         [ #  # ]:          0 :                 EditPaM aPaM( pNode, 0 );
    4319 [ #  # ][ #  # ]:          0 :                 InsertTab( aPaM );
    4320                 :            :             }
    4321                 :            :             else
    4322                 :            :             {
    4323                 :            :                 // Remove Tabs
    4324         [ #  # ]:          0 :                 const EditCharAttrib* pFeature = pNode->GetCharAttribs().FindFeature( 0 );
    4325         [ #  # ]:          0 :                 if ( pFeature && ( pFeature->GetStart() == 0 ) &&
           [ #  #  #  # ]
                 [ #  # ]
    4326                 :          0 :                    ( pFeature->GetItem()->Which() == EE_FEATURE_TAB ) )
    4327                 :            :                 {
    4328         [ #  # ]:          0 :                     EditPaM aStartPaM( pNode, 0 );
    4329         [ #  # ]:          0 :                     EditPaM aEndPaM( pNode, 1 );
    4330 [ #  # ][ #  # ]:          0 :                     ImpDeleteSelection( EditSelection( aStartPaM, aEndPaM ) );
    4331                 :            :                 }
    4332                 :            :             }
    4333                 :            :         }
    4334                 :            : 
    4335 [ #  # ][ #  # ]:          0 :         UndoActionEnd( bRight ? EDITUNDO_INDENTBLOCK : EDITUNDO_UNINDENTBLOCK );
    4336         [ #  # ]:          0 :         UpdateSelections();
    4337         [ #  # ]:          0 :         FormatAndUpdate( pEditView );
    4338                 :            : 
    4339         [ #  # ]:          0 :         ContentNode* pLastNode = GetEditDoc().GetObject( aNewSel.nEndPara );
    4340 [ #  # ][ #  # ]:          0 :         if ( pLastNode->Len() < aNewSel.nEndPos )
    4341         [ #  # ]:          0 :             aNewSel.nEndPos = pLastNode->Len();
    4342 [ #  # ][ #  # ]:          0 :         pEditView->pImpEditView->SetEditSelection( CreateSel( aNewSel ) );
    4343         [ #  # ]:          0 :         pEditView->pImpEditView->DrawSelection();
    4344         [ #  # ]:          0 :         pEditView->pImpEditView->ShowCursor( sal_False, sal_True );
    4345                 :            :     }
    4346                 :          0 : }
    4347                 :            : 
    4348                 :     100770 : rtl::Reference<SvxForbiddenCharactersTable> ImpEditEngine::GetForbiddenCharsTable( sal_Bool bGetInternal ) const
    4349                 :            : {
    4350                 :     100770 :     rtl::Reference<SvxForbiddenCharactersTable> xF = xForbiddenCharsTable;
    4351 [ +  - ][ +  - ]:     100770 :     if ( !xF.is() && bGetInternal )
                 [ +  - ]
    4352 [ +  - ][ +  - ]:     100770 :         xF = EE_DLL().GetGlobalData()->GetForbiddenCharsTable();
         [ +  - ][ +  - ]
    4353                 :     100770 :     return xF;
    4354                 :            : }
    4355                 :            : 
    4356                 :      44863 : void ImpEditEngine::SetForbiddenCharsTable( rtl::Reference<SvxForbiddenCharactersTable> xForbiddenChars )
    4357                 :            : {
    4358 [ +  - ][ +  - ]:      44863 :     EE_DLL().GetGlobalData()->SetForbiddenCharsTable( xForbiddenChars );
    4359                 :      44863 : }
    4360                 :            : 
    4361                 :      17654 : svtools::ColorConfig& ImpEditEngine::GetColorConfig()
    4362                 :            : {
    4363         [ +  + ]:      17654 :     if ( !pColorConfig )
    4364         [ +  - ]:        555 :         pColorConfig = new svtools::ColorConfig;
    4365                 :            : 
    4366                 :      17654 :     return *pColorConfig;
    4367                 :            : }
    4368                 :            : 
    4369                 :          0 : sal_Bool ImpEditEngine::IsVisualCursorTravelingEnabled()
    4370                 :            : {
    4371                 :          0 :     sal_Bool bVisualCursorTravaling = sal_False;
    4372                 :            : 
    4373         [ #  # ]:          0 :     if( !pCTLOptions )
    4374         [ #  # ]:          0 :         pCTLOptions = new SvtCTLOptions;
    4375                 :            : 
    4376 [ #  # ][ #  # ]:          0 :     if ( pCTLOptions->IsCTLFontEnabled() && ( pCTLOptions->GetCTLCursorMovement() == SvtCTLOptions::MOVEMENT_VISUAL ) )
                 [ #  # ]
    4377                 :            :     {
    4378                 :          0 :         bVisualCursorTravaling = sal_True;
    4379                 :            :     }
    4380                 :            : 
    4381                 :          0 :     return bVisualCursorTravaling;
    4382                 :            : 
    4383                 :            : }
    4384                 :            : 
    4385                 :          0 : sal_Bool ImpEditEngine::DoVisualCursorTraveling( const ContentNode* )
    4386                 :            : {
    4387                 :            :     // Don't check if it's necessary, because we also need it when leaving the paragraph
    4388                 :          0 :     return IsVisualCursorTravelingEnabled();
    4389                 :            : }
    4390                 :            : 
    4391                 :            : 
    4392                 :        415 : void ImpEditEngine::CallNotify( EENotify& rNotify )
    4393                 :            : {
    4394         [ +  + ]:        415 :     if ( !nBlockNotifications )
    4395         [ +  - ]:        339 :         GetNotifyHdl().Call( &rNotify );
    4396                 :            :     else
    4397                 :         76 :         aNotifyCache.push_back(rNotify);
    4398                 :        415 : }
    4399                 :            : 
    4400                 :     596723 : void ImpEditEngine::EnterBlockNotifications()
    4401                 :            : {
    4402         [ +  + ]:     596723 :     if( !nBlockNotifications )
    4403                 :            :     {
    4404                 :            :         // #109864# Send out START notification immediately, to allow
    4405                 :            :         // external, non-queued events to be captured as well from
    4406                 :            :         // client side
    4407                 :     463986 :         EENotify aNotify( EE_NOTIFY_BLOCKNOTIFICATION_START );
    4408                 :     463986 :         aNotify.pEditEngine = GetEditEnginePtr();
    4409         [ +  - ]:     463986 :         GetNotifyHdl().Call( &aNotify );
    4410                 :            :     }
    4411                 :            : 
    4412                 :     596723 :     nBlockNotifications++;
    4413                 :     596723 : }
    4414                 :            : 
    4415                 :     596723 : void ImpEditEngine::LeaveBlockNotifications()
    4416                 :            : {
    4417                 :            :     OSL_ENSURE( nBlockNotifications, "LeaveBlockNotifications - Why?" );
    4418                 :            : 
    4419                 :     596723 :     nBlockNotifications--;
    4420         [ +  + ]:     596723 :     if ( !nBlockNotifications )
    4421                 :            :     {
    4422                 :            :         // Call blocked notify events...
    4423         [ +  + ]:     464062 :         while(!aNotifyCache.empty())
    4424                 :            :         {
    4425                 :         76 :             EENotify aNotify(aNotifyCache[0]);
    4426                 :            :             // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
    4427         [ +  - ]:         76 :             aNotifyCache.erase(aNotifyCache.begin());
    4428         [ +  - ]:         76 :             GetNotifyHdl().Call( &aNotify );
    4429                 :            :         }
    4430                 :            : 
    4431                 :     463986 :         EENotify aNotify( EE_NOTIFY_BLOCKNOTIFICATION_END );
    4432                 :     463986 :         aNotify.pEditEngine = GetEditEnginePtr();
    4433         [ +  - ]:     463986 :         GetNotifyHdl().Call( &aNotify );
    4434                 :            :     }
    4435                 :     596723 : }
    4436                 :            : 
    4437                 :     747697 : IMPL_LINK_NOARG(ImpEditEngine, DocModified)
    4438                 :            : {
    4439                 :     747697 :     aModifyHdl.Call( NULL /*GetEditEnginePtr()*/ ); // NULL, because also used for Outliner
    4440                 :     747697 :     return 0;
    4441                 :            : }
    4442                 :            : 
    4443                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10