1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: impedit.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <eeng_pch.hxx>
36 #include <impedit.hxx>
37 #include <svx/editeng.hxx>
38 #include <svx/editview.hxx>
39 #include <tools/poly.hxx>
40 #include <unolingu.hxx>
41 #include <sfx2/sfxuno.hxx>
42 #include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
43 #include <com/sun/star/linguistic2/DictionaryType.hpp>
44 #include <com/sun/star/linguistic2/DictionaryEvent.hpp>
45 #include <com/sun/star/linguistic2/XDictionaryEventListener.hpp>
46 #include <com/sun/star/linguistic2/DictionaryEventFlags.hpp>
47 #include <com/sun/star/linguistic2/XDictionary.hpp>
49 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_DNDCONSTANS_HPP_
50 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
52 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
53 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
54 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
55 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
57 #include <vos/mutex.hxx>
59 #include <svx/flditem.hxx>
60 #include <svtools/intitem.hxx>
61 #include <svtools/transfer.hxx>
63 #include <sot/exchange.hxx>
64 #include <sot/formats.hxx>
67 using namespace ::com::sun::star
;
68 using namespace ::com::sun::star::uno
;
69 using namespace ::com::sun::star::linguistic2
;
71 #define SCRLRANGE 20 // 1/20 der Breite/Hoehe scrollen, wenn im QueryDrop
73 inline void lcl_AllignToPixel( Point
& rPoint
, OutputDevice
* pOutDev
, short nDiffX
, short nDiffY
)
75 rPoint
= pOutDev
->LogicToPixel( rPoint
);
82 rPoint
= pOutDev
->PixelToLogic( rPoint
);
85 \f// ----------------------------------------------------------------------
87 // ----------------------------------------------------------------------
88 ImpEditView::ImpEditView( EditView
* pView
, EditEngine
* pEng
, Window
* pWindow
) :
89 aOutArea( Point(), pEng
->GetPaperSize() )
95 pBackgroundColor
= NULL
;
97 nExtraCursorFlags
= 0;
98 nCursorBidiLevel
= CURSOR_BIDILEVEL_DONTKNOW
;
100 pDragAndDropInfo
= NULL
;
101 bReadOnly
= sal_False
;
102 bClickedInSelection
= sal_False
;
103 eSelectionMode
= EE_SELMODE_TXTONLY
;
104 eAnchorMode
= ANCHOR_TOP_LEFT
;
106 nTravelXPos
= TRAVEL_X_DONTKNOW
;
107 nControl
= EV_CNTRL_AUTOSCROLL
| EV_CNTRL_ENABLEPASTE
;
108 bActiveDragAndDropListener
= FALSE
;
110 aEditSelection
.Min() = pEng
->pImpEditEngine
->GetEditDoc().GetStartPaM();
111 aEditSelection
.Max() = pEng
->pImpEditEngine
->GetEditDoc().GetEndPaM();
114 ImpEditView::~ImpEditView()
116 RemoveDragAndDropListeners();
118 if ( pOutWin
&& ( pOutWin
->GetCursor() == pCursor
) )
119 pOutWin
->SetCursor( NULL
);
122 delete pBackgroundColor
;
124 delete pDragAndDropInfo
;
127 void ImpEditView::SetBackgroundColor( const Color
& rColor
)
129 delete pBackgroundColor
;
130 pBackgroundColor
= new Color( rColor
);
133 void ImpEditView::SetEditSelection( const EditSelection
& rEditSelection
)
135 // #100856# set state before notification
136 aEditSelection
= rEditSelection
;
138 if ( pEditEngine
->pImpEditEngine
->GetNotifyHdl().IsSet() )
140 EENotify
aNotify( EE_NOTIFY_TEXTVIEWSELECTIONCHANGED
);
141 aNotify
.pEditEngine
= pEditEngine
;
142 aNotify
.pEditView
= GetEditViewPtr();
143 pEditEngine
->pImpEditEngine
->CallNotify( aNotify
);
148 void ImpEditView::DrawSelection( EditSelection aTmpSel
, Region
* pRegion
)
150 if ( GetSelectionMode() == EE_SELMODE_HIDDEN
)
153 // Vor dem Zeichnen der Selektion muss sichergestellt werden,
154 // das der Fensterinhalt komplett gueltig ist!
155 // Muss hier stehen, damit auf jeden Fall weg wenn lerr, nicht spaeter
156 // zwei Paint-Events!
157 // 19.10: Muss sogar vor Abfrage von bUpdate, falls nach Invalidate
158 // noch Paints in der Queue, aber jemand schaltet den UpdateMode um!
160 // pRegion: Wenn nicht NULL, dann nur Region berechnen.
161 PolyPolygon
* pPolyPoly
= NULL
;
163 pPolyPoly
= new PolyPolygon
;
165 sal_Bool bClipRegion
= pOutWin
->IsClipRegion();
166 Region aOldRegion
= pOutWin
->GetClipRegion();
170 if ( pEditEngine
->pImpEditEngine
->GetUpdateMode() == sal_False
)
172 if ( pEditEngine
->pImpEditEngine
->IsInUndo() )
175 if ( !aTmpSel
.HasRange() )
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 pOutWin
->IntersectClipRegion( aTmpOutArea
);
185 if ( pOutWin
->GetCursor() )
186 pOutWin
->GetCursor()->Hide();
189 DBG_ASSERT( !pEditEngine
->pImpEditEngine
->aIdleFormatter
.IsActive(), "DrawSelection: Not formatted!" );
190 aTmpSel
.Adjust( pEditEngine
->pImpEditEngine
->GetEditDoc() );
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
++ )
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!" );
203 if ( !pTmpPortion
->IsVisible() || pTmpPortion
->IsInvalid() )
206 long nParaStart
= pEditEngine
->pImpEditEngine
->GetParaPortions().GetYOffset( pTmpPortion
);
207 if ( ( nParaStart
+ pTmpPortion
->GetHeight() ) < GetVisDocTop() )
209 if ( nParaStart
> GetVisDocBottom() )
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
);
219 // ueber die Zeilen iterieren....
220 for ( sal_uInt16 nLine
= nStartLine
; nLine
<= nEndLine
; nLine
++ )
222 EditLine
* pLine
= pTmpPortion
->GetLines().GetObject( nLine
);
223 DBG_ASSERT( pLine
, "Zeile nicht gefunden: DrawSelection()" );
225 BOOL bPartOfLine
= FALSE
;
226 sal_uInt16 nStartIndex
= pLine
->GetStart();
227 sal_uInt16 nEndIndex
= pLine
->GetEnd();
228 if ( ( nPara
== nStartPara
) && ( nLine
== nStartLine
) && ( nStartIndex
!= aTmpSel
.Min().GetIndex() ) )
230 nStartIndex
= aTmpSel
.Min().GetIndex();
233 if ( ( nPara
== nEndPara
) && ( nLine
== nEndLine
) && ( nEndIndex
!= aTmpSel
.Max().GetIndex() ) )
235 nEndIndex
= aTmpSel
.Max().GetIndex();
239 // Kann passieren, wenn am Anfang einer umgebrochenen Zeile.
240 if ( nEndIndex
< nStartIndex
)
241 nEndIndex
= nStartIndex
;
243 Rectangle
aTmpRec( pEditEngine
->pImpEditEngine
->GetEditCursor( pTmpPortion
, nStartIndex
) );
244 Point
aTopLeft( aTmpRec
.TopLeft() );
245 Point
aBottomRight( aTmpRec
.BottomRight() );
247 aTopLeft
.Y() += nParaStart
;
248 aBottomRight
.Y() += nParaStart
;
250 // Nur Painten, wenn im sichtbaren Bereich...
251 if ( aTopLeft
.Y() > GetVisDocBottom() )
254 if ( aBottomRight
.Y() < GetVisDocTop() )
257 // Now that we have Bidi, the first/last index doesn't have to be the 'most outside' postion
260 Range aLineXPosStartEnd
= pEditEngine
->pImpEditEngine
->GetLineXPosStartEnd( pTmpPortion
, pLine
);
261 aTopLeft
.X() = aLineXPosStartEnd
.Min();
262 aBottomRight
.X() = aLineXPosStartEnd
.Max();
263 ImplDrawHighlightRect( pOutWin
, aTopLeft
, aBottomRight
, pPolyPoly
);
267 USHORT nTmpStartIndex
= nStartIndex
;
268 USHORT nWritingDirStart
, nTmpEndIndex
;
270 while ( nTmpStartIndex
< nEndIndex
)
272 pEditEngine
->pImpEditEngine
->GetRightToLeft( nPara
, nTmpStartIndex
+1, &nWritingDirStart
, &nTmpEndIndex
);
273 if ( nTmpEndIndex
> nEndIndex
)
274 nTmpEndIndex
= nEndIndex
;
276 DBG_ASSERT( nTmpEndIndex
> nTmpStartIndex
, "DrawSelection, Start >= End?" );
278 long nX1
= pEditEngine
->pImpEditEngine
->GetXPos( pTmpPortion
, pLine
, nTmpStartIndex
, TRUE
);
279 long nX2
= pEditEngine
->pImpEditEngine
->GetXPos( pTmpPortion
, pLine
, nTmpEndIndex
);
281 Point
aPt1( Min( nX1
, nX2
), aTopLeft
.Y() );
282 Point
aPt2( Max( nX1
, nX2
), aBottomRight
.Y() );
284 ImplDrawHighlightRect( pOutWin
, aPt1
, aPt2
, pPolyPoly
);
286 nTmpStartIndex
= nTmpEndIndex
;
295 *pRegion
= Region( *pPolyPoly
);
300 if ( pOutWin
->GetCursor() )
301 pOutWin
->GetCursor()->Show();
304 pOutWin
->SetClipRegion( aOldRegion
);
306 pOutWin
->SetClipRegion();
310 void ImpEditView::ImplDrawHighlightRect( Window
* _pOutWin
, const Point
& rDocPosTopLeft
, const Point
& rDocPosBottomRight
, PolyPolygon
* pPolyPoly
)
312 if ( rDocPosTopLeft
.X() != rDocPosBottomRight
.X() )
314 sal_Bool bPixelMode
= _pOutWin
->GetMapMode() == MAP_PIXEL
;
316 Point
aPnt1( GetWindowPos( rDocPosTopLeft
) );
317 Point
aPnt2( GetWindowPos( rDocPosBottomRight
) );
321 lcl_AllignToPixel( aPnt1
, _pOutWin
, +1, 0 );
322 lcl_AllignToPixel( aPnt2
, _pOutWin
, 0, ( bPixelMode
? 0 : -1 ) );
326 lcl_AllignToPixel( aPnt1
, _pOutWin
, 0, +1 );
327 lcl_AllignToPixel( aPnt2
, _pOutWin
, ( bPixelMode
? 0 : +1 ), 0 );
330 Rectangle
aRect( aPnt1
, aPnt2
);
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
);
342 _pOutWin
->Invert( aRect
);
348 BOOL
ImpEditView::IsVertical() const
350 return pEditEngine
->pImpEditEngine
->IsVertical();
353 Rectangle
ImpEditView::GetVisDocArea() const
355 return Rectangle( GetVisDocLeft(), GetVisDocTop(), GetVisDocRight(), GetVisDocBottom() );
358 Point
ImpEditView::GetDocPos( const Point
& rWindowPos
) const
360 // Fensterposition => Dokumentposition
363 if ( !pEditEngine
->pImpEditEngine
->IsVertical() )
365 aPoint
.X() = rWindowPos
.X() - aOutArea
.Left() + GetVisDocLeft();
366 aPoint
.Y() = rWindowPos
.Y() - aOutArea
.Top() + GetVisDocTop();
370 aPoint
.X() = rWindowPos
.Y() - aOutArea
.Top() + GetVisDocLeft();
371 aPoint
.Y() = aOutArea
.Right() - rWindowPos
.X() + GetVisDocTop();
377 Point
ImpEditView::GetWindowPos( const Point
& rDocPos
) const
379 // Dokumentposition => Fensterposition
382 if ( !pEditEngine
->pImpEditEngine
->IsVertical() )
384 aPoint
.X() = rDocPos
.X() + aOutArea
.Left() - GetVisDocLeft();
385 aPoint
.Y() = rDocPos
.Y() + aOutArea
.Top() - GetVisDocTop();
389 aPoint
.X() = aOutArea
.Right() - rDocPos
.Y() + GetVisDocTop();
390 aPoint
.Y() = rDocPos
.X() + aOutArea
.Top() - GetVisDocLeft();
396 Rectangle
ImpEditView::GetWindowPos( const Rectangle
& rDocRect
) const
398 // Dokumentposition => Fensterposition
399 Point
aPos( GetWindowPos( rDocRect
.TopLeft() ) );
400 Size aSz
= rDocRect
.GetSize();
402 if ( !pEditEngine
->pImpEditEngine
->IsVertical() )
404 aRect
= Rectangle( aPos
, aSz
);
408 Point
aNewPos( aPos
.X()-aSz
.Height(), aPos
.Y() );
409 aRect
= Rectangle( aNewPos
, Size( aSz
.Height(), aSz
.Width() ) );
415 Region
* ImpEditView::CalcSelectedRegion()
417 Region
* pRegion
= new Region
;
418 DrawSelection( GetEditSelection(), pRegion
);
422 void ImpEditView::SetSelectionMode( EESelectionMode eNewMode
)
424 if ( eSelectionMode
!= eNewMode
)
426 DrawSelection(); // 'Wegmalen' ...
427 eSelectionMode
= eNewMode
;
428 DrawSelection(); // und neu zeichnen.
432 void ImpEditView::SetOutputArea( const Rectangle
& rRec
)
434 // sollte besser auf Pixel allignt sein!
435 Rectangle
aNewRec( pOutWin
->LogicToPixel( rRec
) );
436 aNewRec
= pOutWin
->PixelToLogic( aNewRec
);
438 if ( aOutArea
.Right() < aOutArea
.Left() )
439 aOutArea
.Right() = aOutArea
.Left();
440 if ( aOutArea
.Bottom() < aOutArea
.Top() )
441 aOutArea
.Bottom() = aOutArea
.Top();
444 SetScrollDiffX( (sal_uInt16
)aOutArea
.GetWidth() * 3 / 10 );
446 SetScrollDiffX( (sal_uInt16
)aOutArea
.GetWidth() * 2 / 10 );
449 void ImpEditView::ResetOutputArea( const Rectangle
& rRec
)
451 Rectangle
aCurArea( aOutArea
);
452 SetOutputArea( rRec
);
453 // Umliegende Bereiche invalidieren, wenn UpdateMode der Engine auf sal_True
454 if ( !aCurArea
.IsEmpty() && pEditEngine
->pImpEditEngine
->GetUpdateMode() )
457 if ( DoInvalidateMore() )
458 nMore
= GetWindow()->PixelToLogic( Size( nInvMore
, 0 ) ).Width();
459 if ( aCurArea
.Left() < aOutArea
.Left() )
461 Rectangle
aRect( aCurArea
.TopLeft(),
462 Size( aOutArea
.Left()-aCurArea
.Left(), aCurArea
.GetHeight() ) );
465 aRect
.Left() -= nMore
;
466 aRect
.Top() -= nMore
;
467 aRect
.Bottom() += nMore
;
469 GetWindow()->Invalidate( aRect
);
471 if ( aCurArea
.Right() > aOutArea
.Right() )
473 long nW
= aCurArea
.Right() - aOutArea
.Right();
474 Point
aPos( aCurArea
.TopRight() );
476 Rectangle
aRect( aPos
, Size( nW
, aCurArea
.GetHeight() ) );
479 aRect
.Right() += nMore
;
480 aRect
.Top() -= nMore
;
481 aRect
.Bottom() += nMore
;
483 GetWindow()->Invalidate( aRect
);
485 if ( aCurArea
.Top() < aOutArea
.Top() )
487 Rectangle
aRect( aCurArea
.TopLeft(), Size( aCurArea
.GetWidth(), aOutArea
.Top() - aCurArea
.Top() ) );
490 aRect
.Top() -= nMore
;
491 aRect
.Left() -= nMore
;
492 aRect
.Right() += nMore
;
494 GetWindow()->Invalidate( aRect
);
496 if ( aCurArea
.Bottom() > aOutArea
.Bottom() )
498 long nH
= aCurArea
.Bottom() - aOutArea
.Bottom();
499 Point
aPos( aCurArea
.BottomLeft() );
501 Rectangle
aRect( aPos
, Size( aCurArea
.GetWidth(), nH
) );
504 aRect
.Bottom() += nMore
;
505 aRect
.Left() -= nMore
;
506 aRect
.Right() += nMore
;
509 GetWindow()->Invalidate( aRect
);
514 void ImpEditView::RecalcOutputArea()
516 Rectangle
aOldArea( aOutArea
);
517 Point
aNewTopLeft( aOutArea
.TopLeft() );
518 Size
aNewSz( aOutArea
.GetSize() );
523 if ( pEditEngine
->pImpEditEngine
->GetStatus().AutoPageWidth() )
524 aNewSz
.Width() = pEditEngine
->pImpEditEngine
->GetPaperSize().Width();
525 switch ( eAnchorMode
)
527 case ANCHOR_TOP_LEFT
:
528 case ANCHOR_VCENTER_LEFT
:
529 case ANCHOR_BOTTOM_LEFT
:
531 aNewTopLeft
.X() = aAnchorPoint
.X();
534 case ANCHOR_TOP_HCENTER
:
535 case ANCHOR_VCENTER_HCENTER
:
536 case ANCHOR_BOTTOM_HCENTER
:
538 aNewTopLeft
.X() = aAnchorPoint
.X() - aNewSz
.Width() / 2;
541 case ANCHOR_TOP_RIGHT
:
542 case ANCHOR_VCENTER_RIGHT
:
543 case ANCHOR_BOTTOM_RIGHT
:
545 aNewTopLeft
.X() = aAnchorPoint
.X() - aNewSz
.Width() - 1;
552 if ( DoAutoHeight() )
554 if ( pEditEngine
->pImpEditEngine
->GetStatus().AutoPageHeight() )
555 aNewSz
.Height() = pEditEngine
->pImpEditEngine
->GetPaperSize().Height();
556 switch ( eAnchorMode
)
558 case ANCHOR_TOP_LEFT
:
559 case ANCHOR_TOP_HCENTER
:
560 case ANCHOR_TOP_RIGHT
:
562 aNewTopLeft
.Y() = aAnchorPoint
.Y();
565 case ANCHOR_VCENTER_LEFT
:
566 case ANCHOR_VCENTER_HCENTER
:
567 case ANCHOR_VCENTER_RIGHT
:
569 aNewTopLeft
.Y() = aAnchorPoint
.Y() - aNewSz
.Height() / 2;
572 case ANCHOR_BOTTOM_LEFT
:
573 case ANCHOR_BOTTOM_HCENTER
:
574 case ANCHOR_BOTTOM_RIGHT
:
576 aNewTopLeft
.Y() = aAnchorPoint
.Y() - aNewSz
.Height() - 1;
581 ResetOutputArea( Rectangle( aNewTopLeft
, aNewSz
) );
584 void ImpEditView::SetAnchorMode( EVAnchorMode eMode
)
590 void ImpEditView::CalcAnchorPoint()
592 // GetHeight() und GetWidth() -1, da Rectangle-Berechnung nicht erwuenscht.
595 switch ( eAnchorMode
)
597 case ANCHOR_TOP_LEFT
:
598 case ANCHOR_VCENTER_LEFT
:
599 case ANCHOR_BOTTOM_LEFT
:
601 aAnchorPoint
.X() = aOutArea
.Left();
604 case ANCHOR_TOP_HCENTER
:
605 case ANCHOR_VCENTER_HCENTER
:
606 case ANCHOR_BOTTOM_HCENTER
:
608 aAnchorPoint
.X() = aOutArea
.Left() + (aOutArea
.GetWidth()-1) / 2;
611 case ANCHOR_TOP_RIGHT
:
612 case ANCHOR_VCENTER_RIGHT
:
613 case ANCHOR_BOTTOM_RIGHT
:
615 aAnchorPoint
.X() = aOutArea
.Right();
621 switch ( eAnchorMode
)
623 case ANCHOR_TOP_LEFT
:
624 case ANCHOR_TOP_HCENTER
:
625 case ANCHOR_TOP_RIGHT
:
627 aAnchorPoint
.Y() = aOutArea
.Top();
630 case ANCHOR_VCENTER_LEFT
:
631 case ANCHOR_VCENTER_HCENTER
:
632 case ANCHOR_VCENTER_RIGHT
:
634 aAnchorPoint
.Y() = aOutArea
.Top() + (aOutArea
.GetHeight()-1) / 2;
637 case ANCHOR_BOTTOM_LEFT
:
638 case ANCHOR_BOTTOM_HCENTER
:
639 case ANCHOR_BOTTOM_RIGHT
:
641 aAnchorPoint
.Y() = aOutArea
.Bottom() - 1;
647 void ImpEditView::ShowCursor( sal_Bool bGotoCursor
, sal_Bool bForceVisCursor
, USHORT nShowCursorFlags
)
649 // Kein ShowCursor bei einer leeren View...
650 if ( ( aOutArea
.Left() >= aOutArea
.Right() ) && ( aOutArea
.Top() >= aOutArea
.Bottom() ) )
653 pEditEngine
->pImpEditEngine
->CheckIdleFormatter();
654 if ( !pEditEngine
->pImpEditEngine
->IsFormatted() )
655 pEditEngine
->pImpEditEngine
->FormatDoc();
657 // Aus irgendwelchen Gruenden lande ich waehrend der Formatierung hier,
658 // wenn sich der Outiner im Paint initialisiert, weil kein SetPool();
659 if ( pEditEngine
->pImpEditEngine
->IsFormatting() )
661 if ( pEditEngine
->pImpEditEngine
->GetUpdateMode() == sal_False
)
663 if ( pEditEngine
->pImpEditEngine
->IsInUndo() )
666 if ( pOutWin
->GetCursor() != GetCursor() )
667 pOutWin
->SetCursor( GetCursor() );
669 EditPaM
aPaM( aEditSelection
.Max() );
671 USHORT nTextPortionStart
= 0;
672 USHORT nPara
= pEditEngine
->pImpEditEngine
->aEditDoc
.GetPos( aPaM
.GetNode() );
673 if (nPara
== USHRT_MAX
) // #i94322
675 ParaPortion
* pParaPortion
= pEditEngine
->pImpEditEngine
->GetParaPortions().GetObject( nPara
);
677 nShowCursorFlags
|= nExtraCursorFlags
;
679 nShowCursorFlags
|= GETCRSR_TXTONLY
;
681 // Use CursorBidiLevel 0/1 in meaning of
682 // 0: prefer portion end, normal mode
683 // 1: prefer portion start
685 if ( ( GetCursorBidiLevel() != CURSOR_BIDILEVEL_DONTKNOW
) && GetCursorBidiLevel() )
687 nShowCursorFlags
|= GETCRSR_PREFERPORTIONSTART
;
690 Rectangle aEditCursor
= pEditEngine
->pImpEditEngine
->PaMtoEditCursor( aPaM
, nShowCursorFlags
);
691 if ( !IsInsertMode() && !aEditSelection
.HasRange() )
693 if ( aPaM
.GetNode()->Len() && ( aPaM
.GetIndex() < aPaM
.GetNode()->Len() ) )
695 // If we are behind a portion, and the next portion has other direction, we must change position...
696 aEditCursor
.Left() = aEditCursor
.Right() = pEditEngine
->pImpEditEngine
->PaMtoEditCursor( aPaM
, GETCRSR_TXTONLY
|GETCRSR_PREFERPORTIONSTART
).Left();
698 USHORT nTextPortion
= pParaPortion
->GetTextPortions().FindPortion( aPaM
.GetIndex(), nTextPortionStart
, TRUE
);
699 TextPortion
* pTextPortion
= pParaPortion
->GetTextPortions().GetObject( nTextPortion
);
700 if ( pTextPortion
->GetKind() == PORTIONKIND_TAB
)
702 aEditCursor
.Right() += pTextPortion
->GetSize().Width();
706 EditPaM aNext
= pEditEngine
->pImpEditEngine
->CursorRight( aPaM
, (USHORT
)i18n::CharacterIteratorMode::SKIPCELL
);
707 Rectangle aTmpRect
= pEditEngine
->pImpEditEngine
->PaMtoEditCursor( aNext
, GETCRSR_TXTONLY
);
708 if ( aTmpRect
.Top() != aEditCursor
.Top() )
709 aTmpRect
= pEditEngine
->pImpEditEngine
->PaMtoEditCursor( aNext
, GETCRSR_TXTONLY
|GETCRSR_ENDOFLINE
);
710 aEditCursor
.Right() = aTmpRect
.Left();
714 long nMaxHeight
= !IsVertical() ? aOutArea
.GetHeight() : aOutArea
.GetWidth();
715 if ( aEditCursor
.GetHeight() > nMaxHeight
)
717 aEditCursor
.Bottom() = aEditCursor
.Top() + nMaxHeight
- 1;
719 if ( bGotoCursor
) // && (!pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() ) )
721 // pruefen, ob scrollen notwendig...
722 // wenn scrollen, dann Update() und Scroll() !
726 Rectangle
aTmpVisArea( GetVisDocArea() );
727 // aTmpOutArea: Falls OutputArea > Papierbreite und
728 // Text > Papierbreite ( uebergrosse Felder )
729 long nMaxTextWidth
= !IsVertical() ? pEditEngine
->pImpEditEngine
->GetPaperSize().Width() : pEditEngine
->pImpEditEngine
->GetPaperSize().Height();
730 if ( aTmpVisArea
.GetWidth() > nMaxTextWidth
)
731 aTmpVisArea
.Right() = aTmpVisArea
.Left() + nMaxTextWidth
;
733 if ( aEditCursor
.Bottom() > aTmpVisArea
.Bottom() )
734 { // hochscrollen, hier positiv
735 nDocDiffY
= aEditCursor
.Bottom() - aTmpVisArea
.Bottom();
737 else if ( aEditCursor
.Top() < aTmpVisArea
.Top() )
738 { // runterscrollen, negativ
739 nDocDiffY
= aEditCursor
.Top() - aTmpVisArea
.Top();
742 if ( aEditCursor
.Right() > aTmpVisArea
.Right() )
744 // linksscrollen, positiv
745 nDocDiffX
= aEditCursor
.Right() - aTmpVisArea
.Right();
746 // Darfs ein bischen mehr sein?
747 if ( aEditCursor
.Right() < ( nMaxTextWidth
- GetScrollDiffX() ) )
748 nDocDiffX
+= GetScrollDiffX();
751 long n
= nMaxTextWidth
- aEditCursor
.Right();
752 // Bei einem MapMode != RefMapMode kann der EditCursor auch mal ueber
753 // die Papierbreite Wandern!
754 nDocDiffX
+= ( n
> 0 ? n
: -n
);
757 else if ( aEditCursor
.Left() < aTmpVisArea
.Left() )
760 nDocDiffX
= aEditCursor
.Left() - aTmpVisArea
.Left();
761 // Darfs ein bischen mehr sein?
762 if ( aEditCursor
.Left() > ( - (long)GetScrollDiffX() ) )
763 nDocDiffX
-= GetScrollDiffX();
765 nDocDiffX
-= aEditCursor
.Left();
767 if ( aPaM
.GetIndex() == 0 ) // braucht Olli fuer den Outliner
769 // Aber sicherstellen, dass dadurch der Cursor nicht den
770 // sichtbaren bereich verlaesst!
771 if ( aEditCursor
.Left() < aTmpVisArea
.GetWidth() )
773 nDocDiffX
= -aTmpVisArea
.Left();
777 if ( nDocDiffX
| nDocDiffY
)
779 long nDiffX
= !IsVertical() ? nDocDiffX
: -nDocDiffY
;
780 long nDiffY
= !IsVertical() ? nDocDiffY
: nDocDiffX
;
782 // Negativ: Zum Anfang bzw. linken Rand
783 if ( ( Abs( nDiffY
) > pEditEngine
->pImpEditEngine
->nOnePixelInRef
) && DoBigScroll() )
785 long nH
= aOutArea
.GetHeight() / 4;
786 if ( ( nH
> aEditCursor
.GetHeight() ) && ( Abs( nDiffY
) < nH
) )
795 if ( ( Abs( nDiffX
) > pEditEngine
->pImpEditEngine
->nOnePixelInRef
) && DoBigScroll() )
797 long nW
= aOutArea
.GetWidth() / 4;
798 if ( Abs( nDiffX
) < nW
)
808 pEditEngine
->pImpEditEngine
->aStatus
.GetStatusWord() = pEditEngine
->pImpEditEngine
->aStatus
.GetStatusWord() | EE_STAT_HSCROLL
;
810 pEditEngine
->pImpEditEngine
->aStatus
.GetStatusWord() = pEditEngine
->pImpEditEngine
->aStatus
.GetStatusWord() | EE_STAT_VSCROLL
;
811 Scroll( -nDiffX
, -nDiffY
);
812 pEditEngine
->pImpEditEngine
->DelayedCallStatusHdl();
816 // Cursor evtl. etwas stutzen...
817 if ( ( aEditCursor
.Bottom() > GetVisDocTop() ) &&
818 ( aEditCursor
.Top() < GetVisDocBottom() ) )
820 if ( aEditCursor
.Bottom() > GetVisDocBottom() )
821 aEditCursor
.Bottom() = GetVisDocBottom();
822 if ( aEditCursor
.Top() < GetVisDocTop() )
823 aEditCursor
.Top() = GetVisDocTop();
826 long nOnePixel
= pOutWin
->PixelToLogic( Size( 1, 0 ) ).Width();
828 if ( /* pEditEngine->pImpEditEngine->GetStatus().AutoPageSize() || */
829 ( ( aEditCursor
.Top() + nOnePixel
>= GetVisDocTop() ) &&
830 ( aEditCursor
.Bottom() - nOnePixel
<= GetVisDocBottom() ) &&
831 ( aEditCursor
.Left() + nOnePixel
>= GetVisDocLeft() ) &&
832 ( aEditCursor
.Right() - nOnePixel
<= GetVisDocRight() ) ) )
834 Rectangle aCursorRect
= GetWindowPos( aEditCursor
);
835 GetCursor()->SetPos( aCursorRect
.TopLeft() );
836 Size
aCursorSz( aCursorRect
.GetSize() );
837 // Rectangle is inclusive
839 aCursorSz
.Height()--;
840 if ( !aCursorSz
.Width() || !aCursorSz
.Height() )
842 long nCursorSz
= pOutWin
->GetSettings().GetStyleSettings().GetCursorSize();
843 nCursorSz
= pOutWin
->PixelToLogic( Size( nCursorSz
, 0 ) ).Width();
844 if ( !aCursorSz
.Width() )
845 aCursorSz
.Width() = nCursorSz
;
846 if ( !aCursorSz
.Height() )
847 aCursorSz
.Height() = nCursorSz
;
849 // #111036# Let VCL do orientation for cursor, otherwise problem when cursor has direction flag
852 Size
aOldSz( aCursorSz
);
853 aCursorSz
.Width() = aOldSz
.Height();
854 aCursorSz
.Height() = aOldSz
.Width();
855 GetCursor()->SetPos( aCursorRect
.TopRight() );
856 GetCursor()->SetOrientation( 2700 );
859 // --> FME 2004-10-18 #i32593#
860 // Reset correct orientation in horizontal layout
861 GetCursor()->SetOrientation( 0 );
864 GetCursor()->SetSize( aCursorSz
);
866 unsigned char nCursorDir
= CURSOR_DIRECTION_NONE
;
867 if ( IsInsertMode() && !aEditSelection
.HasRange() && ( pEditEngine
->pImpEditEngine
->HasDifferentRTLLevels( aPaM
.GetNode() ) ) )
869 USHORT nTextPortion
= pParaPortion
->GetTextPortions().FindPortion( aPaM
.GetIndex(), nTextPortionStart
, nShowCursorFlags
& GETCRSR_PREFERPORTIONSTART
? TRUE
: FALSE
);
870 TextPortion
* pTextPortion
= pParaPortion
->GetTextPortions().GetObject( nTextPortion
);
871 USHORT nRTLLevel
= pTextPortion
->GetRightToLeft();
873 nCursorDir
= CURSOR_DIRECTION_RTL
;
875 nCursorDir
= CURSOR_DIRECTION_LTR
;
878 GetCursor()->SetDirection( nCursorDir
);
880 if ( bForceVisCursor
)
883 // #102936# Call SetInputContext every time, otherwise we may have the wrong font
884 // if ( !pEditEngine->pImpEditEngine->mpIMEInfos )
887 pEditEngine
->pImpEditEngine
->SeekCursor( aPaM
.GetNode(), aPaM
.GetIndex()+1, aFont
);
888 ULONG nContextFlags
= INPUTCONTEXT_TEXT
|INPUTCONTEXT_EXTTEXTINPUT
;
889 GetWindow()->SetInputContext( InputContext( aFont
, nContextFlags
) );
894 pEditEngine
->pImpEditEngine
->GetStatus().GetStatusWord() = pEditEngine
->pImpEditEngine
->GetStatus().GetStatusWord() | EE_STAT_CURSOROUT
;
896 GetCursor()->SetPos( Point( -1, -1 ) );
897 GetCursor()->SetSize( Size( 0, 0 ) );
901 Pair
ImpEditView::Scroll( long ndX
, long ndY
, BYTE nRangeCheck
)
903 DBG_ASSERT( pEditEngine
->pImpEditEngine
->IsFormatted(), "Scroll: Nicht formatiert!" );
905 return Range( 0, 0 );
908 Rectangle
aR( aOutArea
);
909 aR
= pOutWin
->LogicToPixel( aR
);
910 aR
= pOutWin
->PixelToLogic( aR
);
911 DBG_ASSERTWARNING( aR
== aOutArea
, "OutArea vor Scroll nicht aligned" );
914 Rectangle
aNewVisArea( GetVisDocArea() );
915 Size
aPaperSz( pEditEngine
->pImpEditEngine
->GetPaperSize() );
920 aNewVisArea
.Top() -= ndY
;
921 aNewVisArea
.Bottom() -= ndY
;
925 aNewVisArea
.Top() += ndX
;
926 aNewVisArea
.Bottom() += ndX
;
928 if ( ( nRangeCheck
== RGCHK_PAPERSZ1
) && ( aNewVisArea
.Bottom() > (long)pEditEngine
->pImpEditEngine
->GetTextHeight() ) )
930 // GetTextHeight noch optimieren!
931 long nDiff
= pEditEngine
->pImpEditEngine
->GetTextHeight() - aNewVisArea
.Bottom(); // negativ
932 aNewVisArea
.Move( 0, nDiff
); // koennte im neg. Bereich landen...
934 if ( ( aNewVisArea
.Top() < 0 ) && ( nRangeCheck
!= RGCHK_NONE
) )
935 aNewVisArea
.Move( 0, -aNewVisArea
.Top() );
940 aNewVisArea
.Left() -= ndX
;
941 aNewVisArea
.Right() -= ndX
;
945 aNewVisArea
.Left() -= ndY
;
946 aNewVisArea
.Right() -= ndY
;
948 if ( ( nRangeCheck
== RGCHK_PAPERSZ1
) && ( aNewVisArea
.Right() > (long)pEditEngine
->pImpEditEngine
->CalcTextWidth( FALSE
) ) )
950 long nDiff
= pEditEngine
->pImpEditEngine
->CalcTextWidth( FALSE
) - aNewVisArea
.Right(); // negativ
951 aNewVisArea
.Move( nDiff
, 0 ); // koennte im neg. Bereich landen...
953 if ( ( aNewVisArea
.Left() < 0 ) && ( nRangeCheck
!= RGCHK_NONE
) )
954 aNewVisArea
.Move( -aNewVisArea
.Left(), 0 );
956 // Die Differenz muss auf Pixel alignt sein (wegen Scroll!)
957 long nDiffX
= !IsVertical() ? ( GetVisDocLeft() - aNewVisArea
.Left() ) : -( GetVisDocTop() - aNewVisArea
.Top() );
958 long nDiffY
= !IsVertical() ? ( GetVisDocTop() - aNewVisArea
.Top() ) : ( GetVisDocLeft() - aNewVisArea
.Left() );
960 Size
aDiffs( nDiffX
, nDiffY
);
961 aDiffs
= pOutWin
->LogicToPixel( aDiffs
);
962 aDiffs
= pOutWin
->PixelToLogic( aDiffs
);
964 long nRealDiffX
= aDiffs
.Width();
965 long nRealDiffY
= aDiffs
.Height();
968 if ( nRealDiffX
|| nRealDiffY
)
970 Cursor
* pCrsr
= GetCursor();
971 sal_Bool bVisCursor
= pCrsr
->IsVisible();
975 aVisDocStartPos
.Move( -nRealDiffX
, -nRealDiffY
);
977 aVisDocStartPos
.Move( -nRealDiffY
, nRealDiffX
);
978 // Das Move um den allignten Wert ergibt nicht unbedingt ein
979 // alligntes Rechteck...
980 // MT 11/00: Align VisArea???
981 aVisDocStartPos
= pOutWin
->LogicToPixel( aVisDocStartPos
);
982 aVisDocStartPos
= pOutWin
->PixelToLogic( aVisDocStartPos
);
983 Rectangle
aRec( aOutArea
);
984 pOutWin
->Scroll( nRealDiffX
, nRealDiffY
, aRec
, sal_True
);
986 pCrsr
->SetPos( pCrsr
->GetPos() + Point( nRealDiffX
, nRealDiffY
) );
989 Rectangle
aCursorRec( pCrsr
->GetPos(), pCrsr
->GetSize() );
990 if ( aOutArea
.IsInside( aCursorRec
) )
994 if ( pEditEngine
->pImpEditEngine
->GetNotifyHdl().IsSet() )
996 EENotify
aNotify( EE_NOTIFY_TEXTVIEWSCROLLED
);
997 aNotify
.pEditEngine
= pEditEngine
;
998 aNotify
.pEditView
= GetEditViewPtr();
999 pEditEngine
->pImpEditEngine
->CallNotify( aNotify
);
1003 return Pair( nRealDiffX
, nRealDiffY
);
1006 sal_Bool
ImpEditView::PostKeyEvent( const KeyEvent
& rKeyEvent
, Window
* pFrameWin
)
1010 KeyFuncType eFunc
= rKeyEvent
.GetKeyCode().GetFunction();
1011 if ( eFunc
!= KEYFUNC_DONTKNOW
)
1019 Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aClipBoard(GetWindow()->GetClipboard());
1020 CutCopy( aClipBoard
, sal_True
);
1027 Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aClipBoard(GetWindow()->GetClipboard());
1028 CutCopy( aClipBoard
, sal_False
);
1034 if ( !bReadOnly
&& IsPasteEnabled() )
1036 pEditEngine
->pImpEditEngine
->UndoActionStart( EDITUNDO_PASTE
);
1037 Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aClipBoard(GetWindow()->GetClipboard());
1038 Paste( aClipBoard
, pEditEngine
->pImpEditEngine
->GetStatus().AllowPasteSpecial() );
1039 pEditEngine
->pImpEditEngine
->UndoActionEnd( EDITUNDO_PASTE
);
1050 bDone
= pEditEngine
->PostKeyEvent( rKeyEvent
, GetEditViewPtr(), pFrameWin
);
1055 sal_Bool
ImpEditView::MouseButtonUp( const MouseEvent
& rMouseEvent
)
1057 if ( pEditEngine
->pImpEditEngine
->aStatus
.NotifyCursorMovements() )
1059 if ( pEditEngine
->pImpEditEngine
->aStatus
.GetPrevParagraph() != pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() ) )
1061 pEditEngine
->pImpEditEngine
->aStatus
.GetStatusWord() = pEditEngine
->pImpEditEngine
->aStatus
.GetStatusWord() | EE_STAT_CRSRLEFTPARA
;
1062 pEditEngine
->pImpEditEngine
->CallStatusHdl();
1065 nTravelXPos
= TRAVEL_X_DONTKNOW
;
1066 nCursorBidiLevel
= CURSOR_BIDILEVEL_DONTKNOW
;
1067 nExtraCursorFlags
= 0;
1068 bClickedInSelection
= sal_False
;
1070 if ( rMouseEvent
.IsMiddle() && !bReadOnly
&&
1071 ( GetWindow()->GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
) )
1073 Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aClipBoard(GetWindow()->GetPrimarySelection());
1074 Paste( aClipBoard
);
1076 else if ( rMouseEvent
.IsLeft() && GetEditSelection().HasRange() )
1078 Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aClipBoard(GetWindow()->GetPrimarySelection());
1079 CutCopy( aClipBoard
, FALSE
);
1082 return pEditEngine
->pImpEditEngine
->MouseButtonUp( rMouseEvent
, GetEditViewPtr() );
1085 sal_Bool
ImpEditView::MouseButtonDown( const MouseEvent
& rMouseEvent
)
1087 pEditEngine
->pImpEditEngine
->CheckIdleFormatter(); // Falls schnelles Tippen und MouseButtonDown
1088 if ( pEditEngine
->pImpEditEngine
->aStatus
.NotifyCursorMovements() )
1089 pEditEngine
->pImpEditEngine
->aStatus
.GetPrevParagraph() = pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( GetEditSelection().Max().GetNode() );
1090 nTravelXPos
= TRAVEL_X_DONTKNOW
;
1091 nExtraCursorFlags
= 0;
1092 nCursorBidiLevel
= CURSOR_BIDILEVEL_DONTKNOW
;
1093 bClickedInSelection
= IsSelectionAtPoint( rMouseEvent
.GetPosPixel() );
1094 return pEditEngine
->pImpEditEngine
->MouseButtonDown( rMouseEvent
, GetEditViewPtr() );
1097 sal_Bool
ImpEditView::MouseMove( const MouseEvent
& rMouseEvent
)
1099 return pEditEngine
->pImpEditEngine
->MouseMove( rMouseEvent
, GetEditViewPtr() );
1102 void ImpEditView::Command( const CommandEvent
& rCEvt
)
1104 pEditEngine
->pImpEditEngine
->CheckIdleFormatter(); // Falls schnelles Tippen und MouseButtonDown
1105 pEditEngine
->pImpEditEngine
->Command( rCEvt
, GetEditViewPtr() );
1109 void ImpEditView::SetInsertMode( sal_Bool bInsert
)
1111 if ( bInsert
!= IsInsertMode() )
1113 SetFlags( nControl
, EV_CNTRL_OVERWRITE
, !bInsert
);
1114 ShowCursor( DoAutoScroll(), sal_False
);
1118 sal_Bool
ImpEditView::IsWrongSpelledWord( const EditPaM
& rPaM
, sal_Bool bMarkIfWrong
)
1120 sal_Bool bIsWrong
= sal_False
;
1122 if ( rPaM
.GetNode()->GetWrongList() )
1124 EditSelection aSel
= pEditEngine
->pImpEditEngine
->SelectWord( rPaM
, ::com::sun::star::i18n::WordType::DICTIONARY_WORD
);
1125 bIsWrong
= rPaM
.GetNode()->GetWrongList()->HasWrong( aSel
.Min().GetIndex(), aSel
.Max().GetIndex() );
1126 if ( bIsWrong
&& bMarkIfWrong
)
1128 DrawSelection(); // alte Selektion 'weg-zeichnen'
1129 SetEditSelection( aSel
);
1133 #endif // !SVX_LIGHT
1137 String
ImpEditView::SpellIgnoreOrAddWord( sal_Bool bAdd
)
1141 if ( pEditEngine
->pImpEditEngine
->GetSpeller().is() )
1143 EditPaM aPaM
= GetEditSelection().Max();
1144 if ( !HasSelection() )
1146 EditSelection aSel
= pEditEngine
->pImpEditEngine
->SelectWord( aPaM
);
1147 aWord
= pEditEngine
->pImpEditEngine
->GetSelected( aSel
);
1151 aWord
= pEditEngine
->pImpEditEngine
->GetSelected( GetEditSelection() );
1152 // Und deselektieren
1153 DrawSelection(); // alte Selektion 'weg-zeichnen'
1154 SetEditSelection( EditSelection( aPaM
, aPaM
) );
1162 DBG_ERROR( "Sorry, AddWord not implemented" );
1166 Reference
< XDictionary
> xDic( SvxGetIgnoreAllList(), UNO_QUERY
);
1168 xDic
->add( aWord
, sal_False
, String() );
1170 const EditDoc
& rDoc
= pEditEngine
->pImpEditEngine
->GetEditDoc();
1171 sal_uInt16 nNodes
= rDoc
.Count();
1172 for ( sal_uInt16 n
= 0; n
< nNodes
; n
++ )
1174 ContentNode
* pNode
= rDoc
.GetObject( n
);
1175 pNode
->GetWrongList()->MarkWrongsInvalid();
1177 pEditEngine
->pImpEditEngine
->DoOnlineSpelling( aPaM
.GetNode() );
1178 pEditEngine
->pImpEditEngine
->StartOnlineSpellTimer();
1181 #endif // !SVX_LIGHT
1185 void ImpEditView::DeleteSelected()
1189 pEditEngine
->pImpEditEngine
->UndoActionStart( EDITUNDO_DELETE
);
1191 EditPaM aPaM
= pEditEngine
->pImpEditEngine
->DeleteSelected( GetEditSelection() );
1193 pEditEngine
->pImpEditEngine
->UndoActionEnd( EDITUNDO_DELETE
);
1195 SetEditSelection( EditSelection( aPaM
, aPaM
) );
1196 pEditEngine
->pImpEditEngine
->FormatAndUpdate( GetEditViewPtr() );
1197 ShowCursor( DoAutoScroll(), TRUE
);
1200 const SvxFieldItem
* ImpEditView::GetField( const Point
& rPos
, sal_uInt16
* pPara
, sal_uInt16
* pPos
) const
1202 if( !GetOutputArea().IsInside( rPos
) )
1205 Point
aDocPos( GetDocPos( rPos
) );
1206 EditPaM aPaM
= pEditEngine
->pImpEditEngine
->GetPaM( aDocPos
, sal_False
);
1208 if ( aPaM
.GetIndex() == aPaM
.GetNode()->Len() )
1210 // Sonst immer, wenn Feld ganz am Schluss und Mouse unter Text
1214 const CharAttribArray
& rAttrs
= aPaM
.GetNode()->GetCharAttribs().GetAttribs();
1215 sal_uInt16 nXPos
= aPaM
.GetIndex();
1216 for ( sal_uInt16 nAttr
= rAttrs
.Count(); nAttr
; )
1218 EditCharAttrib
* pAttr
= rAttrs
[--nAttr
];
1219 if ( pAttr
->GetStart() == nXPos
)
1220 if ( pAttr
->Which() == EE_FEATURE_FIELD
)
1222 DBG_ASSERT( pAttr
->GetItem()->ISA( SvxFieldItem
), "Kein FeldItem..." );
1224 *pPara
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( aPaM
.GetNode() );
1226 *pPos
= pAttr
->GetStart();
1227 return (const SvxFieldItem
*)pAttr
->GetItem();
1233 BOOL
ImpEditView::IsBulletArea( const Point
& rPos
, sal_uInt16
* pPara
)
1238 if( !GetOutputArea().IsInside( rPos
) )
1241 Point
aDocPos( GetDocPos( rPos
) );
1242 EditPaM aPaM
= pEditEngine
->pImpEditEngine
->GetPaM( aDocPos
, sal_False
);
1244 if ( aPaM
.GetIndex() == 0 )
1246 USHORT nPara
= pEditEngine
->pImpEditEngine
->aEditDoc
.GetPos( aPaM
.GetNode() );
1247 Rectangle aBulletArea
= pEditEngine
->GetBulletArea( nPara
);
1248 long nY
= pEditEngine
->GetDocPosTopLeft( nPara
).Y();
1249 ParaPortion
* pParaPortion
= pEditEngine
->pImpEditEngine
->GetParaPortions().GetObject( nPara
);
1250 nY
+= pParaPortion
->GetFirstLineOffset();
1251 if ( ( aDocPos
.Y() > ( nY
+ aBulletArea
.Top() ) ) &&
1252 ( aDocPos
.Y() < ( nY
+ aBulletArea
.Bottom() ) ) &&
1253 ( aDocPos
.X() > ( aBulletArea
.Left() ) ) &&
1254 ( aDocPos
.X() < ( aBulletArea
.Right() ) ) )
1265 void ImpEditView::CutCopy( ::com::sun::star::uno::Reference
< ::com::sun::star::datatransfer::clipboard::XClipboard
>& rxClipboard
, BOOL bCut
)
1267 if ( rxClipboard
.is() && GetEditSelection().HasRange() )
1269 uno::Reference
< datatransfer::XTransferable
> xData
= pEditEngine
->pImpEditEngine
->CreateTransferable( GetEditSelection() );
1271 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
1275 rxClipboard
->setContents( xData
, NULL
);
1277 // #87756# FlushClipboard, but it would be better to become a TerminateListener to the Desktop and flush on demand...
1278 uno::Reference
< datatransfer::clipboard::XFlushableClipboard
> xFlushableClipboard( rxClipboard
, uno::UNO_QUERY
);
1279 if( xFlushableClipboard
.is() )
1280 xFlushableClipboard
->flushClipboard();
1282 catch( const ::com::sun::star::uno::Exception
& )
1286 Application::AcquireSolarMutex( nRef
);
1290 pEditEngine
->pImpEditEngine
->UndoActionStart( EDITUNDO_CUT
);
1292 pEditEngine
->pImpEditEngine
->UndoActionEnd( EDITUNDO_CUT
);
1298 void ImpEditView::Paste( ::com::sun::star::uno::Reference
< ::com::sun::star::datatransfer::clipboard::XClipboard
>& rxClipboard
, BOOL bUseSpecial
)
1300 if ( rxClipboard
.is() )
1302 uno::Reference
< datatransfer::XTransferable
> xDataObj
;
1304 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
1308 xDataObj
= rxClipboard
->getContents();
1310 catch( const ::com::sun::star::uno::Exception
& )
1314 Application::AcquireSolarMutex( nRef
);
1316 if ( xDataObj
.is() && EditEngine::HasValidData( xDataObj
) )
1318 pEditEngine
->pImpEditEngine
->UndoActionStart( EDITUNDO_PASTE
);
1320 EditSelection
aSel( GetEditSelection() );
1321 if ( aSel
.HasRange() )
1324 aSel
= pEditEngine
->pImpEditEngine
->ImpDeleteSelection( aSel
);
1327 PasteOrDropInfos aPasteOrDropInfos
;
1328 aPasteOrDropInfos
.nAction
= EE_ACTION_PASTE
;
1329 aPasteOrDropInfos
.nStartPara
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( aSel
.Min().GetNode() );
1330 pEditEngine
->pImpEditEngine
->aBeginPasteOrDropHdl
.Call( &aPasteOrDropInfos
);
1332 if ( DoSingleLinePaste() )
1334 datatransfer::DataFlavor aFlavor
;
1335 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING
, aFlavor
);
1336 if ( xDataObj
->isDataFlavorSupported( aFlavor
) )
1340 uno::Any aData
= xDataObj
->getTransferData( aFlavor
);
1341 ::rtl::OUString aTmpText
;
1343 String
aText( aTmpText
);
1344 aText
.ConvertLineEnd( LINEEND_LF
);
1345 aText
.SearchAndReplaceAll( LINE_SEP
, ' ' );
1346 aSel
= pEditEngine
->pImpEditEngine
->ImpInsertText( aSel
, aText
);
1350 ; // #i9286# can happen, even if isDataFlavorSupported returns true...
1356 aSel
= pEditEngine
->pImpEditEngine
->InsertText( xDataObj
, String(), aSel
.Min(), bUseSpecial
&& pEditEngine
->pImpEditEngine
->GetStatus().AllowPasteSpecial() );
1359 aPasteOrDropInfos
.nEndPara
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( aSel
.Max().GetNode() );
1360 pEditEngine
->pImpEditEngine
->aEndPasteOrDropHdl
.Call( &aPasteOrDropInfos
);
1362 pEditEngine
->pImpEditEngine
->UndoActionEnd( EDITUNDO_PASTE
);
1363 SetEditSelection( aSel
);
1364 pEditEngine
->pImpEditEngine
->UpdateSelections();
1365 pEditEngine
->pImpEditEngine
->FormatAndUpdate( GetEditViewPtr() );
1366 ShowCursor( DoAutoScroll(), TRUE
);
1372 BOOL
ImpEditView::IsInSelection( const EditPaM
& rPaM
)
1374 EditSelection aSel
= GetEditSelection();
1375 if ( !aSel
.HasRange() )
1378 aSel
.Adjust( pEditEngine
->pImpEditEngine
->GetEditDoc() );
1380 USHORT nStartNode
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( aSel
.Min().GetNode() );
1381 USHORT nEndNode
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( aSel
.Max().GetNode() );
1382 USHORT nCurNode
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( rPaM
.GetNode() );
1384 if ( ( nCurNode
> nStartNode
) && ( nCurNode
< nEndNode
) )
1387 if ( nStartNode
== nEndNode
)
1389 if ( nCurNode
== nStartNode
)
1390 if ( ( rPaM
.GetIndex() >= aSel
.Min().GetIndex() ) && ( rPaM
.GetIndex() < aSel
.Max().GetIndex() ) )
1393 else if ( ( nCurNode
== nStartNode
) && ( rPaM
.GetIndex() >= aSel
.Min().GetIndex() ) )
1395 else if ( ( nCurNode
== nEndNode
) && ( rPaM
.GetIndex() < aSel
.Max().GetIndex() ) )
1401 void ImpEditView::CreateAnchor()
1403 pEditEngine
->pImpEditEngine
->bInSelection
= TRUE
;
1404 GetEditSelection().Min() = GetEditSelection().Max();
1407 void ImpEditView::DeselectAll()
1409 pEditEngine
->pImpEditEngine
->bInSelection
= FALSE
;
1411 GetEditSelection().Min() = GetEditSelection().Max();
1414 BOOL
ImpEditView::IsSelectionAtPoint( const Point
& rPosPixel
)
1416 if ( pDragAndDropInfo
&& pDragAndDropInfo
->pField
)
1419 Point
aMousePos( rPosPixel
);
1421 // Logische Einheiten...
1422 aMousePos
= GetWindow()->PixelToLogic( aMousePos
);
1424 if ( ( !GetOutputArea().IsInside( aMousePos
) ) && !pEditEngine
->pImpEditEngine
->IsInSelectionMode() )
1429 Point
aDocPos( GetDocPos( aMousePos
) );
1430 EditPaM aPaM
= pEditEngine
->pImpEditEngine
->GetPaM( aDocPos
, FALSE
);
1431 return IsInSelection( aPaM
);
1434 BOOL
ImpEditView::SetCursorAtPoint( const Point
& rPointPixel
)
1436 pEditEngine
->pImpEditEngine
->CheckIdleFormatter();
1438 Point
aMousePos( rPointPixel
);
1440 // Logische Einheiten...
1441 aMousePos
= GetWindow()->PixelToLogic( aMousePos
);
1443 if ( ( !GetOutputArea().IsInside( aMousePos
) ) && !pEditEngine
->pImpEditEngine
->IsInSelectionMode() )
1448 Point
aDocPos( GetDocPos( aMousePos
) );
1450 // Kann optimiert werden: Erst innerhalb eines Absatzes die Zeilen
1451 // fuer den PaM durchwuehlen, dann nochmal mit dem PaM fuer das Rect,
1452 // obwohl die Zeile schon bekannt ist....
1453 // Das muss doch nicht sein !
1455 EditPaM aPaM
= pEditEngine
->pImpEditEngine
->GetPaM( aDocPos
);
1456 BOOL bGotoCursor
= DoAutoScroll();
1458 // aTmpNewSel: Diff zwischen alt und neu, nicht die neue Selektion
1459 EditSelection
aTmpNewSel( GetEditSelection().Max(), aPaM
);
1461 // --> OD 2005-12-16 #i27299#
1462 // work on copy of current selection and set new selection, if it has changed.
1463 EditSelection
aNewEditSelection( GetEditSelection() );
1465 aNewEditSelection
.Max() = aPaM
;
1466 if ( !pEditEngine
->pImpEditEngine
->aSelEngine
.HasAnchor() )
1468 if ( aNewEditSelection
.Min() != aPaM
)
1469 pEditEngine
->pImpEditEngine
->CursorMoved( aNewEditSelection
.Min().GetNode() );
1470 aNewEditSelection
.Min() = aPaM
;
1474 DrawSelection( aTmpNewSel
);
1477 // set changed text selection
1478 if ( GetEditSelection() != aNewEditSelection
)
1480 SetEditSelection( aNewEditSelection
);
1484 BOOL bForceCursor
= ( pDragAndDropInfo
? FALSE
: TRUE
) && !pEditEngine
->pImpEditEngine
->IsInSelectionMode();
1485 ShowCursor( bGotoCursor
, bForceCursor
);
1490 void ImpEditView::HideDDCursor()
1492 if ( pDragAndDropInfo
&& pDragAndDropInfo
->bVisCursor
)
1494 GetWindow()->DrawOutDev( pDragAndDropInfo
->aCurSavedCursor
.TopLeft(), pDragAndDropInfo
->aCurSavedCursor
.GetSize(),
1495 Point(0,0), pDragAndDropInfo
->aCurSavedCursor
.GetSize(),*pDragAndDropInfo
->pBackground
);
1496 pDragAndDropInfo
->bVisCursor
= sal_False
;
1500 void ImpEditView::ShowDDCursor( const Rectangle
& rRect
)
1502 if ( !pDragAndDropInfo
->bVisCursor
)
1504 if ( pOutWin
->GetCursor() )
1505 pOutWin
->GetCursor()->Hide();
1507 Color aOldFillColor
= GetWindow()->GetFillColor();
1508 GetWindow()->SetFillColor( Color(4210752) ); // GRAY BRUSH_50, OLDSV, change to DDCursor!
1510 // Hintergrund sichern...
1511 Rectangle
aSaveRec( GetWindow()->LogicToPixel( rRect
) );
1512 // lieber etwas mehr sichern...
1513 aSaveRec
.Right() += 1;
1514 aSaveRec
.Bottom() += 1;
1516 Size
aNewSzPx( aSaveRec
.GetSize() );
1517 if ( !pDragAndDropInfo
->pBackground
)
1519 pDragAndDropInfo
->pBackground
= new VirtualDevice( *GetWindow() );
1520 MapMode
aMapMode( GetWindow()->GetMapMode() );
1521 aMapMode
.SetOrigin( Point( 0, 0 ) );
1522 pDragAndDropInfo
->pBackground
->SetMapMode( aMapMode
);
1527 Size
aCurSzPx( pDragAndDropInfo
->pBackground
->GetOutputSizePixel() );
1528 if ( ( aCurSzPx
.Width() < aNewSzPx
.Width() ) ||( aCurSzPx
.Height() < aNewSzPx
.Height() ) )
1530 sal_Bool bDone
= pDragAndDropInfo
->pBackground
->SetOutputSizePixel( aNewSzPx
);
1531 DBG_ASSERT( bDone
, "Virtuelles Device kaputt?" );
1535 aSaveRec
= GetWindow()->PixelToLogic( aSaveRec
);
1537 pDragAndDropInfo
->pBackground
->DrawOutDev( Point(0,0), aSaveRec
.GetSize(),
1538 aSaveRec
.TopLeft(), aSaveRec
.GetSize(), *GetWindow() );
1539 pDragAndDropInfo
->aCurSavedCursor
= aSaveRec
;
1542 GetWindow()->DrawRect( rRect
);
1544 pDragAndDropInfo
->bVisCursor
= sal_True
;
1545 pDragAndDropInfo
->aCurCursor
= rRect
;
1547 GetWindow()->SetFillColor( aOldFillColor
);
1551 void ImpEditView::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent
& rDGE
) throw (::com::sun::star::uno::RuntimeException
)
1553 DBG_ASSERT( !pDragAndDropInfo
, "dragGestureRecognized - DragAndDropInfo exist!" );
1555 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
1557 Point
aMousePosPixel( rDGE
.DragOriginX
, rDGE
.DragOriginY
);
1559 EditSelection
aCopySel( GetEditSelection() );
1560 aCopySel
.Adjust( pEditEngine
->pImpEditEngine
->GetEditDoc() );
1562 if ( GetEditSelection().HasRange() && bClickedInSelection
)
1564 pDragAndDropInfo
= new DragAndDropInfo();
1570 Point aMousePos
= GetWindow()->PixelToLogic( aMousePosPixel
);
1571 const SvxFieldItem
* pField
= GetField( aMousePos
, &nPara
, &nPos
);
1574 pDragAndDropInfo
= new DragAndDropInfo();
1575 pDragAndDropInfo
->pField
= pField
;
1576 ContentNode
* pNode
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetObject( nPara
);
1577 aCopySel
= EditSelection( EditPaM( pNode
, nPos
), EditPaM( pNode
, nPos
+1 ) );
1578 GetEditSelection() = aCopySel
;
1580 BOOL bGotoCursor
= DoAutoScroll();
1581 BOOL bForceCursor
= ( pDragAndDropInfo
? FALSE
: TRUE
) && !pEditEngine
->pImpEditEngine
->IsInSelectionMode();
1582 ShowCursor( bGotoCursor
, bForceCursor
);
1584 else if ( IsBulletArea( aMousePos
, &nPara
) )
1586 pDragAndDropInfo
= new DragAndDropInfo();
1587 pDragAndDropInfo
->bOutlinerMode
= TRUE
;
1588 EditPaM
aStartPaM( pEditEngine
->pImpEditEngine
->GetEditDoc().GetObject( nPara
), 0 );
1589 EditPaM
aEndPaM( aStartPaM
);
1590 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_OUTLLEVEL
);
1591 for ( USHORT n
= nPara
+1; n
< pEditEngine
->pImpEditEngine
->GetEditDoc().Count(); n
++ )
1593 const SfxInt16Item
& rL
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( n
, EE_PARA_OUTLLEVEL
);
1594 if ( rL
.GetValue() > rLevel
.GetValue() )
1596 aEndPaM
.SetNode( pEditEngine
->pImpEditEngine
->GetEditDoc().GetObject( n
) );
1603 aEndPaM
.GetIndex() = aEndPaM
.GetNode()->Len();
1604 SetEditSelection( EditSelection( aStartPaM
, aEndPaM
) );
1608 if ( pDragAndDropInfo
)
1611 pDragAndDropInfo
->bStarterOfDD
= sal_True
;
1613 // Sensibler Bereich, wo gescrollt werden soll.
1615 aSz
= GetWindow()->PixelToLogic( aSz
);
1616 pDragAndDropInfo
->nSensibleRange
= (sal_uInt16
) aSz
.Width();
1617 pDragAndDropInfo
->nCursorWidth
= (sal_uInt16
) aSz
.Width() / 2;
1618 pDragAndDropInfo
->aBeginDragSel
= pEditEngine
->pImpEditEngine
->CreateESel( aCopySel
);
1620 uno::Reference
< datatransfer::XTransferable
> xData
= pEditEngine
->pImpEditEngine
->CreateTransferable( aCopySel
);
1622 sal_Int8 nActions
= bReadOnly
? datatransfer::dnd::DNDConstants::ACTION_COPY
: datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE
;
1624 rDGE
.DragSource
->startDrag( rDGE
, nActions
, 0 /*cursor*/, 0 /*image*/, xData
, mxDnDListener
);
1625 // Falls Drag&Move in einer Engine, muessen Copy&Del geklammert sein!
1626 GetCursor()->Hide();
1631 void ImpEditView::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent
& rDSDE
) throw (::com::sun::star::uno::RuntimeException
)
1633 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
1635 DBG_ASSERT( pDragAndDropInfo
, "ImpEditView::dragDropEnd: pDragAndDropInfo is NULL!" );
1637 // #123688# Shouldn't happen, but seems to happen...
1638 if ( pDragAndDropInfo
)
1640 if ( !bReadOnly
&& rDSDE
.DropSuccess
&& !pDragAndDropInfo
->bOutlinerMode
&& ( rDSDE
.DropAction
& datatransfer::dnd::DNDConstants::ACTION_MOVE
) )
1642 if ( pDragAndDropInfo
->bStarterOfDD
&& pDragAndDropInfo
->bDroppedInMe
)
1644 // DropPos: Wohin wurde gedroppt, unabhaengig von laenge.
1645 ESelection
aDropPos( pDragAndDropInfo
->aDropSel
.nStartPara
, pDragAndDropInfo
->aDropSel
.nStartPos
, pDragAndDropInfo
->aDropSel
.nStartPara
, pDragAndDropInfo
->aDropSel
.nStartPos
);
1646 ESelection aToBeDelSel
= pDragAndDropInfo
->aBeginDragSel
;
1647 ESelection
aNewSel( pDragAndDropInfo
->aDropSel
.nEndPara
, pDragAndDropInfo
->aDropSel
.nEndPos
,
1648 pDragAndDropInfo
->aDropSel
.nEndPara
, pDragAndDropInfo
->aDropSel
.nEndPos
);
1649 sal_Bool bBeforeSelection
= aDropPos
.IsLess( pDragAndDropInfo
->aBeginDragSel
);
1650 sal_uInt16 nParaDiff
= pDragAndDropInfo
->aBeginDragSel
.nEndPara
- pDragAndDropInfo
->aBeginDragSel
.nStartPara
;
1651 if ( bBeforeSelection
)
1653 // aToBeDelSel anpassen.
1654 DBG_ASSERT( pDragAndDropInfo
->aBeginDragSel
.nStartPara
>= pDragAndDropInfo
->aDropSel
.nStartPara
, "Doch nicht davor?" );
1655 aToBeDelSel
.nStartPara
= aToBeDelSel
.nStartPara
+ nParaDiff
;
1656 aToBeDelSel
.nEndPara
= aToBeDelSel
.nEndPara
+ nParaDiff
;
1657 // Zeichen korrigieren?
1658 if ( aToBeDelSel
.nStartPara
== pDragAndDropInfo
->aDropSel
.nEndPara
)
1660 sal_uInt16 nMoreChars
;
1661 if ( pDragAndDropInfo
->aDropSel
.nStartPara
== pDragAndDropInfo
->aDropSel
.nEndPara
)
1662 nMoreChars
= pDragAndDropInfo
->aDropSel
.nEndPos
- pDragAndDropInfo
->aDropSel
.nStartPos
;
1664 nMoreChars
= pDragAndDropInfo
->aDropSel
.nEndPos
;
1665 aToBeDelSel
.nStartPos
=
1666 aToBeDelSel
.nStartPos
+ nMoreChars
;
1667 if ( aToBeDelSel
.nStartPara
== aToBeDelSel
.nEndPara
)
1668 aToBeDelSel
.nEndPos
=
1669 aToBeDelSel
.nEndPos
+ nMoreChars
;
1674 // aToBeDelSel ist ok, aber Selektion der View
1675 // muss angepasst werden, wenn davor geloescht wird!
1676 DBG_ASSERT( pDragAndDropInfo
->aBeginDragSel
.nStartPara
<= pDragAndDropInfo
->aDropSel
.nStartPara
, "Doch nicht davor?" );
1677 aNewSel
.nStartPara
= aNewSel
.nStartPara
- nParaDiff
;
1678 aNewSel
.nEndPara
= aNewSel
.nEndPara
- nParaDiff
;
1679 // Zeichen korrigieren?
1680 if ( pDragAndDropInfo
->aBeginDragSel
.nEndPara
== pDragAndDropInfo
->aDropSel
.nStartPara
)
1682 sal_uInt16 nLessChars
;
1683 if ( pDragAndDropInfo
->aBeginDragSel
.nStartPara
== pDragAndDropInfo
->aBeginDragSel
.nEndPara
)
1684 nLessChars
= pDragAndDropInfo
->aBeginDragSel
.nEndPos
- pDragAndDropInfo
->aBeginDragSel
.nStartPos
;
1686 nLessChars
= pDragAndDropInfo
->aBeginDragSel
.nEndPos
;
1687 aNewSel
.nStartPos
= aNewSel
.nStartPos
- nLessChars
;
1688 if ( aNewSel
.nStartPara
== aNewSel
.nEndPara
)
1689 aNewSel
.nEndPos
= aNewSel
.nEndPos
- nLessChars
;
1694 EditSelection
aDelSel( pEditEngine
->pImpEditEngine
->CreateSel( aToBeDelSel
) );
1695 DBG_ASSERT( !aDelSel
.DbgIsBuggy( pEditEngine
->pImpEditEngine
->aEditDoc
), "ToBeDel ist buggy!" );
1696 pEditEngine
->pImpEditEngine
->ImpDeleteSelection( aDelSel
);
1697 if ( !bBeforeSelection
)
1699 DBG_ASSERT( !pEditEngine
->pImpEditEngine
->CreateSel( aNewSel
).DbgIsBuggy(pEditEngine
->pImpEditEngine
->aEditDoc
), "Bad" );
1700 SetEditSelection( pEditEngine
->pImpEditEngine
->CreateSel( aNewSel
) );
1702 pEditEngine
->pImpEditEngine
->FormatAndUpdate( pEditEngine
->pImpEditEngine
->GetActiveView() );
1707 // andere EditEngine...
1708 if ( pEditEngine
->pImpEditEngine
->ImplHasText() ) // #88630# SC ist removing the content when switching the task
1713 if ( pDragAndDropInfo
->bUndoAction
)
1714 pEditEngine
->pImpEditEngine
->UndoActionEnd( EDITUNDO_DRAGANDDROP
);
1717 ShowCursor( DoAutoScroll(), TRUE
);
1718 delete pDragAndDropInfo
;
1719 pDragAndDropInfo
= NULL
;
1720 pEditEngine
->GetEndDropHdl().Call(GetEditViewPtr());
1724 void ImpEditView::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent
& rDTDE
) throw (::com::sun::star::uno::RuntimeException
)
1726 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
1728 DBG_ASSERT( pDragAndDropInfo
, "Drop - No Drag&Drop info?!" );
1730 if ( pDragAndDropInfo
->bDragAccepted
)
1732 pEditEngine
->GetBeginDropHdl().Call(GetEditViewPtr());
1733 BOOL bChanges
= FALSE
;
1737 if ( pDragAndDropInfo
->bStarterOfDD
)
1739 pEditEngine
->pImpEditEngine
->UndoActionStart( EDITUNDO_DRAGANDDROP
);
1740 pDragAndDropInfo
->bUndoAction
= TRUE
;
1743 if ( pDragAndDropInfo
->bOutlinerMode
)
1746 GetEditViewPtr()->MoveParagraphs( Range( pDragAndDropInfo
->aBeginDragSel
.nStartPara
, pDragAndDropInfo
->aBeginDragSel
.nEndPara
), pDragAndDropInfo
->nOutlinerDropDest
);
1750 uno::Reference
< datatransfer::XTransferable
> xDataObj
= rDTDE
.Transferable
;
1751 if ( xDataObj
.is() )
1754 // Selektion wegmalen...
1756 EditPaM
aPaM( pDragAndDropInfo
->aDropDest
);
1758 PasteOrDropInfos aPasteOrDropInfos
;
1759 aPasteOrDropInfos
.nAction
= EE_ACTION_DROP
;
1760 aPasteOrDropInfos
.nStartPara
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( aPaM
.GetNode() );
1761 pEditEngine
->pImpEditEngine
->aBeginPasteOrDropHdl
.Call( &aPasteOrDropInfos
);
1763 EditSelection aNewSel
= pEditEngine
->pImpEditEngine
->InsertText( xDataObj
, String(), aPaM
, pEditEngine
->pImpEditEngine
->GetStatus().AllowPasteSpecial() );
1765 aPasteOrDropInfos
.nEndPara
= pEditEngine
->pImpEditEngine
->GetEditDoc().GetPos( aNewSel
.Max().GetNode() );
1766 pEditEngine
->pImpEditEngine
->aEndPasteOrDropHdl
.Call( &aPasteOrDropInfos
);
1768 SetEditSelection( aNewSel
);
1769 pEditEngine
->pImpEditEngine
->FormatAndUpdate( pEditEngine
->pImpEditEngine
->GetActiveView() );
1770 if ( pDragAndDropInfo
->bStarterOfDD
)
1772 // Nur dann setzen, wenn in gleicher Engine!
1773 pDragAndDropInfo
->aDropSel
.nStartPara
= pEditEngine
->pImpEditEngine
->aEditDoc
.GetPos( aPaM
.GetNode() );
1774 pDragAndDropInfo
->aDropSel
.nStartPos
= aPaM
.GetIndex();
1775 pDragAndDropInfo
->aDropSel
.nEndPara
= pEditEngine
->pImpEditEngine
->aEditDoc
.GetPos( aNewSel
.Max().GetNode() );
1776 pDragAndDropInfo
->aDropSel
.nEndPos
= aNewSel
.Max().GetIndex();
1777 pDragAndDropInfo
->bDroppedInMe
= sal_True
;
1784 rDTDE
.Context
->acceptDrop( rDTDE
.DropAction
);
1787 if ( !pDragAndDropInfo
->bStarterOfDD
)
1789 delete pDragAndDropInfo
;
1790 pDragAndDropInfo
= NULL
;
1793 rDTDE
.Context
->dropComplete( bChanges
);
1797 void ImpEditView::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent
& rDTDEE
) throw (::com::sun::star::uno::RuntimeException
)
1799 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
1801 if ( !pDragAndDropInfo
)
1802 pDragAndDropInfo
= new DragAndDropInfo( );
1804 pDragAndDropInfo
->bHasValidData
= sal_False
;
1806 // Check for supported format...
1807 // Only check for text, will also be there if bin or rtf
1808 datatransfer::DataFlavor aTextFlavor
;
1809 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING
, aTextFlavor
);
1810 const ::com::sun::star::datatransfer::DataFlavor
* pFlavors
= rDTDEE
.SupportedDataFlavors
.getConstArray();
1811 int nFlavors
= rDTDEE
.SupportedDataFlavors
.getLength();
1812 for ( int n
= 0; n
< nFlavors
; n
++ )
1814 if( TransferableDataHelper::IsEqual( pFlavors
[n
], aTextFlavor
) )
1816 pDragAndDropInfo
->bHasValidData
= sal_True
;
1824 void ImpEditView::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent
& ) throw (::com::sun::star::uno::RuntimeException
)
1826 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
1830 if ( !pDragAndDropInfo
->bStarterOfDD
)
1832 delete pDragAndDropInfo
;
1833 pDragAndDropInfo
= NULL
;
1837 void ImpEditView::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent
& rDTDE
) throw (::com::sun::star::uno::RuntimeException
)
1839 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
1841 Point
aMousePos( rDTDE
.LocationX
, rDTDE
.LocationY
);
1842 aMousePos
= GetWindow()->PixelToLogic( aMousePos
);
1844 sal_Bool bAccept
= sal_False
;
1846 if ( GetOutputArea().IsInside( aMousePos
) && !bReadOnly
)
1848 // sal_Int8 nSupportedActions = bReadOnly ? datatransfer::dnd::DNDConstants::ACTION_COPY : datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE;
1850 if ( pDragAndDropInfo
->bHasValidData
/* && ( nSupportedActions & rDTDE.DropAction ) MT: Default = 0x80 ?! */ )
1854 sal_Bool bAllowScroll
= DoAutoScroll();
1859 // pruefen, ob im sensitiven Bereich
1860 if ( ( (aMousePos
.X()-pDragAndDropInfo
->nSensibleRange
) < GetOutputArea().Left() ) && ( ( aMousePos
.X() + pDragAndDropInfo
->nSensibleRange
) > GetOutputArea().Left() ) )
1861 nScrollX
= GetOutputArea().GetWidth() / SCRLRANGE
;
1862 else if ( ( (aMousePos
.X()+pDragAndDropInfo
->nSensibleRange
) > GetOutputArea().Right() ) && ( ( aMousePos
.X() - pDragAndDropInfo
->nSensibleRange
) < GetOutputArea().Right() ) )
1863 nScrollX
= -( GetOutputArea().GetWidth() / SCRLRANGE
);
1865 if ( ( (aMousePos
.Y()-pDragAndDropInfo
->nSensibleRange
) < GetOutputArea().Top() ) && ( ( aMousePos
.Y() + pDragAndDropInfo
->nSensibleRange
) > GetOutputArea().Top() ) )
1866 nScrollY
= GetOutputArea().GetHeight() / SCRLRANGE
;
1867 else if ( ( (aMousePos
.Y()+pDragAndDropInfo
->nSensibleRange
) > GetOutputArea().Bottom() ) && ( ( aMousePos
.Y() - pDragAndDropInfo
->nSensibleRange
) < GetOutputArea().Bottom() ) )
1868 nScrollY
= -( GetOutputArea().GetHeight() / SCRLRANGE
);
1870 if ( nScrollX
|| nScrollY
)
1873 Scroll( nScrollX
, nScrollY
, RGCHK_PAPERSZ1
);
1877 Point
aDocPos( GetDocPos( aMousePos
) );
1878 EditPaM aPaM
= pEditEngine
->pImpEditEngine
->GetPaM( aDocPos
);
1879 pDragAndDropInfo
->aDropDest
= aPaM
;
1880 if ( pDragAndDropInfo
->bOutlinerMode
)
1882 USHORT nPara
= pEditEngine
->pImpEditEngine
->aEditDoc
.GetPos( aPaM
.GetNode() );
1883 ParaPortion
* pPPortion
= pEditEngine
->pImpEditEngine
->GetParaPortions().SaveGetObject( nPara
);
1884 long nDestParaStartY
= pEditEngine
->pImpEditEngine
->GetParaPortions().GetYOffset( pPPortion
);
1885 long nRel
= aDocPos
.Y() - nDestParaStartY
;
1886 if ( nRel
< ( pPPortion
->GetHeight() / 2 ) )
1888 pDragAndDropInfo
->nOutlinerDropDest
= nPara
;
1892 pDragAndDropInfo
->nOutlinerDropDest
= nPara
+1;
1895 if( ( pDragAndDropInfo
->nOutlinerDropDest
>= pDragAndDropInfo
->aBeginDragSel
.nStartPara
) &&
1896 ( pDragAndDropInfo
->nOutlinerDropDest
<= (pDragAndDropInfo
->aBeginDragSel
.nEndPara
+1) ) )
1901 else if ( HasSelection() )
1903 // es darf nicht in eine Selektion gedroppt werden
1904 EPaM aP
= pEditEngine
->pImpEditEngine
->CreateEPaM( aPaM
);
1905 ESelection
aDestSel( aP
.nPara
, aP
.nIndex
, aP
.nPara
, aP
.nIndex
);
1906 ESelection aCurSel
= pEditEngine
->pImpEditEngine
->CreateESel( GetEditSelection() );
1908 if ( !aDestSel
.IsLess( aCurSel
) && !aDestSel
.IsGreater( aCurSel
) )
1915 Rectangle aEditCursor
;
1916 if ( pDragAndDropInfo
->bOutlinerMode
)
1919 if ( pDragAndDropInfo
->nOutlinerDropDest
< pEditEngine
->pImpEditEngine
->GetEditDoc().Count() )
1921 ParaPortion
* pPPortion
= pEditEngine
->pImpEditEngine
->GetParaPortions().SaveGetObject( pDragAndDropInfo
->nOutlinerDropDest
);
1922 nDDYPos
= pEditEngine
->pImpEditEngine
->GetParaPortions().GetYOffset( pPPortion
);
1926 nDDYPos
= pEditEngine
->pImpEditEngine
->GetTextHeight();
1928 Point
aStartPos( 0, nDDYPos
);
1929 aStartPos
= GetWindowPos( aStartPos
);
1930 Point
aEndPos( GetOutputArea().GetWidth(), nDDYPos
);
1931 aEndPos
= GetWindowPos( aEndPos
);
1932 aEditCursor
= GetWindow()->LogicToPixel( Rectangle( aStartPos
, aEndPos
) );
1933 if ( !pEditEngine
->IsVertical() )
1935 aEditCursor
.Top()--;
1936 aEditCursor
.Bottom()++;
1940 aEditCursor
.Left()--;
1941 aEditCursor
.Right()++;
1943 aEditCursor
= GetWindow()->PixelToLogic( aEditCursor
);
1947 aEditCursor
= pEditEngine
->pImpEditEngine
->PaMtoEditCursor( aPaM
);
1948 Point
aTopLeft( GetWindowPos( aEditCursor
.TopLeft() ) );
1949 aEditCursor
.SetPos( aTopLeft
);
1950 aEditCursor
.Right() = aEditCursor
.Left() + pDragAndDropInfo
->nCursorWidth
;
1951 aEditCursor
= GetWindow()->LogicToPixel( aEditCursor
);
1952 aEditCursor
= GetWindow()->PixelToLogic( aEditCursor
);
1955 sal_Bool bCursorChanged
= !pDragAndDropInfo
->bVisCursor
|| ( pDragAndDropInfo
->aCurCursor
!= aEditCursor
);
1956 if ( bCursorChanged
)
1959 ShowDDCursor(aEditCursor
);
1961 pDragAndDropInfo
->bDragAccepted
= TRUE
;
1962 rDTDE
.Context
->acceptDrag( rDTDE
.DropAction
);
1970 pDragAndDropInfo
->bDragAccepted
= FALSE
;
1971 rDTDE
.Context
->rejectDrag();
1975 void ImpEditView::AddDragAndDropListeners()
1977 Window
* pWindow
= GetWindow();
1978 if ( !bActiveDragAndDropListener
&& pWindow
&& pWindow
->GetDragGestureRecognizer().is() )
1980 vcl::unohelper::DragAndDropWrapper
* pDnDWrapper
= new vcl::unohelper::DragAndDropWrapper( this );
1981 mxDnDListener
= pDnDWrapper
;
1983 uno::Reference
< datatransfer::dnd::XDragGestureListener
> xDGL( mxDnDListener
, uno::UNO_QUERY
);
1984 pWindow
->GetDragGestureRecognizer()->addDragGestureListener( xDGL
);
1985 uno::Reference
< datatransfer::dnd::XDropTargetListener
> xDTL( xDGL
, uno::UNO_QUERY
);
1986 pWindow
->GetDropTarget()->addDropTargetListener( xDTL
);
1987 pWindow
->GetDropTarget()->setActive( sal_True
);
1988 pWindow
->GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE
);
1990 bActiveDragAndDropListener
= TRUE
;
1994 void ImpEditView::RemoveDragAndDropListeners()
1996 if ( bActiveDragAndDropListener
&& GetWindow() && GetWindow()->GetDragGestureRecognizer().is() )
1998 uno::Reference
< datatransfer::dnd::XDragGestureListener
> xDGL( mxDnDListener
, uno::UNO_QUERY
);
1999 GetWindow()->GetDragGestureRecognizer()->removeDragGestureListener( xDGL
);
2000 uno::Reference
< datatransfer::dnd::XDropTargetListener
> xDTL( xDGL
, uno::UNO_QUERY
);
2001 GetWindow()->GetDropTarget()->removeDropTargetListener( xDTL
);
2003 if ( mxDnDListener
.is() )
2005 uno::Reference
< lang::XEventListener
> xEL( mxDnDListener
, uno::UNO_QUERY
);
2006 xEL
->disposing( lang::EventObject() ); // #95154# Empty Source means it's the Client
2007 mxDnDListener
.clear();
2010 bActiveDragAndDropListener
= FALSE
;