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