LCOV - code coverage report
Current view: top level - vcl/source/edit - textview.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 203 1251 16.2 %
Date: 2015-06-13 12:38:46 Functions: 28 112 25.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <vcl/textview.hxx>
      21             : #include <vcl/texteng.hxx>
      22             : #include <vcl/settings.hxx>
      23             : #include <textdoc.hxx>
      24             : #include <vcl/textdata.hxx>
      25             : #include <textdat2.hxx>
      26             : 
      27             : #include <svl/undo.hxx>
      28             : #include <vcl/cursor.hxx>
      29             : #include <vcl/window.hxx>
      30             : #include <vcl/svapp.hxx>
      31             : #include <tools/stream.hxx>
      32             : 
      33             : #include <sot/formats.hxx>
      34             : #include <svl/urlbmk.hxx>
      35             : 
      36             : #include <com/sun/star/i18n/XBreakIterator.hpp>
      37             : 
      38             : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
      39             : 
      40             : #include <com/sun/star/i18n/WordType.hpp>
      41             : #include <cppuhelper/weak.hxx>
      42             : #include <cppuhelper/queryinterface.hxx>
      43             : #include <vcl/unohelp.hxx>
      44             : #include <com/sun/star/datatransfer/XTransferable.hpp>
      45             : #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
      46             : #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
      47             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      48             : 
      49             : #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
      50             : #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
      51             : #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
      52             : 
      53             : #include <vcl/edit.hxx>
      54             : 
      55             : #include <sot/exchange.hxx>
      56             : 
      57             : #include <osl/mutex.hxx>
      58             : 
      59             : using namespace ::com::sun::star;
      60             : 
      61             : class TETextDataObject :    public ::com::sun::star::datatransfer::XTransferable,
      62             :                         public ::cppu::OWeakObject
      63             : 
      64             : {
      65             : private:
      66             :     OUString        maText;
      67             :     SvMemoryStream  maHTMLStream;
      68             : 
      69             : public:
      70             :     explicit TETextDataObject( const OUString& rText );
      71             :     virtual ~TETextDataObject();
      72             : 
      73           0 :     OUString&        GetText() { return maText; }
      74           0 :     SvMemoryStream& GetHTMLStream() { return maHTMLStream; }
      75             : 
      76             :     // ::com::sun::star::uno::XInterface
      77             :     ::com::sun::star::uno::Any                  SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      78           0 :     void                                        SAL_CALL acquire() throw() SAL_OVERRIDE  { OWeakObject::acquire(); }
      79           0 :     void                                        SAL_CALL release() throw() SAL_OVERRIDE  { OWeakObject::release(); }
      80             : 
      81             :     // ::com::sun::star::datatransfer::XTransferable
      82             :     ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) throw(::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      83             :     ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors(  ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      84             :     sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      85             : };
      86             : 
      87           0 : TETextDataObject::TETextDataObject( const OUString& rText ) : maText( rText )
      88             : {
      89           0 : }
      90             : 
      91           0 : TETextDataObject::~TETextDataObject()
      92             : {
      93           0 : }
      94             : 
      95             : // uno::XInterface
      96           0 : uno::Any TETextDataObject::queryInterface( const uno::Type & rType ) throw(uno::RuntimeException, std::exception)
      97             : {
      98           0 :     uno::Any aRet = ::cppu::queryInterface( rType, (static_cast< datatransfer::XTransferable* >(this)) );
      99           0 :     return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
     100             : }
     101             : 
     102             : // datatransfer::XTransferable
     103           0 : uno::Any TETextDataObject::getTransferData( const datatransfer::DataFlavor& rFlavor ) throw(datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException, std::exception)
     104             : {
     105           0 :     uno::Any aAny;
     106             : 
     107           0 :     SotClipboardFormatId nT = SotExchange::GetFormat( rFlavor );
     108           0 :     if ( nT == SotClipboardFormatId::STRING )
     109             :     {
     110           0 :         aAny <<= GetText();
     111             :     }
     112           0 :     else if ( nT == SotClipboardFormatId::HTML )
     113             :     {
     114           0 :         GetHTMLStream().Seek( STREAM_SEEK_TO_END );
     115           0 :         sal_uLong nLen = GetHTMLStream().Tell();
     116           0 :         GetHTMLStream().Seek(0);
     117             : 
     118           0 :         uno::Sequence< sal_Int8 > aSeq( nLen );
     119           0 :         memcpy( aSeq.getArray(), GetHTMLStream().GetData(), nLen );
     120           0 :         aAny <<= aSeq;
     121             :     }
     122             :     else
     123             :     {
     124           0 :         throw datatransfer::UnsupportedFlavorException();
     125             :     }
     126           0 :     return aAny;
     127             : }
     128             : 
     129           0 : uno::Sequence< datatransfer::DataFlavor > TETextDataObject::getTransferDataFlavors(  ) throw(uno::RuntimeException, std::exception)
     130             : {
     131           0 :     GetHTMLStream().Seek( STREAM_SEEK_TO_END );
     132           0 :     bool bHTML = GetHTMLStream().Tell() > 0;
     133           0 :     uno::Sequence< datatransfer::DataFlavor > aDataFlavors( bHTML ? 2 : 1 );
     134           0 :     SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aDataFlavors.getArray()[0] );
     135           0 :     if ( bHTML )
     136           0 :         SotExchange::GetFormatDataFlavor( SotClipboardFormatId::HTML, aDataFlavors.getArray()[1] );
     137           0 :     return aDataFlavors;
     138             : }
     139             : 
     140           0 : sal_Bool TETextDataObject::isDataFlavorSupported( const datatransfer::DataFlavor& rFlavor ) throw(uno::RuntimeException, std::exception)
     141             : {
     142           0 :     SotClipboardFormatId nT = SotExchange::GetFormat( rFlavor );
     143           0 :     return ( nT == SotClipboardFormatId::STRING );
     144             : }
     145             : 
     146         102 : struct ImpTextView
     147             : {
     148             :     TextEngine*         mpTextEngine;
     149             : 
     150             :     VclPtr<vcl::Window> mpWindow;
     151             :     TextSelection       maSelection;
     152             :     Point               maStartDocPos;
     153             : //    TextPaM             maMBDownPaM;
     154             : 
     155             :     vcl::Cursor*        mpCursor;
     156             : 
     157             :     TextDDInfo*         mpDDInfo;
     158             : 
     159             :     VclPtr<VirtualDevice>  mpVirtDev;
     160             : 
     161             :     SelectionEngine*    mpSelEngine;
     162             :     TextSelFunctionSet* mpSelFuncSet;
     163             : 
     164             :     ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSourceListener > mxDnDListener;
     165             : 
     166             :     sal_uInt16              mnTravelXPos;
     167             : 
     168             :     bool                mbAutoScroll            : 1;
     169             :     bool                mbInsertMode            : 1;
     170             :     bool                mbReadOnly              : 1;
     171             :     bool                mbPaintSelection        : 1;
     172             :     bool                mbAutoIndent            : 1;
     173             :     bool                mbHighlightSelection    : 1;
     174             :     bool                mbCursorEnabled         : 1;
     175             :     bool                mbClickedInSelection    : 1;
     176             :     bool                mbSupportProtectAttribute : 1;
     177             :     bool                mbCursorAtEndOfLine;
     178             : };
     179             : 
     180          52 : TextView::TextView( TextEngine* pEng, vcl::Window* pWindow ) :
     181          52 :     mpImpl(new ImpTextView)
     182             : {
     183          52 :     pWindow->EnableRTL( false );
     184             : 
     185          52 :     mpImpl->mpWindow = pWindow;
     186          52 :     mpImpl->mpTextEngine = pEng;
     187          52 :     mpImpl->mpVirtDev = NULL;
     188             : 
     189          52 :     mpImpl->mbPaintSelection = true;
     190          52 :     mpImpl->mbAutoScroll = true;
     191          52 :     mpImpl->mbInsertMode = true;
     192          52 :     mpImpl->mbReadOnly = false;
     193          52 :     mpImpl->mbHighlightSelection = false;
     194          52 :     mpImpl->mbAutoIndent = false;
     195          52 :     mpImpl->mbCursorEnabled = true;
     196          52 :     mpImpl->mbClickedInSelection = false;
     197          52 :     mpImpl->mbSupportProtectAttribute = false;
     198          52 :     mpImpl->mbCursorAtEndOfLine = false;
     199             : //  mbInSelection = false;
     200             : 
     201          52 :     mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
     202             : 
     203          52 :     mpImpl->mpSelFuncSet = new TextSelFunctionSet( this );
     204          52 :     mpImpl->mpSelEngine = new SelectionEngine( mpImpl->mpWindow, mpImpl->mpSelFuncSet );
     205          52 :     mpImpl->mpSelEngine->SetSelectionMode( RANGE_SELECTION );
     206          52 :     mpImpl->mpSelEngine->EnableDrag( true );
     207             : 
     208          52 :     mpImpl->mpCursor = new vcl::Cursor;
     209          52 :     mpImpl->mpCursor->Show();
     210          52 :     pWindow->SetCursor( mpImpl->mpCursor );
     211          52 :     pWindow->SetInputContext( InputContext( pEng->GetFont(), InputContextFlags::Text|InputContextFlags::ExtText ) );
     212             : 
     213          52 :     if ( pWindow->GetSettings().GetStyleSettings().GetSelectionOptions() & SelectionOptions::Invert )
     214           0 :         mpImpl->mbHighlightSelection = true;
     215             : 
     216          52 :     pWindow->SetLineColor();
     217             : 
     218          52 :     mpImpl->mpDDInfo = NULL;
     219             : 
     220          52 :     if ( pWindow->GetDragGestureRecognizer().is() )
     221             :     {
     222          52 :         vcl::unohelper::DragAndDropWrapper* pDnDWrapper = new vcl::unohelper::DragAndDropWrapper( this );
     223          52 :         mpImpl->mxDnDListener = pDnDWrapper;
     224             : 
     225          52 :         uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mpImpl->mxDnDListener, uno::UNO_QUERY );
     226          52 :         pWindow->GetDragGestureRecognizer()->addDragGestureListener( xDGL );
     227         104 :         uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
     228          52 :         pWindow->GetDropTarget()->addDropTargetListener( xDTL );
     229          52 :         pWindow->GetDropTarget()->setActive( true );
     230         104 :         pWindow->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );
     231             :     }
     232          52 : }
     233             : 
     234         100 : TextView::~TextView()
     235             : {
     236          50 :     delete mpImpl->mpSelEngine;
     237          50 :     delete mpImpl->mpSelFuncSet;
     238          50 :     mpImpl->mpVirtDev.disposeAndClear();
     239             : 
     240          50 :     if ( mpImpl->mpWindow->GetCursor() == mpImpl->mpCursor )
     241          50 :         mpImpl->mpWindow->SetCursor( 0 );
     242          50 :     delete mpImpl->mpCursor;
     243          50 :     delete mpImpl->mpDDInfo;
     244          50 :     delete mpImpl;
     245          50 : }
     246             : 
     247          91 : void TextView::Invalidate()
     248             : {
     249          91 :     mpImpl->mpWindow->Invalidate();
     250          91 : }
     251             : 
     252         198 : void TextView::SetSelection( const TextSelection& rTextSel, bool bGotoCursor )
     253             : {
     254             :     // if someone left an empty attribute and then the Outliner manipulated the selection
     255         198 :     if ( !mpImpl->maSelection.HasRange() )
     256         198 :         mpImpl->mpTextEngine->CursorMoved( mpImpl->maSelection.GetStart().GetPara() );
     257             : 
     258             :     // if the selection is manipulated after a KeyInput
     259         198 :     mpImpl->mpTextEngine->CheckIdleFormatter();
     260             : 
     261         198 :     HideSelection();
     262         198 :     TextSelection aNewSel( rTextSel );
     263         198 :     mpImpl->mpTextEngine->ValidateSelection( aNewSel );
     264         198 :     ImpSetSelection( aNewSel );
     265         198 :     ShowSelection();
     266         198 :     ShowCursor( bGotoCursor );
     267         198 : }
     268             : 
     269         198 : void TextView::SetSelection( const TextSelection& rTextSel )
     270             : {
     271         198 :     SetSelection( rTextSel, mpImpl->mbAutoScroll );
     272         198 : }
     273             : 
     274           0 : const TextSelection& TextView::GetSelection() const
     275             : {
     276           0 :     return mpImpl->maSelection;
     277             : }
     278           0 : TextSelection&      TextView::GetSelection()
     279             : {
     280           0 :     return mpImpl->maSelection;
     281             : }
     282             : 
     283           0 : void TextView::DeleteSelected()
     284             : {
     285             : //  HideSelection();
     286             : 
     287           0 :     mpImpl->mpTextEngine->UndoActionStart();
     288           0 :     TextPaM aPaM = mpImpl->mpTextEngine->ImpDeleteText( mpImpl->maSelection );
     289           0 :     mpImpl->mpTextEngine->UndoActionEnd();
     290             : 
     291           0 :     ImpSetSelection( aPaM );
     292           0 :     mpImpl->mpTextEngine->FormatAndUpdate( this );
     293           0 :     ShowCursor();
     294           0 : }
     295             : 
     296         100 : void TextView::ImpPaint(vcl::RenderContext& rRenderContext, const Point& rStartPos, Rectangle const* pPaintArea, TextSelection const* pPaintRange, TextSelection const* pSelection)
     297             : {
     298         100 :     if (!mpImpl->mbPaintSelection)
     299             :     {
     300           0 :         pSelection = NULL;
     301             :     }
     302             :     else
     303             :     {
     304             :         // set correct background color;
     305             :         // unfortunately we cannot detect if it has changed
     306         100 :         vcl::Font aFont = mpImpl->mpTextEngine->GetFont();
     307         100 :         Color aColor = rRenderContext.GetBackground().GetColor();
     308         100 :         aColor.SetTransparency(0);
     309         100 :         if (aColor != aFont.GetFillColor())
     310             :         {
     311           0 :             if (aFont.IsTransparent())
     312           0 :                 aColor = Color(COL_TRANSPARENT);
     313           0 :             aFont.SetFillColor(aColor);
     314           0 :             mpImpl->mpTextEngine->maFont = aFont;
     315         100 :         }
     316             :     }
     317             : 
     318         100 :     mpImpl->mpTextEngine->ImpPaint(&rRenderContext, rStartPos, pPaintArea, pPaintRange, pSelection);
     319         100 : }
     320             : 
     321         100 : void TextView::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
     322             : {
     323         100 :     ImpPaint(rRenderContext, rRect, false);
     324         100 : }
     325             : 
     326         100 : void TextView::ImpPaint(vcl::RenderContext& rRenderContext, const Rectangle& rRect, bool bUseVirtDev)
     327             : {
     328         100 :     if ( !mpImpl->mpTextEngine->GetUpdateMode() || mpImpl->mpTextEngine->IsInUndo() )
     329           0 :         return;
     330             : 
     331         100 :     TextSelection *pDrawSelection = NULL;
     332         100 :     if (!mpImpl->mbHighlightSelection && mpImpl->maSelection.HasRange())
     333           0 :         pDrawSelection = &mpImpl->maSelection;
     334             : 
     335         100 :     if (bUseVirtDev)
     336             :     {
     337           0 :         VirtualDevice* pVDev = GetVirtualDevice();
     338             : 
     339           0 :         const Color& rBackgroundColor = mpImpl->mpWindow->GetBackground().GetColor();
     340           0 :         if (pVDev->GetFillColor() != rBackgroundColor)
     341           0 :             pVDev->SetFillColor( rBackgroundColor );
     342           0 :         if (pVDev->GetBackground().GetColor() != rBackgroundColor)
     343           0 :             pVDev->SetBackground( rBackgroundColor );
     344             : 
     345           0 :         bool bVDevValid = true;
     346           0 :         Size aOutSz(pVDev->GetOutputSizePixel());
     347           0 :         if ((aOutSz.Width() < rRect.GetWidth()) ||
     348           0 :             (aOutSz.Height() < rRect.GetHeight()))
     349             :         {
     350           0 :             bVDevValid = pVDev->SetOutputSizePixel(rRect.GetSize());
     351             :         }
     352             :         else
     353             :         {
     354             :             // the VirtDev can get very large on Resize =>
     355             :             // shrink now and then
     356           0 :             if ((aOutSz.Height() > (rRect.GetHeight() + 20)) ||
     357           0 :                 (aOutSz.Width() > (rRect.GetWidth() + 20)))
     358             :             {
     359           0 :                 bVDevValid = pVDev->SetOutputSizePixel(rRect.GetSize());
     360             :             }
     361             :             else
     362             :             {
     363           0 :                 pVDev->Erase();
     364             :             }
     365             :         }
     366           0 :         if (!bVDevValid)
     367             :         {
     368           0 :             ImpPaint(rRenderContext, rRect, false);
     369           0 :             return;
     370             :         }
     371             : 
     372           0 :         Rectangle aTmpRect(Point(0, 0), rRect.GetSize());
     373             : 
     374           0 :         Point aDocPos(mpImpl->maStartDocPos.X(), mpImpl->maStartDocPos.Y() + rRect.Top());
     375           0 :         Point aStartPos = ImpGetOutputStartPos(aDocPos);
     376           0 :         ImpPaint(*pVDev, aStartPos, &aTmpRect, NULL, pDrawSelection);
     377           0 :         rRenderContext.DrawOutDev(rRect.TopLeft(), rRect.GetSize(), Point(0,0), rRect.GetSize(), *pVDev);
     378           0 :         if (mpImpl->mbHighlightSelection)
     379           0 :             ImpHighlight(mpImpl->maSelection);
     380             :     }
     381             :     else
     382             :     {
     383         100 :         Point aStartPos = ImpGetOutputStartPos(mpImpl->maStartDocPos);
     384         100 :         ImpPaint(rRenderContext, aStartPos, &rRect, NULL, pDrawSelection);
     385         100 :         if (mpImpl->mbHighlightSelection)
     386           0 :             ImpHighlight(mpImpl->maSelection);
     387             :     }
     388             : }
     389             : 
     390           0 : void TextView::ImpHighlight( const TextSelection& rSel )
     391             : {
     392           0 :     TextSelection aSel( rSel );
     393           0 :     aSel.Justify();
     394           0 :     if ( aSel.HasRange() && !mpImpl->mpTextEngine->IsInUndo() && mpImpl->mpTextEngine->GetUpdateMode() )
     395             :     {
     396           0 :         mpImpl->mpCursor->Hide();
     397             : 
     398             :         DBG_ASSERT( !mpImpl->mpTextEngine->mpIdleFormatter->IsActive(), "ImpHighlight: Not formatted!" );
     399             : 
     400           0 :         Rectangle aVisArea( mpImpl->maStartDocPos, mpImpl->mpWindow->GetOutputSizePixel() );
     401           0 :         long nY = 0;
     402           0 :         sal_uLong nStartPara = aSel.GetStart().GetPara();
     403           0 :         sal_uLong nEndPara = aSel.GetEnd().GetPara();
     404           0 :         for ( sal_uLong nPara = 0; nPara <= nEndPara; nPara++ )
     405             :         {
     406           0 :             long nParaHeight = (long)mpImpl->mpTextEngine->CalcParaHeight( nPara );
     407           0 :             if ( ( nPara >= nStartPara ) && ( ( nY + nParaHeight ) > aVisArea.Top() ) )
     408             :             {
     409           0 :                 TEParaPortion* pTEParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( nPara );
     410           0 :                 sal_uInt16 nStartLine = 0;
     411           0 :                 sal_uInt16 nEndLine = pTEParaPortion->GetLines().size() -1;
     412           0 :                 if ( nPara == nStartPara )
     413           0 :                     nStartLine = pTEParaPortion->GetLineNumber( aSel.GetStart().GetIndex(), false );
     414           0 :                 if ( nPara == nEndPara )
     415           0 :                     nEndLine = pTEParaPortion->GetLineNumber( aSel.GetEnd().GetIndex(), true );
     416             : 
     417             :                 // iterate over all lines
     418           0 :                 for ( sal_uInt16 nLine = nStartLine; nLine <= nEndLine; nLine++ )
     419             :                 {
     420           0 :                     TextLine& pLine = pTEParaPortion->GetLines()[ nLine ];
     421           0 :                     sal_uInt16 nStartIndex = pLine.GetStart();
     422           0 :                     sal_uInt16 nEndIndex = pLine.GetEnd();
     423           0 :                     if ( ( nPara == nStartPara ) && ( nLine == nStartLine ) )
     424           0 :                         nStartIndex = aSel.GetStart().GetIndex();
     425           0 :                     if ( ( nPara == nEndPara ) && ( nLine == nEndLine ) )
     426           0 :                         nEndIndex = aSel.GetEnd().GetIndex();
     427             : 
     428             :                     // possible if at the beginning of a wrapped line
     429           0 :                     if ( nEndIndex < nStartIndex )
     430           0 :                         nEndIndex = nStartIndex;
     431             : 
     432           0 :                     Rectangle aTmpRect( mpImpl->mpTextEngine->GetEditCursor( TextPaM( nPara, nStartIndex ), false ) );
     433           0 :                     aTmpRect.Top() += nY;
     434           0 :                     aTmpRect.Bottom() += nY;
     435           0 :                     Point aTopLeft( aTmpRect.TopLeft() );
     436             : 
     437           0 :                     aTmpRect = mpImpl->mpTextEngine->GetEditCursor( TextPaM( nPara, nEndIndex ), true );
     438           0 :                     aTmpRect.Top() += nY;
     439           0 :                     aTmpRect.Bottom() += nY;
     440           0 :                     Point aBottomRight( aTmpRect.BottomRight() );
     441           0 :                     aBottomRight.X()--;
     442             : 
     443             :                     // only paint if in the visible region
     444           0 :                     if ( ( aTopLeft.X() < aBottomRight.X() ) && ( aBottomRight.Y() >= aVisArea.Top() ) )
     445             :                     {
     446           0 :                         Point aPnt1( GetWindowPos( aTopLeft ) );
     447           0 :                         Point aPnt2( GetWindowPos( aBottomRight ) );
     448             : 
     449           0 :                         Rectangle aRect( aPnt1, aPnt2 );
     450           0 :                         mpImpl->mpWindow->Invert( aRect );
     451             :                     }
     452             :                 }
     453             :             }
     454           0 :             nY += nParaHeight;
     455             : 
     456           0 :             if ( nY >= aVisArea.Bottom() )
     457           0 :                 break;
     458             :         }
     459             :     }
     460           0 : }
     461             : 
     462         456 : void TextView::ImpSetSelection( const TextSelection& rSelection )
     463             : {
     464         456 :     if (rSelection != mpImpl->maSelection)
     465             :     {
     466           4 :         bool bCaret = false, bSelection = false;
     467           4 :         const TextPaM &rEnd = rSelection.GetEnd();
     468           4 :         const TextPaM &rOldEnd = mpImpl->maSelection.GetEnd();
     469           4 :         bool bGap = rSelection.HasRange(), bOldGap = mpImpl->maSelection.HasRange();
     470           4 :         if (rEnd != rOldEnd)
     471           0 :             bCaret = true;
     472           4 :         if (bGap || bOldGap)
     473           4 :             bSelection = true;
     474             : 
     475           4 :         mpImpl->maSelection = rSelection;
     476             : 
     477           4 :         if (bSelection)
     478           4 :             mpImpl->mpTextEngine->Broadcast(TextHint(TEXT_HINT_VIEWSELECTIONCHANGED));
     479             : 
     480           4 :         if (bCaret)
     481           0 :             mpImpl->mpTextEngine->Broadcast(TextHint(TEXT_HINT_VIEWCARETCHANGED));
     482             :     }
     483         456 : }
     484             : 
     485         250 : void TextView::ShowSelection()
     486             : {
     487         250 :     ImpShowHideSelection( true );
     488         250 : }
     489             : 
     490         198 : void TextView::HideSelection()
     491             : {
     492         198 :     ImpShowHideSelection( false );
     493         198 : }
     494             : 
     495           0 : void TextView::ShowSelection( const TextSelection& rRange )
     496             : {
     497           0 :     ImpShowHideSelection( true, &rRange );
     498           0 : }
     499             : 
     500         448 : void TextView::ImpShowHideSelection(bool /*bShow*/, const TextSelection* pRange)
     501             : {
     502         448 :     const TextSelection* pRangeOrSelection = pRange ? pRange : &mpImpl->maSelection;
     503             : 
     504         448 :     if ( pRangeOrSelection->HasRange() )
     505             :     {
     506           4 :         if ( mpImpl->mbHighlightSelection )
     507             :         {
     508           0 :             ImpHighlight( *pRangeOrSelection );
     509             :         }
     510             :         else
     511             :         {
     512           4 :             if( mpImpl->mpWindow->IsPaintTransparent() )
     513           0 :                 mpImpl->mpWindow->Invalidate();
     514             :             else
     515             :             {
     516           4 :                 TextSelection aRange( *pRangeOrSelection );
     517           4 :                 aRange.Justify();
     518           4 :                 bool bVisCursor = mpImpl->mpCursor->IsVisible();
     519           4 :                 mpImpl->mpCursor->Hide();
     520           4 :                 Invalidate();
     521           4 :                 if (bVisCursor)
     522           4 :                     mpImpl->mpCursor->Show();
     523             :             }
     524             :         }
     525             :     }
     526         448 : }
     527             : 
     528           0 : VirtualDevice* TextView::GetVirtualDevice()
     529             : {
     530           0 :     if ( !mpImpl->mpVirtDev )
     531             :     {
     532           0 :         mpImpl->mpVirtDev = VclPtr<VirtualDevice>::Create();
     533           0 :         mpImpl->mpVirtDev->SetLineColor();
     534             :     }
     535           0 :     return mpImpl->mpVirtDev;
     536             : }
     537             : 
     538           0 : void TextView::EraseVirtualDevice()
     539             : {
     540           0 :     mpImpl->mpVirtDev.disposeAndClear();
     541           0 : }
     542             : 
     543           0 : bool TextView::KeyInput( const KeyEvent& rKeyEvent )
     544             : {
     545           0 :     bool bDone      = true;
     546           0 :     bool bModified  = false;
     547           0 :     bool bMoved     = false;
     548           0 :     bool bEndKey    = false;    // special CursorPosition
     549           0 :     bool bAllowIdle = true;
     550             : 
     551             :     // check mModified;
     552             :     // the local bModified is not set e.g. by Cut/Paste, as here
     553             :     // the update happens somewhere else
     554           0 :     bool bWasModified = mpImpl->mpTextEngine->IsModified();
     555           0 :     mpImpl->mpTextEngine->SetModified( false );
     556             : 
     557           0 :     TextSelection aCurSel( mpImpl->maSelection );
     558           0 :     TextSelection aOldSel( aCurSel );
     559             : 
     560           0 :     sal_uInt16 nCode = rKeyEvent.GetKeyCode().GetCode();
     561           0 :     KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
     562           0 :     if ( eFunc != KeyFuncType::DONTKNOW )
     563             :     {
     564           0 :         switch ( eFunc )
     565             :         {
     566             :             case KeyFuncType::CUT:
     567             :             {
     568           0 :                 if ( !mpImpl->mbReadOnly )
     569           0 :                     Cut();
     570             :             }
     571           0 :             break;
     572             :             case KeyFuncType::COPY:
     573             :             {
     574           0 :                 Copy();
     575             :             }
     576           0 :             break;
     577             :             case KeyFuncType::PASTE:
     578             :             {
     579           0 :                 if ( !mpImpl->mbReadOnly )
     580           0 :                     Paste();
     581             :             }
     582           0 :             break;
     583             :             case KeyFuncType::UNDO:
     584             :             {
     585           0 :                 if ( !mpImpl->mbReadOnly )
     586           0 :                     Undo();
     587             :             }
     588           0 :             break;
     589             :             case KeyFuncType::REDO:
     590             :             {
     591           0 :                 if ( !mpImpl->mbReadOnly )
     592           0 :                     Redo();
     593             :             }
     594           0 :             break;
     595             : 
     596             :             default:    // might get processed below
     597           0 :                         eFunc = KeyFuncType::DONTKNOW;
     598             :         }
     599             :     }
     600           0 :     if ( eFunc == KeyFuncType::DONTKNOW )
     601             :     {
     602           0 :         switch ( nCode )
     603             :         {
     604             :             case KEY_UP:
     605             :             case KEY_DOWN:
     606             :             case KEY_LEFT:
     607             :             case KEY_RIGHT:
     608             :             case KEY_HOME:
     609             :             case KEY_END:
     610             :             case KEY_PAGEUP:
     611             :             case KEY_PAGEDOWN:
     612             :             case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
     613             :             case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
     614             :             case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
     615             :             case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
     616             :             case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
     617             :             case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
     618             :             case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
     619             :             case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
     620             :             case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
     621             :             case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
     622             :             case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
     623             :             case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
     624             :             case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
     625             :             case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
     626             :             case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
     627             :             case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
     628             :             {
     629           0 :                 if ( ( !rKeyEvent.GetKeyCode().IsMod2() || ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) )
     630           0 :                       && !( rKeyEvent.GetKeyCode().IsMod1() && ( nCode == KEY_PAGEUP || nCode == KEY_PAGEDOWN ) ) )
     631             :                 {
     632           0 :                     aCurSel = ImpMoveCursor( rKeyEvent );
     633           0 :                     if ( aCurSel.HasRange() ) {
     634           0 :                         uno::Reference<datatransfer::clipboard::XClipboard> aSelection(GetWindow()->GetPrimarySelection());
     635           0 :                         Copy( aSelection );
     636             :                     }
     637           0 :                     bMoved = true;
     638           0 :                     if ( nCode == KEY_END )
     639           0 :                         bEndKey = true;
     640             :                 }
     641             :                 else
     642           0 :                     bDone = false;
     643             :             }
     644           0 :             break;
     645             :             case KEY_BACKSPACE:
     646             :             case KEY_DELETE:
     647             :             case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
     648             :             case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
     649             :             case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE:
     650             :             case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE:
     651             :             {
     652           0 :                 if ( !mpImpl->mbReadOnly && !rKeyEvent.GetKeyCode().IsMod2() )
     653             :                 {
     654           0 :                     sal_uInt8 nDel = ( nCode == KEY_DELETE ) ? DEL_RIGHT : DEL_LEFT;
     655           0 :                     sal_uInt8 nMode = rKeyEvent.GetKeyCode().IsMod1() ? DELMODE_RESTOFWORD : DELMODE_SIMPLE;
     656           0 :                     if ( ( nMode == DELMODE_RESTOFWORD ) && rKeyEvent.GetKeyCode().IsShift() )
     657           0 :                         nMode = DELMODE_RESTOFCONTENT;
     658             : 
     659           0 :                     switch( nCode )
     660             :                     {
     661             :                     case com::sun::star::awt::Key::DELETE_WORD_BACKWARD:
     662           0 :                         nDel = DEL_LEFT;
     663           0 :                         nMode = DELMODE_RESTOFWORD;
     664           0 :                         break;
     665             :                     case com::sun::star::awt::Key::DELETE_WORD_FORWARD:
     666           0 :                         nDel = DEL_RIGHT;
     667           0 :                         nMode = DELMODE_RESTOFWORD;
     668           0 :                         break;
     669             :                     case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE:
     670           0 :                         nDel = DEL_LEFT;
     671           0 :                         nMode = DELMODE_RESTOFCONTENT;
     672           0 :                         break;
     673             :                     case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE:
     674           0 :                         nDel = DEL_RIGHT;
     675           0 :                         nMode = DELMODE_RESTOFCONTENT;
     676           0 :                         break;
     677           0 :                     default: break;
     678             :                     }
     679             : 
     680           0 :                     mpImpl->mpTextEngine->UndoActionStart();
     681           0 :                     if(mpImpl->mbSupportProtectAttribute)
     682             :                     {
     683             :                         //expand selection to include all protected content - if there is any
     684             :                         const TextCharAttrib* pStartAttr = mpImpl->mpTextEngine->FindCharAttrib(
     685           0 :                                     TextPaM(mpImpl->maSelection.GetStart().GetPara(),
     686           0 :                                     mpImpl->maSelection.GetStart().GetIndex()),
     687           0 :                                     TEXTATTR_PROTECTED );
     688             :                         const TextCharAttrib* pEndAttr = mpImpl->mpTextEngine->FindCharAttrib(
     689           0 :                                     TextPaM(mpImpl->maSelection.GetEnd().GetPara(),
     690           0 :                                     mpImpl->maSelection.GetEnd().GetIndex()),
     691           0 :                                     TEXTATTR_PROTECTED );
     692           0 :                         if(pStartAttr && pStartAttr->GetStart() < mpImpl->maSelection.GetStart().GetIndex())
     693             :                         {
     694           0 :                             mpImpl->maSelection.GetStart().GetIndex() = pStartAttr->GetStart();
     695             :                         }
     696           0 :                         if(pEndAttr && pEndAttr->GetEnd() > mpImpl->maSelection.GetEnd().GetIndex())
     697             :                         {
     698           0 :                             mpImpl->maSelection.GetEnd().GetIndex() = pEndAttr->GetEnd();
     699             :                         }
     700             :                     }
     701           0 :                     aCurSel = ImpDelete( nDel, nMode );
     702           0 :                     mpImpl->mpTextEngine->UndoActionEnd();
     703           0 :                     bModified = true;
     704           0 :                     bAllowIdle = false;
     705             :                 }
     706             :                 else
     707           0 :                     bDone = false;
     708             :             }
     709           0 :             break;
     710             :             case KEY_TAB:
     711             :             {
     712           0 :                 if ( !mpImpl->mbReadOnly && !rKeyEvent.GetKeyCode().IsShift() &&
     713           0 :                         !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() &&
     714           0 :                         ImplCheckTextLen( OUString('x') ) )
     715             :                 {
     716           0 :                     aCurSel = mpImpl->mpTextEngine->ImpInsertText( aCurSel, '\t', !IsInsertMode() );
     717           0 :                     bModified = true;
     718             :                 }
     719             :                 else
     720           0 :                     bDone = false;
     721             :             }
     722           0 :             break;
     723             :             case KEY_RETURN:
     724             :             {
     725             :                 // do not swallow Shift-RETURN, as this would disable multi-line entries
     726             :                 // in dialogs & property editors
     727           0 :                 if ( !mpImpl->mbReadOnly && !rKeyEvent.GetKeyCode().IsMod1() &&
     728           0 :                         !rKeyEvent.GetKeyCode().IsMod2() && ImplCheckTextLen( OUString('x') ) )
     729             :                 {
     730           0 :                     mpImpl->mpTextEngine->UndoActionStart();
     731           0 :                     aCurSel = mpImpl->mpTextEngine->ImpInsertParaBreak( aCurSel );
     732           0 :                     if ( mpImpl->mbAutoIndent )
     733             :                     {
     734           0 :                         TextNode* pPrev = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aCurSel.GetEnd().GetPara() - 1 ];
     735           0 :                         sal_uInt16 n = 0;
     736           0 :                         while ( ( n < pPrev->GetText().getLength() ) && (
     737           0 :                                     ( pPrev->GetText()[ n ] == ' ' ) ||
     738           0 :                                     ( pPrev->GetText()[ n ] == '\t' ) ) )
     739             :                         {
     740           0 :                             n++;
     741             :                         }
     742           0 :                         if ( n )
     743           0 :                             aCurSel = mpImpl->mpTextEngine->ImpInsertText( aCurSel, pPrev->GetText().copy( 0, n ) );
     744             :                     }
     745           0 :                     mpImpl->mpTextEngine->UndoActionEnd();
     746           0 :                     bModified = true;
     747             :                 }
     748             :                 else
     749           0 :                     bDone = false;
     750             :             }
     751           0 :             break;
     752             :             case KEY_INSERT:
     753             :             {
     754           0 :                 if ( !mpImpl->mbReadOnly )
     755           0 :                     SetInsertMode( !IsInsertMode() );
     756             :             }
     757           0 :             break;
     758             :             default:
     759             :             {
     760           0 :                 if ( TextEngine::IsSimpleCharInput( rKeyEvent ) )
     761             :                 {
     762           0 :                     sal_Unicode nCharCode = rKeyEvent.GetCharCode();
     763           0 :                     if ( !mpImpl->mbReadOnly && ImplCheckTextLen( OUString(nCharCode) ) )    // otherwise swallow the character anyway
     764             :                     {
     765           0 :                         aCurSel = mpImpl->mpTextEngine->ImpInsertText( nCharCode, aCurSel, !IsInsertMode(), true );
     766           0 :                         bModified = true;
     767             :                     }
     768             :                 }
     769             :                 else
     770           0 :                     bDone = false;
     771             :             }
     772             :         }
     773             :     }
     774             : 
     775           0 :     if ( aCurSel != aOldSel )   // Check if changed, maybe other method already changed mpImpl->maSelection, don't overwrite that!
     776           0 :         ImpSetSelection( aCurSel );
     777             : 
     778           0 :     if ( ( nCode != KEY_UP ) && ( nCode != KEY_DOWN ) )
     779           0 :         mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
     780             : 
     781           0 :     if ( bModified )
     782             :     {
     783             :         // Idle-Formatter only if AnyInput
     784           0 :         if ( bAllowIdle && Application::AnyInput( VclInputFlags::KEYBOARD) )
     785           0 :             mpImpl->mpTextEngine->IdleFormatAndUpdate( this );
     786             :         else
     787           0 :             mpImpl->mpTextEngine->FormatAndUpdate( this);
     788             :     }
     789           0 :     else if ( bMoved )
     790             :     {
     791             :         // selection is painted now in ImpMoveCursor
     792           0 :         ImpShowCursor( mpImpl->mbAutoScroll, true, bEndKey );
     793             :     }
     794             : 
     795           0 :     if ( mpImpl->mpTextEngine->IsModified() )
     796           0 :         mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
     797           0 :     else if ( bWasModified )
     798           0 :         mpImpl->mpTextEngine->SetModified( true );
     799             : 
     800           0 :     return bDone;
     801             : }
     802             : 
     803           0 : void TextView::MouseButtonUp( const MouseEvent& rMouseEvent )
     804             : {
     805           0 :     mpImpl->mbClickedInSelection = false;
     806           0 :     mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
     807           0 :     mpImpl->mpSelEngine->SelMouseButtonUp( rMouseEvent );
     808           0 :     if ( rMouseEvent.IsMiddle() && !IsReadOnly() &&
     809           0 :          ( GetWindow()->GetSettings().GetMouseSettings().GetMiddleButtonAction() == MouseMiddleButtonAction::PasteSelection ) )
     810             :     {
     811           0 :         uno::Reference<datatransfer::clipboard::XClipboard> aSelection(GetWindow()->GetPrimarySelection());
     812           0 :         Paste( aSelection );
     813           0 :         if ( mpImpl->mpTextEngine->IsModified() )
     814           0 :             mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
     815             :     }
     816           0 :     else if ( rMouseEvent.IsLeft() && GetSelection().HasRange() )
     817             :     {
     818           0 :         uno::Reference<datatransfer::clipboard::XClipboard> aSelection(GetWindow()->GetPrimarySelection());
     819           0 :         Copy( aSelection );
     820             :     }
     821           0 : }
     822             : 
     823           0 : void TextView::MouseButtonDown( const MouseEvent& rMouseEvent )
     824             : {
     825           0 :     mpImpl->mpTextEngine->CheckIdleFormatter();    // for fast typing and MouseButtonDown
     826           0 :     mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
     827           0 :     mpImpl->mbClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
     828             : 
     829           0 :     mpImpl->mpTextEngine->SetActiveView( this );
     830             : 
     831           0 :     mpImpl->mpSelEngine->SelMouseButtonDown( rMouseEvent );
     832             : 
     833             :     // mbu 20.01.2005 - SelMouseButtonDown() possibly triggers a 'selection changed'
     834             :     // notification. The appropriate handler could change the current selection,
     835             :     // which is the case in the MailMerge address block control. To enable select'n'drag
     836             :     // we need to reevaluate the selection after the notification has been fired.
     837           0 :     mpImpl->mbClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
     838             : 
     839             :     // special cases
     840           0 :     if ( !rMouseEvent.IsShift() && ( rMouseEvent.GetClicks() >= 2 ) )
     841             :     {
     842           0 :         if ( rMouseEvent.IsMod2() )
     843             :         {
     844           0 :             HideSelection();
     845           0 :             ImpSetSelection( mpImpl->maSelection.GetEnd() );
     846           0 :             SetCursorAtPoint( rMouseEvent.GetPosPixel() );  // not set by SelectionEngine for MOD2
     847             :         }
     848             : 
     849           0 :         if ( rMouseEvent.GetClicks() == 2 )
     850             :         {
     851             :             // select word
     852           0 :             if ( mpImpl->maSelection.GetEnd().GetIndex() < mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection.GetEnd().GetPara() ) )
     853             :             {
     854           0 :                 HideSelection();
     855           0 :                 TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[  mpImpl->maSelection.GetEnd().GetPara() ];
     856           0 :                 uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
     857           0 :                 i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, true );
     858           0 :                 TextSelection aNewSel( mpImpl->maSelection );
     859           0 :                 aNewSel.GetStart().GetIndex() = (sal_uInt16)aBoundary.startPos;
     860           0 :                 aNewSel.GetEnd().GetIndex() = (sal_uInt16)aBoundary.endPos;
     861           0 :                 if(mpImpl->mbSupportProtectAttribute)
     862             :                 {
     863             :                     //expand selection to include all protected content - if there is any
     864             :                     const TextCharAttrib* pStartAttr = mpImpl->mpTextEngine->FindCharAttrib(
     865           0 :                                 TextPaM(aNewSel.GetStart().GetPara(),
     866             :                                 (sal_uInt16)aBoundary.startPos),
     867           0 :                                 TEXTATTR_PROTECTED );
     868             :                     const TextCharAttrib* pEndAttr = mpImpl->mpTextEngine->FindCharAttrib(
     869           0 :                                 TextPaM(aNewSel.GetEnd().GetPara(),
     870             :                                 (sal_uInt16)aBoundary.endPos),
     871           0 :                                 TEXTATTR_PROTECTED );
     872           0 :                     if(pStartAttr && pStartAttr->GetStart() < aNewSel.GetStart().GetIndex())
     873             :                     {
     874           0 :                         aNewSel.GetStart().GetIndex() = pStartAttr->GetStart();
     875             :                     }
     876           0 :                     if(pEndAttr && pEndAttr->GetEnd() > aNewSel.GetEnd().GetIndex())
     877             :                     {
     878           0 :                         aNewSel.GetEnd().GetIndex() = pEndAttr->GetEnd();
     879             :                     }
     880             :                 }
     881           0 :                 ImpSetSelection( aNewSel );
     882           0 :                 ShowSelection();
     883           0 :                 ShowCursor( true, true );
     884             :             }
     885             :         }
     886           0 :         else if ( rMouseEvent.GetClicks() == 3 )
     887             :         {
     888             :             // select paragraph
     889           0 :             if ( mpImpl->maSelection.GetStart().GetIndex() || ( mpImpl->maSelection.GetEnd().GetIndex() < mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection.GetEnd().GetPara() ) ) )
     890             :             {
     891           0 :                 HideSelection();
     892           0 :                 TextSelection aNewSel( mpImpl->maSelection );
     893           0 :                 aNewSel.GetStart().GetIndex() = 0;
     894           0 :                 aNewSel.GetEnd().GetIndex() = mpImpl->mpTextEngine->mpDoc->GetNodes()[ mpImpl->maSelection.GetEnd().GetPara() ]->GetText().getLength();
     895           0 :                 ImpSetSelection( aNewSel );
     896           0 :                 ShowSelection();
     897           0 :                 ShowCursor( true, true );
     898             :             }
     899             :         }
     900             :     }
     901           0 : }
     902             : 
     903           0 : void TextView::MouseMove( const MouseEvent& rMouseEvent )
     904             : {
     905           0 :     mpImpl->mnTravelXPos = TRAVEL_X_DONTKNOW;
     906           0 :     mpImpl->mpSelEngine->SelMouseMove( rMouseEvent );
     907           0 : }
     908             : 
     909           0 : void TextView::Command( const CommandEvent& rCEvt )
     910             : {
     911           0 :     mpImpl->mpTextEngine->CheckIdleFormatter();    // for fast typing and MouseButtonDown
     912           0 :     mpImpl->mpTextEngine->SetActiveView( this );
     913             : 
     914           0 :     if ( rCEvt.GetCommand() == CommandEventId::StartExtTextInput )
     915             :     {
     916           0 :         DeleteSelected();
     917           0 :         delete mpImpl->mpTextEngine->mpIMEInfos;
     918           0 :         TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ GetSelection().GetEnd().GetPara() ];
     919           0 :         mpImpl->mpTextEngine->mpIMEInfos = new TEIMEInfos( GetSelection().GetEnd(), pNode->GetText().copy( GetSelection().GetEnd().GetIndex() ) );
     920           0 :         mpImpl->mpTextEngine->mpIMEInfos->bWasCursorOverwrite = !IsInsertMode();
     921             :     }
     922           0 :     else if ( rCEvt.GetCommand() == CommandEventId::EndExtTextInput )
     923             :     {
     924             :         DBG_ASSERT( mpImpl->mpTextEngine->mpIMEInfos, "CommandEventId::EndExtTextInput => No Start ?" );
     925           0 :         if( mpImpl->mpTextEngine->mpIMEInfos )
     926             :         {
     927           0 :             TEParaPortion* pPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetPara() );
     928           0 :             pPortion->MarkSelectionInvalid( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex(), 0 );
     929             : 
     930           0 :             bool bInsertMode = !mpImpl->mpTextEngine->mpIMEInfos->bWasCursorOverwrite;
     931             : 
     932           0 :             delete mpImpl->mpTextEngine->mpIMEInfos;
     933           0 :             mpImpl->mpTextEngine->mpIMEInfos = NULL;
     934             : 
     935           0 :             mpImpl->mpTextEngine->FormatAndUpdate( this );
     936             : 
     937           0 :             SetInsertMode( bInsertMode );
     938             : 
     939           0 :             if ( mpImpl->mpTextEngine->IsModified() )
     940           0 :                 mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
     941             :         }
     942             :     }
     943           0 :     else if ( rCEvt.GetCommand() == CommandEventId::ExtTextInput )
     944             :     {
     945             :         DBG_ASSERT( mpImpl->mpTextEngine->mpIMEInfos, "CommandEventId::ExtTextInput => No Start ?" );
     946           0 :         if( mpImpl->mpTextEngine->mpIMEInfos )
     947             :         {
     948           0 :             const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
     949             : 
     950           0 :             if ( !pData->IsOnlyCursorChanged() )
     951             :             {
     952           0 :                 TextSelection aSelect( mpImpl->mpTextEngine->mpIMEInfos->aPos );
     953           0 :                 aSelect.GetEnd().GetIndex() = aSelect.GetEnd().GetIndex() + mpImpl->mpTextEngine->mpIMEInfos->nLen;
     954           0 :                 aSelect = mpImpl->mpTextEngine->ImpDeleteText( aSelect );
     955           0 :                 aSelect = mpImpl->mpTextEngine->ImpInsertText( aSelect, pData->GetText() );
     956             : 
     957           0 :                 if ( mpImpl->mpTextEngine->mpIMEInfos->bWasCursorOverwrite )
     958             :                 {
     959           0 :                     sal_Int32 nOldIMETextLen = mpImpl->mpTextEngine->mpIMEInfos->nLen;
     960           0 :                     sal_Int32 nNewIMETextLen = pData->GetText().getLength();
     961             : 
     962           0 :                     if ( ( nOldIMETextLen > nNewIMETextLen ) &&
     963           0 :                          ( nNewIMETextLen < mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.getLength() ) )
     964             :                     {
     965             :                         // restore old characters
     966           0 :                         sal_Int32 nRestore = nOldIMETextLen - nNewIMETextLen;
     967           0 :                         TextPaM aPaM( mpImpl->mpTextEngine->mpIMEInfos->aPos );
     968           0 :                         aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
     969           0 :                         mpImpl->mpTextEngine->ImpInsertText( aPaM, mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.copy( nNewIMETextLen, nRestore ) );
     970             :                     }
     971           0 :                     else if ( ( nOldIMETextLen < nNewIMETextLen ) &&
     972           0 :                               ( nOldIMETextLen < mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.getLength() ) )
     973             :                     {
     974             :                         // overwrite
     975           0 :                         sal_uInt16 nOverwrite = nNewIMETextLen - nOldIMETextLen;
     976           0 :                         if ( ( nOldIMETextLen + nOverwrite ) > mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.getLength() )
     977           0 :                             nOverwrite = mpImpl->mpTextEngine->mpIMEInfos->aOldTextAfterStartPos.getLength() - nOldIMETextLen;
     978             :                         DBG_ASSERT( nOverwrite && (nOverwrite < 0xFF00), "IME Overwrite?!" );
     979           0 :                         TextPaM aPaM( mpImpl->mpTextEngine->mpIMEInfos->aPos );
     980           0 :                         aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
     981           0 :                         TextSelection aSel( aPaM );
     982           0 :                         aSel.GetEnd().GetIndex() =
     983           0 :                             aSel.GetEnd().GetIndex() + nOverwrite;
     984           0 :                         mpImpl->mpTextEngine->ImpDeleteText( aSel );
     985             :                     }
     986             :                 }
     987             : 
     988           0 :                 if ( pData->GetTextAttr() )
     989             :                 {
     990           0 :                     mpImpl->mpTextEngine->mpIMEInfos->CopyAttribs( pData->GetTextAttr(), pData->GetText().getLength() );
     991           0 :                     mpImpl->mpTextEngine->mpIMEInfos->bCursor = pData->IsCursorVisible();
     992             :                 }
     993             :                 else
     994             :                 {
     995           0 :                     mpImpl->mpTextEngine->mpIMEInfos->DestroyAttribs();
     996             :                 }
     997             : 
     998           0 :                 TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetPara() );
     999           0 :                 pPPortion->MarkSelectionInvalid( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex(), 0 );
    1000           0 :                 mpImpl->mpTextEngine->FormatAndUpdate( this );
    1001             :             }
    1002             : 
    1003           0 :             TextSelection aNewSel = TextPaM( mpImpl->mpTextEngine->mpIMEInfos->aPos.GetPara(), mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex()+pData->GetCursorPos() );
    1004           0 :             SetSelection( aNewSel );
    1005           0 :             SetInsertMode( !pData->IsCursorOverwrite() );
    1006             : 
    1007           0 :             if ( pData->IsCursorVisible() )
    1008           0 :                 ShowCursor();
    1009             :             else
    1010           0 :                 HideCursor();
    1011             :         }
    1012             :     }
    1013           0 :     else if ( rCEvt.GetCommand() == CommandEventId::CursorPos )
    1014             :     {
    1015           0 :         if ( mpImpl->mpTextEngine->mpIMEInfos && mpImpl->mpTextEngine->mpIMEInfos->nLen )
    1016             :         {
    1017           0 :             TextPaM aPaM( GetSelection().GetEnd() );
    1018           0 :             Rectangle aR1 = mpImpl->mpTextEngine->PaMtoEditCursor( aPaM );
    1019             : 
    1020           0 :             sal_uInt16 nInputEnd = mpImpl->mpTextEngine->mpIMEInfos->aPos.GetIndex() + mpImpl->mpTextEngine->mpIMEInfos->nLen;
    1021             : 
    1022           0 :             if ( !mpImpl->mpTextEngine->IsFormatted() )
    1023           0 :                 mpImpl->mpTextEngine->FormatDoc();
    1024             : 
    1025           0 :             TEParaPortion* pParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
    1026           0 :             sal_uInt16 nLine = pParaPortion->GetLineNumber( aPaM.GetIndex(), true );
    1027           0 :             TextLine& pLine = pParaPortion->GetLines()[ nLine ];
    1028           0 :             if ( nInputEnd > pLine.GetEnd() )
    1029           0 :                 nInputEnd = pLine.GetEnd();
    1030           0 :             Rectangle aR2 = mpImpl->mpTextEngine->PaMtoEditCursor( TextPaM( aPaM.GetPara(), nInputEnd ) );
    1031             : 
    1032           0 :             long nWidth = aR2.Left()-aR1.Right();
    1033           0 :             aR1.Move( -GetStartDocPos().X(), -GetStartDocPos().Y() );
    1034           0 :             GetWindow()->SetCursorRect( &aR1, nWidth );
    1035             :         }
    1036             :         else
    1037             :         {
    1038           0 :             GetWindow()->SetCursorRect();
    1039             :         }
    1040             :     }
    1041             :     else
    1042             :     {
    1043           0 :         mpImpl->mpSelEngine->Command( rCEvt );
    1044             :     }
    1045           0 : }
    1046             : 
    1047         250 : void TextView::ShowCursor( bool bGotoCursor, bool bForceVisCursor )
    1048             : {
    1049             :     // this setting has more weight
    1050         250 :     if ( !mpImpl->mbAutoScroll )
    1051           0 :         bGotoCursor = false;
    1052         250 :     ImpShowCursor( bGotoCursor, bForceVisCursor, false );
    1053         250 : }
    1054             : 
    1055         409 : void TextView::HideCursor()
    1056             : {
    1057         409 :     mpImpl->mpCursor->Hide();
    1058         409 : }
    1059             : 
    1060           0 : void TextView::Scroll( long ndX, long ndY )
    1061             : {
    1062             :     DBG_ASSERT( mpImpl->mpTextEngine->IsFormatted(), "Scroll: Not formatted!" );
    1063             : 
    1064           0 :     if ( !ndX && !ndY )
    1065           0 :         return;
    1066             : 
    1067           0 :     Point aNewStartPos( mpImpl->maStartDocPos );
    1068             : 
    1069             :     // Vertical:
    1070           0 :     aNewStartPos.Y() -= ndY;
    1071           0 :     if ( aNewStartPos.Y() < 0 )
    1072           0 :         aNewStartPos.Y() = 0;
    1073             : 
    1074             :     // Horizontal:
    1075           0 :     aNewStartPos.X() -= ndX;
    1076           0 :     if ( aNewStartPos.X() < 0 )
    1077           0 :         aNewStartPos.X() = 0;
    1078             : 
    1079           0 :     long nDiffX = mpImpl->maStartDocPos.X() - aNewStartPos.X();
    1080           0 :     long nDiffY = mpImpl->maStartDocPos.Y() - aNewStartPos.Y();
    1081             : 
    1082           0 :     if ( nDiffX || nDiffY )
    1083             :     {
    1084           0 :         bool bVisCursor = mpImpl->mpCursor->IsVisible();
    1085           0 :         mpImpl->mpCursor->Hide();
    1086           0 :         mpImpl->mpWindow->Update();
    1087           0 :         mpImpl->maStartDocPos = aNewStartPos;
    1088             : 
    1089           0 :         if ( mpImpl->mpTextEngine->IsRightToLeft() )
    1090           0 :             nDiffX = -nDiffX;
    1091           0 :         mpImpl->mpWindow->Scroll( nDiffX, nDiffY );
    1092           0 :         mpImpl->mpWindow->Update();
    1093           0 :         mpImpl->mpCursor->SetPos( mpImpl->mpCursor->GetPos() + Point( nDiffX, nDiffY ) );
    1094           0 :         if ( bVisCursor && !mpImpl->mbReadOnly )
    1095           0 :             mpImpl->mpCursor->Show();
    1096             :     }
    1097             : 
    1098           0 :     mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_VIEWSCROLLED ) );
    1099             : }
    1100             : 
    1101           0 : void TextView::Undo()
    1102             : {
    1103           0 :     mpImpl->mpTextEngine->SetActiveView( this );
    1104           0 :     mpImpl->mpTextEngine->GetUndoManager().Undo();
    1105           0 : }
    1106             : 
    1107           0 : void TextView::Redo()
    1108             : {
    1109           0 :     mpImpl->mpTextEngine->SetActiveView( this );
    1110           0 :     mpImpl->mpTextEngine->GetUndoManager().Redo();
    1111           0 : }
    1112             : 
    1113           0 : void TextView::Cut()
    1114             : {
    1115           0 :     mpImpl->mpTextEngine->UndoActionStart();
    1116           0 :     Copy();
    1117           0 :     DeleteSelected();
    1118           0 :     mpImpl->mpTextEngine->UndoActionEnd();
    1119           0 : }
    1120             : 
    1121           0 : void TextView::Copy( uno::Reference< datatransfer::clipboard::XClipboard >& rxClipboard )
    1122             : {
    1123           0 :     if ( rxClipboard.is() )
    1124             :     {
    1125           0 :         TETextDataObject* pDataObj = new TETextDataObject( GetSelected() );
    1126             : 
    1127           0 :         if ( mpImpl->mpTextEngine->HasAttrib( TEXTATTR_HYPERLINK ) )  // then also as HTML
    1128           0 :             mpImpl->mpTextEngine->Write( pDataObj->GetHTMLStream(), &mpImpl->maSelection, true );
    1129             : 
    1130           0 :         SolarMutexReleaser aReleaser;
    1131             : 
    1132             :         try
    1133             :         {
    1134           0 :             rxClipboard->setContents( pDataObj, NULL );
    1135             : 
    1136           0 :             uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY );
    1137           0 :             if( xFlushableClipboard.is() )
    1138           0 :                 xFlushableClipboard->flushClipboard();
    1139             :         }
    1140           0 :         catch( const ::com::sun::star::uno::Exception& )
    1141             :         {
    1142           0 :         }
    1143             :     }
    1144           0 : }
    1145             : 
    1146           0 : void TextView::Copy()
    1147             : {
    1148           0 :     uno::Reference<datatransfer::clipboard::XClipboard> aClipboard(GetWindow()->GetClipboard());
    1149           0 :     Copy( aClipboard );
    1150           0 : }
    1151             : 
    1152           0 : void TextView::Paste( uno::Reference< datatransfer::clipboard::XClipboard >& rxClipboard )
    1153             : {
    1154           0 :     if ( rxClipboard.is() )
    1155             :     {
    1156           0 :         uno::Reference< datatransfer::XTransferable > xDataObj;
    1157             : 
    1158             :         try
    1159             :             {
    1160           0 :                 SolarMutexReleaser aReleaser;
    1161           0 :                 xDataObj = rxClipboard->getContents();
    1162             :             }
    1163           0 :         catch( const ::com::sun::star::uno::Exception& )
    1164             :             {
    1165             :             }
    1166             : 
    1167           0 :         if ( xDataObj.is() )
    1168             :         {
    1169           0 :             datatransfer::DataFlavor aFlavor;
    1170           0 :             SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
    1171           0 :             if ( xDataObj->isDataFlavorSupported( aFlavor ) )
    1172             :             {
    1173             :                 try
    1174             :                 {
    1175           0 :                     uno::Any aData = xDataObj->getTransferData( aFlavor );
    1176           0 :                     OUString aText;
    1177           0 :                     aData >>= aText;
    1178           0 :                     bool bWasTruncated = false;
    1179           0 :                     if( mpImpl->mpTextEngine->GetMaxTextLen() != 0 )
    1180           0 :                         bWasTruncated = ImplTruncateNewText( aText );
    1181           0 :                     InsertText( aText, false );
    1182           0 :                     mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
    1183             : 
    1184           0 :                     if( bWasTruncated )
    1185           0 :                         Edit::ShowTruncationWarning( mpImpl->mpWindow );
    1186             :                 }
    1187           0 :                 catch( const ::com::sun::star::datatransfer::UnsupportedFlavorException& )
    1188             :                 {
    1189             :                 }
    1190           0 :             }
    1191           0 :         }
    1192             :     }
    1193           0 : }
    1194             : 
    1195           0 : void TextView::Paste()
    1196             : {
    1197           0 :     uno::Reference<datatransfer::clipboard::XClipboard> aClipboard(GetWindow()->GetClipboard());
    1198           0 :     Paste( aClipboard );
    1199           0 : }
    1200             : 
    1201           0 : OUString TextView::GetSelected()
    1202             : {
    1203           0 :     return GetSelected( GetSystemLineEnd() );
    1204             : }
    1205             : 
    1206           0 : OUString TextView::GetSelected( LineEnd aSeparator )
    1207             : {
    1208           0 :     return mpImpl->mpTextEngine->GetText( mpImpl->maSelection, aSeparator );
    1209             : }
    1210             : 
    1211           0 : void TextView::SetInsertMode( bool bInsert )
    1212             : {
    1213           0 :     if ( mpImpl->mbInsertMode != bInsert )
    1214             :     {
    1215           0 :         mpImpl->mbInsertMode = bInsert;
    1216           0 :         ShowCursor( mpImpl->mbAutoScroll, false );
    1217             :     }
    1218           0 : }
    1219             : 
    1220         191 : void TextView::SetReadOnly( bool bReadOnly )
    1221             : {
    1222         191 :     if ( mpImpl->mbReadOnly != bReadOnly )
    1223             :     {
    1224          18 :         mpImpl->mbReadOnly = bReadOnly;
    1225          18 :         if ( !mpImpl->mbReadOnly )
    1226           0 :             ShowCursor( mpImpl->mbAutoScroll, false );
    1227             :         else
    1228          18 :             HideCursor();
    1229             : 
    1230          18 :         GetWindow()->SetInputContext( InputContext( mpImpl->mpTextEngine->GetFont(), bReadOnly ? InputContextFlags::Text|InputContextFlags::ExtText : InputContextFlags::NONE ) );
    1231             :     }
    1232         191 : }
    1233             : 
    1234           0 : TextSelection TextView::ImpMoveCursor( const KeyEvent& rKeyEvent )
    1235             : {
    1236             :     // normally only needed for Up/Down; but who cares
    1237           0 :     mpImpl->mpTextEngine->CheckIdleFormatter();
    1238             : 
    1239           0 :     TextPaM aPaM( mpImpl->maSelection.GetEnd() );
    1240           0 :     TextPaM aOldEnd( aPaM );
    1241             : 
    1242           0 :     TextDirectionality eTextDirection = TextDirectionality_LeftToRight_TopToBottom;
    1243           0 :     if ( mpImpl->mpTextEngine->IsRightToLeft() )
    1244           0 :         eTextDirection = TextDirectionality_RightToLeft_TopToBottom;
    1245             : 
    1246           0 :     KeyEvent aTranslatedKeyEvent = rKeyEvent.LogicalTextDirectionality( eTextDirection );
    1247             : 
    1248           0 :     bool bCtrl = aTranslatedKeyEvent.GetKeyCode().IsMod1();
    1249           0 :     sal_uInt16 nCode = aTranslatedKeyEvent.GetKeyCode().GetCode();
    1250             : 
    1251           0 :     bool bSelect = aTranslatedKeyEvent.GetKeyCode().IsShift();
    1252           0 :     switch ( nCode )
    1253             :     {
    1254           0 :         case KEY_UP:        aPaM = CursorUp( aPaM );
    1255           0 :                             break;
    1256           0 :         case KEY_DOWN:      aPaM = CursorDown( aPaM );
    1257           0 :                             break;
    1258           0 :         case KEY_HOME:      aPaM = bCtrl ? CursorStartOfDoc() : CursorStartOfLine( aPaM );
    1259           0 :                             break;
    1260           0 :         case KEY_END:       aPaM = bCtrl ? CursorEndOfDoc() : CursorEndOfLine( aPaM );
    1261           0 :                             break;
    1262           0 :         case KEY_PAGEUP:    aPaM = bCtrl ? CursorStartOfDoc() : PageUp( aPaM );
    1263           0 :                             break;
    1264           0 :         case KEY_PAGEDOWN:  aPaM = bCtrl ? CursorEndOfDoc() : PageDown( aPaM );
    1265           0 :                             break;
    1266           0 :         case KEY_LEFT:      aPaM = bCtrl ? CursorWordLeft( aPaM ) : CursorLeft( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? (sal_uInt16)i18n::CharacterIteratorMode::SKIPCHARACTER : (sal_uInt16)i18n::CharacterIteratorMode::SKIPCELL );
    1267           0 :                             break;
    1268           0 :         case KEY_RIGHT:     aPaM = bCtrl ? CursorWordRight( aPaM ) : CursorRight( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? (sal_uInt16)i18n::CharacterIteratorMode::SKIPCHARACTER : (sal_uInt16)i18n::CharacterIteratorMode::SKIPCELL );
    1269           0 :                             break;
    1270             :         case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
    1271           0 :                             bSelect = true; // fallthrough intentional
    1272             :         case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
    1273           0 :                             aPaM = CursorWordRight( aPaM );
    1274           0 :                             break;
    1275             :         case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
    1276           0 :                             bSelect = true; // fallthrough intentional
    1277             :         case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
    1278           0 :                             aPaM = CursorWordLeft( aPaM );
    1279           0 :                             break;
    1280             :         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
    1281           0 :                             bSelect = true; // fallthrough intentional
    1282             :         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
    1283           0 :                             aPaM = CursorStartOfLine( aPaM );
    1284           0 :                             break;
    1285             :         case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
    1286           0 :                             bSelect = true; // fallthrough intentional
    1287             :         case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
    1288           0 :                             aPaM = CursorEndOfLine( aPaM );
    1289           0 :                             break;
    1290             :         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
    1291           0 :                             bSelect = true; // falltthrough intentional
    1292             :         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
    1293           0 :                             aPaM = CursorStartOfParagraph( aPaM );
    1294           0 :                             break;
    1295             :         case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
    1296           0 :                             bSelect = true; // falltthrough intentional
    1297             :         case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
    1298           0 :                             aPaM = CursorEndOfParagraph( aPaM );
    1299           0 :                             break;
    1300             :         case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
    1301           0 :                             bSelect = true; // falltthrough intentional
    1302             :         case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
    1303           0 :                             aPaM = CursorStartOfDoc();
    1304           0 :                             break;
    1305             :         case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
    1306           0 :                             bSelect = true; // falltthrough intentional
    1307             :         case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
    1308           0 :                             aPaM = CursorEndOfDoc();
    1309           0 :                             break;
    1310             :     }
    1311             : 
    1312             :     // might cause a CreateAnchor or Deselection all
    1313           0 :     mpImpl->mpSelEngine->CursorPosChanging( bSelect, aTranslatedKeyEvent.GetKeyCode().IsMod1() );
    1314             : 
    1315           0 :     if ( aOldEnd != aPaM )
    1316             :     {
    1317           0 :         mpImpl->mpTextEngine->CursorMoved( aOldEnd.GetPara() );
    1318             : 
    1319           0 :         TextSelection aNewSelection( mpImpl->maSelection );
    1320           0 :         aNewSelection.GetEnd() = aPaM;
    1321           0 :         if ( bSelect )
    1322             :         {
    1323             :             // extend the selection
    1324           0 :             ImpSetSelection( aNewSelection );
    1325           0 :             ShowSelection( TextSelection( aOldEnd, aPaM ) );
    1326             :         }
    1327             :         else
    1328             :         {
    1329           0 :             aNewSelection.GetStart() = aPaM;
    1330           0 :             ImpSetSelection( aNewSelection );
    1331             :         }
    1332             :     }
    1333             : 
    1334           0 :     return mpImpl->maSelection;
    1335             : }
    1336             : 
    1337           0 : void TextView::InsertText( const OUString& rStr, bool bSelect )
    1338             : {
    1339           0 :     mpImpl->mpTextEngine->UndoActionStart();
    1340             : 
    1341           0 :     TextSelection aNewSel( mpImpl->maSelection );
    1342           0 :     TextPaM aPaM = mpImpl->mpTextEngine->ImpInsertText( mpImpl->maSelection, rStr );
    1343             : 
    1344           0 :     if ( bSelect )
    1345             :     {
    1346           0 :         aNewSel.Justify();
    1347           0 :         aNewSel.GetEnd() = aPaM;
    1348             :     }
    1349             :     else
    1350             :     {
    1351           0 :         aNewSel = aPaM;
    1352             :     }
    1353             : 
    1354           0 :     ImpSetSelection( aNewSel );
    1355             : 
    1356           0 :     mpImpl->mpTextEngine->UndoActionEnd();
    1357             : 
    1358           0 :     mpImpl->mpTextEngine->FormatAndUpdate( this );
    1359           0 : }
    1360             : 
    1361           0 : TextPaM TextView::CursorLeft( const TextPaM& rPaM, sal_uInt16 nCharacterIteratorMode )
    1362             : {
    1363           0 :     TextPaM aPaM( rPaM );
    1364             : 
    1365           0 :     if ( aPaM.GetIndex() )
    1366             :     {
    1367           0 :         TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ];
    1368           0 :         uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
    1369           0 :         sal_Int32 nCount = 1;
    1370           0 :         aPaM.GetIndex() = (sal_uInt16)xBI->previousCharacters( pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), nCharacterIteratorMode, nCount, nCount );
    1371             :     }
    1372           0 :     else if ( aPaM.GetPara() )
    1373             :     {
    1374           0 :         aPaM.GetPara()--;
    1375           0 :         TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ];
    1376           0 :         aPaM.GetIndex() = pNode->GetText().getLength();
    1377             :     }
    1378           0 :     return aPaM;
    1379             : }
    1380             : 
    1381           0 : TextPaM TextView::CursorRight( const TextPaM& rPaM, sal_uInt16 nCharacterIteratorMode )
    1382             : {
    1383           0 :     TextPaM aPaM( rPaM );
    1384             : 
    1385           0 :     TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ];
    1386           0 :     if ( aPaM.GetIndex() < pNode->GetText().getLength() )
    1387             :     {
    1388           0 :         uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
    1389           0 :         sal_Int32 nCount = 1;
    1390           0 :         aPaM.GetIndex() = (sal_uInt16)xBI->nextCharacters( pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), nCharacterIteratorMode, nCount, nCount );
    1391             :     }
    1392           0 :     else if ( aPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().size()-1) )
    1393             :     {
    1394           0 :         aPaM.GetPara()++;
    1395           0 :         aPaM.GetIndex() = 0;
    1396             :     }
    1397             : 
    1398           0 :     return aPaM;
    1399             : }
    1400             : 
    1401           0 : TextPaM TextView::CursorWordLeft( const TextPaM& rPaM )
    1402             : {
    1403           0 :     TextPaM aPaM( rPaM );
    1404             : 
    1405           0 :     if ( aPaM.GetIndex() )
    1406             :     {
    1407           0 :         TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ];
    1408           0 :         uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
    1409           0 :         i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), rPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, true );
    1410           0 :         if ( aBoundary.startPos >= rPaM.GetIndex() )
    1411           0 :             aBoundary = xBI->previousWord( pNode->GetText(), rPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
    1412           0 :         aPaM.GetIndex() = ( aBoundary.startPos != -1 ) ? (sal_uInt16)aBoundary.startPos : 0;
    1413             :     }
    1414           0 :     else if ( aPaM.GetPara() )
    1415             :     {
    1416           0 :         aPaM.GetPara()--;
    1417           0 :         TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ];
    1418           0 :         aPaM.GetIndex() = pNode->GetText().getLength();
    1419             :     }
    1420           0 :     return aPaM;
    1421             : }
    1422             : 
    1423           0 : TextPaM TextView::CursorWordRight( const TextPaM& rPaM )
    1424             : {
    1425           0 :     TextPaM aPaM( rPaM );
    1426             : 
    1427           0 :     TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ];
    1428           0 :     if ( aPaM.GetIndex() < pNode->GetText().getLength() )
    1429             :     {
    1430           0 :         uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
    1431           0 :         i18n::Boundary aBoundary = xBI->nextWord(  pNode->GetText(), aPaM.GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
    1432           0 :         aPaM.GetIndex() = (sal_uInt16)aBoundary.startPos;
    1433             :     }
    1434           0 :     else if ( aPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().size()-1) )
    1435             :     {
    1436           0 :         aPaM.GetPara()++;
    1437           0 :         aPaM.GetIndex() = 0;
    1438             :     }
    1439             : 
    1440           0 :     return aPaM;
    1441             : }
    1442             : 
    1443           0 : TextPaM TextView::ImpDelete( sal_uInt8 nMode, sal_uInt8 nDelMode )
    1444             : {
    1445           0 :     if ( mpImpl->maSelection.HasRange() )  // only delete selection
    1446           0 :         return mpImpl->mpTextEngine->ImpDeleteText( mpImpl->maSelection );
    1447             : 
    1448           0 :     TextPaM aStartPaM = mpImpl->maSelection.GetStart();
    1449           0 :     TextPaM aEndPaM = aStartPaM;
    1450           0 :     if ( nMode == DEL_LEFT )
    1451             :     {
    1452           0 :         if ( nDelMode == DELMODE_SIMPLE )
    1453             :         {
    1454           0 :             aEndPaM = CursorLeft( aEndPaM, (sal_uInt16)i18n::CharacterIteratorMode::SKIPCHARACTER );
    1455             :         }
    1456           0 :         else if ( nDelMode == DELMODE_RESTOFWORD )
    1457             :         {
    1458           0 :             TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[  aEndPaM.GetPara() ];
    1459           0 :             uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
    1460           0 :             i18n::Boundary aBoundary = xBI->getWordBoundary( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, true );
    1461           0 :             if ( aBoundary.startPos == mpImpl->maSelection.GetEnd().GetIndex() )
    1462           0 :                 aBoundary = xBI->previousWord( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
    1463             :             // #i63506# startPos is -1 when the paragraph starts with a tab
    1464           0 :             aEndPaM.GetIndex() = (aBoundary.startPos >= 0) ? (sal_uInt16)aBoundary.startPos : 0;
    1465             :         }
    1466             :         else    // DELMODE_RESTOFCONTENT
    1467             :         {
    1468           0 :             if ( aEndPaM.GetIndex() != 0 )
    1469           0 :                 aEndPaM.GetIndex() = 0;
    1470           0 :             else if ( aEndPaM.GetPara() )
    1471             :             {
    1472             :                 // previous paragraph
    1473           0 :                 aEndPaM.GetPara()--;
    1474           0 :                 aEndPaM.GetIndex() = 0;
    1475             :             }
    1476             :         }
    1477             :     }
    1478             :     else
    1479             :     {
    1480           0 :         if ( nDelMode == DELMODE_SIMPLE )
    1481             :         {
    1482           0 :             aEndPaM = CursorRight( aEndPaM, (sal_uInt16)i18n::CharacterIteratorMode::SKIPCELL );
    1483             :         }
    1484           0 :         else if ( nDelMode == DELMODE_RESTOFWORD )
    1485             :         {
    1486           0 :             TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[  aEndPaM.GetPara() ];
    1487           0 :             uno::Reference < i18n::XBreakIterator > xBI = mpImpl->mpTextEngine->GetBreakIterator();
    1488           0 :             i18n::Boundary aBoundary = xBI->nextWord( pNode->GetText(), mpImpl->maSelection.GetEnd().GetIndex(), mpImpl->mpTextEngine->GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
    1489           0 :             aEndPaM.GetIndex() = (sal_uInt16)aBoundary.startPos;
    1490             :         }
    1491             :         else    // DELMODE_RESTOFCONTENT
    1492             :         {
    1493           0 :             TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aEndPaM.GetPara() ];
    1494           0 :             if ( aEndPaM.GetIndex() < pNode->GetText().getLength() )
    1495           0 :                 aEndPaM.GetIndex() = pNode->GetText().getLength();
    1496           0 :             else if ( aEndPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().size() - 1 ) )
    1497             :             {
    1498             :                 // next paragraph
    1499           0 :                 aEndPaM.GetPara()++;
    1500           0 :                 TextNode* pNextNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aEndPaM.GetPara() ];
    1501           0 :                 aEndPaM.GetIndex() = pNextNode->GetText().getLength();
    1502             :             }
    1503             :         }
    1504             :     }
    1505             : 
    1506           0 :     return mpImpl->mpTextEngine->ImpDeleteText( TextSelection( aStartPaM, aEndPaM ) );
    1507             : }
    1508             : 
    1509           0 : TextPaM TextView::CursorUp( const TextPaM& rPaM )
    1510             : {
    1511           0 :     TextPaM aPaM( rPaM );
    1512             : 
    1513             :     long nX;
    1514           0 :     if ( mpImpl->mnTravelXPos == TRAVEL_X_DONTKNOW )
    1515             :     {
    1516           0 :         nX = mpImpl->mpTextEngine->GetEditCursor( rPaM, false ).Left();
    1517           0 :         mpImpl->mnTravelXPos = (sal_uInt16)nX+1;
    1518             :     }
    1519             :     else
    1520           0 :         nX = mpImpl->mnTravelXPos;
    1521             : 
    1522           0 :     TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
    1523           0 :     sal_uInt16 nLine = pPPortion->GetLineNumber( rPaM.GetIndex(), false );
    1524           0 :     if ( nLine )    // same paragraph
    1525             :     {
    1526           0 :         sal_uInt16 nCharPos = mpImpl->mpTextEngine->GetCharPos( rPaM.GetPara(), nLine-1, nX );
    1527           0 :         aPaM.GetIndex() = nCharPos;
    1528             :         // If we need to go to the end of a line that was wrapped automatically,
    1529             :         // the cursor ends up at the beginning of the 2nd line
    1530             :         // Problem: Last character of an automatically wrapped line = Cursor
    1531           0 :         TextLine& pLine = pPPortion->GetLines()[ nLine - 1 ];
    1532           0 :         if ( aPaM.GetIndex() && ( aPaM.GetIndex() == pLine.GetEnd() ) )
    1533           0 :             aPaM.GetIndex()--;
    1534             :     }
    1535           0 :     else if ( rPaM.GetPara() )  // previous paragraph
    1536             :     {
    1537           0 :         aPaM.GetPara()--;
    1538           0 :         pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
    1539           0 :         sal_uInt16 nL = pPPortion->GetLines().size() - 1;
    1540           0 :         sal_uInt16 nCharPos = mpImpl->mpTextEngine->GetCharPos( aPaM.GetPara(), nL, nX+1 );
    1541           0 :         aPaM.GetIndex() = nCharPos;
    1542             :     }
    1543             : 
    1544           0 :     return aPaM;
    1545             : }
    1546             : 
    1547           0 : TextPaM TextView::CursorDown( const TextPaM& rPaM )
    1548             : {
    1549           0 :     TextPaM aPaM( rPaM );
    1550             : 
    1551             :     long nX;
    1552           0 :     if ( mpImpl->mnTravelXPos == TRAVEL_X_DONTKNOW )
    1553             :     {
    1554           0 :         nX = mpImpl->mpTextEngine->GetEditCursor( rPaM, false ).Left();
    1555           0 :         mpImpl->mnTravelXPos = (sal_uInt16)nX+1;
    1556             :     }
    1557             :     else
    1558           0 :         nX = mpImpl->mnTravelXPos;
    1559             : 
    1560           0 :     TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
    1561           0 :     sal_uInt16 nLine = pPPortion->GetLineNumber( rPaM.GetIndex(), false );
    1562           0 :     if ( nLine < ( pPPortion->GetLines().size() - 1 ) )
    1563             :     {
    1564           0 :         sal_uInt16 nCharPos = mpImpl->mpTextEngine->GetCharPos( rPaM.GetPara(), nLine+1, nX );
    1565           0 :         aPaM.GetIndex() = nCharPos;
    1566             : 
    1567             :         // special case CursorUp
    1568           0 :         TextLine& pLine = pPPortion->GetLines()[ nLine + 1 ];
    1569           0 :         if ( ( aPaM.GetIndex() == pLine.GetEnd() ) && ( aPaM.GetIndex() > pLine.GetStart() ) && aPaM.GetIndex() < pPPortion->GetNode()->GetText().getLength() )
    1570           0 :             aPaM.GetIndex()--;
    1571             :     }
    1572           0 :     else if ( rPaM.GetPara() < ( mpImpl->mpTextEngine->mpDoc->GetNodes().size() - 1 ) )   // next paragraph
    1573             :     {
    1574           0 :         aPaM.GetPara()++;
    1575           0 :         pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
    1576           0 :         sal_uInt16 nCharPos = mpImpl->mpTextEngine->GetCharPos( aPaM.GetPara(), 0, nX+1 );
    1577           0 :         aPaM.GetIndex() = nCharPos;
    1578           0 :         TextLine& pLine = pPPortion->GetLines().front();
    1579           0 :         if ( ( aPaM.GetIndex() == pLine.GetEnd() ) && ( aPaM.GetIndex() > pLine.GetStart() ) && ( pPPortion->GetLines().size() > 1 ) )
    1580           0 :             aPaM.GetIndex()--;
    1581             :     }
    1582             : 
    1583           0 :     return aPaM;
    1584             : }
    1585             : 
    1586           0 : TextPaM TextView::CursorStartOfLine( const TextPaM& rPaM )
    1587             : {
    1588           0 :     TextPaM aPaM( rPaM );
    1589             : 
    1590           0 :     TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
    1591           0 :     sal_uInt16 nLine = pPPortion->GetLineNumber( aPaM.GetIndex(), false );
    1592           0 :     TextLine& pLine = pPPortion->GetLines()[ nLine ];
    1593           0 :     aPaM.GetIndex() = pLine.GetStart();
    1594             : 
    1595           0 :     return aPaM;
    1596             : }
    1597             : 
    1598           0 : TextPaM TextView::CursorEndOfLine( const TextPaM& rPaM )
    1599             : {
    1600           0 :     TextPaM aPaM( rPaM );
    1601             : 
    1602           0 :     TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( rPaM.GetPara() );
    1603           0 :     sal_uInt16 nLine = pPPortion->GetLineNumber( aPaM.GetIndex(), false );
    1604           0 :     TextLine& pLine = pPPortion->GetLines()[ nLine ];
    1605           0 :     aPaM.GetIndex() = pLine.GetEnd();
    1606             : 
    1607           0 :     if ( pLine.GetEnd() > pLine.GetStart() )  // empty line
    1608             :     {
    1609           0 :         sal_Unicode cLastChar = pPPortion->GetNode()->GetText()[ aPaM.GetIndex()-1 ];
    1610           0 :         if ( ( cLastChar == ' ' ) && ( aPaM.GetIndex() != pPPortion->GetNode()->GetText().getLength() ) )
    1611             :         {
    1612             :             // for a blank in an automatically-wrapped line it is better to stand before it,
    1613             :             // as the user will intend to stand behind the prior word.
    1614             :             // If there is a change, special case for Pos1 after End!
    1615           0 :             aPaM.GetIndex()--;
    1616             :         }
    1617             :     }
    1618           0 :     return aPaM;
    1619             : }
    1620             : 
    1621           0 : TextPaM TextView::CursorStartOfParagraph( const TextPaM& rPaM )
    1622             : {
    1623           0 :     TextPaM aPaM( rPaM );
    1624           0 :     aPaM.GetIndex() = 0;
    1625           0 :     return aPaM;
    1626             : }
    1627             : 
    1628           0 : TextPaM TextView::CursorEndOfParagraph( const TextPaM& rPaM )
    1629             : {
    1630           0 :     TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ rPaM.GetPara() ];
    1631           0 :     TextPaM aPaM( rPaM );
    1632           0 :     aPaM.GetIndex() = pNode->GetText().getLength();
    1633           0 :     return aPaM;
    1634             : }
    1635             : 
    1636           0 : TextPaM TextView::CursorStartOfDoc()
    1637             : {
    1638           0 :     TextPaM aPaM( 0, 0 );
    1639           0 :     return aPaM;
    1640             : }
    1641             : 
    1642           0 : TextPaM TextView::CursorEndOfDoc()
    1643             : {
    1644           0 :     sal_uLong nNode = mpImpl->mpTextEngine->mpDoc->GetNodes().size() - 1;
    1645           0 :     TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ nNode ];
    1646           0 :     TextPaM aPaM( nNode, pNode->GetText().getLength() );
    1647           0 :     return aPaM;
    1648             : }
    1649             : 
    1650           0 : TextPaM TextView::PageUp( const TextPaM& rPaM )
    1651             : {
    1652           0 :     Rectangle aRect = mpImpl->mpTextEngine->PaMtoEditCursor( rPaM );
    1653           0 :     Point aTopLeft = aRect.TopLeft();
    1654           0 :     aTopLeft.Y() -= mpImpl->mpWindow->GetOutputSizePixel().Height() * 9/10;
    1655           0 :     aTopLeft.X() += 1;
    1656           0 :     if ( aTopLeft.Y() < 0 )
    1657           0 :         aTopLeft.Y() = 0;
    1658             : 
    1659           0 :     TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aTopLeft );
    1660           0 :     return aPaM;
    1661             : }
    1662             : 
    1663           0 : TextPaM TextView::PageDown( const TextPaM& rPaM )
    1664             : {
    1665           0 :     Rectangle aRect = mpImpl->mpTextEngine->PaMtoEditCursor( rPaM );
    1666           0 :     Point aBottomRight = aRect.BottomRight();
    1667           0 :     aBottomRight.Y() += mpImpl->mpWindow->GetOutputSizePixel().Height() * 9/10;
    1668           0 :     aBottomRight.X() += 1;
    1669           0 :     long nHeight = mpImpl->mpTextEngine->GetTextHeight();
    1670           0 :     if ( aBottomRight.Y() > nHeight )
    1671           0 :         aBottomRight.Y() = nHeight-1;
    1672             : 
    1673           0 :     TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aBottomRight );
    1674           0 :     return aPaM;
    1675             : }
    1676             : 
    1677         250 : void TextView::ImpShowCursor( bool bGotoCursor, bool bForceVisCursor, bool bSpecial )
    1678             : {
    1679         250 :     if ( mpImpl->mpTextEngine->IsFormatting() )
    1680           0 :         return;
    1681         250 :     if ( !mpImpl->mpTextEngine->GetUpdateMode() )
    1682           0 :         return;
    1683         250 :     if ( mpImpl->mpTextEngine->IsInUndo() )
    1684           0 :         return;
    1685             : 
    1686         250 :     mpImpl->mpTextEngine->CheckIdleFormatter();
    1687         250 :     if ( !mpImpl->mpTextEngine->IsFormatted() )
    1688           0 :         mpImpl->mpTextEngine->FormatAndUpdate( this );
    1689             : 
    1690         250 :     TextPaM aPaM( mpImpl->maSelection.GetEnd() );
    1691         250 :     Rectangle aEditCursor = mpImpl->mpTextEngine->PaMtoEditCursor( aPaM, bSpecial );
    1692             : 
    1693             :     // Remember that we placed the cursor behind the last character of a line
    1694         250 :     mpImpl->mbCursorAtEndOfLine = false;
    1695         250 :     if( bSpecial )
    1696             :     {
    1697           0 :         TEParaPortion* pParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
    1698             :         mpImpl->mbCursorAtEndOfLine =
    1699           0 :             pParaPortion->GetLineNumber( aPaM.GetIndex(), true ) != pParaPortion->GetLineNumber( aPaM.GetIndex(), false );
    1700             :     }
    1701             : 
    1702         250 :     if ( !IsInsertMode() && !mpImpl->maSelection.HasRange() )
    1703             :     {
    1704           0 :         TextNode* pNode = mpImpl->mpTextEngine->mpDoc->GetNodes()[ aPaM.GetPara() ];
    1705           0 :         if ( !pNode->GetText().isEmpty() && ( aPaM.GetIndex() < pNode->GetText().getLength() ) )
    1706             :         {
    1707             :             // If we are behind a portion, and the next portion has other direction, we must change position...
    1708           0 :             aEditCursor.Left() = aEditCursor.Right() = mpImpl->mpTextEngine->GetEditCursor( aPaM, false, true ).Left();
    1709             : 
    1710           0 :             TEParaPortion* pParaPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
    1711             : 
    1712           0 :             sal_uInt16 nTextPortionStart = 0;
    1713           0 :             sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, true );
    1714           0 :             TETextPortion* pTextPortion = pParaPortion->GetTextPortions()[ nTextPortion ];
    1715           0 :             if ( pTextPortion->GetKind() == PORTIONKIND_TAB )
    1716             :             {
    1717           0 :                 if ( mpImpl->mpTextEngine->IsRightToLeft() )
    1718             :                 {
    1719             : 
    1720             :                 }
    1721           0 :                 aEditCursor.Right() += pTextPortion->GetWidth();
    1722             :             }
    1723             :             else
    1724             :             {
    1725           0 :                 TextPaM aNext = CursorRight( TextPaM( aPaM.GetPara(), aPaM.GetIndex() ), (sal_uInt16)i18n::CharacterIteratorMode::SKIPCELL );
    1726           0 :                 aEditCursor.Right() = mpImpl->mpTextEngine->GetEditCursor( aNext, true ).Left();
    1727             :             }
    1728             :         }
    1729             :     }
    1730             : 
    1731         250 :     Size aOutSz = mpImpl->mpWindow->GetOutputSizePixel();
    1732         250 :     if ( aEditCursor.GetHeight() > aOutSz.Height() )
    1733         144 :         aEditCursor.Bottom() = aEditCursor.Top() + aOutSz.Height() - 1;
    1734             : 
    1735         250 :     aEditCursor.Left() -= 1;
    1736             : 
    1737         250 :     if ( bGotoCursor
    1738             :         // #i81283# protext maStartDocPos against initialization problems
    1739         250 :         && aOutSz.Width() && aOutSz.Height()
    1740             :     )
    1741             :     {
    1742         106 :         long nVisStartY = mpImpl->maStartDocPos.Y();
    1743         106 :         long nVisEndY = mpImpl->maStartDocPos.Y() + aOutSz.Height();
    1744         106 :         long nVisStartX = mpImpl->maStartDocPos.X();
    1745         106 :         long nVisEndX = mpImpl->maStartDocPos.X() + aOutSz.Width();
    1746         106 :         long nMoreX = aOutSz.Width() / 4;
    1747             : 
    1748         106 :         Point aNewStartPos( mpImpl->maStartDocPos );
    1749             : 
    1750         106 :         if ( aEditCursor.Bottom() > nVisEndY )
    1751             :         {
    1752           0 :             aNewStartPos.Y() += ( aEditCursor.Bottom() - nVisEndY );
    1753             :         }
    1754         106 :         else if ( aEditCursor.Top() < nVisStartY )
    1755             :         {
    1756           0 :             aNewStartPos.Y() -= ( nVisStartY - aEditCursor.Top() );
    1757             :         }
    1758             : 
    1759         106 :         if ( aEditCursor.Right() >= nVisEndX )
    1760             :         {
    1761           0 :             aNewStartPos.X() += ( aEditCursor.Right() - nVisEndX );
    1762             : 
    1763             :             // do you want some more?
    1764           0 :             aNewStartPos.X() += nMoreX;
    1765             :         }
    1766         106 :         else if ( aEditCursor.Left() <= nVisStartX )
    1767             :         {
    1768         103 :             aNewStartPos.X() -= ( nVisStartX - aEditCursor.Left() );
    1769             : 
    1770             :             // do you want some more?
    1771         103 :             aNewStartPos.X() -= nMoreX;
    1772             :         }
    1773             : 
    1774             :         // X can be wrong for the 'some more' above:
    1775             : //      sal_uLong nMaxTextWidth = mpImpl->mpTextEngine->GetMaxTextWidth();
    1776             : //      if ( !nMaxTextWidth || ( nMaxTextWidth > 0x7FFFFFFF ) )
    1777             : //          nMaxTextWidth = 0x7FFFFFFF;
    1778             : //      long nMaxX = (long)nMaxTextWidth - aOutSz.Width();
    1779         106 :         long nMaxX = mpImpl->mpTextEngine->CalcTextWidth() - aOutSz.Width();
    1780         106 :         if ( nMaxX < 0 )
    1781         106 :             nMaxX = 0;
    1782             : 
    1783         106 :         if ( aNewStartPos.X() < 0 )
    1784         103 :             aNewStartPos.X() = 0;
    1785           3 :         else if ( aNewStartPos.X() > nMaxX )
    1786           0 :             aNewStartPos.X() = nMaxX;
    1787             : 
    1788             :         // Y should not be further down than needed
    1789         106 :         long nYMax = mpImpl->mpTextEngine->GetTextHeight() - aOutSz.Height();
    1790         106 :         if ( nYMax < 0 )
    1791         106 :             nYMax = 0;
    1792         106 :         if ( aNewStartPos.Y() > nYMax )
    1793           0 :             aNewStartPos.Y() = nYMax;
    1794             : 
    1795         106 :         if ( aNewStartPos != mpImpl->maStartDocPos )
    1796           0 :             Scroll( -(aNewStartPos.X() - mpImpl->maStartDocPos.X()), -(aNewStartPos.Y() - mpImpl->maStartDocPos.Y()) );
    1797             :     }
    1798             : 
    1799         250 :     if ( aEditCursor.Right() < aEditCursor.Left() )
    1800             :     {
    1801           0 :         long n = aEditCursor.Left();
    1802           0 :         aEditCursor.Left() = aEditCursor.Right();
    1803           0 :         aEditCursor.Right() = n;
    1804             :     }
    1805             : 
    1806         250 :     Point aPoint( GetWindowPos( !mpImpl->mpTextEngine->IsRightToLeft() ? aEditCursor.TopLeft() : aEditCursor.TopRight() ) );
    1807         250 :     mpImpl->mpCursor->SetPos( aPoint );
    1808         250 :     mpImpl->mpCursor->SetSize( aEditCursor.GetSize() );
    1809         250 :     if ( bForceVisCursor && mpImpl->mbCursorEnabled )
    1810         250 :         mpImpl->mpCursor->Show();
    1811             : }
    1812             : 
    1813           0 : bool TextView::SetCursorAtPoint( const Point& rPosPixel )
    1814             : {
    1815           0 :     mpImpl->mpTextEngine->CheckIdleFormatter();
    1816             : 
    1817           0 :     Point aDocPos = GetDocPos( rPosPixel );
    1818             : 
    1819           0 :     TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aDocPos );
    1820             : 
    1821             :     // aTmpNewSel: Diff between old and new; not the new selection
    1822           0 :     TextSelection aTmpNewSel( mpImpl->maSelection.GetEnd(), aPaM );
    1823           0 :     TextSelection aNewSel( mpImpl->maSelection );
    1824           0 :     aNewSel.GetEnd() = aPaM;
    1825             : 
    1826           0 :     if ( !mpImpl->mpSelEngine->HasAnchor() )
    1827             :     {
    1828           0 :         if ( mpImpl->maSelection.GetStart() != aPaM )
    1829           0 :             mpImpl->mpTextEngine->CursorMoved( mpImpl->maSelection.GetStart().GetPara() );
    1830           0 :         aNewSel.GetStart() = aPaM;
    1831           0 :         ImpSetSelection( aNewSel );
    1832             :     }
    1833             :     else
    1834             :     {
    1835           0 :         ImpSetSelection( aNewSel );
    1836           0 :         ShowSelection( aTmpNewSel );
    1837             :     }
    1838             : 
    1839           0 :     bool bForceCursor =  mpImpl->mpDDInfo == nullptr; // && !mbInSelection
    1840           0 :     ImpShowCursor( mpImpl->mbAutoScroll, bForceCursor, false );
    1841           0 :     return true;
    1842             : }
    1843             : 
    1844           0 : bool TextView::IsSelectionAtPoint( const Point& rPosPixel )
    1845             : {
    1846             : //  if ( !Rectangle( Point(), mpImpl->mpWindow->GetOutputSizePixel() ).IsInside( rPosPixel ) && !mbInSelection )
    1847             : //      return false;
    1848             : 
    1849           0 :     Point aDocPos = GetDocPos( rPosPixel );
    1850           0 :     TextPaM aPaM = mpImpl->mpTextEngine->GetPaM( aDocPos, false );
    1851             :     // For Hyperlinks D&D also start w/o a selection.
    1852             :     // BeginDrag is only called, however, if IsSelectionAtPoint()
    1853             :     // Problem: IsSelectionAtPoint is not called by Command()
    1854             :     // if before MBDown returned false.
    1855           0 :     return ( IsInSelection( aPaM ) ||
    1856           0 :             ( /* mpImpl->mpSelEngine->IsInCommand() && */ mpImpl->mpTextEngine->FindAttrib( aPaM, TEXTATTR_HYPERLINK ) ) );
    1857             : }
    1858             : 
    1859           0 : bool TextView::IsInSelection( const TextPaM& rPaM )
    1860             : {
    1861           0 :     TextSelection aSel = mpImpl->maSelection;
    1862           0 :     aSel.Justify();
    1863             : 
    1864           0 :     sal_uLong nStartNode = aSel.GetStart().GetPara();
    1865           0 :     sal_uLong nEndNode = aSel.GetEnd().GetPara();
    1866           0 :     sal_uLong nCurNode = rPaM.GetPara();
    1867             : 
    1868           0 :     if ( ( nCurNode > nStartNode ) && ( nCurNode < nEndNode ) )
    1869           0 :         return true;
    1870             : 
    1871           0 :     if ( nStartNode == nEndNode )
    1872             :     {
    1873           0 :         if ( nCurNode == nStartNode )
    1874           0 :             if ( ( rPaM.GetIndex() >= aSel.GetStart().GetIndex() ) && ( rPaM.GetIndex() < aSel.GetEnd().GetIndex() ) )
    1875           0 :                 return true;
    1876             :     }
    1877           0 :     else if ( ( nCurNode == nStartNode ) && ( rPaM.GetIndex() >= aSel.GetStart().GetIndex() ) )
    1878           0 :         return true;
    1879           0 :     else if ( ( nCurNode == nEndNode ) && ( rPaM.GetIndex() < aSel.GetEnd().GetIndex() ) )
    1880           0 :         return true;
    1881             : 
    1882           0 :     return false;
    1883             : }
    1884             : 
    1885           0 : void TextView::ImpHideDDCursor()
    1886             : {
    1887           0 :     if ( mpImpl->mpDDInfo && mpImpl->mpDDInfo->mbVisCursor )
    1888             :     {
    1889           0 :         mpImpl->mpDDInfo->maCursor.Hide();
    1890           0 :         mpImpl->mpDDInfo->mbVisCursor = false;
    1891             :     }
    1892           0 : }
    1893             : 
    1894           0 : void TextView::ImpShowDDCursor()
    1895             : {
    1896           0 :     if ( !mpImpl->mpDDInfo->mbVisCursor )
    1897             :     {
    1898           0 :         Rectangle aCursor = mpImpl->mpTextEngine->PaMtoEditCursor( mpImpl->mpDDInfo->maDropPos, true );
    1899           0 :         aCursor.Right()++;
    1900           0 :         aCursor.SetPos( GetWindowPos( aCursor.TopLeft() ) );
    1901             : 
    1902           0 :         mpImpl->mpDDInfo->maCursor.SetWindow( mpImpl->mpWindow );
    1903           0 :         mpImpl->mpDDInfo->maCursor.SetPos( aCursor.TopLeft() );
    1904           0 :         mpImpl->mpDDInfo->maCursor.SetSize( aCursor.GetSize() );
    1905           0 :         mpImpl->mpDDInfo->maCursor.Show();
    1906           0 :         mpImpl->mpDDInfo->mbVisCursor = true;
    1907             :     }
    1908           0 : }
    1909             : 
    1910           0 : void TextView::SetPaintSelection( bool bPaint )
    1911             : {
    1912           0 :     if ( bPaint != mpImpl->mbPaintSelection )
    1913             :     {
    1914           0 :         mpImpl->mbPaintSelection = bPaint;
    1915           0 :         ShowSelection( mpImpl->maSelection );
    1916             :     }
    1917           0 : }
    1918             : 
    1919           0 : bool TextView::Read( SvStream& rInput )
    1920             : {
    1921           0 :     bool bDone = mpImpl->mpTextEngine->Read( rInput, &mpImpl->maSelection );
    1922           0 :     ShowCursor();
    1923           0 :     return bDone;
    1924             : }
    1925             : 
    1926           0 : bool TextView::ImplTruncateNewText( OUString& rNewText ) const
    1927             : {
    1928           0 :     bool bTruncated = false;
    1929             : 
    1930           0 :     sal_uLong nMaxLen = mpImpl->mpTextEngine->GetMaxTextLen();
    1931             :     // 0 means unlimited
    1932           0 :     if( nMaxLen != 0 )
    1933             :     {
    1934           0 :         sal_uLong nCurLen = mpImpl->mpTextEngine->GetTextLen();
    1935             : 
    1936           0 :         sal_uInt32 nNewLen = rNewText.getLength();
    1937           0 :         if ( nCurLen + nNewLen > nMaxLen )
    1938             :         {
    1939             :             // see how much text will be replaced
    1940           0 :             sal_uLong nSelLen = mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection );
    1941           0 :             if ( nCurLen + nNewLen - nSelLen > nMaxLen )
    1942             :             {
    1943           0 :                 sal_uInt32 nTruncatedLen = static_cast<sal_uInt32>(nMaxLen - (nCurLen - nSelLen));
    1944           0 :                 rNewText = rNewText.copy( 0, nTruncatedLen );
    1945           0 :                 bTruncated = true;
    1946             :             }
    1947             :         }
    1948             :     }
    1949           0 :     return bTruncated;
    1950             : }
    1951             : 
    1952           0 : bool TextView::ImplCheckTextLen( const OUString& rNewText )
    1953             : {
    1954           0 :     bool bOK = true;
    1955           0 :     if ( mpImpl->mpTextEngine->GetMaxTextLen() )
    1956             :     {
    1957           0 :         sal_uLong n = mpImpl->mpTextEngine->GetTextLen();
    1958           0 :         n += rNewText.getLength();
    1959           0 :         if ( n > mpImpl->mpTextEngine->GetMaxTextLen() )
    1960             :         {
    1961             :             // calculate how much text is being deleted
    1962           0 :             n -= mpImpl->mpTextEngine->GetTextLen( mpImpl->maSelection );
    1963           0 :             if ( n > mpImpl->mpTextEngine->GetMaxTextLen() )
    1964           0 :                 bOK = false;
    1965             :         }
    1966             :     }
    1967           0 :     return bOK;
    1968             : }
    1969             : 
    1970           0 : void TextView::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& rDGE ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    1971             : {
    1972           0 :     if ( mpImpl->mbClickedInSelection )
    1973             :     {
    1974           0 :         SolarMutexGuard aVclGuard;
    1975             : 
    1976             :         DBG_ASSERT( mpImpl->maSelection.HasRange(), "TextView::dragGestureRecognized: mpImpl->mbClickedInSelection, but no selection?" );
    1977             : 
    1978           0 :         delete mpImpl->mpDDInfo;
    1979           0 :         mpImpl->mpDDInfo = new TextDDInfo;
    1980           0 :         mpImpl->mpDDInfo->mbStarterOfDD = true;
    1981             : 
    1982           0 :         TETextDataObject* pDataObj = new TETextDataObject( GetSelected() );
    1983             : 
    1984           0 :         if ( mpImpl->mpTextEngine->HasAttrib( TEXTATTR_HYPERLINK ) )  // then also as HTML
    1985           0 :             mpImpl->mpTextEngine->Write( pDataObj->GetHTMLStream(), &mpImpl->maSelection, true );
    1986             : 
    1987             :         /*
    1988             :         // D&D of a Hyperlink
    1989             :         // TODO: Better would be to store MBDownPaM in MBDown,
    1990             :         // but this would be incompatible => change later
    1991             :         TextPaM aPaM( mpImpl->mpTextEngine->GetPaM( GetDocPos( GetWindow()->GetPointerPosPixel() ) ) );
    1992             :         const TextCharAttrib* pAttr = mpImpl->mpTextEngine->FindCharAttrib( aPaM, TEXTATTR_HYPERLINK );
    1993             :         if ( pAttr )
    1994             :         {
    1995             :             aSel = aPaM;
    1996             :             aSel.GetStart().GetIndex() = pAttr->GetStart();
    1997             :             aSel.GetEnd().GetIndex() = pAttr->GetEnd();
    1998             : 
    1999             :             const TextAttribHyperLink& rLink = (const TextAttribHyperLink&)pAttr->GetAttr();
    2000             :             String aText( rLink.GetDescription() );
    2001             :             if ( !aText.Len() )
    2002             :                 aText = mpImpl->mpTextEngine->GetText( aSel );
    2003             :             INetBookmark aBookmark( rLink.GetURL(), aText );
    2004             :             aBookmark.CopyDragServer();
    2005             :         }
    2006             :         */
    2007             : 
    2008           0 :         mpImpl->mpCursor->Hide();
    2009             : 
    2010           0 :         sal_Int8 nActions = datatransfer::dnd::DNDConstants::ACTION_COPY;
    2011           0 :         if ( !IsReadOnly() )
    2012           0 :             nActions |= datatransfer::dnd::DNDConstants::ACTION_MOVE;
    2013           0 :         rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, pDataObj, mpImpl->mxDnDListener );
    2014             :     }
    2015           0 : }
    2016             : 
    2017           0 : void TextView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    2018             : {
    2019           0 :     ImpHideDDCursor();
    2020           0 :     delete mpImpl->mpDDInfo;
    2021           0 :     mpImpl->mpDDInfo = NULL;
    2022           0 : }
    2023             : 
    2024           0 : void TextView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    2025             : {
    2026           0 :     SolarMutexGuard aVclGuard;
    2027             : 
    2028           0 :     bool bChanges = false;
    2029           0 :     if ( !mpImpl->mbReadOnly && mpImpl->mpDDInfo )
    2030             :     {
    2031           0 :         ImpHideDDCursor();
    2032             : 
    2033             :         // Data for deleting after DROP_MOVE:
    2034           0 :         TextSelection aPrevSel( mpImpl->maSelection );
    2035           0 :         aPrevSel.Justify();
    2036           0 :         sal_uLong nPrevParaCount = mpImpl->mpTextEngine->GetParagraphCount();
    2037           0 :         sal_uInt16 nPrevStartParaLen = mpImpl->mpTextEngine->GetTextLen( aPrevSel.GetStart().GetPara() );
    2038             : 
    2039           0 :         bool bStarterOfDD = false;
    2040           0 :         for ( sal_uInt16 nView = mpImpl->mpTextEngine->GetViewCount(); nView && !bStarterOfDD; )
    2041           0 :             bStarterOfDD = mpImpl->mpTextEngine->GetView( --nView )->mpImpl->mpDDInfo && mpImpl->mpTextEngine->GetView( nView )->mpImpl->mpDDInfo->mbStarterOfDD;
    2042             : 
    2043           0 :         HideSelection();
    2044           0 :         ImpSetSelection( mpImpl->mpDDInfo->maDropPos );
    2045             : 
    2046           0 :         mpImpl->mpTextEngine->UndoActionStart();
    2047             : 
    2048           0 :         OUString aText;
    2049           0 :         uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
    2050           0 :         if ( xDataObj.is() )
    2051             :         {
    2052           0 :             datatransfer::DataFlavor aFlavor;
    2053           0 :             SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
    2054           0 :             if ( xDataObj->isDataFlavorSupported( aFlavor ) )
    2055             :             {
    2056           0 :                 uno::Any aData = xDataObj->getTransferData( aFlavor );
    2057           0 :                 OUString aOUString;
    2058           0 :                 aData >>= aOUString;
    2059           0 :                 aText = convertLineEnd(aOUString, LINEEND_LF);
    2060           0 :             }
    2061             :         }
    2062             : 
    2063           0 :         if ( !aText.isEmpty() && ( aText[ aText.getLength()-1 ] == LINE_SEP ) )
    2064           0 :             aText = aText.copy(0, aText.getLength()-1);
    2065             : 
    2066           0 :         TextPaM aTempStart = mpImpl->maSelection.GetStart();
    2067           0 :         if ( ImplCheckTextLen( aText ) )
    2068           0 :             ImpSetSelection( mpImpl->mpTextEngine->ImpInsertText( mpImpl->mpDDInfo->maDropPos, aText ) );
    2069           0 :         if(mpImpl->mbSupportProtectAttribute)
    2070             :         {
    2071             :             mpImpl->mpTextEngine->SetAttrib( TextAttribProtect(),
    2072           0 :                 aTempStart.GetPara(),
    2073           0 :                 aTempStart.GetIndex(),
    2074           0 :                 mpImpl->maSelection.GetEnd().GetIndex(), false );
    2075             :         }
    2076             : 
    2077           0 :         if ( aPrevSel.HasRange() &&
    2078           0 :                 !mpImpl->mbSupportProtectAttribute && // don't remove currently selected element
    2079           0 :                 (( rDTDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE ) || !bStarterOfDD) )
    2080             :         {
    2081             :             // adjust selection if necessary
    2082           0 :             if ( ( mpImpl->mpDDInfo->maDropPos.GetPara() < aPrevSel.GetStart().GetPara() ) ||
    2083           0 :                  ( ( mpImpl->mpDDInfo->maDropPos.GetPara() == aPrevSel.GetStart().GetPara() )
    2084           0 :                         && ( mpImpl->mpDDInfo->maDropPos.GetIndex() < aPrevSel.GetStart().GetIndex() ) ) )
    2085             :             {
    2086             :                 sal_uLong nNewParasBeforeSelection =
    2087           0 :                     mpImpl->mpTextEngine->GetParagraphCount() -    nPrevParaCount;
    2088             : 
    2089           0 :                 aPrevSel.GetStart().GetPara() += nNewParasBeforeSelection;
    2090           0 :                 aPrevSel.GetEnd().GetPara() += nNewParasBeforeSelection;
    2091             : 
    2092           0 :                 if ( mpImpl->mpDDInfo->maDropPos.GetPara() == aPrevSel.GetStart().GetPara() )
    2093             :                 {
    2094             :                     sal_uInt16 nNewChars =
    2095           0 :                         mpImpl->mpTextEngine->GetTextLen( aPrevSel.GetStart().GetPara() ) - nPrevStartParaLen;
    2096             : 
    2097           0 :                     aPrevSel.GetStart().GetIndex() =
    2098           0 :                         aPrevSel.GetStart().GetIndex() + nNewChars;
    2099           0 :                     if ( aPrevSel.GetStart().GetPara() == aPrevSel.GetEnd().GetPara() )
    2100           0 :                         aPrevSel.GetEnd().GetIndex() =
    2101           0 :                             aPrevSel.GetEnd().GetIndex() + nNewChars;
    2102             :                 }
    2103             :             }
    2104             :             else
    2105             :             {
    2106             :                 // adjust current selection
    2107           0 :                 TextPaM aPaM = mpImpl->maSelection.GetStart();
    2108           0 :                 aPaM.GetPara() -= ( aPrevSel.GetEnd().GetPara() - aPrevSel.GetStart().GetPara() );
    2109           0 :                 if ( aPrevSel.GetEnd().GetPara() == mpImpl->mpDDInfo->maDropPos.GetPara() )
    2110             :                 {
    2111           0 :                     aPaM.GetIndex() =
    2112           0 :                         aPaM.GetIndex() - aPrevSel.GetEnd().GetIndex();
    2113           0 :                     if ( aPrevSel.GetStart().GetPara() == mpImpl->mpDDInfo->maDropPos.GetPara() )
    2114           0 :                         aPaM.GetIndex() =
    2115           0 :                             aPaM.GetIndex() + aPrevSel.GetStart().GetIndex();
    2116             :                 }
    2117           0 :                 ImpSetSelection( aPaM );
    2118             : 
    2119             :             }
    2120           0 :             mpImpl->mpTextEngine->ImpDeleteText( aPrevSel );
    2121             :         }
    2122             : 
    2123           0 :         mpImpl->mpTextEngine->UndoActionEnd();
    2124             : 
    2125           0 :         delete mpImpl->mpDDInfo;
    2126           0 :         mpImpl->mpDDInfo = 0;
    2127             : 
    2128           0 :         mpImpl->mpTextEngine->FormatAndUpdate( this );
    2129             : 
    2130           0 :         mpImpl->mpTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
    2131             :     }
    2132           0 :     rDTDE.Context->dropComplete( bChanges );
    2133           0 : }
    2134             : 
    2135           0 : void TextView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    2136             : {
    2137           0 : }
    2138             : 
    2139           0 : void TextView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    2140             : {
    2141           0 :     SolarMutexGuard aVclGuard;
    2142           0 :     ImpHideDDCursor();
    2143           0 : }
    2144             : 
    2145           0 : void TextView::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    2146             : {
    2147           0 :     SolarMutexGuard aVclGuard;
    2148             : 
    2149           0 :     if ( !mpImpl->mpDDInfo )
    2150           0 :         mpImpl->mpDDInfo = new TextDDInfo;
    2151             : 
    2152           0 :     TextPaM aPrevDropPos = mpImpl->mpDDInfo->maDropPos;
    2153           0 :     Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
    2154           0 :     Point aDocPos = GetDocPos( aMousePos );
    2155           0 :     mpImpl->mpDDInfo->maDropPos = mpImpl->mpTextEngine->GetPaM( aDocPos );
    2156             : 
    2157           0 :     bool bProtected = false;
    2158           0 :     if(mpImpl->mbSupportProtectAttribute)
    2159             :     {
    2160             :         const TextCharAttrib* pStartAttr = mpImpl->mpTextEngine->FindCharAttrib(
    2161             :                     mpImpl->mpDDInfo->maDropPos,
    2162           0 :                     TEXTATTR_PROTECTED );
    2163           0 :         bProtected = pStartAttr != 0 &&
    2164           0 :                 pStartAttr->GetStart() != mpImpl->mpDDInfo->maDropPos.GetIndex() &&
    2165           0 :                 pStartAttr->GetEnd() != mpImpl->mpDDInfo->maDropPos.GetIndex();
    2166             :     }
    2167             :     // Don't drop in selection or in read only engine
    2168           0 :     if ( IsReadOnly() || IsInSelection( mpImpl->mpDDInfo->maDropPos ) || bProtected)
    2169             :     {
    2170           0 :         ImpHideDDCursor();
    2171           0 :         rDTDE.Context->rejectDrag();
    2172             :     }
    2173             :     else
    2174             :     {
    2175             :         // delete old Cursor
    2176           0 :         if ( !mpImpl->mpDDInfo->mbVisCursor || ( aPrevDropPos != mpImpl->mpDDInfo->maDropPos ) )
    2177             :         {
    2178           0 :             ImpHideDDCursor();
    2179           0 :             ImpShowDDCursor();
    2180             :         }
    2181           0 :         rDTDE.Context->acceptDrag( rDTDE.DropAction );
    2182           0 :     }
    2183           0 : }
    2184             : 
    2185         100 : Point TextView::ImpGetOutputStartPos( const Point& rStartDocPos ) const
    2186             : {
    2187         100 :     Point aStartPos( -rStartDocPos.X(), -rStartDocPos.Y() );
    2188         100 :     if ( mpImpl->mpTextEngine->IsRightToLeft() )
    2189             :     {
    2190           0 :         Size aSz = mpImpl->mpWindow->GetOutputSizePixel();
    2191           0 :         aStartPos.X() = rStartDocPos.X() + aSz.Width() - 1; // -1: Start is 0
    2192             :     }
    2193         100 :     return aStartPos;
    2194             : }
    2195             : 
    2196           0 : Point TextView::GetDocPos( const Point& rWindowPos ) const
    2197             : {
    2198             :     // Window Position => Document Position
    2199             : 
    2200           0 :     Point aPoint;
    2201             : 
    2202           0 :     aPoint.Y() = rWindowPos.Y() + mpImpl->maStartDocPos.Y();
    2203             : 
    2204           0 :     if ( !mpImpl->mpTextEngine->IsRightToLeft() )
    2205             :     {
    2206           0 :         aPoint.X() = rWindowPos.X() + mpImpl->maStartDocPos.X();
    2207             :     }
    2208             :     else
    2209             :     {
    2210           0 :         Size aSz = mpImpl->mpWindow->GetOutputSizePixel();
    2211           0 :         aPoint.X() = ( aSz.Width() - 1 ) - rWindowPos.X() + mpImpl->maStartDocPos.X();
    2212             :     }
    2213             : 
    2214           0 :     return aPoint;
    2215             : }
    2216             : 
    2217         498 : Point TextView::GetWindowPos( const Point& rDocPos ) const
    2218             : {
    2219             :     // Document Position => Window Position
    2220             : 
    2221         498 :     Point aPoint;
    2222             : 
    2223         498 :     aPoint.Y() = rDocPos.Y() - mpImpl->maStartDocPos.Y();
    2224             : 
    2225         498 :     if ( !mpImpl->mpTextEngine->IsRightToLeft() )
    2226             :     {
    2227         498 :         aPoint.X() = rDocPos.X() - mpImpl->maStartDocPos.X();
    2228             :     }
    2229             :     else
    2230             :     {
    2231           0 :         Size aSz = mpImpl->mpWindow->GetOutputSizePixel();
    2232           0 :         aPoint.X() = ( aSz.Width() - 1 ) - ( rDocPos.X() - mpImpl->maStartDocPos.X() );
    2233             :     }
    2234             : 
    2235         498 :     return aPoint;
    2236             : }
    2237             : 
    2238           0 : sal_Int32 TextView::GetLineNumberOfCursorInSelection() const
    2239             : {
    2240             :  // PROGRESS
    2241           0 :     sal_Int32 nLineNo = -1;
    2242           0 :     if( mpImpl->mbCursorEnabled )
    2243             :     {
    2244           0 :         TextPaM aPaM = GetSelection().GetEnd();
    2245           0 :         TEParaPortion* pPPortion = mpImpl->mpTextEngine->mpTEParaPortions->GetObject( aPaM.GetPara() );
    2246           0 :         nLineNo = pPPortion->GetLineNumber( aPaM.GetIndex(), false );
    2247           0 :         if( mpImpl->mbCursorAtEndOfLine )
    2248           0 :             --nLineNo;
    2249             :     }
    2250           0 :     return nLineNo;
    2251             : }
    2252             : 
    2253             : // (+) class TextSelFunctionSet
    2254             : 
    2255          52 : TextSelFunctionSet::TextSelFunctionSet( TextView* pView )
    2256             : {
    2257          52 :     mpView = pView;
    2258          52 : }
    2259             : 
    2260           0 : void TextSelFunctionSet::BeginDrag()
    2261             : {
    2262           0 : }
    2263             : 
    2264           0 : void TextSelFunctionSet::CreateAnchor()
    2265             : {
    2266             : //  TextSelection aSel( mpView->GetSelection() );
    2267             : //  aSel.GetStart() = aSel.GetEnd();
    2268             : //  mpView->SetSelection( aSel );
    2269             : 
    2270             :     // may not be followed by ShowCursor
    2271           0 :     mpView->HideSelection();
    2272           0 :     mpView->ImpSetSelection( mpView->mpImpl->maSelection.GetEnd() );
    2273           0 : }
    2274             : 
    2275           0 : bool TextSelFunctionSet::SetCursorAtPoint( const Point& rPointPixel, bool )
    2276             : {
    2277           0 :     return mpView->SetCursorAtPoint( rPointPixel );
    2278             : }
    2279             : 
    2280           0 : bool TextSelFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
    2281             : {
    2282           0 :     return mpView->IsSelectionAtPoint( rPointPixel );
    2283             : }
    2284             : 
    2285           0 : void TextSelFunctionSet::DeselectAll()
    2286             : {
    2287           0 :     CreateAnchor();
    2288           0 : }
    2289             : 
    2290           0 : void TextSelFunctionSet::DeselectAtPoint( const Point& )
    2291             : {
    2292             :     // only for multiple selection
    2293           0 : }
    2294             : 
    2295           0 : void TextSelFunctionSet::DestroyAnchor()
    2296             : {
    2297             :     // only for multiple selection
    2298           0 : }
    2299           0 : TextEngine*         TextView::GetTextEngine() const
    2300           0 : { return mpImpl->mpTextEngine; }
    2301         639 : vcl::Window*             TextView::GetWindow() const
    2302         639 : { return mpImpl->mpWindow; }
    2303           7 : void                TextView::EnableCursor( bool bEnable )
    2304           7 : { mpImpl->mbCursorEnabled = bEnable; }
    2305           0 : bool                TextView::IsCursorEnabled() const
    2306           0 : { return mpImpl->mbCursorEnabled; }
    2307           0 : void                TextView::SetStartDocPos( const Point& rPos )
    2308           0 : { mpImpl->maStartDocPos = rPos; }
    2309         713 : const Point&        TextView::GetStartDocPos() const
    2310         713 : { return mpImpl->maStartDocPos; }
    2311           0 : void                TextView::SetAutoIndentMode( bool bAutoIndent )
    2312           0 : { mpImpl->mbAutoIndent = bAutoIndent; }
    2313         241 : bool                TextView::IsReadOnly() const
    2314         241 : { return mpImpl->mbReadOnly; }
    2315           0 : void                TextView::SetAutoScroll( bool bAutoScroll )
    2316           0 : { mpImpl->mbAutoScroll = bAutoScroll; }
    2317           0 : bool                TextView::IsAutoScroll() const
    2318           0 : { return mpImpl->mbAutoScroll; }
    2319           0 : bool                TextView::HasSelection() const
    2320           0 : { return mpImpl->maSelection.HasRange(); }
    2321         250 : bool                TextView::IsInsertMode() const
    2322         250 : { return mpImpl->mbInsertMode; }
    2323           0 : void                TextView::SupportProtectAttribute(bool bSupport)
    2324         801 : { mpImpl->mbSupportProtectAttribute = bSupport;}
    2325             : 
    2326             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11