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