Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/wrkwin.hxx>
21 : #include <vcl/dialog.hxx>
22 : #include <vcl/msgbox.hxx>
23 : #include <vcl/svapp.hxx>
24 : #include <impedit.hxx>
25 : #include <editeng/editeng.hxx>
26 : #include <editeng/editview.hxx>
27 : #include <tools/poly.hxx>
28 : #include <editeng/unolingu.hxx>
29 : #include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
30 : #include <com/sun/star/linguistic2/DictionaryType.hpp>
31 : #include <com/sun/star/linguistic2/DictionaryEvent.hpp>
32 : #include <com/sun/star/linguistic2/XDictionaryEventListener.hpp>
33 : #include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
34 : #include <com/sun/star/linguistic2/XDictionary.hpp>
35 : #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
36 : #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
37 : #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
38 : #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
39 : #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
40 : #include <osl/mutex.hxx>
41 : #include <editeng/flditem.hxx>
42 : #include <svl/intitem.hxx>
43 : #include <svtools/transfer.hxx>
44 : #include <sot/exchange.hxx>
45 : #include <sot/formats.hxx>
46 :
47 :
48 : using namespace ::com::sun::star;
49 : using namespace ::com::sun::star::uno;
50 : using namespace ::com::sun::star::linguistic2;
51 :
52 : #define SCRLRANGE 20 // Scroll 1/20 of the width/height, when in QueryDrop
53 :
54 16 : static inline void lcl_AllignToPixel( Point& rPoint, OutputDevice* pOutDev, short nDiffX, short nDiffY )
55 : {
56 16 : rPoint = pOutDev->LogicToPixel( rPoint );
57 :
58 16 : if ( nDiffX )
59 8 : rPoint.X() += nDiffX;
60 16 : if ( nDiffY )
61 0 : rPoint.Y() += nDiffY;
62 :
63 16 : rPoint = pOutDev->PixelToLogic( rPoint );
64 16 : }
65 :
66 : // ----------------------------------------------------------------------
67 : // class ImpEditView
68 : // ----------------------------------------------------------------------
69 14 : ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, Window* pWindow ) :
70 14 : aOutArea( Point(), pEng->GetPaperSize() )
71 : {
72 14 : pEditView = pView;
73 14 : pEditEngine = pEng;
74 14 : pOutWin = pWindow;
75 14 : pPointer = NULL;
76 14 : pBackgroundColor = NULL;
77 14 : nScrollDiffX = 0;
78 14 : nExtraCursorFlags = 0;
79 14 : nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
80 14 : pCursor = NULL;
81 14 : pDragAndDropInfo = NULL;
82 14 : bReadOnly = sal_False;
83 14 : bClickedInSelection = sal_False;
84 14 : eSelectionMode = EE_SELMODE_TXTONLY;
85 14 : eAnchorMode = ANCHOR_TOP_LEFT;
86 14 : nInvMore = 1;
87 14 : nTravelXPos = TRAVEL_X_DONTKNOW;
88 14 : nControl = EV_CNTRL_AUTOSCROLL | EV_CNTRL_ENABLEPASTE;
89 14 : bActiveDragAndDropListener = sal_False;
90 :
91 14 : aEditSelection.Min() = pEng->GetEditDoc().GetStartPaM();
92 14 : aEditSelection.Max() = pEng->GetEditDoc().GetEndPaM();
93 14 : }
94 :
95 33 : ImpEditView::~ImpEditView()
96 : {
97 11 : RemoveDragAndDropListeners();
98 :
99 11 : if ( pOutWin && ( pOutWin->GetCursor() == pCursor ) )
100 0 : pOutWin->SetCursor( NULL );
101 :
102 11 : delete pCursor;
103 11 : delete pBackgroundColor;
104 11 : delete pPointer;
105 11 : delete pDragAndDropInfo;
106 22 : }
107 :
108 6 : void ImpEditView::SetBackgroundColor( const Color& rColor )
109 : {
110 6 : delete pBackgroundColor;
111 6 : pBackgroundColor = new Color( rColor );
112 6 : }
113 :
114 100 : void ImpEditView::SetEditSelection( const EditSelection& rEditSelection )
115 : {
116 : // set state before notification
117 100 : aEditSelection = rEditSelection;
118 :
119 100 : if ( pEditEngine->pImpEditEngine->GetNotifyHdl().IsSet() )
120 : {
121 0 : EENotify aNotify( EE_NOTIFY_TEXTVIEWSELECTIONCHANGED );
122 0 : aNotify.pEditEngine = pEditEngine;
123 0 : aNotify.pEditView = GetEditViewPtr();
124 0 : pEditEngine->pImpEditEngine->CallNotify( aNotify );
125 : }
126 100 : }
127 :
128 :
129 132 : void ImpEditView::DrawSelection( EditSelection aTmpSel, Region* pRegion )
130 : {
131 132 : if ( GetSelectionMode() == EE_SELMODE_HIDDEN )
132 : return;
133 :
134 : // It must be ensured before rendering the selection, that the contents of
135 : // the window is completely valid! Must be here so that in any case if
136 : // empty, then later on two-Paint Events! Must be done even before the
137 : // query from bUpdate, if after Invalidate paints still in the queue,
138 : // but someone switches the update mode!
139 :
140 : // pRegion: When not NULL, then only calculate Region.
141 132 : PolyPolygon* pPolyPoly = NULL;
142 132 : if ( pRegion )
143 0 : pPolyPoly = new PolyPolygon;
144 :
145 132 : sal_Bool bClipRegion = pOutWin->IsClipRegion();
146 132 : Region aOldRegion = pOutWin->GetClipRegion();
147 :
148 132 : if ( !pRegion )
149 : {
150 132 : if ( pEditEngine->pImpEditEngine->GetUpdateMode() == sal_False )
151 : return;
152 118 : if ( pEditEngine->pImpEditEngine->IsInUndo() )
153 : return;
154 :
155 118 : if ( !aTmpSel.HasRange() )
156 : return;
157 :
158 : // aTmpOutArea: if OutputArea > Paper width and
159 : // Text > Paper width ( over large fields )
160 8 : Rectangle aTmpOutArea( aOutArea );
161 8 : if ( aTmpOutArea.GetWidth() > pEditEngine->pImpEditEngine->GetPaperSize().Width() )
162 0 : aTmpOutArea.Right() = aTmpOutArea.Left() + pEditEngine->pImpEditEngine->GetPaperSize().Width();
163 8 : pOutWin->IntersectClipRegion( aTmpOutArea );
164 :
165 8 : if ( pOutWin->GetCursor() )
166 0 : pOutWin->GetCursor()->Hide();
167 : }
168 :
169 : DBG_ASSERT( !pEditEngine->IsIdleFormatterActive(), "DrawSelection: Not formatted!" );
170 8 : aTmpSel.Adjust( pEditEngine->GetEditDoc() );
171 :
172 8 : ContentNode* pStartNode = aTmpSel.Min().GetNode();
173 8 : ContentNode* pEndNode = aTmpSel.Max().GetNode();
174 8 : sal_uInt16 nStartPara = pEditEngine->GetEditDoc().GetPos( pStartNode );
175 8 : sal_uInt16 nEndPara = pEditEngine->GetEditDoc().GetPos( pEndNode );
176 16 : for ( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
177 : {
178 8 : ParaPortion* pTmpPortion = pEditEngine->GetParaPortions().SafeGetObject( nPara );
179 : DBG_ASSERT( pTmpPortion, "Portion in Selection not found!" );
180 : DBG_ASSERT( !pTmpPortion->IsInvalid(), "Portion in Selection not formatted!" );
181 :
182 8 : if ( !pTmpPortion->IsVisible() || pTmpPortion->IsInvalid() )
183 0 : continue;
184 :
185 8 : long nParaStart = pEditEngine->GetParaPortions().GetYOffset( pTmpPortion );
186 8 : if ( ( nParaStart + pTmpPortion->GetHeight() ) < GetVisDocTop() )
187 0 : continue;
188 8 : if ( nParaStart > GetVisDocBottom() )
189 0 : break;
190 :
191 8 : sal_uInt16 nStartLine = 0;
192 8 : sal_uInt16 nEndLine = pTmpPortion->GetLines().Count() -1;
193 8 : if ( nPara == nStartPara )
194 8 : nStartLine = pTmpPortion->GetLines().FindLine( aTmpSel.Min().GetIndex(), sal_False );
195 8 : if ( nPara == nEndPara )
196 8 : nEndLine = pTmpPortion->GetLines().FindLine( aTmpSel.Max().GetIndex(), sal_True );
197 :
198 16 : for ( sal_uInt16 nLine = nStartLine; nLine <= nEndLine; nLine++ )
199 : {
200 8 : const EditLine* pLine = pTmpPortion->GetLines()[nLine];
201 : DBG_ASSERT( pLine, "Line not found: DrawSelection()" );
202 :
203 8 : sal_Bool bPartOfLine = sal_False;
204 8 : sal_uInt16 nStartIndex = pLine->GetStart();
205 8 : sal_uInt16 nEndIndex = pLine->GetEnd();
206 8 : if ( ( nPara == nStartPara ) && ( nLine == nStartLine ) && ( nStartIndex != aTmpSel.Min().GetIndex() ) )
207 : {
208 6 : nStartIndex = aTmpSel.Min().GetIndex();
209 6 : bPartOfLine = sal_True;
210 : }
211 8 : if ( ( nPara == nEndPara ) && ( nLine == nEndLine ) && ( nEndIndex != aTmpSel.Max().GetIndex() ) )
212 : {
213 6 : nEndIndex = aTmpSel.Max().GetIndex();
214 6 : bPartOfLine = sal_True;
215 : }
216 :
217 : // Can happen if at the beginning of a wrapped line.
218 8 : if ( nEndIndex < nStartIndex )
219 0 : nEndIndex = nStartIndex;
220 :
221 8 : Rectangle aTmpRec( pEditEngine->pImpEditEngine->GetEditCursor( pTmpPortion, nStartIndex ) );
222 8 : Point aTopLeft( aTmpRec.TopLeft() );
223 8 : Point aBottomRight( aTmpRec.BottomRight() );
224 :
225 8 : aTopLeft.Y() += nParaStart;
226 8 : aBottomRight.Y() += nParaStart;
227 :
228 : // Only paint if in the visible range ...
229 8 : if ( aTopLeft.Y() > GetVisDocBottom() )
230 : break;
231 :
232 8 : if ( aBottomRight.Y() < GetVisDocTop() )
233 0 : continue;
234 :
235 : // Now that we have Bidi, the first/last index doesn't have to be the 'most outside' postion
236 8 : if ( !bPartOfLine )
237 : {
238 0 : Range aLineXPosStartEnd = pEditEngine->GetLineXPosStartEnd(pTmpPortion, pLine);
239 0 : aTopLeft.X() = aLineXPosStartEnd.Min();
240 0 : aBottomRight.X() = aLineXPosStartEnd.Max();
241 0 : ImplDrawHighlightRect( pOutWin, aTopLeft, aBottomRight, pPolyPoly );
242 : }
243 : else
244 : {
245 8 : sal_uInt16 nTmpStartIndex = nStartIndex;
246 : sal_uInt16 nWritingDirStart, nTmpEndIndex;
247 :
248 24 : while ( nTmpStartIndex < nEndIndex )
249 : {
250 8 : pEditEngine->pImpEditEngine->GetRightToLeft( nPara, nTmpStartIndex+1, &nWritingDirStart, &nTmpEndIndex );
251 8 : if ( nTmpEndIndex > nEndIndex )
252 6 : nTmpEndIndex = nEndIndex;
253 :
254 : DBG_ASSERT( nTmpEndIndex > nTmpStartIndex, "DrawSelection, Start >= End?" );
255 :
256 8 : long nX1 = pEditEngine->GetXPos(pTmpPortion, pLine, nTmpStartIndex, true);
257 8 : long nX2 = pEditEngine->GetXPos(pTmpPortion, pLine, nTmpEndIndex);
258 :
259 8 : Point aPt1( Min( nX1, nX2 ), aTopLeft.Y() );
260 8 : Point aPt2( Max( nX1, nX2 ), aBottomRight.Y() );
261 :
262 8 : ImplDrawHighlightRect( pOutWin, aPt1, aPt2, pPolyPoly );
263 :
264 8 : nTmpStartIndex = nTmpEndIndex;
265 : }
266 : }
267 :
268 : }
269 : }
270 :
271 8 : if ( pRegion )
272 : {
273 0 : *pRegion = Region( *pPolyPoly );
274 0 : delete pPolyPoly;
275 : }
276 : else
277 : {
278 8 : if ( pOutWin->GetCursor() )
279 0 : pOutWin->GetCursor()->Show();
280 :
281 8 : if ( bClipRegion )
282 0 : pOutWin->SetClipRegion( aOldRegion );
283 : else
284 8 : pOutWin->SetClipRegion();
285 132 : }
286 : }
287 :
288 8 : void ImpEditView::ImplDrawHighlightRect( Window* _pOutWin, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, PolyPolygon* pPolyPoly )
289 : {
290 8 : if ( rDocPosTopLeft.X() != rDocPosBottomRight.X() )
291 : {
292 8 : sal_Bool bPixelMode = _pOutWin->GetMapMode() == MAP_PIXEL;
293 :
294 8 : Point aPnt1( GetWindowPos( rDocPosTopLeft ) );
295 8 : Point aPnt2( GetWindowPos( rDocPosBottomRight ) );
296 :
297 8 : if ( !IsVertical() )
298 : {
299 8 : lcl_AllignToPixel( aPnt1, _pOutWin, +1, 0 );
300 8 : lcl_AllignToPixel( aPnt2, _pOutWin, 0, ( bPixelMode ? 0 : -1 ) );
301 : }
302 : else
303 : {
304 0 : lcl_AllignToPixel( aPnt1, _pOutWin, 0, +1 );
305 0 : lcl_AllignToPixel( aPnt2, _pOutWin, ( bPixelMode ? 0 : +1 ), 0 );
306 : }
307 :
308 8 : Rectangle aRect( aPnt1, aPnt2 );
309 8 : if ( pPolyPoly )
310 : {
311 0 : Polygon aTmpPoly( 4 );
312 0 : aTmpPoly[0] = aRect.TopLeft();
313 0 : aTmpPoly[1] = aRect.TopRight();
314 0 : aTmpPoly[2] = aRect.BottomRight();
315 0 : aTmpPoly[3] = aRect.BottomLeft();
316 0 : pPolyPoly->Insert( aTmpPoly );
317 : }
318 : else
319 : {
320 8 : _pOutWin->Invert( aRect );
321 : }
322 : }
323 8 : }
324 :
325 :
326 890 : sal_Bool ImpEditView::IsVertical() const
327 : {
328 890 : return pEditEngine->pImpEditEngine->IsVertical();
329 : }
330 :
331 168 : Rectangle ImpEditView::GetVisDocArea() const
332 : {
333 168 : return Rectangle( GetVisDocLeft(), GetVisDocTop(), GetVisDocRight(), GetVisDocBottom() );
334 : }
335 :
336 31 : Point ImpEditView::GetDocPos( const Point& rWindowPos ) const
337 : {
338 : // Window Position => Position Document
339 31 : Point aPoint;
340 :
341 31 : if ( !pEditEngine->pImpEditEngine->IsVertical() )
342 : {
343 31 : aPoint.X() = rWindowPos.X() - aOutArea.Left() + GetVisDocLeft();
344 31 : aPoint.Y() = rWindowPos.Y() - aOutArea.Top() + GetVisDocTop();
345 : }
346 : else
347 : {
348 0 : aPoint.X() = rWindowPos.Y() - aOutArea.Top() + GetVisDocLeft();
349 0 : aPoint.Y() = aOutArea.Right() - rWindowPos.X() + GetVisDocTop();
350 : }
351 :
352 31 : return aPoint;
353 : }
354 :
355 148 : Point ImpEditView::GetWindowPos( const Point& rDocPos ) const
356 : {
357 : // Document position => window position
358 148 : Point aPoint;
359 :
360 148 : if ( !pEditEngine->pImpEditEngine->IsVertical() )
361 : {
362 148 : aPoint.X() = rDocPos.X() + aOutArea.Left() - GetVisDocLeft();
363 148 : aPoint.Y() = rDocPos.Y() + aOutArea.Top() - GetVisDocTop();
364 : }
365 : else
366 : {
367 0 : aPoint.X() = aOutArea.Right() - rDocPos.Y() + GetVisDocTop();
368 0 : aPoint.Y() = rDocPos.X() + aOutArea.Top() - GetVisDocLeft();
369 : }
370 :
371 148 : return aPoint;
372 : }
373 :
374 132 : Rectangle ImpEditView::GetWindowPos( const Rectangle& rDocRect ) const
375 : {
376 : // Document position => window position
377 132 : Point aPos( GetWindowPos( rDocRect.TopLeft() ) );
378 132 : Size aSz = rDocRect.GetSize();
379 132 : Rectangle aRect;
380 132 : if ( !pEditEngine->pImpEditEngine->IsVertical() )
381 : {
382 132 : aRect = Rectangle( aPos, aSz );
383 : }
384 : else
385 : {
386 0 : Point aNewPos( aPos.X()-aSz.Height(), aPos.Y() );
387 0 : aRect = Rectangle( aNewPos, Size( aSz.Height(), aSz.Width() ) );
388 : }
389 132 : return aRect;
390 : }
391 :
392 6 : void ImpEditView::SetSelectionMode( EESelectionMode eNewMode )
393 : {
394 6 : if ( eSelectionMode != eNewMode )
395 : {
396 0 : DrawSelection();
397 0 : eSelectionMode = eNewMode;
398 0 : DrawSelection(); // redraw
399 : }
400 6 : }
401 :
402 32 : void ImpEditView::SetOutputArea( const Rectangle& rRec )
403 : {
404 : // should be better be aligned on pixels!
405 32 : Rectangle aNewRec( pOutWin->LogicToPixel( rRec ) );
406 32 : aNewRec = pOutWin->PixelToLogic( aNewRec );
407 32 : aOutArea = aNewRec;
408 32 : if ( aOutArea.Right() < aOutArea.Left() )
409 20 : aOutArea.Right() = aOutArea.Left();
410 32 : if ( aOutArea.Bottom() < aOutArea.Top() )
411 20 : aOutArea.Bottom() = aOutArea.Top();
412 :
413 32 : if ( DoBigScroll() )
414 0 : SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 3 / 10 );
415 : else
416 32 : SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 2 / 10 );
417 32 : }
418 :
419 0 : void ImpEditView::ResetOutputArea( const Rectangle& rRec )
420 : {
421 0 : Rectangle aCurArea( aOutArea );
422 0 : SetOutputArea( rRec );
423 : // Invalidate surrounding areas if in update mode of the engine on sal_True
424 0 : if ( !aCurArea.IsEmpty() && pEditEngine->pImpEditEngine->GetUpdateMode() )
425 : {
426 0 : long nMore = 0;
427 0 : if ( DoInvalidateMore() )
428 0 : nMore = GetWindow()->PixelToLogic( Size( nInvMore, 0 ) ).Width();
429 0 : if ( aCurArea.Left() < aOutArea.Left() )
430 : {
431 : Rectangle aRect( aCurArea.TopLeft(),
432 0 : Size( aOutArea.Left()-aCurArea.Left(), aCurArea.GetHeight() ) );
433 0 : if ( nMore )
434 : {
435 0 : aRect.Left() -= nMore;
436 0 : aRect.Top() -= nMore;
437 0 : aRect.Bottom() += nMore;
438 : }
439 0 : GetWindow()->Invalidate( aRect );
440 : }
441 0 : if ( aCurArea.Right() > aOutArea.Right() )
442 : {
443 0 : long nW = aCurArea.Right() - aOutArea.Right();
444 0 : Point aPos( aCurArea.TopRight() );
445 0 : aPos.X() -= nW;
446 0 : Rectangle aRect( aPos, Size( nW, aCurArea.GetHeight() ) );
447 0 : if ( nMore )
448 : {
449 0 : aRect.Right() += nMore;
450 0 : aRect.Top() -= nMore;
451 0 : aRect.Bottom() += nMore;
452 : }
453 0 : GetWindow()->Invalidate( aRect );
454 : }
455 0 : if ( aCurArea.Top() < aOutArea.Top() )
456 : {
457 0 : Rectangle aRect( aCurArea.TopLeft(), Size( aCurArea.GetWidth(), aOutArea.Top() - aCurArea.Top() ) );
458 0 : if ( nMore )
459 : {
460 0 : aRect.Top() -= nMore;
461 0 : aRect.Left() -= nMore;
462 0 : aRect.Right() += nMore;
463 : }
464 0 : GetWindow()->Invalidate( aRect );
465 : }
466 0 : if ( aCurArea.Bottom() > aOutArea.Bottom() )
467 : {
468 0 : long nH = aCurArea.Bottom() - aOutArea.Bottom();
469 0 : Point aPos( aCurArea.BottomLeft() );
470 0 : aPos.Y() -= nH;
471 0 : Rectangle aRect( aPos, Size( aCurArea.GetWidth(), nH ) );
472 0 : if ( nMore )
473 : {
474 0 : aRect.Bottom() += nMore;
475 0 : aRect.Left() -= nMore;
476 0 : aRect.Right() += nMore;
477 : }
478 :
479 0 : GetWindow()->Invalidate( aRect );
480 : }
481 : }
482 0 : }
483 :
484 0 : void ImpEditView::RecalcOutputArea()
485 : {
486 0 : Point aNewTopLeft( aOutArea.TopLeft() );
487 0 : Size aNewSz( aOutArea.GetSize() );
488 :
489 : // X:
490 0 : if ( DoAutoWidth() )
491 : {
492 0 : if ( pEditEngine->pImpEditEngine->GetStatus().AutoPageWidth() )
493 0 : aNewSz.Width() = pEditEngine->pImpEditEngine->GetPaperSize().Width();
494 0 : switch ( eAnchorMode )
495 : {
496 : case ANCHOR_TOP_LEFT:
497 : case ANCHOR_VCENTER_LEFT:
498 : case ANCHOR_BOTTOM_LEFT:
499 : {
500 0 : aNewTopLeft.X() = aAnchorPoint.X();
501 : }
502 0 : break;
503 : case ANCHOR_TOP_HCENTER:
504 : case ANCHOR_VCENTER_HCENTER:
505 : case ANCHOR_BOTTOM_HCENTER:
506 : {
507 0 : aNewTopLeft.X() = aAnchorPoint.X() - aNewSz.Width() / 2;
508 : }
509 0 : break;
510 : case ANCHOR_TOP_RIGHT:
511 : case ANCHOR_VCENTER_RIGHT:
512 : case ANCHOR_BOTTOM_RIGHT:
513 : {
514 0 : aNewTopLeft.X() = aAnchorPoint.X() - aNewSz.Width() - 1;
515 : }
516 0 : break;
517 : }
518 : }
519 :
520 : // Y:
521 0 : if ( DoAutoHeight() )
522 : {
523 0 : if ( pEditEngine->pImpEditEngine->GetStatus().AutoPageHeight() )
524 0 : aNewSz.Height() = pEditEngine->pImpEditEngine->GetPaperSize().Height();
525 0 : switch ( eAnchorMode )
526 : {
527 : case ANCHOR_TOP_LEFT:
528 : case ANCHOR_TOP_HCENTER:
529 : case ANCHOR_TOP_RIGHT:
530 : {
531 0 : aNewTopLeft.Y() = aAnchorPoint.Y();
532 : }
533 0 : break;
534 : case ANCHOR_VCENTER_LEFT:
535 : case ANCHOR_VCENTER_HCENTER:
536 : case ANCHOR_VCENTER_RIGHT:
537 : {
538 0 : aNewTopLeft.Y() = aAnchorPoint.Y() - aNewSz.Height() / 2;
539 : }
540 0 : break;
541 : case ANCHOR_BOTTOM_LEFT:
542 : case ANCHOR_BOTTOM_HCENTER:
543 : case ANCHOR_BOTTOM_RIGHT:
544 : {
545 0 : aNewTopLeft.Y() = aAnchorPoint.Y() - aNewSz.Height() - 1;
546 : }
547 0 : break;
548 : }
549 : }
550 0 : ResetOutputArea( Rectangle( aNewTopLeft, aNewSz ) );
551 0 : }
552 :
553 0 : void ImpEditView::SetAnchorMode( EVAnchorMode eMode )
554 : {
555 0 : eAnchorMode = eMode;
556 0 : CalcAnchorPoint();
557 0 : }
558 :
559 32 : void ImpEditView::CalcAnchorPoint()
560 : {
561 : // GetHeight() and GetWidth() -1, because rectangle calculation not prefered.
562 :
563 : // X:
564 32 : switch ( eAnchorMode )
565 : {
566 : case ANCHOR_TOP_LEFT:
567 : case ANCHOR_VCENTER_LEFT:
568 : case ANCHOR_BOTTOM_LEFT:
569 : {
570 32 : aAnchorPoint.X() = aOutArea.Left();
571 : }
572 32 : break;
573 : case ANCHOR_TOP_HCENTER:
574 : case ANCHOR_VCENTER_HCENTER:
575 : case ANCHOR_BOTTOM_HCENTER:
576 : {
577 0 : aAnchorPoint.X() = aOutArea.Left() + (aOutArea.GetWidth()-1) / 2;
578 : }
579 0 : break;
580 : case ANCHOR_TOP_RIGHT:
581 : case ANCHOR_VCENTER_RIGHT:
582 : case ANCHOR_BOTTOM_RIGHT:
583 : {
584 0 : aAnchorPoint.X() = aOutArea.Right();
585 : }
586 0 : break;
587 : }
588 :
589 : // Y:
590 32 : switch ( eAnchorMode )
591 : {
592 : case ANCHOR_TOP_LEFT:
593 : case ANCHOR_TOP_HCENTER:
594 : case ANCHOR_TOP_RIGHT:
595 : {
596 32 : aAnchorPoint.Y() = aOutArea.Top();
597 : }
598 32 : break;
599 : case ANCHOR_VCENTER_LEFT:
600 : case ANCHOR_VCENTER_HCENTER:
601 : case ANCHOR_VCENTER_RIGHT:
602 : {
603 0 : aAnchorPoint.Y() = aOutArea.Top() + (aOutArea.GetHeight()-1) / 2;
604 : }
605 0 : break;
606 : case ANCHOR_BOTTOM_LEFT:
607 : case ANCHOR_BOTTOM_HCENTER:
608 : case ANCHOR_BOTTOM_RIGHT:
609 : {
610 0 : aAnchorPoint.Y() = aOutArea.Bottom() - 1;
611 : }
612 0 : break;
613 : }
614 32 : }
615 :
616 174 : void ImpEditView::ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor, sal_uInt16 nShowCursorFlags )
617 : {
618 : // No ShowCursor in an empty View ...
619 174 : if ( ( aOutArea.Left() >= aOutArea.Right() ) && ( aOutArea.Top() >= aOutArea.Bottom() ) )
620 : return;
621 :
622 108 : pEditEngine->CheckIdleFormatter();
623 108 : if (!pEditEngine->IsFormatted())
624 4 : pEditEngine->pImpEditEngine->FormatDoc();
625 :
626 : // For some reasons I end up here during the formatting, if the Outliner
627 : // is initialized in Paint, because no SetPool();
628 108 : if ( pEditEngine->pImpEditEngine->IsFormatting() )
629 : return;
630 108 : if ( pEditEngine->pImpEditEngine->GetUpdateMode() == sal_False )
631 : return;
632 76 : if ( pEditEngine->pImpEditEngine->IsInUndo() )
633 : return;
634 :
635 76 : if ( pOutWin->GetCursor() != GetCursor() )
636 6 : pOutWin->SetCursor( GetCursor() );
637 :
638 76 : EditPaM aPaM( aEditSelection.Max() );
639 :
640 76 : sal_uInt16 nTextPortionStart = 0;
641 76 : sal_uInt16 nPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
642 76 : if (nPara == USHRT_MAX) // #i94322
643 : return;
644 :
645 76 : const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
646 :
647 76 : nShowCursorFlags |= nExtraCursorFlags;
648 :
649 76 : nShowCursorFlags |= GETCRSR_TXTONLY;
650 :
651 : // Use CursorBidiLevel 0/1 in meaning of
652 : // 0: prefer portion end, normal mode
653 : // 1: prefer portion start
654 :
655 76 : if ( ( GetCursorBidiLevel() != CURSOR_BIDILEVEL_DONTKNOW ) && GetCursorBidiLevel() )
656 : {
657 0 : nShowCursorFlags |= GETCRSR_PREFERPORTIONSTART;
658 : }
659 :
660 76 : Rectangle aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, nShowCursorFlags );
661 76 : if ( !IsInsertMode() && !aEditSelection.HasRange() )
662 : {
663 0 : if ( aPaM.GetNode()->Len() && ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) )
664 : {
665 : // If we are behind a portion, and the next portion has other direction, we must change position...
666 0 : aEditCursor.Left() = aEditCursor.Right() = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, GETCRSR_TXTONLY|GETCRSR_PREFERPORTIONSTART ).Left();
667 :
668 0 : sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, sal_True );
669 0 : const TextPortion* pTextPortion = pParaPortion->GetTextPortions()[nTextPortion];
670 0 : if ( pTextPortion->GetKind() == PORTIONKIND_TAB )
671 : {
672 0 : aEditCursor.Right() += pTextPortion->GetSize().Width();
673 : }
674 : else
675 : {
676 0 : EditPaM aNext = pEditEngine->CursorRight( aPaM, (sal_uInt16)i18n::CharacterIteratorMode::SKIPCELL );
677 0 : Rectangle aTmpRect = pEditEngine->pImpEditEngine->PaMtoEditCursor( aNext, GETCRSR_TXTONLY );
678 0 : if ( aTmpRect.Top() != aEditCursor.Top() )
679 0 : aTmpRect = pEditEngine->pImpEditEngine->PaMtoEditCursor( aNext, GETCRSR_TXTONLY|GETCRSR_ENDOFLINE );
680 0 : aEditCursor.Right() = aTmpRect.Left();
681 : }
682 : }
683 : }
684 76 : long nMaxHeight = !IsVertical() ? aOutArea.GetHeight() : aOutArea.GetWidth();
685 76 : if ( aEditCursor.GetHeight() > nMaxHeight )
686 : {
687 70 : aEditCursor.Bottom() = aEditCursor.Top() + nMaxHeight - 1;
688 : }
689 76 : if ( bGotoCursor ) // && (!pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) )
690 : {
691 : // check if scrolling is necessary...
692 : // if scrolling, then update () and Scroll ()!
693 52 : long nDocDiffX = 0;
694 52 : long nDocDiffY = 0;
695 :
696 52 : Rectangle aTmpVisArea( GetVisDocArea() );
697 : // aTmpOutArea: if OutputArea > Paper width and
698 : // Text > Paper width ( over large fields )
699 52 : long nMaxTextWidth = !IsVertical() ? pEditEngine->pImpEditEngine->GetPaperSize().Width() : pEditEngine->pImpEditEngine->GetPaperSize().Height();
700 52 : if ( aTmpVisArea.GetWidth() > nMaxTextWidth )
701 0 : aTmpVisArea.Right() = aTmpVisArea.Left() + nMaxTextWidth;
702 :
703 52 : if ( aEditCursor.Bottom() > aTmpVisArea.Bottom() )
704 : { // Scroll up, here positive
705 0 : nDocDiffY = aEditCursor.Bottom() - aTmpVisArea.Bottom();
706 : }
707 52 : else if ( aEditCursor.Top() < aTmpVisArea.Top() )
708 : { // Scroll down, here negative
709 0 : nDocDiffY = aEditCursor.Top() - aTmpVisArea.Top();
710 : }
711 :
712 52 : if ( aEditCursor.Right() > aTmpVisArea.Right() )
713 : {
714 : // Scroll left, positiv
715 2 : nDocDiffX = aEditCursor.Right() - aTmpVisArea.Right();
716 : // Can it be a little more?
717 2 : if ( aEditCursor.Right() < ( nMaxTextWidth - GetScrollDiffX() ) )
718 2 : nDocDiffX += GetScrollDiffX();
719 : else
720 : {
721 0 : long n = nMaxTextWidth - aEditCursor.Right();
722 : // If MapMode != RefMapMode then the EditCursor can go beyond
723 : // the paper width!
724 0 : nDocDiffX += ( n > 0 ? n : -n );
725 : }
726 : }
727 50 : else if ( aEditCursor.Left() < aTmpVisArea.Left() )
728 : {
729 : // Scroll right, negative:
730 0 : nDocDiffX = aEditCursor.Left() - aTmpVisArea.Left();
731 : // Can it be a little more?
732 0 : if ( aEditCursor.Left() > ( - (long)GetScrollDiffX() ) )
733 0 : nDocDiffX -= GetScrollDiffX();
734 : else
735 0 : nDocDiffX -= aEditCursor.Left();
736 : }
737 52 : if ( aPaM.GetIndex() == 0 ) // Olli needed for the Outliner
738 : {
739 : // But make sure that the cursor is not leaving visible area
740 : // because of this!
741 46 : if ( aEditCursor.Left() < aTmpVisArea.GetWidth() )
742 : {
743 46 : nDocDiffX = -aTmpVisArea.Left();
744 : }
745 : }
746 :
747 52 : if ( nDocDiffX | nDocDiffY )
748 : {
749 2 : long nDiffX = !IsVertical() ? nDocDiffX : -nDocDiffY;
750 2 : long nDiffY = !IsVertical() ? nDocDiffY : nDocDiffX;
751 :
752 : // Negative: Back to the top or left edge
753 2 : if ( ( Abs( nDiffY ) > pEditEngine->GetOnePixelInRef() ) && DoBigScroll() )
754 : {
755 0 : long nH = aOutArea.GetHeight() / 4;
756 0 : if ( ( nH > aEditCursor.GetHeight() ) && ( Abs( nDiffY ) < nH ) )
757 : {
758 0 : if ( nDiffY < 0 )
759 0 : nDiffY -= nH;
760 : else
761 0 : nDiffY += nH;
762 : }
763 : }
764 :
765 2 : if ( ( Abs( nDiffX ) > pEditEngine->GetOnePixelInRef() ) && DoBigScroll() )
766 : {
767 0 : long nW = aOutArea.GetWidth() / 4;
768 0 : if ( Abs( nDiffX ) < nW )
769 : {
770 0 : if ( nDiffY < 0 )
771 0 : nDiffY -= nW;
772 : else
773 0 : nDiffY += nW;
774 : }
775 : }
776 :
777 2 : if ( nDiffX )
778 2 : pEditEngine->GetInternalEditStatus().GetStatusWord() = pEditEngine->GetInternalEditStatus().GetStatusWord() | EE_STAT_HSCROLL;
779 2 : if ( nDiffY )
780 0 : pEditEngine->GetInternalEditStatus().GetStatusWord() = pEditEngine->GetInternalEditStatus().GetStatusWord() | EE_STAT_VSCROLL;
781 2 : Scroll( -nDiffX, -nDiffY );
782 2 : pEditEngine->pImpEditEngine->DelayedCallStatusHdl();
783 : }
784 : }
785 :
786 : // Cursor may trim a little ...
787 228 : if ( ( aEditCursor.Bottom() > GetVisDocTop() ) &&
788 152 : ( aEditCursor.Top() < GetVisDocBottom() ) )
789 : {
790 76 : if ( aEditCursor.Bottom() > GetVisDocBottom() )
791 0 : aEditCursor.Bottom() = GetVisDocBottom();
792 76 : if ( aEditCursor.Top() < GetVisDocTop() )
793 0 : aEditCursor.Top() = GetVisDocTop();
794 : }
795 :
796 76 : long nOnePixel = pOutWin->PixelToLogic( Size( 1, 0 ) ).Width();
797 :
798 608 : if ( /* pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() || */
799 152 : ( ( aEditCursor.Top() + nOnePixel >= GetVisDocTop() ) &&
800 152 : ( aEditCursor.Bottom() - nOnePixel <= GetVisDocBottom() ) &&
801 152 : ( aEditCursor.Left() + nOnePixel >= GetVisDocLeft() ) &&
802 152 : ( aEditCursor.Right() - nOnePixel <= GetVisDocRight() ) ) )
803 : {
804 76 : Rectangle aCursorRect = GetWindowPos( aEditCursor );
805 76 : GetCursor()->SetPos( aCursorRect.TopLeft() );
806 76 : Size aCursorSz( aCursorRect.GetSize() );
807 : // Rectangle is inclusive
808 76 : aCursorSz.Width()--;
809 76 : aCursorSz.Height()--;
810 76 : if ( !aCursorSz.Width() || !aCursorSz.Height() )
811 : {
812 76 : long nCursorSz = pOutWin->GetSettings().GetStyleSettings().GetCursorSize();
813 76 : nCursorSz = pOutWin->PixelToLogic( Size( nCursorSz, 0 ) ).Width();
814 76 : if ( !aCursorSz.Width() )
815 76 : aCursorSz.Width() = nCursorSz;
816 76 : if ( !aCursorSz.Height() )
817 0 : aCursorSz.Height() = nCursorSz;
818 : }
819 : // #111036# Let VCL do orientation for cursor, otherwise problem when cursor has direction flag
820 76 : if ( IsVertical() )
821 : {
822 0 : Size aOldSz( aCursorSz );
823 0 : aCursorSz.Width() = aOldSz.Height();
824 0 : aCursorSz.Height() = aOldSz.Width();
825 0 : GetCursor()->SetPos( aCursorRect.TopRight() );
826 0 : GetCursor()->SetOrientation( 2700 );
827 : }
828 : else
829 : // #i32593# Reset correct orientation in horizontal layout
830 76 : GetCursor()->SetOrientation( 0 );
831 :
832 76 : GetCursor()->SetSize( aCursorSz );
833 :
834 76 : unsigned char nCursorDir = CURSOR_DIRECTION_NONE;
835 76 : if ( IsInsertMode() && !aEditSelection.HasRange() && ( pEditEngine->pImpEditEngine->HasDifferentRTLLevels( aPaM.GetNode() ) ) )
836 : {
837 0 : sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTextPortionStart, nShowCursorFlags & GETCRSR_PREFERPORTIONSTART ? sal_True : sal_False );
838 0 : const TextPortion* pTextPortion = pParaPortion->GetTextPortions()[nTextPortion];
839 0 : sal_uInt16 nRTLLevel = pTextPortion->GetRightToLeft();
840 0 : if ( nRTLLevel%2 )
841 0 : nCursorDir = CURSOR_DIRECTION_RTL;
842 : else
843 0 : nCursorDir = CURSOR_DIRECTION_LTR;
844 :
845 : }
846 76 : GetCursor()->SetDirection( nCursorDir );
847 :
848 76 : if ( bForceVisCursor )
849 40 : GetCursor()->Show();
850 : {
851 76 : SvxFont aFont;
852 76 : pEditEngine->SeekCursor( aPaM.GetNode(), aPaM.GetIndex()+1, aFont );
853 76 : sal_uLong nContextFlags = INPUTCONTEXT_TEXT|INPUTCONTEXT_EXTTEXTINPUT;
854 76 : GetWindow()->SetInputContext( InputContext( aFont, nContextFlags ) );
855 : }
856 : }
857 : else
858 : {
859 0 : pEditEngine->pImpEditEngine->GetStatus().GetStatusWord() = pEditEngine->pImpEditEngine->GetStatus().GetStatusWord() | EE_STAT_CURSOROUT;
860 0 : GetCursor()->Hide();
861 0 : GetCursor()->SetPos( Point( -1, -1 ) );
862 0 : GetCursor()->SetSize( Size( 0, 0 ) );
863 : }
864 : }
865 :
866 2 : Pair ImpEditView::Scroll( long ndX, long ndY, sal_uInt8 nRangeCheck )
867 : {
868 : DBG_ASSERT( pEditEngine->pImpEditEngine->IsFormatted(), "Scroll: Not formatted!" );
869 2 : if ( !ndX && !ndY )
870 0 : return Range( 0, 0 );
871 :
872 : #ifdef DBG_UTIL
873 : Rectangle aR( aOutArea );
874 : aR = pOutWin->LogicToPixel( aR );
875 : aR = pOutWin->PixelToLogic( aR );
876 : DBG_ASSERTWARNING( aR == aOutArea, "OutArea before Scroll not aligned" );
877 : #endif
878 :
879 2 : Rectangle aNewVisArea( GetVisDocArea() );
880 :
881 : // Vertical:
882 2 : if ( !IsVertical() )
883 : {
884 2 : aNewVisArea.Top() -= ndY;
885 2 : aNewVisArea.Bottom() -= ndY;
886 : }
887 : else
888 : {
889 0 : aNewVisArea.Top() += ndX;
890 0 : aNewVisArea.Bottom() += ndX;
891 : }
892 2 : if ( ( nRangeCheck == RGCHK_PAPERSZ1 ) && ( aNewVisArea.Bottom() > (long)pEditEngine->pImpEditEngine->GetTextHeight() ) )
893 : {
894 : // GetTextHeight still optimizing!
895 0 : long nDiff = pEditEngine->pImpEditEngine->GetTextHeight() - aNewVisArea.Bottom(); // negative
896 0 : aNewVisArea.Move( 0, nDiff ); // could end up in the negative area...
897 : }
898 2 : if ( ( aNewVisArea.Top() < 0 ) && ( nRangeCheck != RGCHK_NONE ) )
899 0 : aNewVisArea.Move( 0, -aNewVisArea.Top() );
900 :
901 : // Horizontal:
902 2 : if ( !IsVertical() )
903 : {
904 2 : aNewVisArea.Left() -= ndX;
905 2 : aNewVisArea.Right() -= ndX;
906 : }
907 : else
908 : {
909 0 : aNewVisArea.Left() -= ndY;
910 0 : aNewVisArea.Right() -= ndY;
911 : }
912 2 : if ( ( nRangeCheck == RGCHK_PAPERSZ1 ) && ( aNewVisArea.Right() > (long)pEditEngine->pImpEditEngine->CalcTextWidth( sal_False ) ) )
913 : {
914 0 : long nDiff = pEditEngine->pImpEditEngine->CalcTextWidth( sal_False ) - aNewVisArea.Right(); // negative
915 0 : aNewVisArea.Move( nDiff, 0 ); // could end up in the negative area...
916 : }
917 2 : if ( ( aNewVisArea.Left() < 0 ) && ( nRangeCheck != RGCHK_NONE ) )
918 0 : aNewVisArea.Move( -aNewVisArea.Left(), 0 );
919 :
920 : // The difference must be alignt on pixel (due to scroll!)
921 2 : long nDiffX = !IsVertical() ? ( GetVisDocLeft() - aNewVisArea.Left() ) : -( GetVisDocTop() - aNewVisArea.Top() );
922 2 : long nDiffY = !IsVertical() ? ( GetVisDocTop() - aNewVisArea.Top() ) : ( GetVisDocLeft() - aNewVisArea.Left() );
923 :
924 2 : Size aDiffs( nDiffX, nDiffY );
925 2 : aDiffs = pOutWin->LogicToPixel( aDiffs );
926 2 : aDiffs = pOutWin->PixelToLogic( aDiffs );
927 :
928 2 : long nRealDiffX = aDiffs.Width();
929 2 : long nRealDiffY = aDiffs.Height();
930 :
931 :
932 2 : if ( nRealDiffX || nRealDiffY )
933 : {
934 2 : Cursor* pCrsr = GetCursor();
935 2 : sal_Bool bVisCursor = pCrsr->IsVisible();
936 2 : pCrsr->Hide();
937 2 : pOutWin->Update();
938 2 : if ( !IsVertical() )
939 2 : aVisDocStartPos.Move( -nRealDiffX, -nRealDiffY );
940 : else
941 0 : aVisDocStartPos.Move( -nRealDiffY, nRealDiffX );
942 : // Das Move um den allignten Wert ergibt nicht unbedingt ein
943 : // alligntes Rechteck...
944 : // Aligned value of the move does not necessarily result in aligned
945 : // rectangle ...
946 2 : aVisDocStartPos = pOutWin->LogicToPixel( aVisDocStartPos );
947 2 : aVisDocStartPos = pOutWin->PixelToLogic( aVisDocStartPos );
948 2 : Rectangle aRec( aOutArea );
949 2 : pOutWin->Scroll( nRealDiffX, nRealDiffY, aRec, sal_True );
950 2 : pOutWin->Update();
951 2 : pCrsr->SetPos( pCrsr->GetPos() + Point( nRealDiffX, nRealDiffY ) );
952 2 : if ( bVisCursor )
953 : {
954 0 : Rectangle aCursorRec( pCrsr->GetPos(), pCrsr->GetSize() );
955 0 : if ( aOutArea.IsInside( aCursorRec ) )
956 0 : pCrsr->Show();
957 : }
958 :
959 2 : if ( pEditEngine->pImpEditEngine->GetNotifyHdl().IsSet() )
960 : {
961 0 : EENotify aNotify( EE_NOTIFY_TEXTVIEWSCROLLED );
962 0 : aNotify.pEditEngine = pEditEngine;
963 0 : aNotify.pEditView = GetEditViewPtr();
964 0 : pEditEngine->pImpEditEngine->CallNotify( aNotify );
965 : }
966 : }
967 :
968 2 : return Pair( nRealDiffX, nRealDiffY );
969 : }
970 :
971 0 : sal_Bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent, Window* pFrameWin )
972 : {
973 0 : sal_Bool bDone = sal_False;
974 :
975 0 : KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
976 0 : if ( eFunc != KEYFUNC_DONTKNOW )
977 : {
978 0 : switch ( eFunc )
979 : {
980 : case KEYFUNC_CUT:
981 : {
982 0 : if ( !bReadOnly )
983 : {
984 0 : Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
985 0 : CutCopy( aClipBoard, sal_True );
986 0 : bDone = sal_True;
987 : }
988 : }
989 0 : break;
990 : case KEYFUNC_COPY:
991 : {
992 0 : Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
993 0 : CutCopy( aClipBoard, sal_False );
994 0 : bDone = sal_True;
995 : }
996 0 : break;
997 : case KEYFUNC_PASTE:
998 : {
999 0 : if ( !bReadOnly && IsPasteEnabled() )
1000 : {
1001 0 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
1002 0 : Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
1003 0 : Paste( aClipBoard, pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
1004 0 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
1005 0 : bDone = sal_True;
1006 : }
1007 : }
1008 0 : break;
1009 : default:
1010 0 : break;
1011 : }
1012 : }
1013 :
1014 0 : if( !bDone )
1015 0 : bDone = pEditEngine->PostKeyEvent( rKeyEvent, GetEditViewPtr(), pFrameWin );
1016 :
1017 0 : return bDone;
1018 : }
1019 :
1020 0 : sal_Bool ImpEditView::MouseButtonUp( const MouseEvent& rMouseEvent )
1021 : {
1022 0 : if ( pEditEngine->GetInternalEditStatus().NotifyCursorMovements() )
1023 : {
1024 0 : if ( pEditEngine->GetInternalEditStatus().GetPrevParagraph() != pEditEngine->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() ) )
1025 : {
1026 0 : pEditEngine->GetInternalEditStatus().GetStatusWord() = pEditEngine->GetInternalEditStatus().GetStatusWord() | EE_STAT_CRSRLEFTPARA;
1027 0 : pEditEngine->pImpEditEngine->CallStatusHdl();
1028 : }
1029 : }
1030 0 : nTravelXPos = TRAVEL_X_DONTKNOW;
1031 0 : nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
1032 0 : nExtraCursorFlags = 0;
1033 0 : bClickedInSelection = sal_False;
1034 :
1035 0 : if ( rMouseEvent.IsMiddle() && !bReadOnly &&
1036 0 : ( GetWindow()->GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION ) )
1037 : {
1038 0 : Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetPrimarySelection());
1039 0 : Paste( aClipBoard );
1040 : }
1041 0 : else if ( rMouseEvent.IsLeft() && GetEditSelection().HasRange() )
1042 : {
1043 0 : Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetPrimarySelection());
1044 0 : CutCopy( aClipBoard, sal_False );
1045 : }
1046 :
1047 0 : return pEditEngine->pImpEditEngine->MouseButtonUp( rMouseEvent, GetEditViewPtr() );
1048 : }
1049 :
1050 0 : sal_Bool ImpEditView::MouseButtonDown( const MouseEvent& rMouseEvent )
1051 : {
1052 0 : pEditEngine->CheckIdleFormatter(); // If fast typing and mouse button downs
1053 0 : if ( pEditEngine->GetInternalEditStatus().NotifyCursorMovements() )
1054 0 : pEditEngine->GetInternalEditStatus().GetPrevParagraph() = pEditEngine->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() );
1055 0 : nTravelXPos = TRAVEL_X_DONTKNOW;
1056 0 : nExtraCursorFlags = 0;
1057 0 : nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
1058 0 : bClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
1059 0 : return pEditEngine->pImpEditEngine->MouseButtonDown( rMouseEvent, GetEditViewPtr() );
1060 : }
1061 :
1062 0 : sal_Bool ImpEditView::MouseMove( const MouseEvent& rMouseEvent )
1063 : {
1064 0 : return pEditEngine->pImpEditEngine->MouseMove( rMouseEvent, GetEditViewPtr() );
1065 : }
1066 :
1067 0 : void ImpEditView::Command( const CommandEvent& rCEvt )
1068 : {
1069 0 : pEditEngine->CheckIdleFormatter(); // If fast typing and mouse button down
1070 0 : pEditEngine->pImpEditEngine->Command( rCEvt, GetEditViewPtr() );
1071 0 : }
1072 :
1073 :
1074 0 : void ImpEditView::SetInsertMode( sal_Bool bInsert )
1075 : {
1076 0 : if ( bInsert != IsInsertMode() )
1077 : {
1078 0 : SetFlags( nControl, EV_CNTRL_OVERWRITE, !bInsert );
1079 0 : ShowCursor( DoAutoScroll(), sal_False );
1080 : }
1081 0 : }
1082 :
1083 0 : sal_Bool ImpEditView::IsWrongSpelledWord( const EditPaM& rPaM, sal_Bool bMarkIfWrong )
1084 : {
1085 0 : bool bIsWrong = false;
1086 0 : if ( rPaM.GetNode()->GetWrongList() )
1087 : {
1088 0 : EditSelection aSel = pEditEngine->SelectWord( rPaM, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
1089 0 : bIsWrong = rPaM.GetNode()->GetWrongList()->HasWrong( aSel.Min().GetIndex(), aSel.Max().GetIndex() );
1090 0 : if ( bIsWrong && bMarkIfWrong )
1091 : {
1092 0 : DrawSelection();
1093 0 : SetEditSelection( aSel );
1094 0 : DrawSelection();
1095 : }
1096 : }
1097 0 : return bIsWrong;
1098 : }
1099 :
1100 0 : String ImpEditView::SpellIgnoreOrAddWord( sal_Bool bAdd )
1101 : {
1102 0 : String aWord;
1103 0 : if ( pEditEngine->pImpEditEngine->GetSpeller().is() )
1104 : {
1105 0 : EditPaM aPaM = GetEditSelection().Max();
1106 0 : if ( !HasSelection() )
1107 : {
1108 0 : EditSelection aSel = pEditEngine->SelectWord(aPaM);
1109 0 : aWord = pEditEngine->pImpEditEngine->GetSelected( aSel );
1110 : }
1111 : else
1112 : {
1113 0 : aWord = pEditEngine->pImpEditEngine->GetSelected( GetEditSelection() );
1114 : // And deselect
1115 0 : DrawSelection();
1116 0 : SetEditSelection( EditSelection( aPaM, aPaM ) );
1117 0 : DrawSelection();
1118 : }
1119 :
1120 0 : if ( aWord.Len() )
1121 : {
1122 0 : if ( bAdd )
1123 : {
1124 : OSL_FAIL( "Sorry, AddWord not implemented" );
1125 : }
1126 : else // Ignore
1127 : {
1128 0 : Reference< XDictionary > xDic( SvxGetIgnoreAllList(), UNO_QUERY );
1129 0 : if (xDic.is())
1130 0 : xDic->add( aWord, sal_False, String() );
1131 : }
1132 0 : EditDoc& rDoc = pEditEngine->GetEditDoc();
1133 0 : sal_uInt16 nNodes = rDoc.Count();
1134 0 : for ( sal_uInt16 n = 0; n < nNodes; n++ )
1135 : {
1136 0 : ContentNode* pNode = rDoc.GetObject( n );
1137 0 : pNode->GetWrongList()->MarkWrongsInvalid();
1138 : }
1139 0 : pEditEngine->pImpEditEngine->DoOnlineSpelling( aPaM.GetNode() );
1140 0 : pEditEngine->pImpEditEngine->StartOnlineSpellTimer();
1141 : }
1142 : }
1143 0 : return aWord;
1144 : }
1145 :
1146 3 : void ImpEditView::DeleteSelected()
1147 : {
1148 3 : DrawSelection();
1149 :
1150 3 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DELETE );
1151 :
1152 3 : EditPaM aPaM = pEditEngine->pImpEditEngine->DeleteSelected( GetEditSelection() );
1153 :
1154 3 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DELETE );
1155 :
1156 3 : SetEditSelection( EditSelection( aPaM, aPaM ) );
1157 3 : pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
1158 3 : ShowCursor( DoAutoScroll(), sal_True );
1159 3 : }
1160 :
1161 0 : const SvxFieldItem* ImpEditView::GetField( const Point& rPos, sal_uInt16* pPara, sal_uInt16* pPos ) const
1162 : {
1163 0 : if( !GetOutputArea().IsInside( rPos ) )
1164 0 : return 0;
1165 :
1166 0 : Point aDocPos( GetDocPos( rPos ) );
1167 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos, false);
1168 :
1169 0 : if ( aPaM.GetIndex() == aPaM.GetNode()->Len() )
1170 : {
1171 : // Otherwise, whenever the Field at the very end and mouse under the text
1172 0 : return 0;
1173 : }
1174 :
1175 0 : const CharAttribList::AttribsType& rAttrs = aPaM.GetNode()->GetCharAttribs().GetAttribs();
1176 0 : sal_uInt16 nXPos = aPaM.GetIndex();
1177 0 : for (size_t nAttr = rAttrs.size(); nAttr; )
1178 : {
1179 0 : const EditCharAttrib& rAttr = rAttrs[--nAttr];
1180 0 : if (rAttr.GetStart() == nXPos)
1181 : {
1182 0 : if (rAttr.Which() == EE_FEATURE_FIELD)
1183 : {
1184 : DBG_ASSERT(dynamic_cast<const SvxFieldItem*>(rAttr.GetItem()), "No FieldItem...");
1185 0 : if ( pPara )
1186 0 : *pPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1187 0 : if ( pPos )
1188 0 : *pPos = rAttr.GetStart();
1189 0 : return static_cast<const SvxFieldItem*>(rAttr.GetItem());
1190 : }
1191 : }
1192 : }
1193 0 : return NULL;
1194 : }
1195 :
1196 0 : sal_Bool ImpEditView::IsBulletArea( const Point& rPos, sal_uInt16* pPara )
1197 : {
1198 0 : if ( pPara )
1199 0 : *pPara = 0xFFFF;
1200 :
1201 0 : if( !GetOutputArea().IsInside( rPos ) )
1202 0 : return sal_False;
1203 :
1204 0 : Point aDocPos( GetDocPos( rPos ) );
1205 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos, false);
1206 :
1207 0 : if ( aPaM.GetIndex() == 0 )
1208 : {
1209 0 : sal_uInt16 nPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1210 0 : Rectangle aBulletArea = pEditEngine->GetBulletArea( nPara );
1211 0 : long nY = pEditEngine->GetDocPosTopLeft( nPara ).Y();
1212 0 : const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
1213 0 : nY += pParaPortion->GetFirstLineOffset();
1214 0 : if ( ( aDocPos.Y() > ( nY + aBulletArea.Top() ) ) &&
1215 0 : ( aDocPos.Y() < ( nY + aBulletArea.Bottom() ) ) &&
1216 0 : ( aDocPos.X() > ( aBulletArea.Left() ) ) &&
1217 0 : ( aDocPos.X() < ( aBulletArea.Right() ) ) )
1218 : {
1219 0 : if ( pPara )
1220 0 : *pPara = nPara;
1221 0 : return sal_True;
1222 : }
1223 : }
1224 :
1225 0 : return sal_False;
1226 : }
1227 :
1228 0 : void ImpEditView::CutCopy( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bCut )
1229 : {
1230 0 : if ( rxClipboard.is() && GetEditSelection().HasRange() )
1231 : {
1232 0 : uno::Reference<datatransfer::XTransferable> xData = pEditEngine->CreateTransferable( GetEditSelection() );
1233 :
1234 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1235 :
1236 : try
1237 : {
1238 0 : rxClipboard->setContents( xData, NULL );
1239 :
1240 : // #87756# FlushClipboard, but it would be better to become a TerminateListener to the Desktop and flush on demand...
1241 0 : uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY );
1242 0 : if( xFlushableClipboard.is() )
1243 0 : xFlushableClipboard->flushClipboard();
1244 : }
1245 0 : catch( const ::com::sun::star::uno::Exception& )
1246 : {
1247 : }
1248 :
1249 0 : Application::AcquireSolarMutex( nRef );
1250 :
1251 0 : if ( bCut )
1252 : {
1253 0 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_CUT );
1254 0 : DeleteSelected();
1255 0 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_CUT );
1256 :
1257 0 : }
1258 : }
1259 0 : }
1260 :
1261 0 : void ImpEditView::Paste( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bUseSpecial )
1262 : {
1263 0 : if ( rxClipboard.is() )
1264 : {
1265 0 : uno::Reference< datatransfer::XTransferable > xDataObj;
1266 :
1267 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1268 :
1269 : try
1270 : {
1271 0 : xDataObj = rxClipboard->getContents();
1272 : }
1273 0 : catch( const ::com::sun::star::uno::Exception& )
1274 : {
1275 : }
1276 :
1277 0 : Application::AcquireSolarMutex( nRef );
1278 :
1279 0 : if ( xDataObj.is() && EditEngine::HasValidData( xDataObj ) )
1280 : {
1281 0 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
1282 :
1283 0 : EditSelection aSel( GetEditSelection() );
1284 0 : if ( aSel.HasRange() )
1285 : {
1286 0 : DrawSelection();
1287 0 : aSel = pEditEngine->DeleteSelection(aSel);
1288 : }
1289 :
1290 0 : PasteOrDropInfos aPasteOrDropInfos;
1291 0 : aPasteOrDropInfos.nAction = EE_ACTION_PASTE;
1292 0 : aPasteOrDropInfos.nStartPara = pEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
1293 0 : pEditEngine->HandleBeginPasteOrDrop(aPasteOrDropInfos);
1294 :
1295 0 : if ( DoSingleLinePaste() )
1296 : {
1297 0 : datatransfer::DataFlavor aFlavor;
1298 0 : SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
1299 0 : if ( xDataObj->isDataFlavorSupported( aFlavor ) )
1300 : {
1301 : try
1302 : {
1303 0 : uno::Any aData = xDataObj->getTransferData( aFlavor );
1304 0 : ::rtl::OUString aTmpText;
1305 0 : aData >>= aTmpText;
1306 0 : String aText(convertLineEnd(aTmpText, LINEEND_LF));
1307 0 : aText.SearchAndReplaceAll( LINE_SEP, ' ' );
1308 0 : aSel = pEditEngine->InsertText(aSel, aText);
1309 : }
1310 0 : catch( ... )
1311 : {
1312 : ; // #i9286# can happen, even if isDataFlavorSupported returns true...
1313 : }
1314 0 : }
1315 : }
1316 : else
1317 : {
1318 : aSel = pEditEngine->InsertText(
1319 0 : xDataObj, String(), aSel.Min(),
1320 0 : bUseSpecial && pEditEngine->GetInternalEditStatus().AllowPasteSpecial());
1321 : }
1322 :
1323 0 : aPasteOrDropInfos.nEndPara = pEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
1324 0 : pEditEngine->HandleEndPasteOrDrop(aPasteOrDropInfos);
1325 :
1326 0 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
1327 0 : SetEditSelection( aSel );
1328 0 : pEditEngine->pImpEditEngine->UpdateSelections();
1329 0 : pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
1330 0 : ShowCursor( DoAutoScroll(), sal_True );
1331 0 : }
1332 : }
1333 0 : }
1334 :
1335 :
1336 0 : sal_Bool ImpEditView::IsInSelection( const EditPaM& rPaM )
1337 : {
1338 0 : EditSelection aSel = GetEditSelection();
1339 0 : if ( !aSel.HasRange() )
1340 0 : return sal_False;
1341 :
1342 0 : aSel.Adjust( pEditEngine->GetEditDoc() );
1343 :
1344 0 : sal_uInt16 nStartNode = pEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
1345 0 : sal_uInt16 nEndNode = pEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
1346 0 : sal_uInt16 nCurNode = pEditEngine->GetEditDoc().GetPos( rPaM.GetNode() );
1347 :
1348 0 : if ( ( nCurNode > nStartNode ) && ( nCurNode < nEndNode ) )
1349 0 : return sal_True;
1350 :
1351 0 : if ( nStartNode == nEndNode )
1352 : {
1353 0 : if ( nCurNode == nStartNode )
1354 0 : if ( ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
1355 0 : return sal_True;
1356 : }
1357 0 : else if ( ( nCurNode == nStartNode ) && ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) )
1358 0 : return sal_True;
1359 0 : else if ( ( nCurNode == nEndNode ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
1360 0 : return sal_True;
1361 :
1362 0 : return sal_False;
1363 : }
1364 :
1365 0 : void ImpEditView::CreateAnchor()
1366 : {
1367 0 : pEditEngine->SetInSelectionMode(true);
1368 0 : GetEditSelection().Min() = GetEditSelection().Max();
1369 0 : }
1370 :
1371 0 : void ImpEditView::DeselectAll()
1372 : {
1373 0 : pEditEngine->SetInSelectionMode(false);
1374 0 : DrawSelection();
1375 0 : GetEditSelection().Min() = GetEditSelection().Max();
1376 0 : }
1377 :
1378 0 : sal_Bool ImpEditView::IsSelectionAtPoint( const Point& rPosPixel )
1379 : {
1380 0 : if ( pDragAndDropInfo && pDragAndDropInfo->pField )
1381 0 : return sal_True;
1382 :
1383 0 : Point aMousePos( rPosPixel );
1384 :
1385 : // Logical units ...
1386 0 : aMousePos = GetWindow()->PixelToLogic( aMousePos );
1387 :
1388 0 : if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
1389 : {
1390 0 : return sal_False;
1391 : }
1392 :
1393 0 : Point aDocPos( GetDocPos( aMousePos ) );
1394 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos, false);
1395 0 : return IsInSelection( aPaM );
1396 : }
1397 :
1398 0 : sal_Bool ImpEditView::SetCursorAtPoint( const Point& rPointPixel )
1399 : {
1400 0 : pEditEngine->CheckIdleFormatter();
1401 :
1402 0 : Point aMousePos( rPointPixel );
1403 :
1404 : // Logical units ...
1405 0 : aMousePos = GetWindow()->PixelToLogic( aMousePos );
1406 :
1407 0 : if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
1408 : {
1409 0 : return sal_False;
1410 : }
1411 :
1412 0 : Point aDocPos( GetDocPos( aMousePos ) );
1413 :
1414 : // Can be optimized: first go through the lines within a paragraph for PAM,
1415 : // then again wiht the PaM for the Rect, even though the line is already
1416 : // known .... This must not be, though!
1417 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos);
1418 0 : sal_Bool bGotoCursor = DoAutoScroll();
1419 :
1420 : // aTmpNewSel: Diff between old and new, not the new selection
1421 0 : EditSelection aTmpNewSel( GetEditSelection().Max(), aPaM );
1422 :
1423 : // #i27299#
1424 : // work on copy of current selection and set new selection, if it has changed.
1425 0 : EditSelection aNewEditSelection( GetEditSelection() );
1426 :
1427 0 : aNewEditSelection.Max() = aPaM;
1428 0 : if (!pEditEngine->GetSelectionEngine().HasAnchor())
1429 : {
1430 0 : if ( aNewEditSelection.Min() != aPaM )
1431 0 : pEditEngine->CursorMoved(aNewEditSelection.Min().GetNode());
1432 0 : aNewEditSelection.Min() = aPaM;
1433 : }
1434 : else
1435 : {
1436 0 : DrawSelection( aTmpNewSel );
1437 : }
1438 :
1439 : // set changed text selection
1440 0 : if ( GetEditSelection() != aNewEditSelection )
1441 : {
1442 0 : SetEditSelection( aNewEditSelection );
1443 : }
1444 :
1445 0 : sal_Bool bForceCursor = ( pDragAndDropInfo ? sal_False : sal_True ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
1446 0 : ShowCursor( bGotoCursor, bForceCursor );
1447 0 : return sal_True;
1448 : }
1449 :
1450 :
1451 0 : void ImpEditView::HideDDCursor()
1452 : {
1453 0 : if ( pDragAndDropInfo && pDragAndDropInfo->bVisCursor )
1454 : {
1455 0 : GetWindow()->DrawOutDev( pDragAndDropInfo->aCurSavedCursor.TopLeft(), pDragAndDropInfo->aCurSavedCursor.GetSize(),
1456 0 : Point(0,0), pDragAndDropInfo->aCurSavedCursor.GetSize(),*pDragAndDropInfo->pBackground );
1457 0 : pDragAndDropInfo->bVisCursor = sal_False;
1458 : }
1459 0 : }
1460 :
1461 0 : void ImpEditView::ShowDDCursor( const Rectangle& rRect )
1462 : {
1463 0 : if ( pDragAndDropInfo && !pDragAndDropInfo->bVisCursor )
1464 : {
1465 0 : if ( pOutWin->GetCursor() )
1466 0 : pOutWin->GetCursor()->Hide();
1467 :
1468 0 : Color aOldFillColor = GetWindow()->GetFillColor();
1469 0 : GetWindow()->SetFillColor( Color(4210752) ); // GRAY BRUSH_50, OLDSV, change to DDCursor!
1470 :
1471 : // Save background ...
1472 0 : Rectangle aSaveRec( GetWindow()->LogicToPixel( rRect ) );
1473 : // prefer to save some more ...
1474 0 : aSaveRec.Right() += 1;
1475 0 : aSaveRec.Bottom() += 1;
1476 :
1477 : #ifdef DBG_UTIL
1478 : Size aNewSzPx( aSaveRec.GetSize() );
1479 : #endif
1480 0 : if ( !pDragAndDropInfo->pBackground )
1481 : {
1482 0 : pDragAndDropInfo->pBackground = new VirtualDevice( *GetWindow() );
1483 0 : MapMode aMapMode( GetWindow()->GetMapMode() );
1484 0 : aMapMode.SetOrigin( Point( 0, 0 ) );
1485 0 : pDragAndDropInfo->pBackground->SetMapMode( aMapMode );
1486 :
1487 : }
1488 :
1489 : #ifdef DBG_UTIL
1490 : Size aCurSzPx( pDragAndDropInfo->pBackground->GetOutputSizePixel() );
1491 : if ( ( aCurSzPx.Width() < aNewSzPx.Width() ) ||( aCurSzPx.Height() < aNewSzPx.Height() ) )
1492 : {
1493 : sal_Bool bDone = pDragAndDropInfo->pBackground->SetOutputSizePixel( aNewSzPx );
1494 : DBG_ASSERT( bDone, "Virtual Device broken?" );
1495 : }
1496 : #endif
1497 :
1498 0 : aSaveRec = GetWindow()->PixelToLogic( aSaveRec );
1499 :
1500 : pDragAndDropInfo->pBackground->DrawOutDev( Point(0,0), aSaveRec.GetSize(),
1501 0 : aSaveRec.TopLeft(), aSaveRec.GetSize(), *GetWindow() );
1502 0 : pDragAndDropInfo->aCurSavedCursor = aSaveRec;
1503 :
1504 : // Draw Cursor...
1505 0 : GetWindow()->DrawRect( rRect );
1506 :
1507 0 : pDragAndDropInfo->bVisCursor = sal_True;
1508 0 : pDragAndDropInfo->aCurCursor = rRect;
1509 :
1510 0 : GetWindow()->SetFillColor( aOldFillColor );
1511 : }
1512 0 : }
1513 :
1514 0 : void ImpEditView::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& rDGE ) throw (::com::sun::star::uno::RuntimeException)
1515 : {
1516 : DBG_ASSERT( !pDragAndDropInfo, "dragGestureRecognized - DragAndDropInfo exist!" );
1517 :
1518 0 : SolarMutexGuard aVclGuard;
1519 :
1520 0 : pDragAndDropInfo = NULL;
1521 :
1522 0 : Point aMousePosPixel( rDGE.DragOriginX, rDGE.DragOriginY );
1523 :
1524 0 : EditSelection aCopySel( GetEditSelection() );
1525 0 : aCopySel.Adjust( pEditEngine->GetEditDoc() );
1526 :
1527 0 : if ( GetEditSelection().HasRange() && bClickedInSelection )
1528 : {
1529 0 : pDragAndDropInfo = new DragAndDropInfo();
1530 : }
1531 : else
1532 : {
1533 : // Field?!
1534 : sal_uInt16 nPara, nPos;
1535 0 : Point aMousePos = GetWindow()->PixelToLogic( aMousePosPixel );
1536 0 : const SvxFieldItem* pField = GetField( aMousePos, &nPara, &nPos );
1537 0 : if ( pField )
1538 : {
1539 0 : pDragAndDropInfo = new DragAndDropInfo();
1540 0 : pDragAndDropInfo->pField = pField;
1541 0 : ContentNode* pNode = pEditEngine->GetEditDoc().GetObject( nPara );
1542 0 : aCopySel = EditSelection( EditPaM( pNode, nPos ), EditPaM( pNode, nPos+1 ) );
1543 0 : GetEditSelection() = aCopySel;
1544 0 : DrawSelection();
1545 0 : sal_Bool bGotoCursor = DoAutoScroll();
1546 0 : sal_Bool bForceCursor = ( pDragAndDropInfo ? sal_False : sal_True ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
1547 0 : ShowCursor( bGotoCursor, bForceCursor );
1548 : }
1549 0 : else if ( IsBulletArea( aMousePos, &nPara ) )
1550 : {
1551 0 : pDragAndDropInfo = new DragAndDropInfo();
1552 0 : pDragAndDropInfo->bOutlinerMode = sal_True;
1553 0 : EditPaM aStartPaM( pEditEngine->GetEditDoc().GetObject( nPara ), 0 );
1554 0 : EditPaM aEndPaM( aStartPaM );
1555 0 : const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
1556 0 : for ( sal_uInt16 n = nPara +1; n < pEditEngine->GetEditDoc().Count(); n++ )
1557 : {
1558 0 : const SfxInt16Item& rL = (const SfxInt16Item&) pEditEngine->GetParaAttrib( n, EE_PARA_OUTLLEVEL );
1559 0 : if ( rL.GetValue() > rLevel.GetValue() )
1560 : {
1561 0 : aEndPaM.SetNode( pEditEngine->GetEditDoc().GetObject( n ) );
1562 : }
1563 : else
1564 : {
1565 0 : break;
1566 : }
1567 : }
1568 0 : aEndPaM.GetIndex() = aEndPaM.GetNode()->Len();
1569 0 : SetEditSelection( EditSelection( aStartPaM, aEndPaM ) );
1570 : }
1571 : }
1572 :
1573 0 : if ( pDragAndDropInfo )
1574 : {
1575 :
1576 0 : pDragAndDropInfo->bStarterOfDD = sal_True;
1577 :
1578 : // Sensitive area to be scrolled.
1579 0 : Size aSz( 5, 0 );
1580 0 : aSz = GetWindow()->PixelToLogic( aSz );
1581 0 : pDragAndDropInfo->nSensibleRange = (sal_uInt16) aSz.Width();
1582 0 : pDragAndDropInfo->nCursorWidth = (sal_uInt16) aSz.Width() / 2;
1583 0 : pDragAndDropInfo->aBeginDragSel = pEditEngine->pImpEditEngine->CreateESel( aCopySel );
1584 :
1585 0 : uno::Reference<datatransfer::XTransferable> xData = pEditEngine->CreateTransferable(aCopySel);
1586 :
1587 0 : sal_Int8 nActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;
1588 :
1589 0 : rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, xData, mxDnDListener );
1590 : // If Drag&Move in an Engine, thenCopy&Del has to be optional!
1591 0 : GetCursor()->Hide();
1592 :
1593 0 : }
1594 0 : }
1595 :
1596 0 : void ImpEditView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& rDSDE ) throw (::com::sun::star::uno::RuntimeException)
1597 : {
1598 0 : SolarMutexGuard aVclGuard;
1599 :
1600 : DBG_ASSERT( pDragAndDropInfo, "ImpEditView::dragDropEnd: pDragAndDropInfo is NULL!" );
1601 :
1602 : // #123688# Shouldn't happen, but seems to happen...
1603 0 : if ( pDragAndDropInfo )
1604 : {
1605 0 : if ( !bReadOnly && rDSDE.DropSuccess && !pDragAndDropInfo->bOutlinerMode && ( rDSDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE ) )
1606 : {
1607 0 : if ( pDragAndDropInfo->bStarterOfDD && pDragAndDropInfo->bDroppedInMe )
1608 : {
1609 : // DropPos: Where was it dropped, irrespective of length.
1610 0 : ESelection aDropPos( pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos, pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos );
1611 0 : ESelection aToBeDelSel = pDragAndDropInfo->aBeginDragSel;
1612 : ESelection aNewSel( pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos,
1613 0 : pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos );
1614 0 : sal_Bool bBeforeSelection = aDropPos.IsLess( pDragAndDropInfo->aBeginDragSel );
1615 0 : sal_uInt16 nParaDiff = pDragAndDropInfo->aBeginDragSel.nEndPara - pDragAndDropInfo->aBeginDragSel.nStartPara;
1616 0 : if ( bBeforeSelection )
1617 : {
1618 : // Adjust aToBeDelSel.
1619 : DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara >= pDragAndDropInfo->aDropSel.nStartPara, "But not before? ");
1620 0 : aToBeDelSel.nStartPara = aToBeDelSel.nStartPara + nParaDiff;
1621 0 : aToBeDelSel.nEndPara = aToBeDelSel.nEndPara + nParaDiff;
1622 : // To correct the character?
1623 0 : if ( aToBeDelSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
1624 : {
1625 : sal_uInt16 nMoreChars;
1626 0 : if ( pDragAndDropInfo->aDropSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
1627 0 : nMoreChars = pDragAndDropInfo->aDropSel.nEndPos - pDragAndDropInfo->aDropSel.nStartPos;
1628 : else
1629 0 : nMoreChars = pDragAndDropInfo->aDropSel.nEndPos;
1630 : aToBeDelSel.nStartPos =
1631 0 : aToBeDelSel.nStartPos + nMoreChars;
1632 0 : if ( aToBeDelSel.nStartPara == aToBeDelSel.nEndPara )
1633 : aToBeDelSel.nEndPos =
1634 0 : aToBeDelSel.nEndPos + nMoreChars;
1635 : }
1636 : }
1637 : else
1638 : {
1639 : // aToBeDelSel is ok, but the selection of the View
1640 : // has to be adapted, if it was deleted before!
1641 : DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara <= pDragAndDropInfo->aDropSel.nStartPara, "But not before? ");
1642 0 : aNewSel.nStartPara = aNewSel.nStartPara - nParaDiff;
1643 0 : aNewSel.nEndPara = aNewSel.nEndPara - nParaDiff;
1644 : // To correct the character?
1645 0 : if ( pDragAndDropInfo->aBeginDragSel.nEndPara == pDragAndDropInfo->aDropSel.nStartPara )
1646 : {
1647 : sal_uInt16 nLessChars;
1648 0 : if ( pDragAndDropInfo->aBeginDragSel.nStartPara == pDragAndDropInfo->aBeginDragSel.nEndPara )
1649 0 : nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos - pDragAndDropInfo->aBeginDragSel.nStartPos;
1650 : else
1651 0 : nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos;
1652 0 : aNewSel.nStartPos = aNewSel.nStartPos - nLessChars;
1653 0 : if ( aNewSel.nStartPara == aNewSel.nEndPara )
1654 0 : aNewSel.nEndPos = aNewSel.nEndPos - nLessChars;
1655 : }
1656 : }
1657 :
1658 0 : DrawSelection();
1659 0 : EditSelection aDelSel( pEditEngine->pImpEditEngine->CreateSel( aToBeDelSel ) );
1660 : DBG_ASSERT( !aDelSel.DbgIsBuggy( pEditEngine->GetEditDoc() ), "ToBeDel is buggy!" );
1661 0 : pEditEngine->DeleteSelection(aDelSel);
1662 0 : if ( !bBeforeSelection )
1663 : {
1664 : DBG_ASSERT( !pEditEngine->pImpEditEngine->CreateSel( aNewSel ).DbgIsBuggy(pEditEngine->GetEditDoc()), "Bad" );
1665 0 : SetEditSelection( pEditEngine->pImpEditEngine->CreateSel( aNewSel ) );
1666 : }
1667 0 : pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
1668 0 : DrawSelection();
1669 : }
1670 : else
1671 : {
1672 : // other EditEngine ...
1673 0 : if (pEditEngine->HasText()) // #88630# SC ist removing the content when switching the task
1674 0 : DeleteSelected();
1675 : }
1676 : }
1677 :
1678 0 : if ( pDragAndDropInfo->bUndoAction )
1679 0 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DRAGANDDROP );
1680 :
1681 0 : HideDDCursor();
1682 0 : ShowCursor( DoAutoScroll(), sal_True );
1683 0 : delete pDragAndDropInfo;
1684 0 : pDragAndDropInfo = NULL;
1685 0 : pEditEngine->GetEndDropHdl().Call(GetEditViewPtr());
1686 0 : }
1687 0 : }
1688 :
1689 0 : void ImpEditView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
1690 : {
1691 0 : SolarMutexGuard aVclGuard;
1692 :
1693 : DBG_ASSERT( pDragAndDropInfo, "Drop - No Drag&Drop info?!" );
1694 :
1695 0 : if ( pDragAndDropInfo && pDragAndDropInfo->bDragAccepted )
1696 : {
1697 0 : pEditEngine->GetBeginDropHdl().Call(GetEditViewPtr());
1698 0 : sal_Bool bChanges = sal_False;
1699 :
1700 0 : HideDDCursor();
1701 :
1702 0 : if ( pDragAndDropInfo->bStarterOfDD )
1703 : {
1704 0 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DRAGANDDROP );
1705 0 : pDragAndDropInfo->bUndoAction = sal_True;
1706 : }
1707 :
1708 0 : if ( pDragAndDropInfo->bOutlinerMode )
1709 : {
1710 0 : bChanges = sal_True;
1711 0 : GetEditViewPtr()->MoveParagraphs( Range( pDragAndDropInfo->aBeginDragSel.nStartPara, pDragAndDropInfo->aBeginDragSel.nEndPara ), pDragAndDropInfo->nOutlinerDropDest );
1712 : }
1713 : else
1714 : {
1715 0 : uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
1716 0 : if ( xDataObj.is() )
1717 : {
1718 0 : bChanges = true;
1719 : // remove Selection ...
1720 0 : DrawSelection();
1721 0 : EditPaM aPaM( pDragAndDropInfo->aDropDest );
1722 :
1723 0 : PasteOrDropInfos aPasteOrDropInfos;
1724 0 : aPasteOrDropInfos.nAction = EE_ACTION_DROP;
1725 0 : aPasteOrDropInfos.nStartPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1726 0 : pEditEngine->HandleBeginPasteOrDrop(aPasteOrDropInfos);
1727 :
1728 : EditSelection aNewSel = pEditEngine->InsertText(
1729 0 : xDataObj, String(), aPaM, pEditEngine->GetInternalEditStatus().AllowPasteSpecial());
1730 :
1731 0 : aPasteOrDropInfos.nEndPara = pEditEngine->GetEditDoc().GetPos( aNewSel.Max().GetNode() );
1732 0 : pEditEngine->HandleEndPasteOrDrop(aPasteOrDropInfos);
1733 :
1734 0 : SetEditSelection( aNewSel );
1735 0 : pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
1736 0 : if ( pDragAndDropInfo->bStarterOfDD )
1737 : {
1738 : // Only set if the same engine!
1739 0 : pDragAndDropInfo->aDropSel.nStartPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1740 0 : pDragAndDropInfo->aDropSel.nStartPos = aPaM.GetIndex();
1741 0 : pDragAndDropInfo->aDropSel.nEndPara = pEditEngine->GetEditDoc().GetPos( aNewSel.Max().GetNode() );
1742 0 : pDragAndDropInfo->aDropSel.nEndPos = aNewSel.Max().GetIndex();
1743 0 : pDragAndDropInfo->bDroppedInMe = sal_True;
1744 : }
1745 0 : }
1746 : }
1747 :
1748 0 : if ( bChanges )
1749 : {
1750 0 : rDTDE.Context->acceptDrop( rDTDE.DropAction );
1751 : }
1752 :
1753 0 : if ( !pDragAndDropInfo->bStarterOfDD )
1754 : {
1755 0 : delete pDragAndDropInfo;
1756 0 : pDragAndDropInfo = NULL;
1757 : }
1758 :
1759 0 : rDTDE.Context->dropComplete( bChanges );
1760 0 : }
1761 0 : }
1762 :
1763 0 : void ImpEditView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& rDTDEE ) throw (::com::sun::star::uno::RuntimeException)
1764 : {
1765 0 : SolarMutexGuard aVclGuard;
1766 :
1767 0 : if ( !pDragAndDropInfo )
1768 0 : pDragAndDropInfo = new DragAndDropInfo( );
1769 :
1770 0 : pDragAndDropInfo->bHasValidData = sal_False;
1771 :
1772 : // Check for supported format...
1773 : // Only check for text, will also be there if bin or rtf
1774 0 : datatransfer::DataFlavor aTextFlavor;
1775 0 : SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aTextFlavor );
1776 0 : const ::com::sun::star::datatransfer::DataFlavor* pFlavors = rDTDEE.SupportedDataFlavors.getConstArray();
1777 0 : int nFlavors = rDTDEE.SupportedDataFlavors.getLength();
1778 0 : for ( int n = 0; n < nFlavors; n++ )
1779 : {
1780 0 : if( TransferableDataHelper::IsEqual( pFlavors[n], aTextFlavor ) )
1781 : {
1782 0 : pDragAndDropInfo->bHasValidData = sal_True;
1783 0 : break;
1784 : }
1785 : }
1786 :
1787 0 : dragOver( rDTDEE );
1788 0 : }
1789 :
1790 0 : void ImpEditView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException)
1791 : {
1792 0 : SolarMutexGuard aVclGuard;
1793 :
1794 0 : HideDDCursor();
1795 :
1796 0 : if ( pDragAndDropInfo && !pDragAndDropInfo->bStarterOfDD )
1797 : {
1798 0 : delete pDragAndDropInfo;
1799 0 : pDragAndDropInfo = NULL;
1800 0 : }
1801 0 : }
1802 :
1803 0 : void ImpEditView::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
1804 : {
1805 0 : SolarMutexGuard aVclGuard;
1806 :
1807 0 : Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
1808 0 : aMousePos = GetWindow()->PixelToLogic( aMousePos );
1809 :
1810 0 : sal_Bool bAccept = sal_False;
1811 :
1812 0 : if ( GetOutputArea().IsInside( aMousePos ) && !bReadOnly )
1813 : {
1814 0 : if ( pDragAndDropInfo && pDragAndDropInfo->bHasValidData )
1815 : {
1816 0 : bAccept = sal_True;
1817 :
1818 0 : sal_Bool bAllowScroll = DoAutoScroll();
1819 0 : if ( bAllowScroll )
1820 : {
1821 0 : long nScrollX = 0;
1822 0 : long nScrollY = 0;
1823 : // Chech if in the sensitive area
1824 0 : if ( ( (aMousePos.X()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Left() ) && ( ( aMousePos.X() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Left() ) )
1825 0 : nScrollX = GetOutputArea().GetWidth() / SCRLRANGE;
1826 0 : else if ( ( (aMousePos.X()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Right() ) && ( ( aMousePos.X() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Right() ) )
1827 0 : nScrollX = -( GetOutputArea().GetWidth() / SCRLRANGE );
1828 :
1829 0 : if ( ( (aMousePos.Y()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Top() ) && ( ( aMousePos.Y() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Top() ) )
1830 0 : nScrollY = GetOutputArea().GetHeight() / SCRLRANGE;
1831 0 : else if ( ( (aMousePos.Y()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Bottom() ) && ( ( aMousePos.Y() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Bottom() ) )
1832 0 : nScrollY = -( GetOutputArea().GetHeight() / SCRLRANGE );
1833 :
1834 0 : if ( nScrollX || nScrollY )
1835 : {
1836 0 : HideDDCursor();
1837 0 : Scroll( nScrollX, nScrollY, RGCHK_PAPERSZ1 );
1838 : }
1839 : }
1840 :
1841 0 : Point aDocPos( GetDocPos( aMousePos ) );
1842 0 : EditPaM aPaM = pEditEngine->GetPaM( aDocPos );
1843 0 : pDragAndDropInfo->aDropDest = aPaM;
1844 0 : if ( pDragAndDropInfo->bOutlinerMode )
1845 : {
1846 0 : sal_uInt16 nPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1847 0 : ParaPortion* pPPortion = pEditEngine->GetParaPortions().SafeGetObject( nPara );
1848 0 : long nDestParaStartY = pEditEngine->GetParaPortions().GetYOffset( pPPortion );
1849 0 : long nRel = aDocPos.Y() - nDestParaStartY;
1850 0 : if ( nRel < ( pPPortion->GetHeight() / 2 ) )
1851 : {
1852 0 : pDragAndDropInfo->nOutlinerDropDest = nPara;
1853 : }
1854 : else
1855 : {
1856 0 : pDragAndDropInfo->nOutlinerDropDest = nPara+1;
1857 : }
1858 :
1859 0 : if( ( pDragAndDropInfo->nOutlinerDropDest >= pDragAndDropInfo->aBeginDragSel.nStartPara ) &&
1860 : ( pDragAndDropInfo->nOutlinerDropDest <= (pDragAndDropInfo->aBeginDragSel.nEndPara+1) ) )
1861 : {
1862 0 : bAccept = sal_False;
1863 : }
1864 : }
1865 0 : else if ( HasSelection() )
1866 : {
1867 : // it must not be dropped into a selection
1868 0 : EPaM aP = pEditEngine->pImpEditEngine->CreateEPaM( aPaM );
1869 0 : ESelection aDestSel( aP.nPara, aP.nIndex, aP.nPara, aP.nIndex);
1870 0 : ESelection aCurSel = pEditEngine->pImpEditEngine->CreateESel( GetEditSelection() );
1871 0 : aCurSel.Adjust();
1872 0 : if ( !aDestSel.IsLess( aCurSel ) && !aDestSel.IsGreater( aCurSel ) )
1873 : {
1874 0 : bAccept = sal_False;
1875 : }
1876 : }
1877 0 : if ( bAccept )
1878 : {
1879 0 : Rectangle aEditCursor;
1880 0 : if ( pDragAndDropInfo->bOutlinerMode )
1881 : {
1882 : long nDDYPos;
1883 0 : if ( pDragAndDropInfo->nOutlinerDropDest < pEditEngine->GetEditDoc().Count() )
1884 : {
1885 0 : ParaPortion* pPPortion = pEditEngine->GetParaPortions().SafeGetObject( pDragAndDropInfo->nOutlinerDropDest );
1886 0 : nDDYPos = pEditEngine->GetParaPortions().GetYOffset( pPPortion );
1887 : }
1888 : else
1889 : {
1890 0 : nDDYPos = pEditEngine->pImpEditEngine->GetTextHeight();
1891 : }
1892 0 : Point aStartPos( 0, nDDYPos );
1893 0 : aStartPos = GetWindowPos( aStartPos );
1894 0 : Point aEndPos( GetOutputArea().GetWidth(), nDDYPos );
1895 0 : aEndPos = GetWindowPos( aEndPos );
1896 0 : aEditCursor = GetWindow()->LogicToPixel( Rectangle( aStartPos, aEndPos ) );
1897 0 : if ( !pEditEngine->IsVertical() )
1898 : {
1899 0 : aEditCursor.Top()--;
1900 0 : aEditCursor.Bottom()++;
1901 : }
1902 : else
1903 : {
1904 0 : aEditCursor.Left()--;
1905 0 : aEditCursor.Right()++;
1906 : }
1907 0 : aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
1908 : }
1909 : else
1910 : {
1911 0 : aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM );
1912 0 : Point aTopLeft( GetWindowPos( aEditCursor.TopLeft() ) );
1913 0 : aEditCursor.SetPos( aTopLeft );
1914 0 : aEditCursor.Right() = aEditCursor.Left() + pDragAndDropInfo->nCursorWidth;
1915 0 : aEditCursor = GetWindow()->LogicToPixel( aEditCursor );
1916 0 : aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
1917 : }
1918 :
1919 0 : sal_Bool bCursorChanged = !pDragAndDropInfo->bVisCursor || ( pDragAndDropInfo->aCurCursor != aEditCursor );
1920 0 : if ( bCursorChanged )
1921 : {
1922 0 : HideDDCursor();
1923 0 : ShowDDCursor(aEditCursor );
1924 : }
1925 0 : pDragAndDropInfo->bDragAccepted = sal_True;
1926 0 : rDTDE.Context->acceptDrag( rDTDE.DropAction );
1927 : }
1928 : }
1929 : }
1930 :
1931 0 : if ( !bAccept )
1932 : {
1933 0 : HideDDCursor();
1934 0 : if (pDragAndDropInfo)
1935 0 : pDragAndDropInfo->bDragAccepted = sal_False;
1936 0 : rDTDE.Context->rejectDrag();
1937 0 : }
1938 0 : }
1939 :
1940 14 : void ImpEditView::AddDragAndDropListeners()
1941 : {
1942 14 : Window* pWindow = GetWindow();
1943 14 : if ( !bActiveDragAndDropListener && pWindow && pWindow->GetDragGestureRecognizer().is() )
1944 : {
1945 14 : vcl::unohelper::DragAndDropWrapper* pDnDWrapper = new vcl::unohelper::DragAndDropWrapper( this );
1946 14 : mxDnDListener = pDnDWrapper;
1947 :
1948 14 : uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
1949 14 : pWindow->GetDragGestureRecognizer()->addDragGestureListener( xDGL );
1950 14 : uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
1951 14 : pWindow->GetDropTarget()->addDropTargetListener( xDTL );
1952 14 : pWindow->GetDropTarget()->setActive( sal_True );
1953 14 : pWindow->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );
1954 :
1955 14 : bActiveDragAndDropListener = sal_True;
1956 : }
1957 14 : }
1958 :
1959 19 : void ImpEditView::RemoveDragAndDropListeners()
1960 : {
1961 19 : if ( bActiveDragAndDropListener && GetWindow() && GetWindow()->GetDragGestureRecognizer().is() )
1962 : {
1963 8 : uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
1964 8 : GetWindow()->GetDragGestureRecognizer()->removeDragGestureListener( xDGL );
1965 8 : uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
1966 8 : GetWindow()->GetDropTarget()->removeDropTargetListener( xDTL );
1967 :
1968 8 : if ( mxDnDListener.is() )
1969 : {
1970 8 : uno::Reference< lang::XEventListener> xEL( mxDnDListener, uno::UNO_QUERY );
1971 8 : xEL->disposing( lang::EventObject() ); // #95154# Empty Source means it's the Client
1972 8 : mxDnDListener.clear();
1973 : }
1974 :
1975 8 : bActiveDragAndDropListener = sal_False;
1976 : }
1977 19 : }
1978 :
1979 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|