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 16 : static inline void lcl_AllignToPixel( Point& rPoint, OutputDevice* pOutDev, short nDiffX, short nDiffY )
56 : {
57 16 : rPoint = pOutDev->LogicToPixel( rPoint );
58 :
59 16 : if ( nDiffX )
60 8 : rPoint.X() += nDiffX;
61 16 : if ( nDiffY )
62 0 : rPoint.Y() += nDiffY;
63 :
64 16 : rPoint = pOutDev->PixelToLogic( rPoint );
65 16 : }
66 :
67 :
68 : // class ImpEditView
69 :
70 301 : ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, Window* pWindow ) :
71 301 : aOutArea( Point(), pEng->GetPaperSize() )
72 : {
73 301 : pEditView = pView;
74 301 : pEditEngine = pEng;
75 301 : pOutWin = pWindow;
76 301 : pPointer = NULL;
77 301 : pBackgroundColor = NULL;
78 301 : nScrollDiffX = 0;
79 301 : nExtraCursorFlags = 0;
80 301 : nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
81 301 : pCursor = NULL;
82 301 : pDragAndDropInfo = NULL;
83 301 : bReadOnly = sal_False;
84 301 : bClickedInSelection = sal_False;
85 301 : eSelectionMode = EE_SELMODE_TXTONLY;
86 301 : eAnchorMode = ANCHOR_TOP_LEFT;
87 301 : nInvMore = 1;
88 301 : nTravelXPos = TRAVEL_X_DONTKNOW;
89 301 : nControl = EV_CNTRL_AUTOSCROLL | EV_CNTRL_ENABLEPASTE;
90 301 : bActiveDragAndDropListener = sal_False;
91 :
92 301 : aEditSelection.Min() = pEng->GetEditDoc().GetStartPaM();
93 301 : aEditSelection.Max() = pEng->GetEditDoc().GetEndPaM();
94 301 : }
95 :
96 903 : ImpEditView::~ImpEditView()
97 : {
98 301 : RemoveDragAndDropListeners();
99 :
100 301 : if ( pOutWin && ( pOutWin->GetCursor() == pCursor ) )
101 225 : pOutWin->SetCursor( NULL );
102 :
103 301 : delete pCursor;
104 301 : delete pBackgroundColor;
105 301 : delete pPointer;
106 301 : delete pDragAndDropInfo;
107 602 : }
108 :
109 48 : void ImpEditView::SetBackgroundColor( const Color& rColor )
110 : {
111 48 : delete pBackgroundColor;
112 48 : pBackgroundColor = new Color( rColor );
113 48 : }
114 :
115 957 : void ImpEditView::SetEditSelection( const EditSelection& rEditSelection )
116 : {
117 : // set state before notification
118 957 : aEditSelection = rEditSelection;
119 :
120 957 : if ( pEditEngine->pImpEditEngine->GetNotifyHdl().IsSet() )
121 : {
122 235 : const EditDoc& rDoc = pEditEngine->GetEditDoc();
123 235 : const EditPaM pmEnd = rDoc.GetEndPaM();
124 : EENotifyType eNotifyType;
125 470 : if (rDoc.Count() > 1 &&
126 235 : 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 235 : eNotifyType = EE_NOTIFY_TEXTVIEWSELECTIONCHANGED;
134 : }
135 : //EENotify aNotify( EE_NOTIFY_TEXTVIEWSELECTIONCHANGED );
136 235 : EENotify aNotify( eNotifyType );
137 235 : aNotify.pEditEngine = pEditEngine;
138 235 : aNotify.pEditView = GetEditViewPtr();
139 235 : pEditEngine->pImpEditEngine->CallNotify( aNotify );
140 : }
141 957 : }
142 :
143 :
144 1530 : void ImpEditView::DrawSelection( EditSelection aTmpSel, Region* pRegion, OutputDevice* pTargetDevice )
145 : {
146 1530 : if ( GetSelectionMode() == EE_SELMODE_HIDDEN )
147 1524 : 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 1528 : PolyPolygon* pPolyPoly = NULL;
157 1528 : if ( pRegion )
158 0 : pPolyPoly = new PolyPolygon;
159 :
160 1528 : OutputDevice* pTarget = pTargetDevice ? pTargetDevice : pOutWin;
161 1528 : sal_Bool bClipRegion = pTarget->IsClipRegion();
162 1528 : Region aOldRegion = pTarget->GetClipRegion();
163 :
164 1528 : if ( !pRegion )
165 : {
166 1528 : if ( !pEditEngine->pImpEditEngine->GetUpdateMode() )
167 1617 : return;
168 1431 : if ( pEditEngine->pImpEditEngine->IsInUndo() )
169 0 : return;
170 :
171 1431 : if ( !aTmpSel.HasRange() )
172 1423 : return;
173 :
174 : // aTmpOutArea: if OutputArea > Paper width and
175 : // Text > Paper width ( over large fields )
176 8 : Rectangle aTmpOutArea( aOutArea );
177 8 : if ( aTmpOutArea.GetWidth() > pEditEngine->pImpEditEngine->GetPaperSize().Width() )
178 0 : aTmpOutArea.Right() = aTmpOutArea.Left() + pEditEngine->pImpEditEngine->GetPaperSize().Width();
179 8 : pTarget->IntersectClipRegion( aTmpOutArea );
180 :
181 8 : if ( pOutWin->GetCursor() )
182 0 : pOutWin->GetCursor()->Hide();
183 : }
184 :
185 : DBG_ASSERT( !pEditEngine->IsIdleFormatterActive(), "DrawSelection: Not formatted!" );
186 8 : aTmpSel.Adjust( pEditEngine->GetEditDoc() );
187 :
188 8 : ContentNode* pStartNode = aTmpSel.Min().GetNode();
189 8 : ContentNode* pEndNode = aTmpSel.Max().GetNode();
190 8 : sal_Int32 nStartPara = pEditEngine->GetEditDoc().GetPos( pStartNode );
191 8 : sal_Int32 nEndPara = pEditEngine->GetEditDoc().GetPos( pEndNode );
192 16 : for ( sal_Int32 nPara = nStartPara; nPara <= nEndPara; nPara++ )
193 : {
194 8 : 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 8 : if ( !pTmpPortion->IsVisible() || pTmpPortion->IsInvalid() )
199 0 : continue;
200 :
201 8 : long nParaStart = pEditEngine->GetParaPortions().GetYOffset( pTmpPortion );
202 8 : if ( ( nParaStart + pTmpPortion->GetHeight() ) < GetVisDocTop() )
203 0 : continue;
204 8 : if ( nParaStart > GetVisDocBottom() )
205 0 : break;
206 :
207 8 : sal_uInt16 nStartLine = 0;
208 8 : sal_uInt16 nEndLine = pTmpPortion->GetLines().Count() -1;
209 8 : if ( nPara == nStartPara )
210 8 : nStartLine = pTmpPortion->GetLines().FindLine( aTmpSel.Min().GetIndex(), false );
211 8 : if ( nPara == nEndPara )
212 8 : nEndLine = pTmpPortion->GetLines().FindLine( aTmpSel.Max().GetIndex(), true );
213 :
214 16 : for ( sal_uInt16 nLine = nStartLine; nLine <= nEndLine; nLine++ )
215 : {
216 8 : const EditLine* pLine = pTmpPortion->GetLines()[nLine];
217 : DBG_ASSERT( pLine, "Line not found: DrawSelection()" );
218 :
219 8 : sal_Bool bPartOfLine = sal_False;
220 8 : sal_Int32 nStartIndex = pLine->GetStart();
221 8 : sal_Int32 nEndIndex = pLine->GetEnd();
222 8 : if ( ( nPara == nStartPara ) && ( nLine == nStartLine ) && ( nStartIndex != aTmpSel.Min().GetIndex() ) )
223 : {
224 6 : nStartIndex = aTmpSel.Min().GetIndex();
225 6 : bPartOfLine = sal_True;
226 : }
227 8 : if ( ( nPara == nEndPara ) && ( nLine == nEndLine ) && ( nEndIndex != aTmpSel.Max().GetIndex() ) )
228 : {
229 6 : nEndIndex = aTmpSel.Max().GetIndex();
230 6 : bPartOfLine = sal_True;
231 : }
232 :
233 : // Can happen if at the beginning of a wrapped line.
234 8 : if ( nEndIndex < nStartIndex )
235 0 : nEndIndex = nStartIndex;
236 :
237 8 : Rectangle aTmpRect( pEditEngine->pImpEditEngine->GetEditCursor( pTmpPortion, nStartIndex ) );
238 8 : Point aTopLeft( aTmpRect.TopLeft() );
239 8 : Point aBottomRight( aTmpRect.BottomRight() );
240 :
241 8 : aTopLeft.Y() += nParaStart;
242 8 : aBottomRight.Y() += nParaStart;
243 :
244 : // Only paint if in the visible range ...
245 8 : if ( aTopLeft.Y() > GetVisDocBottom() )
246 0 : break;
247 :
248 8 : 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' postion
252 8 : 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 8 : sal_Int32 nTmpStartIndex = nStartIndex;
262 : sal_Int32 nWritingDirStart, nTmpEndIndex;
263 :
264 24 : while ( nTmpStartIndex < nEndIndex )
265 : {
266 8 : pEditEngine->pImpEditEngine->GetRightToLeft( nPara, nTmpStartIndex+1, &nWritingDirStart, &nTmpEndIndex );
267 8 : if ( nTmpEndIndex > nEndIndex )
268 6 : nTmpEndIndex = nEndIndex;
269 :
270 : DBG_ASSERT( nTmpEndIndex > nTmpStartIndex, "DrawSelection, Start >= End?" );
271 :
272 8 : long nX1 = pEditEngine->GetXPos(pTmpPortion, pLine, nTmpStartIndex, true);
273 8 : long nX2 = pEditEngine->GetXPos(pTmpPortion, pLine, nTmpEndIndex);
274 :
275 8 : Point aPt1( std::min( nX1, nX2 ), aTopLeft.Y() );
276 8 : Point aPt2( std::max( nX1, nX2 ), aBottomRight.Y() );
277 :
278 8 : ImplDrawHighlightRect( pTarget, aPt1, aPt2, pPolyPoly );
279 :
280 8 : nTmpStartIndex = nTmpEndIndex;
281 : }
282 : }
283 :
284 : }
285 : }
286 :
287 8 : if ( pRegion )
288 : {
289 0 : *pRegion = Region( *pPolyPoly );
290 0 : delete pPolyPoly;
291 : }
292 : else
293 : {
294 8 : if ( pOutWin->GetCursor() )
295 0 : pOutWin->GetCursor()->Show();
296 :
297 8 : if ( bClipRegion )
298 0 : pTarget->SetClipRegion( aOldRegion );
299 : else
300 8 : pTarget->SetClipRegion();
301 8 : }
302 : }
303 :
304 8 : void ImpEditView::ImplDrawHighlightRect( OutputDevice* _pTarget, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, PolyPolygon* pPolyPoly )
305 : {
306 8 : if ( rDocPosTopLeft.X() != rDocPosBottomRight.X() )
307 : {
308 8 : sal_Bool bPixelMode = _pTarget->GetMapMode() == MAP_PIXEL;
309 :
310 8 : Point aPnt1( GetWindowPos( rDocPosTopLeft ) );
311 8 : Point aPnt2( GetWindowPos( rDocPosBottomRight ) );
312 :
313 8 : if ( !IsVertical() )
314 : {
315 8 : lcl_AllignToPixel( aPnt1, _pTarget, +1, 0 );
316 8 : 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 8 : Rectangle aRect( aPnt1, aPnt2 );
325 8 : 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 8 : Window* pWindow = dynamic_cast< Window* >(_pTarget);
337 :
338 8 : if(pWindow)
339 : {
340 8 : pWindow->Invert( aRect );
341 : }
342 : else
343 : {
344 0 : _pTarget->Push(PUSH_LINECOLOR|PUSH_FILLCOLOR|PUSH_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 8 : }
354 :
355 :
356 14124 : sal_Bool ImpEditView::IsVertical() const
357 : {
358 14124 : return pEditEngine->pImpEditEngine->IsVertical();
359 : }
360 :
361 2449 : Rectangle ImpEditView::GetVisDocArea() const
362 : {
363 2449 : return Rectangle( GetVisDocLeft(), GetVisDocTop(), GetVisDocRight(), GetVisDocBottom() );
364 : }
365 :
366 362 : Point ImpEditView::GetDocPos( const Point& rWindowPos ) const
367 : {
368 : // Window Position => Position Document
369 362 : Point aPoint;
370 :
371 362 : if ( !pEditEngine->pImpEditEngine->IsVertical() )
372 : {
373 362 : aPoint.X() = rWindowPos.X() - aOutArea.Left() + GetVisDocLeft();
374 362 : 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 362 : return aPoint;
383 : }
384 :
385 2042 : Point ImpEditView::GetWindowPos( const Point& rDocPos ) const
386 : {
387 : // Document position => window position
388 2042 : Point aPoint;
389 :
390 2042 : if ( !pEditEngine->pImpEditEngine->IsVertical() )
391 : {
392 2042 : aPoint.X() = rDocPos.X() + aOutArea.Left() - GetVisDocLeft();
393 2042 : 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 2042 : return aPoint;
402 : }
403 :
404 2026 : Rectangle ImpEditView::GetWindowPos( const Rectangle& rDocRect ) const
405 : {
406 : // Document position => window position
407 2026 : Point aPos( GetWindowPos( rDocRect.TopLeft() ) );
408 2026 : Size aSz = rDocRect.GetSize();
409 2026 : Rectangle aRect;
410 2026 : if ( !pEditEngine->pImpEditEngine->IsVertical() )
411 : {
412 2026 : 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 2026 : return aRect;
420 : }
421 :
422 61 : void ImpEditView::SetSelectionMode( EESelectionMode eNewMode )
423 : {
424 61 : if ( eSelectionMode != eNewMode )
425 : {
426 13 : DrawSelection();
427 13 : eSelectionMode = eNewMode;
428 13 : DrawSelection(); // redraw
429 : }
430 61 : }
431 :
432 411 : void ImpEditView::SetOutputArea( const Rectangle& rRect )
433 : {
434 : // should be better be aligned on pixels!
435 411 : Rectangle aNewRect( pOutWin->LogicToPixel( rRect ) );
436 411 : aNewRect = pOutWin->PixelToLogic( aNewRect );
437 411 : aOutArea = aNewRect;
438 411 : if ( aOutArea.Right() < aOutArea.Left() )
439 54 : aOutArea.Right() = aOutArea.Left();
440 411 : if ( aOutArea.Bottom() < aOutArea.Top() )
441 54 : aOutArea.Bottom() = aOutArea.Top();
442 :
443 411 : if ( DoBigScroll() )
444 0 : SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 3 / 10 );
445 : else
446 411 : SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 2 / 10 );
447 411 : }
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 411 : void ImpEditView::CalcAnchorPoint()
577 : {
578 : // GetHeight() and GetWidth() -1, because rectangle calculation not preferred.
579 :
580 : // X:
581 411 : switch ( eAnchorMode )
582 : {
583 : case ANCHOR_TOP_LEFT:
584 : case ANCHOR_VCENTER_LEFT:
585 : case ANCHOR_BOTTOM_LEFT:
586 : {
587 411 : aAnchorPoint.X() = aOutArea.Left();
588 : }
589 411 : 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 411 : switch ( eAnchorMode )
608 : {
609 : case ANCHOR_TOP_LEFT:
610 : case ANCHOR_TOP_HCENTER:
611 : case ANCHOR_TOP_RIGHT:
612 : {
613 411 : aAnchorPoint.Y() = aOutArea.Top();
614 : }
615 411 : 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 411 : }
632 :
633 1931 : void ImpEditView::ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor, sal_uInt16 nShowCursorFlags )
634 : {
635 : // No ShowCursor in an empty View ...
636 1931 : if ( ( aOutArea.Left() >= aOutArea.Right() ) && ( aOutArea.Top() >= aOutArea.Bottom() ) )
637 668 : return;
638 :
639 1777 : pEditEngine->CheckIdleFormatter();
640 1777 : if (!pEditEngine->IsFormatted())
641 2 : 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 1777 : if ( pEditEngine->pImpEditEngine->IsFormatting() )
646 0 : return;
647 1777 : if ( !pEditEngine->pImpEditEngine->GetUpdateMode() )
648 357 : return;
649 1420 : if ( pEditEngine->pImpEditEngine->IsInUndo() )
650 0 : return;
651 :
652 1420 : if ( pOutWin->GetCursor() != GetCursor() )
653 273 : pOutWin->SetCursor( GetCursor() );
654 :
655 1420 : EditPaM aPaM( aEditSelection.Max() );
656 :
657 1420 : sal_Int32 nTextPortionStart = 0;
658 1420 : sal_Int32 nPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
659 1420 : if (nPara == EE_PARA_NOT_FOUND) // #i94322
660 3 : return;
661 :
662 1417 : const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
663 :
664 1417 : nShowCursorFlags |= nExtraCursorFlags;
665 :
666 1417 : 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 1417 : if ( ( GetCursorBidiLevel() != CURSOR_BIDILEVEL_DONTKNOW ) && GetCursorBidiLevel() )
673 : {
674 0 : nShowCursorFlags |= GETCRSR_PREFERPORTIONSTART;
675 : }
676 :
677 1417 : Rectangle aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM, nShowCursorFlags );
678 1417 : 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 1417 : long nMaxHeight = !IsVertical() ? aOutArea.GetHeight() : aOutArea.GetWidth();
702 1417 : if ( aEditCursor.GetHeight() > nMaxHeight )
703 : {
704 1272 : aEditCursor.Bottom() = aEditCursor.Top() + nMaxHeight - 1;
705 : }
706 1417 : if ( bGotoCursor ) // && (!pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) )
707 : {
708 : // check if scrolling is necessary...
709 : // if scrolling, then update () and Scroll ()!
710 641 : long nDocDiffX = 0;
711 641 : long nDocDiffY = 0;
712 :
713 641 : Rectangle aTmpVisArea( GetVisDocArea() );
714 : // aTmpOutArea: if OutputArea > Paper width and
715 : // Text > Paper width ( over large fields )
716 641 : long nMaxTextWidth = !IsVertical() ? pEditEngine->pImpEditEngine->GetPaperSize().Width() : pEditEngine->pImpEditEngine->GetPaperSize().Height();
717 641 : if ( aTmpVisArea.GetWidth() > nMaxTextWidth )
718 0 : aTmpVisArea.Right() = aTmpVisArea.Left() + nMaxTextWidth;
719 :
720 641 : if ( aEditCursor.Bottom() > aTmpVisArea.Bottom() )
721 : { // Scroll up, here positive
722 1 : nDocDiffY = aEditCursor.Bottom() - aTmpVisArea.Bottom();
723 : }
724 640 : else if ( aEditCursor.Top() < aTmpVisArea.Top() )
725 : { // Scroll down, here negative
726 0 : nDocDiffY = aEditCursor.Top() - aTmpVisArea.Top();
727 : }
728 :
729 641 : if ( aEditCursor.Right() > aTmpVisArea.Right() )
730 : {
731 : // Scroll left, positiv
732 1 : nDocDiffX = aEditCursor.Right() - aTmpVisArea.Right();
733 : // Can it be a little more?
734 1 : if ( aEditCursor.Right() < ( nMaxTextWidth - GetScrollDiffX() ) )
735 1 : 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 640 : else if ( aEditCursor.Left() < aTmpVisArea.Left() )
745 : {
746 : // Scroll right, negative:
747 1 : nDocDiffX = aEditCursor.Left() - aTmpVisArea.Left();
748 : // Can it be a little more?
749 1 : if ( aEditCursor.Left() > ( - (long)GetScrollDiffX() ) )
750 1 : nDocDiffX -= GetScrollDiffX();
751 : else
752 0 : nDocDiffX -= aEditCursor.Left();
753 : }
754 641 : 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 630 : if ( aEditCursor.Left() < aTmpVisArea.GetWidth() )
759 : {
760 630 : nDocDiffX = -aTmpVisArea.Left();
761 : }
762 : }
763 :
764 641 : if ( nDocDiffX | nDocDiffY )
765 : {
766 2 : long nDiffX = !IsVertical() ? nDocDiffX : -nDocDiffY;
767 2 : long nDiffY = !IsVertical() ? nDocDiffY : nDocDiffX;
768 :
769 : // Negative: Back to the top or left edge
770 2 : 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 2 : 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 2 : if ( nDiffX )
795 2 : pEditEngine->GetInternalEditStatus().GetStatusWord() = pEditEngine->GetInternalEditStatus().GetStatusWord() | EE_STAT_HSCROLL;
796 2 : if ( nDiffY )
797 1 : pEditEngine->GetInternalEditStatus().GetStatusWord() = pEditEngine->GetInternalEditStatus().GetStatusWord() | EE_STAT_VSCROLL;
798 2 : Scroll( -nDiffX, -nDiffY );
799 2 : pEditEngine->pImpEditEngine->DelayedCallStatusHdl();
800 : }
801 : }
802 :
803 : // Cursor may trim a little ...
804 2834 : if ( ( aEditCursor.Bottom() > GetVisDocTop() ) &&
805 1417 : ( aEditCursor.Top() < GetVisDocBottom() ) )
806 : {
807 1417 : if ( aEditCursor.Bottom() > GetVisDocBottom() )
808 0 : aEditCursor.Bottom() = GetVisDocBottom();
809 1417 : if ( aEditCursor.Top() < GetVisDocTop() )
810 0 : aEditCursor.Top() = GetVisDocTop();
811 : }
812 :
813 1417 : long nOnePixel = pOutWin->PixelToLogic( Size( 1, 0 ) ).Width();
814 :
815 1417 : if ( /* pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() || */
816 2834 : ( ( aEditCursor.Top() + nOnePixel >= GetVisDocTop() ) &&
817 2834 : ( aEditCursor.Bottom() - nOnePixel <= GetVisDocBottom() ) &&
818 4251 : ( aEditCursor.Left() + nOnePixel >= GetVisDocLeft() ) &&
819 1417 : ( aEditCursor.Right() - nOnePixel <= GetVisDocRight() ) ) )
820 : {
821 1417 : Rectangle aCursorRect = GetWindowPos( aEditCursor );
822 1417 : GetCursor()->SetPos( aCursorRect.TopLeft() );
823 1417 : Size aCursorSz( aCursorRect.GetSize() );
824 : // Rectangle is inclusive
825 1417 : aCursorSz.Width()--;
826 1417 : aCursorSz.Height()--;
827 1417 : if ( !aCursorSz.Width() || !aCursorSz.Height() )
828 : {
829 1417 : long nCursorSz = pOutWin->GetSettings().GetStyleSettings().GetCursorSize();
830 1417 : nCursorSz = pOutWin->PixelToLogic( Size( nCursorSz, 0 ) ).Width();
831 1417 : if ( !aCursorSz.Width() )
832 1417 : aCursorSz.Width() = nCursorSz;
833 1417 : 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 1417 : 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 1417 : GetCursor()->SetOrientation( 0 );
848 :
849 1417 : GetCursor()->SetSize( aCursorSz );
850 :
851 1417 : unsigned char nCursorDir = CURSOR_DIRECTION_NONE;
852 1417 : 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 1417 : GetCursor()->SetDirection( nCursorDir );
864 :
865 1417 : if ( bForceVisCursor )
866 545 : GetCursor()->Show();
867 : {
868 1417 : SvxFont aFont;
869 1417 : pEditEngine->SeekCursor( aPaM.GetNode(), aPaM.GetIndex()+1, aFont );
870 1417 : sal_uLong nContextFlags = INPUTCONTEXT_TEXT|INPUTCONTEXT_EXTTEXTINPUT;
871 1417 : 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 118 : Pair ImpEditView::Scroll( long ndX, long ndY, sal_uInt8 nRangeCheck )
884 : {
885 : DBG_ASSERT( pEditEngine->pImpEditEngine->IsFormatted(), "Scroll: Not formatted!" );
886 118 : if ( !ndX && !ndY )
887 116 : 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 2 : Rectangle aNewVisArea( GetVisDocArea() );
897 :
898 : // Vertical:
899 2 : if ( !IsVertical() )
900 : {
901 2 : aNewVisArea.Top() -= ndY;
902 2 : aNewVisArea.Bottom() -= ndY;
903 : }
904 : else
905 : {
906 0 : aNewVisArea.Top() += ndX;
907 0 : aNewVisArea.Bottom() += ndX;
908 : }
909 2 : 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 2 : if ( ( aNewVisArea.Top() < 0 ) && ( nRangeCheck != RGCHK_NONE ) )
916 0 : aNewVisArea.Move( 0, -aNewVisArea.Top() );
917 :
918 : // Horizontal:
919 2 : if ( !IsVertical() )
920 : {
921 2 : aNewVisArea.Left() -= ndX;
922 2 : aNewVisArea.Right() -= ndX;
923 : }
924 : else
925 : {
926 0 : aNewVisArea.Left() -= ndY;
927 0 : aNewVisArea.Right() -= ndY;
928 : }
929 2 : if ( ( nRangeCheck == RGCHK_PAPERSZ1 ) && ( aNewVisArea.Right() > (long)pEditEngine->pImpEditEngine->CalcTextWidth( sal_False ) ) )
930 : {
931 0 : long nDiff = pEditEngine->pImpEditEngine->CalcTextWidth( sal_False ) - aNewVisArea.Right(); // negative
932 0 : aNewVisArea.Move( nDiff, 0 ); // could end up in the negative area...
933 : }
934 2 : 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 2 : long nDiffX = !IsVertical() ? ( GetVisDocLeft() - aNewVisArea.Left() ) : -( GetVisDocTop() - aNewVisArea.Top() );
939 2 : long nDiffY = !IsVertical() ? ( GetVisDocTop() - aNewVisArea.Top() ) : ( GetVisDocLeft() - aNewVisArea.Left() );
940 :
941 2 : Size aDiffs( nDiffX, nDiffY );
942 2 : aDiffs = pOutWin->LogicToPixel( aDiffs );
943 2 : aDiffs = pOutWin->PixelToLogic( aDiffs );
944 :
945 2 : long nRealDiffX = aDiffs.Width();
946 2 : long nRealDiffY = aDiffs.Height();
947 :
948 :
949 2 : if ( nRealDiffX || nRealDiffY )
950 : {
951 2 : Cursor* pCrsr = GetCursor();
952 2 : sal_Bool bVisCursor = pCrsr->IsVisible();
953 2 : pCrsr->Hide();
954 2 : pOutWin->Update();
955 2 : if ( !IsVertical() )
956 2 : 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 2 : aVisDocStartPos = pOutWin->LogicToPixel( aVisDocStartPos );
964 2 : aVisDocStartPos = pOutWin->PixelToLogic( aVisDocStartPos );
965 2 : Rectangle aRect( aOutArea );
966 2 : pOutWin->Scroll( nRealDiffX, nRealDiffY, aRect, sal_True );
967 2 : pOutWin->Update();
968 2 : pCrsr->SetPos( pCrsr->GetPos() + Point( nRealDiffX, nRealDiffY ) );
969 2 : if ( bVisCursor )
970 : {
971 0 : Rectangle aCursorRect( pCrsr->GetPos(), pCrsr->GetSize() );
972 0 : if ( aOutArea.IsInside( aCursorRect ) )
973 0 : pCrsr->Show();
974 : }
975 :
976 2 : 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 2 : return Pair( nRealDiffX, nRealDiffY );
986 : }
987 :
988 0 : sal_Bool ImpEditView::PostKeyEvent( const KeyEvent& rKeyEvent, Window* pFrameWin )
989 : {
990 0 : sal_Bool bDone = sal_False;
991 :
992 0 : KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction();
993 0 : if ( eFunc != KEYFUNC_DONTKNOW )
994 : {
995 0 : switch ( eFunc )
996 : {
997 : case KEYFUNC_CUT:
998 : {
999 0 : if ( !bReadOnly )
1000 : {
1001 0 : Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
1002 0 : CutCopy( aClipBoard, sal_True );
1003 0 : bDone = sal_True;
1004 : }
1005 : }
1006 0 : break;
1007 : case KEYFUNC_COPY:
1008 : {
1009 0 : Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipBoard(GetWindow()->GetClipboard());
1010 0 : CutCopy( aClipBoard, sal_False );
1011 0 : bDone = sal_True;
1012 : }
1013 0 : break;
1014 : case KEYFUNC_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 = sal_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 : sal_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 = sal_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, sal_False );
1062 : }
1063 :
1064 0 : return pEditEngine->pImpEditEngine->MouseButtonUp( rMouseEvent, GetEditViewPtr() );
1065 : }
1066 :
1067 0 : sal_Bool ImpEditView::MouseButtonDown( const MouseEvent& rMouseEvent )
1068 : {
1069 0 : pEditEngine->CheckIdleFormatter(); // If fast typing and mouse button downs
1070 0 : if ( pEditEngine->GetInternalEditStatus().NotifyCursorMovements() )
1071 0 : pEditEngine->GetInternalEditStatus().GetPrevParagraph() = pEditEngine->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() );
1072 0 : nTravelXPos = TRAVEL_X_DONTKNOW;
1073 0 : nExtraCursorFlags = 0;
1074 0 : nCursorBidiLevel = CURSOR_BIDILEVEL_DONTKNOW;
1075 0 : bClickedInSelection = IsSelectionAtPoint( rMouseEvent.GetPosPixel() );
1076 0 : return pEditEngine->pImpEditEngine->MouseButtonDown( rMouseEvent, GetEditViewPtr() );
1077 : }
1078 :
1079 0 : sal_Bool ImpEditView::MouseMove( const MouseEvent& rMouseEvent )
1080 : {
1081 0 : return pEditEngine->pImpEditEngine->MouseMove( rMouseEvent, GetEditViewPtr() );
1082 : }
1083 :
1084 0 : void ImpEditView::Command( const CommandEvent& rCEvt )
1085 : {
1086 0 : pEditEngine->CheckIdleFormatter(); // If fast typing and mouse button down
1087 0 : pEditEngine->pImpEditEngine->Command( rCEvt, GetEditViewPtr() );
1088 0 : }
1089 :
1090 :
1091 208 : void ImpEditView::SetInsertMode( sal_Bool bInsert )
1092 : {
1093 208 : if ( bInsert != IsInsertMode() )
1094 : {
1095 0 : SetFlags( nControl, EV_CNTRL_OVERWRITE, !bInsert );
1096 0 : ShowCursor( DoAutoScroll(), sal_False );
1097 : }
1098 208 : }
1099 :
1100 0 : sal_Bool ImpEditView::IsWrongSpelledWord( const EditPaM& rPaM, sal_Bool bMarkIfWrong )
1101 : {
1102 0 : bool bIsWrong = false;
1103 0 : if ( rPaM.GetNode()->GetWrongList() )
1104 : {
1105 0 : EditSelection aSel = pEditEngine->SelectWord( rPaM, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
1106 0 : bIsWrong = rPaM.GetNode()->GetWrongList()->HasWrong( aSel.Min().GetIndex(), aSel.Max().GetIndex() );
1107 0 : if ( bIsWrong && bMarkIfWrong )
1108 : {
1109 0 : DrawSelection();
1110 0 : SetEditSelection( aSel );
1111 0 : DrawSelection();
1112 : }
1113 : }
1114 0 : return bIsWrong;
1115 : }
1116 :
1117 0 : OUString ImpEditView::SpellIgnoreOrAddWord( sal_Bool bAdd )
1118 : {
1119 0 : OUString aWord;
1120 0 : if ( pEditEngine->pImpEditEngine->GetSpeller().is() )
1121 : {
1122 0 : EditPaM aPaM = GetEditSelection().Max();
1123 0 : if ( !HasSelection() )
1124 : {
1125 0 : EditSelection aSel = pEditEngine->SelectWord(aPaM);
1126 0 : aWord = pEditEngine->pImpEditEngine->GetSelected( aSel );
1127 : }
1128 : else
1129 : {
1130 0 : aWord = pEditEngine->pImpEditEngine->GetSelected( GetEditSelection() );
1131 : // And deselect
1132 0 : DrawSelection();
1133 0 : SetEditSelection( EditSelection( aPaM, aPaM ) );
1134 0 : DrawSelection();
1135 : }
1136 :
1137 0 : if ( !aWord.isEmpty() )
1138 : {
1139 0 : if ( bAdd )
1140 : {
1141 : OSL_FAIL( "Sorry, AddWord not implemented" );
1142 : }
1143 : else // Ignore
1144 : {
1145 0 : Reference< XDictionary > xDic( SvxGetIgnoreAllList(), UNO_QUERY );
1146 0 : if (xDic.is())
1147 0 : xDic->add( aWord, sal_False, OUString() );
1148 : }
1149 0 : EditDoc& rDoc = pEditEngine->GetEditDoc();
1150 0 : sal_Int32 nNodes = rDoc.Count();
1151 0 : for ( sal_Int32 n = 0; n < nNodes; n++ )
1152 : {
1153 0 : ContentNode* pNode = rDoc.GetObject( n );
1154 0 : pNode->GetWrongList()->MarkWrongsInvalid();
1155 : }
1156 0 : pEditEngine->pImpEditEngine->DoOnlineSpelling( aPaM.GetNode() );
1157 0 : pEditEngine->pImpEditEngine->StartOnlineSpellTimer();
1158 : }
1159 : }
1160 0 : return aWord;
1161 : }
1162 :
1163 3 : void ImpEditView::DeleteSelected()
1164 : {
1165 3 : DrawSelection();
1166 :
1167 3 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DELETE );
1168 :
1169 3 : EditPaM aPaM = pEditEngine->pImpEditEngine->DeleteSelected( GetEditSelection() );
1170 :
1171 3 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DELETE );
1172 :
1173 3 : SetEditSelection( EditSelection( aPaM, aPaM ) );
1174 3 : pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
1175 3 : ShowCursor( DoAutoScroll(), sal_True );
1176 3 : }
1177 :
1178 0 : const SvxFieldItem* ImpEditView::GetField( const Point& rPos, sal_Int32* pPara, sal_Int32* pPos ) const
1179 : {
1180 0 : if( !GetOutputArea().IsInside( rPos ) )
1181 0 : return 0;
1182 :
1183 0 : Point aDocPos( GetDocPos( rPos ) );
1184 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos, false);
1185 :
1186 0 : if ( aPaM.GetIndex() == aPaM.GetNode()->Len() )
1187 : {
1188 : // Otherwise, whenever the Field at the very end and mouse under the text
1189 0 : return 0;
1190 : }
1191 :
1192 0 : const CharAttribList::AttribsType& rAttrs = aPaM.GetNode()->GetCharAttribs().GetAttribs();
1193 0 : const sal_Int32 nXPos = aPaM.GetIndex();
1194 0 : for (size_t nAttr = rAttrs.size(); nAttr; )
1195 : {
1196 0 : const EditCharAttrib& rAttr = rAttrs[--nAttr];
1197 0 : if (rAttr.GetStart() == nXPos)
1198 : {
1199 0 : if (rAttr.Which() == EE_FEATURE_FIELD)
1200 : {
1201 : DBG_ASSERT(dynamic_cast<const SvxFieldItem*>(rAttr.GetItem()), "No FieldItem...");
1202 0 : if ( pPara )
1203 0 : *pPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1204 0 : if ( pPos )
1205 0 : *pPos = rAttr.GetStart();
1206 0 : return static_cast<const SvxFieldItem*>(rAttr.GetItem());
1207 : }
1208 : }
1209 : }
1210 0 : return NULL;
1211 : }
1212 :
1213 0 : sal_Bool ImpEditView::IsBulletArea( const Point& rPos, sal_Int32* pPara )
1214 : {
1215 0 : if ( pPara )
1216 0 : *pPara = EE_PARA_NOT_FOUND;
1217 :
1218 0 : if( !GetOutputArea().IsInside( rPos ) )
1219 0 : return sal_False;
1220 :
1221 0 : Point aDocPos( GetDocPos( rPos ) );
1222 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos, false);
1223 :
1224 0 : if ( aPaM.GetIndex() == 0 )
1225 : {
1226 0 : sal_Int32 nPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1227 0 : Rectangle aBulletArea = pEditEngine->GetBulletArea( nPara );
1228 0 : long nY = pEditEngine->GetDocPosTopLeft( nPara ).Y();
1229 0 : const ParaPortion* pParaPortion = pEditEngine->GetParaPortions()[nPara];
1230 0 : nY += pParaPortion->GetFirstLineOffset();
1231 0 : if ( ( aDocPos.Y() > ( nY + aBulletArea.Top() ) ) &&
1232 0 : ( aDocPos.Y() < ( nY + aBulletArea.Bottom() ) ) &&
1233 0 : ( aDocPos.X() > ( aBulletArea.Left() ) ) &&
1234 0 : ( aDocPos.X() < ( aBulletArea.Right() ) ) )
1235 : {
1236 0 : if ( pPara )
1237 0 : *pPara = nPara;
1238 0 : return sal_True;
1239 : }
1240 : }
1241 :
1242 0 : return sal_False;
1243 : }
1244 :
1245 0 : void ImpEditView::CutCopy( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bCut )
1246 : {
1247 0 : if ( rxClipboard.is() && GetEditSelection().HasRange() )
1248 : {
1249 0 : uno::Reference<datatransfer::XTransferable> xData = pEditEngine->CreateTransferable( GetEditSelection() );
1250 :
1251 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1252 :
1253 : try
1254 : {
1255 0 : rxClipboard->setContents( xData, NULL );
1256 :
1257 : // #87756# FlushClipboard, but it would be better to become a TerminateListener to the Desktop and flush on demand...
1258 0 : uno::Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( rxClipboard, uno::UNO_QUERY );
1259 0 : if( xFlushableClipboard.is() )
1260 0 : xFlushableClipboard->flushClipboard();
1261 : }
1262 0 : catch( const ::com::sun::star::uno::Exception& )
1263 : {
1264 : }
1265 :
1266 0 : Application::AcquireSolarMutex( nRef );
1267 :
1268 0 : if ( bCut )
1269 : {
1270 0 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_CUT );
1271 0 : DeleteSelected();
1272 0 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_CUT );
1273 :
1274 0 : }
1275 : }
1276 0 : }
1277 :
1278 0 : void ImpEditView::Paste( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& rxClipboard, sal_Bool bUseSpecial )
1279 : {
1280 0 : if ( rxClipboard.is() )
1281 : {
1282 0 : uno::Reference< datatransfer::XTransferable > xDataObj;
1283 :
1284 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1285 :
1286 : try
1287 : {
1288 0 : xDataObj = rxClipboard->getContents();
1289 : }
1290 0 : catch( const ::com::sun::star::uno::Exception& )
1291 : {
1292 : }
1293 :
1294 0 : Application::AcquireSolarMutex( nRef );
1295 :
1296 0 : if ( xDataObj.is() && EditEngine::HasValidData( xDataObj ) )
1297 : {
1298 0 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
1299 :
1300 0 : EditSelection aSel( GetEditSelection() );
1301 0 : if ( aSel.HasRange() )
1302 : {
1303 0 : DrawSelection();
1304 0 : aSel = pEditEngine->DeleteSelection(aSel);
1305 : }
1306 :
1307 0 : PasteOrDropInfos aPasteOrDropInfos;
1308 0 : aPasteOrDropInfos.nAction = EE_ACTION_PASTE;
1309 0 : aPasteOrDropInfos.nStartPara = pEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
1310 0 : pEditEngine->HandleBeginPasteOrDrop(aPasteOrDropInfos);
1311 :
1312 0 : if ( DoSingleLinePaste() )
1313 : {
1314 0 : datatransfer::DataFlavor aFlavor;
1315 0 : SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
1316 0 : if ( xDataObj->isDataFlavorSupported( aFlavor ) )
1317 : {
1318 : try
1319 : {
1320 0 : uno::Any aData = xDataObj->getTransferData( aFlavor );
1321 0 : OUString aTmpText;
1322 0 : aData >>= aTmpText;
1323 0 : OUString aText(convertLineEnd(aTmpText, LINEEND_LF));
1324 0 : aText = aText.replaceAll( OUString(LINE_SEP), " " );
1325 0 : aSel = pEditEngine->InsertText(aSel, aText);
1326 : }
1327 0 : catch( ... )
1328 : {
1329 : ; // #i9286# can happen, even if isDataFlavorSupported returns true...
1330 : }
1331 0 : }
1332 : }
1333 : else
1334 : {
1335 0 : aSel = pEditEngine->InsertText(
1336 0 : xDataObj, OUString(), aSel.Min(),
1337 0 : bUseSpecial && pEditEngine->GetInternalEditStatus().AllowPasteSpecial());
1338 : }
1339 :
1340 0 : aPasteOrDropInfos.nEndPara = pEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
1341 0 : pEditEngine->HandleEndPasteOrDrop(aPasteOrDropInfos);
1342 :
1343 0 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
1344 0 : SetEditSelection( aSel );
1345 0 : pEditEngine->pImpEditEngine->UpdateSelections();
1346 0 : pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
1347 0 : ShowCursor( DoAutoScroll(), sal_True );
1348 0 : }
1349 : }
1350 0 : }
1351 :
1352 :
1353 0 : sal_Bool ImpEditView::IsInSelection( const EditPaM& rPaM )
1354 : {
1355 0 : EditSelection aSel = GetEditSelection();
1356 0 : if ( !aSel.HasRange() )
1357 0 : return sal_False;
1358 :
1359 0 : aSel.Adjust( pEditEngine->GetEditDoc() );
1360 :
1361 0 : sal_Int32 nStartNode = pEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
1362 0 : sal_Int32 nEndNode = pEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
1363 0 : sal_Int32 nCurNode = pEditEngine->GetEditDoc().GetPos( rPaM.GetNode() );
1364 :
1365 0 : if ( ( nCurNode > nStartNode ) && ( nCurNode < nEndNode ) )
1366 0 : return sal_True;
1367 :
1368 0 : if ( nStartNode == nEndNode )
1369 : {
1370 0 : if ( nCurNode == nStartNode )
1371 0 : if ( ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
1372 0 : return sal_True;
1373 : }
1374 0 : else if ( ( nCurNode == nStartNode ) && ( rPaM.GetIndex() >= aSel.Min().GetIndex() ) )
1375 0 : return sal_True;
1376 0 : else if ( ( nCurNode == nEndNode ) && ( rPaM.GetIndex() < aSel.Max().GetIndex() ) )
1377 0 : return sal_True;
1378 :
1379 0 : return sal_False;
1380 : }
1381 :
1382 0 : void ImpEditView::CreateAnchor()
1383 : {
1384 0 : pEditEngine->SetInSelectionMode(true);
1385 0 : GetEditSelection().Min() = GetEditSelection().Max();
1386 0 : }
1387 :
1388 0 : void ImpEditView::DeselectAll()
1389 : {
1390 0 : pEditEngine->SetInSelectionMode(false);
1391 0 : DrawSelection();
1392 0 : GetEditSelection().Min() = GetEditSelection().Max();
1393 0 : }
1394 :
1395 0 : sal_Bool ImpEditView::IsSelectionAtPoint( const Point& rPosPixel )
1396 : {
1397 0 : if ( pDragAndDropInfo && pDragAndDropInfo->pField )
1398 0 : return sal_True;
1399 :
1400 0 : Point aMousePos( rPosPixel );
1401 :
1402 : // Logical units ...
1403 0 : aMousePos = GetWindow()->PixelToLogic( aMousePos );
1404 :
1405 0 : if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
1406 : {
1407 0 : return sal_False;
1408 : }
1409 :
1410 0 : Point aDocPos( GetDocPos( aMousePos ) );
1411 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos, false);
1412 0 : return IsInSelection( aPaM );
1413 : }
1414 :
1415 0 : sal_Bool ImpEditView::SetCursorAtPoint( const Point& rPointPixel )
1416 : {
1417 0 : pEditEngine->CheckIdleFormatter();
1418 :
1419 0 : Point aMousePos( rPointPixel );
1420 :
1421 : // Logical units ...
1422 0 : aMousePos = GetWindow()->PixelToLogic( aMousePos );
1423 :
1424 0 : if ( ( !GetOutputArea().IsInside( aMousePos ) ) && !pEditEngine->pImpEditEngine->IsInSelectionMode() )
1425 : {
1426 0 : return sal_False;
1427 : }
1428 :
1429 0 : Point aDocPos( GetDocPos( aMousePos ) );
1430 :
1431 : // Can be optimized: first go through the lines within a paragraph for PAM,
1432 : // then again with the PaM for the Rect, even though the line is already
1433 : // known .... This must not be, though!
1434 0 : EditPaM aPaM = pEditEngine->GetPaM(aDocPos);
1435 0 : sal_Bool bGotoCursor = DoAutoScroll();
1436 :
1437 : // aTmpNewSel: Diff between old and new, not the new selection
1438 0 : EditSelection aTmpNewSel( GetEditSelection().Max(), aPaM );
1439 :
1440 : // #i27299#
1441 : // work on copy of current selection and set new selection, if it has changed.
1442 0 : EditSelection aNewEditSelection( GetEditSelection() );
1443 :
1444 0 : aNewEditSelection.Max() = aPaM;
1445 0 : if (!pEditEngine->GetSelectionEngine().HasAnchor())
1446 : {
1447 0 : if ( aNewEditSelection.Min() != aPaM )
1448 0 : pEditEngine->CursorMoved(aNewEditSelection.Min().GetNode());
1449 0 : aNewEditSelection.Min() = aPaM;
1450 : }
1451 : else
1452 : {
1453 0 : DrawSelection( aTmpNewSel );
1454 : }
1455 :
1456 : // set changed text selection
1457 0 : if ( GetEditSelection() != aNewEditSelection )
1458 : {
1459 0 : SetEditSelection( aNewEditSelection );
1460 : }
1461 :
1462 0 : sal_Bool bForceCursor = ( pDragAndDropInfo ? sal_False : sal_True ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
1463 0 : ShowCursor( bGotoCursor, bForceCursor );
1464 0 : return sal_True;
1465 : }
1466 :
1467 :
1468 0 : void ImpEditView::HideDDCursor()
1469 : {
1470 0 : if ( pDragAndDropInfo && pDragAndDropInfo->bVisCursor )
1471 : {
1472 0 : GetWindow()->DrawOutDev( pDragAndDropInfo->aCurSavedCursor.TopLeft(), pDragAndDropInfo->aCurSavedCursor.GetSize(),
1473 0 : Point(0,0), pDragAndDropInfo->aCurSavedCursor.GetSize(),*pDragAndDropInfo->pBackground );
1474 0 : pDragAndDropInfo->bVisCursor = sal_False;
1475 : }
1476 0 : }
1477 :
1478 0 : void ImpEditView::ShowDDCursor( const Rectangle& rRect )
1479 : {
1480 0 : if ( pDragAndDropInfo && !pDragAndDropInfo->bVisCursor )
1481 : {
1482 0 : if ( pOutWin->GetCursor() )
1483 0 : pOutWin->GetCursor()->Hide();
1484 :
1485 0 : Color aOldFillColor = GetWindow()->GetFillColor();
1486 0 : GetWindow()->SetFillColor( Color(4210752) ); // GRAY BRUSH_50, OLDSV, change to DDCursor!
1487 :
1488 : // Save background ...
1489 0 : Rectangle aSaveRect( GetWindow()->LogicToPixel( rRect ) );
1490 : // prefer to save some more ...
1491 0 : aSaveRect.Right() += 1;
1492 0 : aSaveRect.Bottom() += 1;
1493 :
1494 : #ifdef DBG_UTIL
1495 : Size aNewSzPx( aSaveRect.GetSize() );
1496 : #endif
1497 0 : if ( !pDragAndDropInfo->pBackground )
1498 : {
1499 0 : pDragAndDropInfo->pBackground = new VirtualDevice( *GetWindow() );
1500 0 : MapMode aMapMode( GetWindow()->GetMapMode() );
1501 0 : aMapMode.SetOrigin( Point( 0, 0 ) );
1502 0 : pDragAndDropInfo->pBackground->SetMapMode( aMapMode );
1503 :
1504 : }
1505 :
1506 : #ifdef DBG_UTIL
1507 : Size aCurSzPx( pDragAndDropInfo->pBackground->GetOutputSizePixel() );
1508 : if ( ( aCurSzPx.Width() < aNewSzPx.Width() ) ||( aCurSzPx.Height() < aNewSzPx.Height() ) )
1509 : {
1510 : sal_Bool bDone = pDragAndDropInfo->pBackground->SetOutputSizePixel( aNewSzPx );
1511 : DBG_ASSERT( bDone, "Virtual Device broken?" );
1512 : }
1513 : #endif
1514 :
1515 0 : aSaveRect = GetWindow()->PixelToLogic( aSaveRect );
1516 :
1517 : pDragAndDropInfo->pBackground->DrawOutDev( Point(0,0), aSaveRect.GetSize(),
1518 0 : aSaveRect.TopLeft(), aSaveRect.GetSize(), *GetWindow() );
1519 0 : pDragAndDropInfo->aCurSavedCursor = aSaveRect;
1520 :
1521 : // Draw Cursor...
1522 0 : GetWindow()->DrawRect( rRect );
1523 :
1524 0 : pDragAndDropInfo->bVisCursor = sal_True;
1525 0 : pDragAndDropInfo->aCurCursor = rRect;
1526 :
1527 0 : GetWindow()->SetFillColor( aOldFillColor );
1528 : }
1529 0 : }
1530 :
1531 0 : void ImpEditView::dragGestureRecognized(const ::com::sun::star::datatransfer::dnd::DragGestureEvent& rDGE)
1532 : throw (::com::sun::star::uno::RuntimeException,
1533 : std::exception)
1534 : {
1535 : DBG_ASSERT( !pDragAndDropInfo, "dragGestureRecognized - DragAndDropInfo exist!" );
1536 :
1537 0 : SolarMutexGuard aVclGuard;
1538 :
1539 0 : pDragAndDropInfo = NULL;
1540 :
1541 0 : Point aMousePosPixel( rDGE.DragOriginX, rDGE.DragOriginY );
1542 :
1543 0 : EditSelection aCopySel( GetEditSelection() );
1544 0 : aCopySel.Adjust( pEditEngine->GetEditDoc() );
1545 :
1546 0 : if ( GetEditSelection().HasRange() && bClickedInSelection )
1547 : {
1548 0 : pDragAndDropInfo = new DragAndDropInfo();
1549 : }
1550 : else
1551 : {
1552 : // Field?!
1553 : sal_Int32 nPara;
1554 : sal_Int32 nPos;
1555 0 : Point aMousePos = GetWindow()->PixelToLogic( aMousePosPixel );
1556 0 : const SvxFieldItem* pField = GetField( aMousePos, &nPara, &nPos );
1557 0 : if ( pField )
1558 : {
1559 0 : pDragAndDropInfo = new DragAndDropInfo();
1560 0 : pDragAndDropInfo->pField = pField;
1561 0 : ContentNode* pNode = pEditEngine->GetEditDoc().GetObject( nPara );
1562 0 : aCopySel = EditSelection( EditPaM( pNode, nPos ), EditPaM( pNode, nPos+1 ) );
1563 0 : GetEditSelection() = aCopySel;
1564 0 : DrawSelection();
1565 0 : sal_Bool bGotoCursor = DoAutoScroll();
1566 0 : ShowCursor( bGotoCursor, /*bForceCursor=*/sal_False );
1567 : }
1568 0 : else if ( IsBulletArea( aMousePos, &nPara ) )
1569 : {
1570 0 : pDragAndDropInfo = new DragAndDropInfo();
1571 0 : pDragAndDropInfo->bOutlinerMode = sal_True;
1572 0 : EditPaM aStartPaM( pEditEngine->GetEditDoc().GetObject( nPara ), 0 );
1573 0 : EditPaM aEndPaM( aStartPaM );
1574 0 : const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
1575 0 : for ( sal_Int32 n = nPara +1; n < pEditEngine->GetEditDoc().Count(); n++ )
1576 : {
1577 0 : const SfxInt16Item& rL = (const SfxInt16Item&) pEditEngine->GetParaAttrib( n, EE_PARA_OUTLLEVEL );
1578 0 : if ( rL.GetValue() > rLevel.GetValue() )
1579 : {
1580 0 : aEndPaM.SetNode( pEditEngine->GetEditDoc().GetObject( n ) );
1581 : }
1582 : else
1583 : {
1584 0 : break;
1585 : }
1586 : }
1587 0 : aEndPaM.SetIndex( aEndPaM.GetNode()->Len() );
1588 0 : SetEditSelection( EditSelection( aStartPaM, aEndPaM ) );
1589 : }
1590 : }
1591 :
1592 0 : if ( pDragAndDropInfo )
1593 : {
1594 :
1595 0 : pDragAndDropInfo->bStarterOfDD = sal_True;
1596 :
1597 : // Sensitive area to be scrolled.
1598 0 : Size aSz( 5, 0 );
1599 0 : aSz = GetWindow()->PixelToLogic( aSz );
1600 0 : pDragAndDropInfo->nSensibleRange = (sal_uInt16) aSz.Width();
1601 0 : pDragAndDropInfo->nCursorWidth = (sal_uInt16) aSz.Width() / 2;
1602 0 : pDragAndDropInfo->aBeginDragSel = pEditEngine->pImpEditEngine->CreateESel( aCopySel );
1603 :
1604 0 : uno::Reference<datatransfer::XTransferable> xData = pEditEngine->CreateTransferable(aCopySel);
1605 :
1606 0 : sal_Int8 nActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;
1607 :
1608 0 : rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, xData, mxDnDListener );
1609 : // If Drag&Move in an Engine, thenCopy&Del has to be optional!
1610 0 : GetCursor()->Hide();
1611 :
1612 0 : }
1613 0 : }
1614 :
1615 0 : void ImpEditView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& rDSDE )
1616 : throw (::com::sun::star::uno::RuntimeException,
1617 : std::exception)
1618 : {
1619 0 : SolarMutexGuard aVclGuard;
1620 :
1621 : DBG_ASSERT( pDragAndDropInfo, "ImpEditView::dragDropEnd: pDragAndDropInfo is NULL!" );
1622 :
1623 : // #123688# Shouldn't happen, but seems to happen...
1624 0 : if ( pDragAndDropInfo )
1625 : {
1626 0 : if ( !bReadOnly && rDSDE.DropSuccess && !pDragAndDropInfo->bOutlinerMode && ( rDSDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE ) )
1627 : {
1628 0 : if ( pDragAndDropInfo->bStarterOfDD && pDragAndDropInfo->bDroppedInMe )
1629 : {
1630 : // DropPos: Where was it dropped, irrespective of length.
1631 0 : ESelection aDropPos( pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos, pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos );
1632 0 : ESelection aToBeDelSel = pDragAndDropInfo->aBeginDragSel;
1633 : ESelection aNewSel( pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos,
1634 0 : pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos );
1635 0 : sal_Bool bBeforeSelection = aDropPos.IsLess( pDragAndDropInfo->aBeginDragSel );
1636 0 : sal_Int32 nParaDiff = pDragAndDropInfo->aBeginDragSel.nEndPara - pDragAndDropInfo->aBeginDragSel.nStartPara;
1637 0 : if ( bBeforeSelection )
1638 : {
1639 : // Adjust aToBeDelSel.
1640 : DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara >= pDragAndDropInfo->aDropSel.nStartPara, "But not before? ");
1641 0 : aToBeDelSel.nStartPara = aToBeDelSel.nStartPara + nParaDiff;
1642 0 : aToBeDelSel.nEndPara = aToBeDelSel.nEndPara + nParaDiff;
1643 : // To correct the character?
1644 0 : if ( aToBeDelSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
1645 : {
1646 : sal_uInt16 nMoreChars;
1647 0 : if ( pDragAndDropInfo->aDropSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
1648 0 : nMoreChars = pDragAndDropInfo->aDropSel.nEndPos - pDragAndDropInfo->aDropSel.nStartPos;
1649 : else
1650 0 : nMoreChars = pDragAndDropInfo->aDropSel.nEndPos;
1651 : aToBeDelSel.nStartPos =
1652 0 : aToBeDelSel.nStartPos + nMoreChars;
1653 0 : if ( aToBeDelSel.nStartPara == aToBeDelSel.nEndPara )
1654 : aToBeDelSel.nEndPos =
1655 0 : aToBeDelSel.nEndPos + nMoreChars;
1656 : }
1657 : }
1658 : else
1659 : {
1660 : // aToBeDelSel is ok, but the selection of the View
1661 : // has to be adapted, if it was deleted before!
1662 : DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara <= pDragAndDropInfo->aDropSel.nStartPara, "But not before? ");
1663 0 : aNewSel.nStartPara = aNewSel.nStartPara - nParaDiff;
1664 0 : aNewSel.nEndPara = aNewSel.nEndPara - nParaDiff;
1665 : // To correct the character?
1666 0 : if ( pDragAndDropInfo->aBeginDragSel.nEndPara == pDragAndDropInfo->aDropSel.nStartPara )
1667 : {
1668 : sal_uInt16 nLessChars;
1669 0 : if ( pDragAndDropInfo->aBeginDragSel.nStartPara == pDragAndDropInfo->aBeginDragSel.nEndPara )
1670 0 : nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos - pDragAndDropInfo->aBeginDragSel.nStartPos;
1671 : else
1672 0 : nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos;
1673 0 : aNewSel.nStartPos = aNewSel.nStartPos - nLessChars;
1674 0 : if ( aNewSel.nStartPara == aNewSel.nEndPara )
1675 0 : aNewSel.nEndPos = aNewSel.nEndPos - nLessChars;
1676 : }
1677 : }
1678 :
1679 0 : DrawSelection();
1680 0 : EditSelection aDelSel( pEditEngine->pImpEditEngine->CreateSel( aToBeDelSel ) );
1681 : DBG_ASSERT( !aDelSel.DbgIsBuggy( pEditEngine->GetEditDoc() ), "ToBeDel is buggy!" );
1682 0 : pEditEngine->DeleteSelection(aDelSel);
1683 0 : if ( !bBeforeSelection )
1684 : {
1685 : DBG_ASSERT( !pEditEngine->pImpEditEngine->CreateSel( aNewSel ).DbgIsBuggy(pEditEngine->GetEditDoc()), "Bad" );
1686 0 : SetEditSelection( pEditEngine->pImpEditEngine->CreateSel( aNewSel ) );
1687 : }
1688 0 : pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
1689 0 : DrawSelection();
1690 : }
1691 : else
1692 : {
1693 : // other EditEngine ...
1694 0 : if (pEditEngine->HasText()) // #88630# SC is removing the content when switching the task
1695 0 : DeleteSelected();
1696 : }
1697 : }
1698 :
1699 0 : if ( pDragAndDropInfo->bUndoAction )
1700 0 : pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DRAGANDDROP );
1701 :
1702 0 : HideDDCursor();
1703 0 : ShowCursor( DoAutoScroll(), sal_True );
1704 0 : delete pDragAndDropInfo;
1705 0 : pDragAndDropInfo = NULL;
1706 0 : pEditEngine->GetEndDropHdl().Call(GetEditViewPtr());
1707 0 : }
1708 0 : }
1709 :
1710 0 : void ImpEditView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE )
1711 : throw (::com::sun::star::uno::RuntimeException,
1712 : std::exception)
1713 : {
1714 0 : SolarMutexGuard aVclGuard;
1715 :
1716 : DBG_ASSERT( pDragAndDropInfo, "Drop - No Drag&Drop info?!" );
1717 :
1718 0 : if ( pDragAndDropInfo && pDragAndDropInfo->bDragAccepted )
1719 : {
1720 0 : pEditEngine->GetBeginDropHdl().Call(GetEditViewPtr());
1721 0 : sal_Bool bChanges = sal_False;
1722 :
1723 0 : HideDDCursor();
1724 :
1725 0 : if ( pDragAndDropInfo->bStarterOfDD )
1726 : {
1727 0 : pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DRAGANDDROP );
1728 0 : pDragAndDropInfo->bUndoAction = sal_True;
1729 : }
1730 :
1731 0 : if ( pDragAndDropInfo->bOutlinerMode )
1732 : {
1733 0 : bChanges = sal_True;
1734 0 : GetEditViewPtr()->MoveParagraphs( Range( pDragAndDropInfo->aBeginDragSel.nStartPara, pDragAndDropInfo->aBeginDragSel.nEndPara ), pDragAndDropInfo->nOutlinerDropDest );
1735 : }
1736 : else
1737 : {
1738 0 : uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
1739 0 : if ( xDataObj.is() )
1740 : {
1741 0 : bChanges = true;
1742 : // remove Selection ...
1743 0 : DrawSelection();
1744 0 : EditPaM aPaM( pDragAndDropInfo->aDropDest );
1745 :
1746 0 : PasteOrDropInfos aPasteOrDropInfos;
1747 0 : aPasteOrDropInfos.nAction = EE_ACTION_DROP;
1748 0 : aPasteOrDropInfos.nStartPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1749 0 : pEditEngine->HandleBeginPasteOrDrop(aPasteOrDropInfos);
1750 :
1751 : EditSelection aNewSel = pEditEngine->InsertText(
1752 0 : xDataObj, OUString(), aPaM, pEditEngine->GetInternalEditStatus().AllowPasteSpecial());
1753 :
1754 0 : aPasteOrDropInfos.nEndPara = pEditEngine->GetEditDoc().GetPos( aNewSel.Max().GetNode() );
1755 0 : pEditEngine->HandleEndPasteOrDrop(aPasteOrDropInfos);
1756 :
1757 0 : SetEditSelection( aNewSel );
1758 0 : pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
1759 0 : if ( pDragAndDropInfo->bStarterOfDD )
1760 : {
1761 : // Only set if the same engine!
1762 0 : pDragAndDropInfo->aDropSel.nStartPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1763 0 : pDragAndDropInfo->aDropSel.nStartPos = aPaM.GetIndex();
1764 0 : pDragAndDropInfo->aDropSel.nEndPara = pEditEngine->GetEditDoc().GetPos( aNewSel.Max().GetNode() );
1765 0 : pDragAndDropInfo->aDropSel.nEndPos = aNewSel.Max().GetIndex();
1766 0 : pDragAndDropInfo->bDroppedInMe = sal_True;
1767 : }
1768 0 : }
1769 : }
1770 :
1771 0 : if ( bChanges )
1772 : {
1773 0 : rDTDE.Context->acceptDrop( rDTDE.DropAction );
1774 : }
1775 :
1776 0 : if ( !pDragAndDropInfo->bStarterOfDD )
1777 : {
1778 0 : delete pDragAndDropInfo;
1779 0 : pDragAndDropInfo = NULL;
1780 : }
1781 :
1782 0 : rDTDE.Context->dropComplete( bChanges );
1783 0 : }
1784 0 : }
1785 :
1786 0 : void ImpEditView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& rDTDEE ) throw (::com::sun::star::uno::RuntimeException, std::exception)
1787 : {
1788 0 : SolarMutexGuard aVclGuard;
1789 :
1790 0 : if ( !pDragAndDropInfo )
1791 0 : pDragAndDropInfo = new DragAndDropInfo( );
1792 :
1793 0 : pDragAndDropInfo->bHasValidData = sal_False;
1794 :
1795 : // Check for supported format...
1796 : // Only check for text, will also be there if bin or rtf
1797 0 : datatransfer::DataFlavor aTextFlavor;
1798 0 : SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aTextFlavor );
1799 0 : const ::com::sun::star::datatransfer::DataFlavor* pFlavors = rDTDEE.SupportedDataFlavors.getConstArray();
1800 0 : int nFlavors = rDTDEE.SupportedDataFlavors.getLength();
1801 0 : for ( int n = 0; n < nFlavors; n++ )
1802 : {
1803 0 : if( TransferableDataHelper::IsEqual( pFlavors[n], aTextFlavor ) )
1804 : {
1805 0 : pDragAndDropInfo->bHasValidData = sal_True;
1806 0 : break;
1807 : }
1808 : }
1809 :
1810 0 : dragOver( rDTDEE );
1811 0 : }
1812 :
1813 0 : void ImpEditView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException, std::exception)
1814 : {
1815 0 : SolarMutexGuard aVclGuard;
1816 :
1817 0 : HideDDCursor();
1818 :
1819 0 : if ( pDragAndDropInfo && !pDragAndDropInfo->bStarterOfDD )
1820 : {
1821 0 : delete pDragAndDropInfo;
1822 0 : pDragAndDropInfo = NULL;
1823 0 : }
1824 0 : }
1825 :
1826 0 : void ImpEditView::dragOver(const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE)
1827 : throw (::com::sun::star::uno::RuntimeException,
1828 : std::exception)
1829 : {
1830 0 : SolarMutexGuard aVclGuard;
1831 :
1832 0 : Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
1833 0 : aMousePos = GetWindow()->PixelToLogic( aMousePos );
1834 :
1835 0 : sal_Bool bAccept = sal_False;
1836 :
1837 0 : if ( GetOutputArea().IsInside( aMousePos ) && !bReadOnly )
1838 : {
1839 0 : if ( pDragAndDropInfo && pDragAndDropInfo->bHasValidData )
1840 : {
1841 0 : bAccept = sal_True;
1842 :
1843 0 : sal_Bool bAllowScroll = DoAutoScroll();
1844 0 : if ( bAllowScroll )
1845 : {
1846 0 : long nScrollX = 0;
1847 0 : long nScrollY = 0;
1848 : // Chech if in the sensitive area
1849 0 : if ( ( (aMousePos.X()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Left() ) && ( ( aMousePos.X() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Left() ) )
1850 0 : nScrollX = GetOutputArea().GetWidth() / SCRLRANGE;
1851 0 : else if ( ( (aMousePos.X()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Right() ) && ( ( aMousePos.X() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Right() ) )
1852 0 : nScrollX = -( GetOutputArea().GetWidth() / SCRLRANGE );
1853 :
1854 0 : if ( ( (aMousePos.Y()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Top() ) && ( ( aMousePos.Y() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Top() ) )
1855 0 : nScrollY = GetOutputArea().GetHeight() / SCRLRANGE;
1856 0 : else if ( ( (aMousePos.Y()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Bottom() ) && ( ( aMousePos.Y() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Bottom() ) )
1857 0 : nScrollY = -( GetOutputArea().GetHeight() / SCRLRANGE );
1858 :
1859 0 : if ( nScrollX || nScrollY )
1860 : {
1861 0 : HideDDCursor();
1862 0 : Scroll( nScrollX, nScrollY, RGCHK_PAPERSZ1 );
1863 : }
1864 : }
1865 :
1866 0 : Point aDocPos( GetDocPos( aMousePos ) );
1867 0 : EditPaM aPaM = pEditEngine->GetPaM( aDocPos );
1868 0 : pDragAndDropInfo->aDropDest = aPaM;
1869 0 : if ( pDragAndDropInfo->bOutlinerMode )
1870 : {
1871 0 : sal_Int32 nPara = pEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1872 0 : ParaPortion* pPPortion = pEditEngine->GetParaPortions().SafeGetObject( nPara );
1873 0 : long nDestParaStartY = pEditEngine->GetParaPortions().GetYOffset( pPPortion );
1874 0 : long nRel = aDocPos.Y() - nDestParaStartY;
1875 0 : if ( nRel < ( pPPortion->GetHeight() / 2 ) )
1876 : {
1877 0 : pDragAndDropInfo->nOutlinerDropDest = nPara;
1878 : }
1879 : else
1880 : {
1881 0 : pDragAndDropInfo->nOutlinerDropDest = nPara+1;
1882 : }
1883 :
1884 0 : if( ( pDragAndDropInfo->nOutlinerDropDest >= pDragAndDropInfo->aBeginDragSel.nStartPara ) &&
1885 0 : ( pDragAndDropInfo->nOutlinerDropDest <= (pDragAndDropInfo->aBeginDragSel.nEndPara+1) ) )
1886 : {
1887 0 : bAccept = sal_False;
1888 : }
1889 : }
1890 0 : else if ( HasSelection() )
1891 : {
1892 : // it must not be dropped into a selection
1893 0 : EPaM aP = pEditEngine->pImpEditEngine->CreateEPaM( aPaM );
1894 0 : ESelection aDestSel( aP.nPara, aP.nIndex, aP.nPara, aP.nIndex);
1895 0 : ESelection aCurSel = pEditEngine->pImpEditEngine->CreateESel( GetEditSelection() );
1896 0 : aCurSel.Adjust();
1897 0 : if ( !aDestSel.IsLess( aCurSel ) && !aDestSel.IsGreater( aCurSel ) )
1898 : {
1899 0 : bAccept = sal_False;
1900 : }
1901 : }
1902 0 : if ( bAccept )
1903 : {
1904 0 : Rectangle aEditCursor;
1905 0 : if ( pDragAndDropInfo->bOutlinerMode )
1906 : {
1907 : long nDDYPos;
1908 0 : if ( pDragAndDropInfo->nOutlinerDropDest < pEditEngine->GetEditDoc().Count() )
1909 : {
1910 0 : ParaPortion* pPPortion = pEditEngine->GetParaPortions().SafeGetObject( pDragAndDropInfo->nOutlinerDropDest );
1911 0 : nDDYPos = pEditEngine->GetParaPortions().GetYOffset( pPPortion );
1912 : }
1913 : else
1914 : {
1915 0 : nDDYPos = pEditEngine->pImpEditEngine->GetTextHeight();
1916 : }
1917 0 : Point aStartPos( 0, nDDYPos );
1918 0 : aStartPos = GetWindowPos( aStartPos );
1919 0 : Point aEndPos( GetOutputArea().GetWidth(), nDDYPos );
1920 0 : aEndPos = GetWindowPos( aEndPos );
1921 0 : aEditCursor = GetWindow()->LogicToPixel( Rectangle( aStartPos, aEndPos ) );
1922 0 : if ( !pEditEngine->IsVertical() )
1923 : {
1924 0 : aEditCursor.Top()--;
1925 0 : aEditCursor.Bottom()++;
1926 : }
1927 : else
1928 : {
1929 0 : aEditCursor.Left()--;
1930 0 : aEditCursor.Right()++;
1931 : }
1932 0 : aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
1933 : }
1934 : else
1935 : {
1936 0 : aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM );
1937 0 : Point aTopLeft( GetWindowPos( aEditCursor.TopLeft() ) );
1938 0 : aEditCursor.SetPos( aTopLeft );
1939 0 : aEditCursor.Right() = aEditCursor.Left() + pDragAndDropInfo->nCursorWidth;
1940 0 : aEditCursor = GetWindow()->LogicToPixel( aEditCursor );
1941 0 : aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
1942 : }
1943 :
1944 0 : sal_Bool bCursorChanged = !pDragAndDropInfo->bVisCursor || ( pDragAndDropInfo->aCurCursor != aEditCursor );
1945 0 : if ( bCursorChanged )
1946 : {
1947 0 : HideDDCursor();
1948 0 : ShowDDCursor(aEditCursor );
1949 : }
1950 0 : pDragAndDropInfo->bDragAccepted = sal_True;
1951 0 : rDTDE.Context->acceptDrag( rDTDE.DropAction );
1952 : }
1953 : }
1954 : }
1955 :
1956 0 : if ( !bAccept )
1957 : {
1958 0 : HideDDCursor();
1959 0 : if (pDragAndDropInfo)
1960 0 : pDragAndDropInfo->bDragAccepted = sal_False;
1961 0 : rDTDE.Context->rejectDrag();
1962 0 : }
1963 0 : }
1964 :
1965 301 : void ImpEditView::AddDragAndDropListeners()
1966 : {
1967 301 : Window* pWindow = GetWindow();
1968 301 : if ( !bActiveDragAndDropListener && pWindow && pWindow->GetDragGestureRecognizer().is() )
1969 : {
1970 301 : vcl::unohelper::DragAndDropWrapper* pDnDWrapper = new vcl::unohelper::DragAndDropWrapper( this );
1971 301 : mxDnDListener = pDnDWrapper;
1972 :
1973 301 : uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
1974 301 : pWindow->GetDragGestureRecognizer()->addDragGestureListener( xDGL );
1975 602 : uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
1976 301 : pWindow->GetDropTarget()->addDropTargetListener( xDTL );
1977 301 : pWindow->GetDropTarget()->setActive( sal_True );
1978 301 : pWindow->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );
1979 :
1980 602 : bActiveDragAndDropListener = sal_True;
1981 : }
1982 301 : }
1983 :
1984 346 : void ImpEditView::RemoveDragAndDropListeners()
1985 : {
1986 346 : if ( bActiveDragAndDropListener && GetWindow() && GetWindow()->GetDragGestureRecognizer().is() )
1987 : {
1988 253 : uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
1989 253 : GetWindow()->GetDragGestureRecognizer()->removeDragGestureListener( xDGL );
1990 506 : uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
1991 253 : GetWindow()->GetDropTarget()->removeDropTargetListener( xDTL );
1992 :
1993 253 : if ( mxDnDListener.is() )
1994 : {
1995 253 : uno::Reference< lang::XEventListener> xEL( mxDnDListener, uno::UNO_QUERY );
1996 253 : xEL->disposing( lang::EventObject() ); // #95154# Empty Source means it's the Client
1997 253 : mxDnDListener.clear();
1998 : }
1999 :
2000 506 : bActiveDragAndDropListener = sal_False;
2001 : }
2002 346 : }
2003 :
2004 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|