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_uInt16 nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( pStartNode );
195 sal_uInt16 nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( pEndNode );
196 // ueber die Absaetze iterieren....
197 for ( sal_uInt16 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' postion
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_uInt16 nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
674 if (nPara == USHRT_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_uInt16 nNodes = rDoc.Count();
1173 for ( sal_uInt16 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_uInt16 * pPara,sal_uInt16 * pPos) const1201 const SvxFieldItem* ImpEditView::GetField( const Point& rPos, sal_uInt16* 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_uInt16 * pPara)1234 sal_Bool ImpEditView::IsBulletArea( const Point& rPos, sal_uInt16* pPara )
1235 {
1236 if ( pPara )
1237 *pPara = 0xFFFF;
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_uInt16 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_uInt16 nStartNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
1382 sal_uInt16 nEndNode = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
1383 sal_uInt16 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_uInt16 nPara, nPos;
1573 Point aMousePos = GetWindow()->PixelToLogic( aMousePosPixel );
1574 const SvxFieldItem* pField = GetField( aMousePos, &nPara, &nPos );
1575 if ( pField )
1576 {
1577 pDragAndDropInfo = new DragAndDropInfo();
1578 pDragAndDropInfo->pField = pField;
1579 ContentNode* pNode = pEditEngine->pImpEditEngine->GetEditDoc().GetObject( nPara );
1580 aCopySel = EditSelection( EditPaM( pNode, nPos ), EditPaM( pNode, nPos+1 ) );
1581 GetEditSelection() = aCopySel;
1582 DrawSelection();
1583 sal_Bool bGotoCursor = DoAutoScroll();
1584 sal_Bool bForceCursor = ( pDragAndDropInfo ? sal_False : sal_True ) && !pEditEngine->pImpEditEngine->IsInSelectionMode();
1585 ShowCursor( bGotoCursor, bForceCursor );
1586 }
1587 else if ( IsBulletArea( aMousePos, &nPara ) )
1588 {
1589 pDragAndDropInfo = new DragAndDropInfo();
1590 pDragAndDropInfo->bOutlinerMode = sal_True;
1591 EditPaM aStartPaM( pEditEngine->pImpEditEngine->GetEditDoc().GetObject( nPara ), 0 );
1592 EditPaM aEndPaM( aStartPaM );
1593 const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
1594 for ( sal_uInt16 n = nPara +1; n < pEditEngine->pImpEditEngine->GetEditDoc().Count(); n++ )
1595 {
1596 const SfxInt16Item& rL = (const SfxInt16Item&) pEditEngine->GetParaAttrib( n, EE_PARA_OUTLLEVEL );
1597 if ( rL.GetValue() > rLevel.GetValue() )
1598 {
1599 aEndPaM.SetNode( pEditEngine->pImpEditEngine->GetEditDoc().GetObject( n ) );
1600 }
1601 else
1602 {
1603 break;
1604 }
1605 }
1606 aEndPaM.GetIndex() = aEndPaM.GetNode()->Len();
1607 SetEditSelection( EditSelection( aStartPaM, aEndPaM ) );
1608 }
1609 }
1610
1611 if ( pDragAndDropInfo )
1612 {
1613
1614 pDragAndDropInfo->bStarterOfDD = sal_True;
1615
1616 // Sensibler Bereich, wo gescrollt werden soll.
1617 Size aSz( 5, 0 );
1618 aSz = GetWindow()->PixelToLogic( aSz );
1619 pDragAndDropInfo->nSensibleRange = (sal_uInt16) aSz.Width();
1620 pDragAndDropInfo->nCursorWidth = (sal_uInt16) aSz.Width() / 2;
1621 pDragAndDropInfo->aBeginDragSel = pEditEngine->pImpEditEngine->CreateESel( aCopySel );
1622
1623 uno::Reference< datatransfer::XTransferable > xData = pEditEngine->pImpEditEngine->CreateTransferable( aCopySel );
1624
1625 sal_Int8 nActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;
1626
1627 rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, xData, mxDnDListener );
1628 // Falls Drag&Move in einer Engine, muessen Copy&Del geklammert sein!
1629 GetCursor()->Hide();
1630
1631 }
1632 }
1633
dragDropEnd(const::com::sun::star::datatransfer::dnd::DragSourceDropEvent & rDSDE)1634 void ImpEditView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent& rDSDE ) throw (::com::sun::star::uno::RuntimeException)
1635 {
1636 vos::OGuard aVclGuard( Application::GetSolarMutex() );
1637
1638 DBG_ASSERT( pDragAndDropInfo, "ImpEditView::dragDropEnd: pDragAndDropInfo is NULL!" );
1639
1640 // #123688# Shouldn't happen, but seems to happen...
1641 if ( pDragAndDropInfo )
1642 {
1643 if ( !bReadOnly && rDSDE.DropSuccess && !pDragAndDropInfo->bOutlinerMode && ( rDSDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE ) )
1644 {
1645 if ( pDragAndDropInfo->bStarterOfDD && pDragAndDropInfo->bDroppedInMe )
1646 {
1647 // DropPos: Wohin wurde gedroppt, unabhaengig von laenge.
1648 ESelection aDropPos( pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos, pDragAndDropInfo->aDropSel.nStartPara, pDragAndDropInfo->aDropSel.nStartPos );
1649 ESelection aToBeDelSel = pDragAndDropInfo->aBeginDragSel;
1650 ESelection aNewSel( pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos,
1651 pDragAndDropInfo->aDropSel.nEndPara, pDragAndDropInfo->aDropSel.nEndPos );
1652 sal_Bool bBeforeSelection = aDropPos.IsLess( pDragAndDropInfo->aBeginDragSel );
1653 sal_uInt16 nParaDiff = pDragAndDropInfo->aBeginDragSel.nEndPara - pDragAndDropInfo->aBeginDragSel.nStartPara;
1654 if ( bBeforeSelection )
1655 {
1656 // aToBeDelSel anpassen.
1657 DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara >= pDragAndDropInfo->aDropSel.nStartPara, "Doch nicht davor?" );
1658 aToBeDelSel.nStartPara = aToBeDelSel.nStartPara + nParaDiff;
1659 aToBeDelSel.nEndPara = aToBeDelSel.nEndPara + nParaDiff;
1660 // Zeichen korrigieren?
1661 if ( aToBeDelSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
1662 {
1663 sal_uInt16 nMoreChars;
1664 if ( pDragAndDropInfo->aDropSel.nStartPara == pDragAndDropInfo->aDropSel.nEndPara )
1665 nMoreChars = pDragAndDropInfo->aDropSel.nEndPos - pDragAndDropInfo->aDropSel.nStartPos;
1666 else
1667 nMoreChars = pDragAndDropInfo->aDropSel.nEndPos;
1668 aToBeDelSel.nStartPos =
1669 aToBeDelSel.nStartPos + nMoreChars;
1670 if ( aToBeDelSel.nStartPara == aToBeDelSel.nEndPara )
1671 aToBeDelSel.nEndPos =
1672 aToBeDelSel.nEndPos + nMoreChars;
1673 }
1674 }
1675 else
1676 {
1677 // aToBeDelSel ist ok, aber Selektion der View
1678 // muss angepasst werden, wenn davor geloescht wird!
1679 DBG_ASSERT( pDragAndDropInfo->aBeginDragSel.nStartPara <= pDragAndDropInfo->aDropSel.nStartPara, "Doch nicht davor?" );
1680 aNewSel.nStartPara = aNewSel.nStartPara - nParaDiff;
1681 aNewSel.nEndPara = aNewSel.nEndPara - nParaDiff;
1682 // Zeichen korrigieren?
1683 if ( pDragAndDropInfo->aBeginDragSel.nEndPara == pDragAndDropInfo->aDropSel.nStartPara )
1684 {
1685 sal_uInt16 nLessChars;
1686 if ( pDragAndDropInfo->aBeginDragSel.nStartPara == pDragAndDropInfo->aBeginDragSel.nEndPara )
1687 nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos - pDragAndDropInfo->aBeginDragSel.nStartPos;
1688 else
1689 nLessChars = pDragAndDropInfo->aBeginDragSel.nEndPos;
1690 aNewSel.nStartPos = aNewSel.nStartPos - nLessChars;
1691 if ( aNewSel.nStartPara == aNewSel.nEndPara )
1692 aNewSel.nEndPos = aNewSel.nEndPos - nLessChars;
1693 }
1694 }
1695
1696 DrawSelection();
1697 EditSelection aDelSel( pEditEngine->pImpEditEngine->CreateSel( aToBeDelSel ) );
1698 DBG_ASSERT( !aDelSel.DbgIsBuggy( pEditEngine->pImpEditEngine->aEditDoc ), "ToBeDel ist buggy!" );
1699 pEditEngine->pImpEditEngine->ImpDeleteSelection( aDelSel );
1700 if ( !bBeforeSelection )
1701 {
1702 DBG_ASSERT( !pEditEngine->pImpEditEngine->CreateSel( aNewSel ).DbgIsBuggy(pEditEngine->pImpEditEngine->aEditDoc), "Bad" );
1703 SetEditSelection( pEditEngine->pImpEditEngine->CreateSel( aNewSel ) );
1704 }
1705 pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
1706 DrawSelection();
1707 }
1708 else
1709 {
1710 // andere EditEngine...
1711 if ( pEditEngine->pImpEditEngine->ImplHasText() ) // #88630# SC ist removing the content when switching the task
1712 DeleteSelected();
1713 }
1714 }
1715
1716 if ( pDragAndDropInfo->bUndoAction )
1717 pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_DRAGANDDROP );
1718
1719 HideDDCursor();
1720 ShowCursor( DoAutoScroll(), sal_True );
1721 delete pDragAndDropInfo;
1722 pDragAndDropInfo = NULL;
1723 pEditEngine->GetEndDropHdl().Call(GetEditViewPtr());
1724 }
1725 }
1726
drop(const::com::sun::star::datatransfer::dnd::DropTargetDropEvent & rDTDE)1727 void ImpEditView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
1728 {
1729 vos::OGuard aVclGuard( Application::GetSolarMutex() );
1730
1731 DBG_ASSERT( pDragAndDropInfo, "Drop - No Drag&Drop info?!" );
1732
1733 if ( pDragAndDropInfo && pDragAndDropInfo->bDragAccepted )
1734 {
1735 pEditEngine->GetBeginDropHdl().Call(GetEditViewPtr());
1736 sal_Bool bChanges = sal_False;
1737
1738 HideDDCursor();
1739
1740 if ( pDragAndDropInfo->bStarterOfDD )
1741 {
1742 pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DRAGANDDROP );
1743 pDragAndDropInfo->bUndoAction = sal_True;
1744 }
1745
1746 if ( pDragAndDropInfo->bOutlinerMode )
1747 {
1748 bChanges = sal_True;
1749 GetEditViewPtr()->MoveParagraphs( Range( pDragAndDropInfo->aBeginDragSel.nStartPara, pDragAndDropInfo->aBeginDragSel.nEndPara ), pDragAndDropInfo->nOutlinerDropDest );
1750 }
1751 else
1752 {
1753 uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
1754 if ( xDataObj.is() )
1755 {
1756 bChanges = sal_True;
1757 // Selektion wegmalen...
1758 DrawSelection();
1759 EditPaM aPaM( pDragAndDropInfo->aDropDest );
1760
1761 PasteOrDropInfos aPasteOrDropInfos;
1762 aPasteOrDropInfos.nAction = EE_ACTION_DROP;
1763 aPasteOrDropInfos.nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aPaM.GetNode() );
1764 pEditEngine->pImpEditEngine->aBeginPasteOrDropHdl.Call( &aPasteOrDropInfos );
1765
1766 EditSelection aNewSel = pEditEngine->pImpEditEngine->InsertText( xDataObj, String(), aPaM, pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
1767
1768 aPasteOrDropInfos.nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aNewSel.Max().GetNode() );
1769 pEditEngine->pImpEditEngine->aEndPasteOrDropHdl.Call( &aPasteOrDropInfos );
1770
1771 SetEditSelection( aNewSel );
1772 pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
1773 if ( pDragAndDropInfo->bStarterOfDD )
1774 {
1775 // Nur dann setzen, wenn in gleicher Engine!
1776 pDragAndDropInfo->aDropSel.nStartPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
1777 pDragAndDropInfo->aDropSel.nStartPos = aPaM.GetIndex();
1778 pDragAndDropInfo->aDropSel.nEndPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aNewSel.Max().GetNode() );
1779 pDragAndDropInfo->aDropSel.nEndPos = aNewSel.Max().GetIndex();
1780 pDragAndDropInfo->bDroppedInMe = sal_True;
1781 }
1782 }
1783 }
1784
1785 if ( bChanges )
1786 {
1787 rDTDE.Context->acceptDrop( rDTDE.DropAction );
1788 }
1789
1790 if ( !pDragAndDropInfo->bStarterOfDD )
1791 {
1792 delete pDragAndDropInfo;
1793 pDragAndDropInfo = NULL;
1794 }
1795
1796 rDTDE.Context->dropComplete( bChanges );
1797 }
1798 }
1799
dragEnter(const::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent & rDTDEE)1800 void ImpEditView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& rDTDEE ) throw (::com::sun::star::uno::RuntimeException)
1801 {
1802 vos::OGuard aVclGuard( Application::GetSolarMutex() );
1803
1804 if ( !pDragAndDropInfo )
1805 pDragAndDropInfo = new DragAndDropInfo( );
1806
1807 pDragAndDropInfo->bHasValidData = sal_False;
1808
1809 // Check for supported format...
1810 // Only check for text, will also be there if bin or rtf
1811 datatransfer::DataFlavor aTextFlavor;
1812 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aTextFlavor );
1813 const ::com::sun::star::datatransfer::DataFlavor* pFlavors = rDTDEE.SupportedDataFlavors.getConstArray();
1814 int nFlavors = rDTDEE.SupportedDataFlavors.getLength();
1815 for ( int n = 0; n < nFlavors; n++ )
1816 {
1817 if( TransferableDataHelper::IsEqual( pFlavors[n], aTextFlavor ) )
1818 {
1819 pDragAndDropInfo->bHasValidData = sal_True;
1820 break;
1821 }
1822 }
1823
1824 dragOver( rDTDEE );
1825 }
1826
dragExit(const::com::sun::star::datatransfer::dnd::DropTargetEvent &)1827 void ImpEditView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException)
1828 {
1829 vos::OGuard aVclGuard( Application::GetSolarMutex() );
1830
1831 HideDDCursor();
1832
1833 if ( pDragAndDropInfo && !pDragAndDropInfo->bStarterOfDD )
1834 {
1835 delete pDragAndDropInfo;
1836 pDragAndDropInfo = NULL;
1837 }
1838 }
1839
dragOver(const::com::sun::star::datatransfer::dnd::DropTargetDragEvent & rDTDE)1840 void ImpEditView::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException)
1841 {
1842 vos::OGuard aVclGuard( Application::GetSolarMutex() );
1843
1844 Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
1845 aMousePos = GetWindow()->PixelToLogic( aMousePos );
1846
1847 sal_Bool bAccept = sal_False;
1848
1849 if ( GetOutputArea().IsInside( aMousePos ) && !bReadOnly )
1850 {
1851 // sal_Int8 nSupportedActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;
1852
1853 if ( pDragAndDropInfo && pDragAndDropInfo->bHasValidData /* && ( nSupportedActions & rDTDE.DropAction ) MT: Default = 0x80 ?! */ )
1854 {
1855 bAccept = sal_True;
1856
1857 sal_Bool bAllowScroll = DoAutoScroll();
1858 if ( bAllowScroll )
1859 {
1860 long nScrollX = 0;
1861 long nScrollY = 0;
1862 // pruefen, ob im sensitiven Bereich
1863 if ( ( (aMousePos.X()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Left() ) && ( ( aMousePos.X() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Left() ) )
1864 nScrollX = GetOutputArea().GetWidth() / SCRLRANGE;
1865 else if ( ( (aMousePos.X()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Right() ) && ( ( aMousePos.X() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Right() ) )
1866 nScrollX = -( GetOutputArea().GetWidth() / SCRLRANGE );
1867
1868 if ( ( (aMousePos.Y()-pDragAndDropInfo->nSensibleRange) < GetOutputArea().Top() ) && ( ( aMousePos.Y() + pDragAndDropInfo->nSensibleRange ) > GetOutputArea().Top() ) )
1869 nScrollY = GetOutputArea().GetHeight() / SCRLRANGE;
1870 else if ( ( (aMousePos.Y()+pDragAndDropInfo->nSensibleRange) > GetOutputArea().Bottom() ) && ( ( aMousePos.Y() - pDragAndDropInfo->nSensibleRange ) < GetOutputArea().Bottom() ) )
1871 nScrollY = -( GetOutputArea().GetHeight() / SCRLRANGE );
1872
1873 if ( nScrollX || nScrollY )
1874 {
1875 HideDDCursor();
1876 Scroll( nScrollX, nScrollY, RGCHK_PAPERSZ1 );
1877 }
1878 }
1879
1880 Point aDocPos( GetDocPos( aMousePos ) );
1881 EditPaM aPaM = pEditEngine->pImpEditEngine->GetPaM( aDocPos );
1882 pDragAndDropInfo->aDropDest = aPaM;
1883 if ( pDragAndDropInfo->bOutlinerMode )
1884 {
1885 sal_uInt16 nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
1886 ParaPortion* pPPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( nPara );
1887 long nDestParaStartY = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pPPortion );
1888 long nRel = aDocPos.Y() - nDestParaStartY;
1889 if ( nRel < ( pPPortion->GetHeight() / 2 ) )
1890 {
1891 pDragAndDropInfo->nOutlinerDropDest = nPara;
1892 }
1893 else
1894 {
1895 pDragAndDropInfo->nOutlinerDropDest = nPara+1;
1896 }
1897
1898 if( ( pDragAndDropInfo->nOutlinerDropDest >= pDragAndDropInfo->aBeginDragSel.nStartPara ) &&
1899 ( pDragAndDropInfo->nOutlinerDropDest <= (pDragAndDropInfo->aBeginDragSel.nEndPara+1) ) )
1900 {
1901 bAccept = sal_False;
1902 }
1903 }
1904 else if ( HasSelection() )
1905 {
1906 // es darf nicht in eine Selektion gedroppt werden
1907 EPaM aP = pEditEngine->pImpEditEngine->CreateEPaM( aPaM );
1908 ESelection aDestSel( aP.nPara, aP.nIndex, aP.nPara, aP.nIndex);
1909 ESelection aCurSel = pEditEngine->pImpEditEngine->CreateESel( GetEditSelection() );
1910 aCurSel.Adjust();
1911 if ( !aDestSel.IsLess( aCurSel ) && !aDestSel.IsGreater( aCurSel ) )
1912 {
1913 bAccept = sal_False;
1914 }
1915 }
1916 if ( bAccept )
1917 {
1918 Rectangle aEditCursor;
1919 if ( pDragAndDropInfo->bOutlinerMode )
1920 {
1921 long nDDYPos;
1922 if ( pDragAndDropInfo->nOutlinerDropDest < pEditEngine->pImpEditEngine->GetEditDoc().Count() )
1923 {
1924 ParaPortion* pPPortion = pEditEngine->pImpEditEngine->GetParaPortions().SaveGetObject( pDragAndDropInfo->nOutlinerDropDest );
1925 nDDYPos = pEditEngine->pImpEditEngine->GetParaPortions().GetYOffset( pPPortion );
1926 }
1927 else
1928 {
1929 nDDYPos = pEditEngine->pImpEditEngine->GetTextHeight();
1930 }
1931 Point aStartPos( 0, nDDYPos );
1932 aStartPos = GetWindowPos( aStartPos );
1933 Point aEndPos( GetOutputArea().GetWidth(), nDDYPos );
1934 aEndPos = GetWindowPos( aEndPos );
1935 aEditCursor = GetWindow()->LogicToPixel( Rectangle( aStartPos, aEndPos ) );
1936 if ( !pEditEngine->IsVertical() )
1937 {
1938 aEditCursor.Top()--;
1939 aEditCursor.Bottom()++;
1940 }
1941 else
1942 {
1943 aEditCursor.Left()--;
1944 aEditCursor.Right()++;
1945 }
1946 aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
1947 }
1948 else
1949 {
1950 aEditCursor = pEditEngine->pImpEditEngine->PaMtoEditCursor( aPaM );
1951 Point aTopLeft( GetWindowPos( aEditCursor.TopLeft() ) );
1952 aEditCursor.SetPos( aTopLeft );
1953 aEditCursor.Right() = aEditCursor.Left() + pDragAndDropInfo->nCursorWidth;
1954 aEditCursor = GetWindow()->LogicToPixel( aEditCursor );
1955 aEditCursor = GetWindow()->PixelToLogic( aEditCursor );
1956 }
1957
1958 sal_Bool bCursorChanged = !pDragAndDropInfo->bVisCursor || ( pDragAndDropInfo->aCurCursor != aEditCursor );
1959 if ( bCursorChanged )
1960 {
1961 HideDDCursor();
1962 ShowDDCursor(aEditCursor );
1963 }
1964 pDragAndDropInfo->bDragAccepted = sal_True;
1965 rDTDE.Context->acceptDrag( rDTDE.DropAction );
1966 }
1967 }
1968 }
1969
1970 if ( !bAccept )
1971 {
1972 HideDDCursor();
1973 if (pDragAndDropInfo)
1974 pDragAndDropInfo->bDragAccepted = sal_False;
1975 rDTDE.Context->rejectDrag();
1976 }
1977 }
1978
AddDragAndDropListeners()1979 void ImpEditView::AddDragAndDropListeners()
1980 {
1981 Window* pWindow = GetWindow();
1982 if ( !bActiveDragAndDropListener && pWindow && pWindow->GetDragGestureRecognizer().is() )
1983 {
1984 vcl::unohelper::DragAndDropWrapper* pDnDWrapper = new vcl::unohelper::DragAndDropWrapper( this );
1985 mxDnDListener = pDnDWrapper;
1986
1987 uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
1988 pWindow->GetDragGestureRecognizer()->addDragGestureListener( xDGL );
1989 uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
1990 pWindow->GetDropTarget()->addDropTargetListener( xDTL );
1991 pWindow->GetDropTarget()->setActive( sal_True );
1992 pWindow->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );
1993
1994 bActiveDragAndDropListener = sal_True;
1995 }
1996 }
1997
RemoveDragAndDropListeners()1998 void ImpEditView::RemoveDragAndDropListeners()
1999 {
2000 if ( bActiveDragAndDropListener && GetWindow() && GetWindow()->GetDragGestureRecognizer().is() )
2001 {
2002 uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
2003 GetWindow()->GetDragGestureRecognizer()->removeDragGestureListener( xDGL );
2004 uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( xDGL, uno::UNO_QUERY );
2005 GetWindow()->GetDropTarget()->removeDropTargetListener( xDTL );
2006
2007 if ( mxDnDListener.is() )
2008 {
2009 uno::Reference< lang::XEventListener> xEL( mxDnDListener, uno::UNO_QUERY );
2010 xEL->disposing( lang::EventObject() ); // #95154# Empty Source means it's the Client
2011 mxDnDListener.clear();
2012 }
2013
2014 bActiveDragAndDropListener = sal_False;
2015 }
2016 }
2017