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