xref: /trunk/main/svx/source/svdraw/svdmrkv.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/svdmrkv.hxx>
32 #include <svx/svdetc.hxx>
33 #include <svx/svdoedge.hxx>
34 #include "svx/svdglob.hxx"
35 #include "svx/svditext.hxx"
36 #include <svx/svdview.hxx>
37 #include <svx/svdpagv.hxx>
38 #include <svx/svdpage.hxx>
39 #include "svddrgm1.hxx"
40 
41 #ifdef DBG_UTIL
42 #include <svdibrow.hxx>
43 #endif
44 
45 #include <svx/svdoole2.hxx>
46 #include <svx/xgrad.hxx>
47 #include <svx/xflgrit.hxx>
48 #include "gradtrns.hxx"
49 #include <svx/xflftrit.hxx>
50 #include <svx/dialmgr.hxx>
51 #include "svx/svdstr.hrc"
52 #include <svx/svdundo.hxx>
53 #include <svx/svdopath.hxx>
54 #include <svx/scene3d.hxx>
55 #include <svx/svdovirt.hxx>
56 #include <svx/sdr/overlay/overlayrollingrectangle.hxx>
57 #include <svx/sdr/overlay/overlaymanager.hxx>
58 #include <svx/sdrpaintwindow.hxx>
59 #include <svx/sdrpagewindow.hxx>
60 #include <svx/sdrhittesthelper.hxx>
61 
62 ////////////////////////////////////////////////////////////////////////////////////////////////////
63 // predefines
64 
65 class SdrUnoControlList;
66 
67 ////////////////////////////////////////////////////////////////////////////////////////////////////
68 // #114409#-3 Migrate Marking of Objects, Points and GluePoints
69 
70 class ImplMarkingOverlay
71 {
72     // The OverlayObjects
73     ::sdr::overlay::OverlayObjectList               maObjects;
74 
75     // The remembered second position in logical coodinates
76     basegfx::B2DPoint                               maSecondPosition;
77 
78     // bitfield
79     // A flag to remember if the action is for unmarking.
80     unsigned                                        mbUnmarking : 1;
81 
82 public:
83     ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking = sal_False);
84     ~ImplMarkingOverlay();
85 
86     void SetSecondPosition(const basegfx::B2DPoint& rNewPosition);
87     sal_Bool IsUnmarking() const { return mbUnmarking; }
88 };
89 
90 ImplMarkingOverlay::ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking)
91 :   maSecondPosition(rStartPos),
92     mbUnmarking(bUnmarking)
93 {
94     for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
95     {
96         SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
97         ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
98 
99         if(pTargetOverlay)
100         {
101             ::sdr::overlay::OverlayRollingRectangleStriped* pNew = new ::sdr::overlay::OverlayRollingRectangleStriped(
102                 rStartPos, rStartPos, false);
103             pTargetOverlay->add(*pNew);
104             maObjects.append(*pNew);
105         }
106     }
107 }
108 
109 ImplMarkingOverlay::~ImplMarkingOverlay()
110 {
111     // The OverlayObjects are cleared using the destructor of OverlayObjectList.
112     // That destructor calls clear() at the list which removes all objects from the
113     // OverlayManager and deletes them.
114 }
115 
116 void ImplMarkingOverlay::SetSecondPosition(const basegfx::B2DPoint& rNewPosition)
117 {
118     if(rNewPosition != maSecondPosition)
119     {
120         // apply to OverlayObjects
121         for(sal_uInt32 a(0L); a < maObjects.count(); a++)
122         {
123             ::sdr::overlay::OverlayRollingRectangleStriped& rCandidate = (::sdr::overlay::OverlayRollingRectangleStriped&)maObjects.getOverlayObject(a);
124             rCandidate.setSecondPosition(rNewPosition);
125         }
126 
127         // remember new position
128         maSecondPosition = rNewPosition;
129     }
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////////////////////////
133 ////////////////////////////////////////////////////////////////////////////////////////////////////
134 //
135 //  @@   @@  @@@@  @@@@@  @@  @@  @@ @@ @@ @@@@@ @@   @@
136 //  @@@ @@@ @@  @@ @@  @@ @@  @@  @@ @@ @@ @@    @@   @@
137 //  @@@@@@@ @@  @@ @@  @@ @@ @@   @@ @@ @@ @@    @@ @ @@
138 //  @@@@@@@ @@@@@@ @@@@@  @@@@    @@@@@ @@ @@@@  @@@@@@@
139 //  @@ @ @@ @@  @@ @@  @@ @@ @@    @@@  @@ @@    @@@@@@@
140 //  @@   @@ @@  @@ @@  @@ @@  @@   @@@  @@ @@    @@@ @@@
141 //  @@   @@ @@  @@ @@  @@ @@  @@    @   @@ @@@@@ @@   @@
142 //
143 ////////////////////////////////////////////////////////////////////////////////////////////////////
144 ////////////////////////////////////////////////////////////////////////////////////////////////////
145 
146 void SdrMarkView::ImpClearVars()
147 {
148     eDragMode=SDRDRAG_MOVE;
149     //HMHbHdlShown=sal_False;
150     bRefHdlShownOnly=sal_False;
151     eEditMode=SDREDITMODE_EDIT;
152     eEditMode0=SDREDITMODE_EDIT;
153     bDesignMode=sal_False;
154     pMarkedObj=NULL;
155     pMarkedPV=NULL;
156     bForceFrameHandles=sal_False;
157     bPlusHdlAlways=sal_False;
158     nFrameHandlesLimit=50;
159     bInsPolyPoint=sal_False;
160     mnInsPointNum = 0L;
161     bMarkedObjRectDirty=sal_False;
162     bMarkedPointsRectsDirty=sal_False;
163     mbMarkHandlesHidden = false;
164     bMrkPntDirty=sal_False;
165     bMarkHdlWhenTextEdit=sal_False;
166     bMarkableObjCountDirty=sal_False; // noch nicht implementiert
167     nMarkableObjCount=0;          // noch nicht implementiert
168 
169     // #114409#-3 Migrate selections
170     BrkMarkObj();
171     BrkMarkPoints();
172     BrkMarkGluePoints();
173 }
174 
175 SdrMarkView::SdrMarkView(SdrModel* pModel1, OutputDevice* pOut)
176 :   SdrSnapView(pModel1,pOut),
177     mpMarkObjOverlay(0L),
178     mpMarkPointsOverlay(0L),
179     mpMarkGluePointsOverlay(0L),
180     aHdl(this),
181     mpSdrViewSelection(new sdr::ViewSelection())
182 {
183     ImpClearVars();
184     StartListening(*pModel1);
185 }
186 
187 SdrMarkView::~SdrMarkView()
188 {
189     // #114409#-3 Migrate selections
190     BrkMarkObj();
191     BrkMarkPoints();
192     BrkMarkGluePoints();
193     delete mpSdrViewSelection;
194 }
195 
196 void __EXPORT SdrMarkView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
197 {
198     SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
199     if (pSdrHint!=NULL)
200     {
201         SdrHintKind eKind=pSdrHint->GetKind();
202 
203         if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED)
204         {
205             bMarkedObjRectDirty=sal_True;
206             bMarkedPointsRectsDirty=sal_True;
207         }
208 /* removed for now since this breaks existing code who iterates over the mark list and sequentially replaces objects
209         if( eKind==HINT_OBJREMOVED && IsObjMarked( const_cast<SdrObject*>(pSdrHint->GetObject()) ) )
210         {
211             MarkObj( const_cast<SdrObject*>(pSdrHint->GetObject()), GetSdrPageView(), sal_True );
212         }
213 */
214     }
215     SdrSnapView::Notify(rBC,rHint);
216 }
217 
218 void SdrMarkView::ModelHasChanged()
219 {
220     SdrPaintView::ModelHasChanged();
221     GetMarkedObjectListWriteAccess().SetNameDirty();
222     bMarkedObjRectDirty=sal_True;
223     bMarkedPointsRectsDirty=sal_True;
224     // Es sind beispielsweise Obj markiert und maMarkedObjectListist Sorted.
225     // In einer anderen View 2 wird die ObjOrder veraendert
226     // (z.B. MovToTop()). Dann ist Neusortieren der MarkList erforderlich.
227     GetMarkedObjectListWriteAccess().SetUnsorted();
228     SortMarkedObjects();
229     bMrkPntDirty=sal_True;
230     UndirtyMrkPnt();
231     SdrView* pV=(SdrView*)this;
232     if (pV!=NULL && !pV->IsDragObj() && !pV->IsInsObjPoint()) { // an dieser Stelle habe ich ein ziemliches Problem !!!
233         AdjustMarkHdl();
234     }
235 }
236 
237 ////////////////////////////////////////////////////////////////////////////////////////////////////
238 
239 sal_Bool SdrMarkView::IsAction() const
240 {
241     return SdrSnapView::IsAction() || IsMarkObj() || IsMarkPoints() || IsMarkGluePoints();
242 }
243 
244 void SdrMarkView::MovAction(const Point& rPnt)
245 {
246     SdrSnapView::MovAction(rPnt);
247 
248     if(IsMarkObj())
249     {
250         MovMarkObj(rPnt);
251     }
252     else if(IsMarkPoints())
253     {
254         MovMarkPoints(rPnt);
255     }
256     else if(IsMarkGluePoints())
257     {
258         MovMarkGluePoints(rPnt);
259     }
260 }
261 
262 void SdrMarkView::EndAction()
263 {
264     if(IsMarkObj())
265     {
266         EndMarkObj();
267     }
268     else if(IsMarkPoints())
269     {
270         EndMarkPoints();
271     }
272     else if(IsMarkGluePoints())
273     {
274         EndMarkGluePoints();
275     }
276 
277     SdrSnapView::EndAction();
278 }
279 
280 void SdrMarkView::BckAction()
281 {
282     SdrSnapView::BckAction();
283     BrkMarkObj();
284     BrkMarkPoints();
285     BrkMarkGluePoints();
286 }
287 
288 void SdrMarkView::BrkAction()
289 {
290     SdrSnapView::BrkAction();
291     BrkMarkObj();
292     BrkMarkPoints();
293     BrkMarkGluePoints();
294 }
295 
296 void SdrMarkView::TakeActionRect(Rectangle& rRect) const
297 {
298     if(IsMarkObj() || IsMarkPoints() || IsMarkGluePoints())
299     {
300         rRect = Rectangle(aDragStat.GetStart(), aDragStat.GetNow());
301     }
302     else
303     {
304         SdrSnapView::TakeActionRect(rRect);
305     }
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////////////////////////
309 
310 void SdrMarkView::ClearPageView()
311 {
312     UnmarkAllObj();
313     SdrSnapView::ClearPageView();
314 }
315 
316 void SdrMarkView::HideSdrPage()
317 {
318     bool bMrkChg(false);
319     //HMHbool bVis(false);
320 
321     if(mpPageView)
322     {
323         // break all creation actions when hiding page (#75081#)
324         BrkAction();
325         //HMHbVis = IsMarkHdlShown();
326 
327         //HMHif(bVis)
328         //HMH{
329         //HMH   HideMarkHdl();
330         //HMH}
331 
332         // Alle Markierungen dieser Seite verwerfen
333         bMrkChg = GetMarkedObjectListWriteAccess().DeletePageView(*mpPageView);
334     }
335 
336     SdrSnapView::HideSdrPage();
337 
338     if(bMrkChg)
339     {
340         MarkListHasChanged();
341         AdjustMarkHdl();
342     }
343 
344     //HMHif(bVis)
345     //HMH{
346     //HMH   ShowMarkHdl();
347     //HMH}
348 }
349 
350 ////////////////////////////////////////////////////////////////////////////////////////////////////
351 
352 sal_Bool SdrMarkView::BegMarkObj(const Point& rPnt, sal_Bool bUnmark)
353 {
354     BrkAction();
355 
356     DBG_ASSERT(0L == mpMarkObjOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkObjOverlay (!)");
357     basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
358     mpMarkObjOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
359 
360     aDragStat.Reset(rPnt);
361     aDragStat.NextPoint();
362     aDragStat.SetMinMove(nMinMovLog);
363 
364     return sal_True;
365 }
366 
367 void SdrMarkView::MovMarkObj(const Point& rPnt)
368 {
369     if(IsMarkObj() && aDragStat.CheckMinMoved(rPnt))
370     {
371         aDragStat.NextMove(rPnt);
372         DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
373         basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
374         mpMarkObjOverlay->SetSecondPosition(aNewPos);
375     }
376 }
377 
378 sal_Bool SdrMarkView::EndMarkObj()
379 {
380     sal_Bool bRetval(sal_False);
381 
382     if(IsMarkObj())
383     {
384         if(aDragStat.IsMinMoved())
385         {
386             Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
387             aRect.Justify();
388             MarkObj(aRect, mpMarkObjOverlay->IsUnmarking());
389             bRetval = sal_True;
390         }
391 
392         // cleanup
393         BrkMarkObj();
394     }
395 
396     return bRetval;
397 }
398 
399 void SdrMarkView::BrkMarkObj()
400 {
401     if(IsMarkObj())
402     {
403         DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
404         delete mpMarkObjOverlay;
405         mpMarkObjOverlay = 0L;
406     }
407 }
408 
409 ////////////////////////////////////////////////////////////////////////////////////////////////////
410 
411 sal_Bool SdrMarkView::BegMarkPoints(const Point& rPnt, sal_Bool bUnmark)
412 {
413     if(HasMarkablePoints())
414     {
415         BrkAction();
416 
417         DBG_ASSERT(0L == mpMarkPointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkPointsOverlay (!)");
418         basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
419         mpMarkPointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
420 
421         aDragStat.Reset(rPnt);
422         aDragStat.NextPoint();
423         aDragStat.SetMinMove(nMinMovLog);
424 
425         return sal_True;
426     }
427 
428     return sal_False;
429 }
430 
431 void SdrMarkView::MovMarkPoints(const Point& rPnt)
432 {
433     if(IsMarkPoints() && aDragStat.CheckMinMoved(rPnt))
434     {
435         aDragStat.NextMove(rPnt);
436 
437         DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
438         basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
439         mpMarkPointsOverlay->SetSecondPosition(aNewPos);
440     }
441 }
442 
443 sal_Bool SdrMarkView::EndMarkPoints()
444 {
445     sal_Bool bRetval(sal_False);
446 
447     if(IsMarkPoints())
448     {
449         if(aDragStat.IsMinMoved())
450         {
451             Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
452             aRect.Justify();
453             MarkPoints(aRect, mpMarkPointsOverlay->IsUnmarking());
454 
455             bRetval = sal_True;
456         }
457 
458         // cleanup
459         BrkMarkPoints();
460     }
461 
462     return bRetval;
463 }
464 
465 void SdrMarkView::BrkMarkPoints()
466 {
467     if(IsMarkPoints())
468     {
469         DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
470         delete mpMarkPointsOverlay;
471         mpMarkPointsOverlay = 0L;
472     }
473 }
474 
475 ////////////////////////////////////////////////////////////////////////////////////////////////////
476 
477 sal_Bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, sal_Bool bUnmark)
478 {
479     if(HasMarkableGluePoints())
480     {
481         BrkAction();
482 
483         DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)");
484         basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
485         mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
486 
487         aDragStat.Reset(rPnt);
488         aDragStat.NextPoint();
489         aDragStat.SetMinMove(nMinMovLog);
490 
491         return sal_True;
492     }
493 
494     return sal_False;
495 }
496 
497 void SdrMarkView::MovMarkGluePoints(const Point& rPnt)
498 {
499     if(IsMarkGluePoints() && aDragStat.CheckMinMoved(rPnt))
500     {
501         aDragStat.NextMove(rPnt);
502 
503         DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
504         basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
505         mpMarkGluePointsOverlay->SetSecondPosition(aNewPos);
506     }
507 }
508 
509 sal_Bool SdrMarkView::EndMarkGluePoints()
510 {
511     sal_Bool bRetval(sal_False);
512 
513     if(IsMarkGluePoints())
514     {
515         if(aDragStat.IsMinMoved())
516         {
517             Rectangle aRect(aDragStat.GetStart(),aDragStat.GetNow());
518             aRect.Justify();
519             MarkGluePoints(&aRect, mpMarkGluePointsOverlay->IsUnmarking());
520 
521             bRetval = sal_True;
522         }
523 
524         // cleanup
525         BrkMarkGluePoints();
526     }
527 
528     return bRetval;
529 }
530 
531 void SdrMarkView::BrkMarkGluePoints()
532 {
533     if(IsMarkGluePoints())
534     {
535         DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
536         delete mpMarkGluePointsOverlay;
537         mpMarkGluePointsOverlay = 0L;
538     }
539 }
540 
541 sal_Bool SdrMarkView::HasMarkableObj() const
542 {
543     sal_uIntPtr nCount=0;
544 
545     SdrPageView* pPV = GetSdrPageView();
546     if(pPV)
547     {
548         SdrObjList* pOL=pPV->GetObjList();
549         sal_uIntPtr nObjAnz=pOL->GetObjCount();
550         for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz && nCount==0; nObjNum++) {
551             SdrObject* pObj=pOL->GetObj(nObjNum);
552             if (IsObjMarkable(pObj,pPV)) {
553                 nCount++;
554             }
555         }
556     }
557     return nCount!=0;
558 }
559 
560 sal_uIntPtr SdrMarkView::GetMarkableObjCount() const
561 {
562     sal_uIntPtr nCount=0;
563     SdrPageView* pPV = GetSdrPageView();
564 
565     if(pPV)
566     {
567         SdrObjList* pOL=pPV->GetObjList();
568         sal_uIntPtr nObjAnz=pOL->GetObjCount();
569         for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
570             SdrObject* pObj=pOL->GetObj(nObjNum);
571             if (IsObjMarkable(pObj,pPV)) {
572                 nCount++;
573             }
574         }
575     }
576     return nCount;
577 }
578 
579 //HMHvoid SdrMarkView::ImpShowMarkHdl(bool /*bNoRefHdl*/)
580 //HMH{
581 //HMH   bNoRefHdl=sal_False; // geht leider erstmal nicht anders
582 //HMH   if (!bHdlShown) {
583 //HMH       bRefHdlShownOnly=sal_False;
584 //HMH       bHdlShown=sal_True;
585 //HMH   }
586 //HMH}
587 
588 //HMHvoid SdrMarkView::ShowMarkHdl(bool /*bNoRefHdl*/)
589 //HMH{
590 //HMH   bNoRefHdl=sal_False; // geht leider erstmal nicht anders
591 //HMH   ImpShowMarkHdl(bNoRefHdl);
592 //HMH}
593 
594 
595 //HMHvoid SdrMarkView::HideMarkHdl(bool /*bNoRefHdl*/)
596 //HMH{
597 //HMH   bNoRefHdl=sal_False; // geht leider erstmal nicht anders
598 //HMH   if (bHdlShown) {
599 //HMH       bRefHdlShownOnly=bNoRefHdl;
600 //HMH       bHdlShown=sal_False;
601 //HMH   }
602 //HMH}
603 
604 void SdrMarkView::hideMarkHandles()
605 {
606     if(!mbMarkHandlesHidden)
607     {
608         mbMarkHandlesHidden = true;
609         AdjustMarkHdl();
610     }
611 }
612 
613 void SdrMarkView::showMarkHandles()
614 {
615     if(mbMarkHandlesHidden)
616     {
617         mbMarkHandlesHidden = false;
618         AdjustMarkHdl();
619     }
620 }
621 
622 sal_Bool SdrMarkView::ImpIsFrameHandles() const
623 {
624     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
625     sal_Bool bFrmHdl=nMarkAnz>nFrameHandlesLimit || bForceFrameHandles;
626     sal_Bool bStdDrag=eDragMode==SDRDRAG_MOVE;
627     if (nMarkAnz==1 && bStdDrag && bFrmHdl)
628     {
629         const SdrObject* pObj=GetMarkedObjectByIndex(0);
630         if (pObj->GetObjInventor()==SdrInventor)
631         {
632             sal_uInt16 nIdent=pObj->GetObjIdentifier();
633             if (nIdent==OBJ_LINE || nIdent==OBJ_EDGE || nIdent==OBJ_CAPTION || nIdent==OBJ_MEASURE || nIdent==OBJ_CUSTOMSHAPE || nIdent==OBJ_TABLE )
634             {
635                 bFrmHdl=sal_False;
636             }
637         }
638     }
639     if (!bStdDrag && !bFrmHdl) {
640         // Grundsaetzlich erstmal alle anderen Dragmodi nur mit FrameHandles
641         bFrmHdl=sal_True;
642         if (eDragMode==SDRDRAG_ROTATE) {
643             // bei Rotate ObjOwn-Drag, wenn mind. 1 PolyObj
644             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && bFrmHdl; nMarkNum++) {
645                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
646                 const SdrObject* pObj=pM->GetMarkedSdrObj();
647                 bFrmHdl=!pObj->IsPolyObj();
648             }
649         }
650     }
651     if (!bFrmHdl) {
652         // FrameHandles, wenn wenigstens 1 Obj kein SpecialDrag kann
653         for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bFrmHdl; nMarkNum++) {
654             const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
655             const SdrObject* pObj=pM->GetMarkedSdrObj();
656             bFrmHdl=!pObj->hasSpecialDrag();
657         }
658     }
659     return bFrmHdl;
660 }
661 
662 void SdrMarkView::SetMarkHandles()
663 {
664     // #105722# remember old focus handle values to search for it again
665     const SdrHdl* pSaveOldFocusHdl = aHdl.GetFocusHdl();
666     sal_Bool bSaveOldFocus(sal_False);
667     sal_uInt32 nSavePolyNum(0L), nSavePointNum(0L);
668     SdrHdlKind eSaveKind(HDL_MOVE);
669     SdrObject* pSaveObj = NULL;
670 
671     if(pSaveOldFocusHdl
672         && pSaveOldFocusHdl->GetObj()
673         && pSaveOldFocusHdl->GetObj()->ISA(SdrPathObj)
674         && (pSaveOldFocusHdl->GetKind() == HDL_POLY || pSaveOldFocusHdl->GetKind() == HDL_BWGT))
675     {
676         bSaveOldFocus = sal_True;
677         nSavePolyNum = pSaveOldFocusHdl->GetPolyNum();
678         nSavePointNum = pSaveOldFocusHdl->GetPointNum();
679         pSaveObj = pSaveOldFocusHdl->GetObj();
680         eSaveKind = pSaveOldFocusHdl->GetKind();
681     }
682 
683     // delete/clear all handles. This will always be done, even with areMarkHandlesHidden()
684     aHdl.Clear();
685     aHdl.SetRotateShear(eDragMode==SDRDRAG_ROTATE);
686     aHdl.SetDistortShear(eDragMode==SDRDRAG_SHEAR);
687     pMarkedObj=NULL;
688     pMarkedPV=NULL;
689 
690     // are handles enabled at all? Create only then
691     if(!areMarkHandlesHidden())
692     {
693         sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
694         sal_Bool bStdDrag=eDragMode==SDRDRAG_MOVE;
695         sal_Bool bSingleTextObjMark=sal_False;
696 
697         if (nMarkAnz==1)
698         {
699             pMarkedObj=GetMarkedObjectByIndex(0);
700             bSingleTextObjMark =
701                 pMarkedObj &&
702                 pMarkedObj->ISA(SdrTextObj) &&
703                 static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame();
704         }
705 
706         sal_Bool bFrmHdl=ImpIsFrameHandles();
707 
708         if (nMarkAnz>0)
709         {
710             pMarkedPV=GetSdrPageViewOfMarkedByIndex(0);
711 
712             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && (pMarkedPV!=NULL || !bFrmHdl); nMarkNum++)
713             {
714                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
715 
716                 if (pMarkedPV!=pM->GetPageView())
717                 {
718                     pMarkedPV=NULL;
719                 }
720             }
721         }
722 
723         if (bFrmHdl)
724         {
725             Rectangle aRect(GetMarkedObjRect());
726 
727             // #i33755#
728             const sal_Bool bHideHandlesWhenInTextEdit(
729                 ((SdrView*)this)->IsTextEdit()
730                 && pMarkedObj
731                 && pMarkedObj->ISA(SdrTextObj)
732                 && ((SdrTextObj*)pMarkedObj)->IsInEditMode());
733 
734             if(!aRect.IsEmpty() && !bHideHandlesWhenInTextEdit)
735             { // sonst nix gefunden
736                 if( bSingleTextObjMark )
737                 {
738                     const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
739                     pMarkedObj->AddToHdlList(aHdl);
740                     const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
741                     for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
742                     {
743                         SdrHdl* pHdl=aHdl.GetHdl(i);
744                         pHdl->SetObj(pMarkedObj);
745                         pHdl->SetPageView(pMarkedPV);
746                         pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
747                     }
748                 }
749                 else if( eDragMode==SDRDRAG_CROP )
750                 {
751                     aHdl.AddHdl(new SdrCropHdl(aRect.TopLeft()     ,HDL_UPLFT));
752                     aHdl.AddHdl(new SdrCropHdl(aRect.TopCenter()   ,HDL_UPPER));
753                     aHdl.AddHdl(new SdrCropHdl(aRect.TopRight()    ,HDL_UPRGT));
754                     aHdl.AddHdl(new SdrCropHdl(aRect.LeftCenter()  ,HDL_LEFT ));
755                     aHdl.AddHdl(new SdrCropHdl(aRect.RightCenter() ,HDL_RIGHT));
756                     aHdl.AddHdl(new SdrCropHdl(aRect.BottomLeft()  ,HDL_LWLFT));
757                     aHdl.AddHdl(new SdrCropHdl(aRect.BottomCenter(),HDL_LOWER));
758                     aHdl.AddHdl(new SdrCropHdl(aRect.BottomRight() ,HDL_LWRGT));
759                 }
760                 else
761                 {
762                     sal_Bool bWdt0=aRect.Left()==aRect.Right();
763                     sal_Bool bHgt0=aRect.Top()==aRect.Bottom();
764                     if (bWdt0 && bHgt0)
765                     {
766                         aHdl.AddHdl(new SdrHdl(aRect.TopLeft(),HDL_UPLFT));
767                     }
768                     else if (!bStdDrag && (bWdt0 || bHgt0))
769                     {
770                         aHdl.AddHdl(new SdrHdl(aRect.TopLeft()    ,HDL_UPLFT));
771                         aHdl.AddHdl(new SdrHdl(aRect.BottomRight(),HDL_LWRGT));
772                     }
773                     else
774                     {
775                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopLeft()     ,HDL_UPLFT));
776                         if (          !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopCenter()   ,HDL_UPPER));
777                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopRight()    ,HDL_UPRGT));
778                         if (!bWdt0          ) aHdl.AddHdl(new SdrHdl(aRect.LeftCenter()  ,HDL_LEFT ));
779                         if (!bWdt0          ) aHdl.AddHdl(new SdrHdl(aRect.RightCenter() ,HDL_RIGHT));
780                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomLeft()  ,HDL_LWLFT));
781                         if (          !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomCenter(),HDL_LOWER));
782                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomRight() ,HDL_LWRGT));
783                     }
784                 }
785             }
786         }
787         else
788         {
789             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
790             {
791                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
792                 SdrObject* pObj=pM->GetMarkedSdrObj();
793                 SdrPageView* pPV=pM->GetPageView();
794                 const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
795                 pObj->AddToHdlList(aHdl);
796                 const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
797                 bool bPoly=pObj->IsPolyObj();
798                 const SdrUShortCont* pMrkPnts=pM->GetMarkedPoints();
799                 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
800                 {
801                     SdrHdl* pHdl=aHdl.GetHdl(i);
802                     pHdl->SetObj(pObj);
803                     pHdl->SetPageView(pPV);
804                     pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
805                     if (bPoly)
806                     {
807                         sal_Bool bSelected=pMrkPnts!=NULL && pMrkPnts->Exist(sal_uInt16(i-nSiz0));
808                         pHdl->SetSelected(bSelected);
809                         //sal_Bool bPlus=bPlusHdlAlways;
810                         if (bPlusHdlAlways || bSelected)
811                         {
812                             sal_uInt32 nPlusAnz=pObj->GetPlusHdlCount(*pHdl);
813                             for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
814                             {
815                                 SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,nPlusNum);
816                                 if (pPlusHdl!=NULL)
817                                 {
818                                     pPlusHdl->SetObj(pObj);
819                                     pPlusHdl->SetPageView(pPV);
820                                     pPlusHdl->SetPlusHdl(sal_True);
821                                     aHdl.AddHdl(pPlusHdl);
822                                 }
823                             }
824                         }
825                     }
826                 }
827             } // for nMarkNum
828         } // if bFrmHdl else
829 
830         // GluePoint-Handles
831         for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
832         {
833             const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
834             SdrObject* pObj=pM->GetMarkedSdrObj();
835             SdrPageView* pPV=pM->GetPageView();
836             const SdrUShortCont* pMrkGlue=pM->GetMarkedGluePoints();
837             if (pMrkGlue!=NULL)
838             {
839                 const SdrGluePointList* pGPL=pObj->GetGluePointList();
840                 if (pGPL!=NULL)
841                 {
842                     //sal_uInt16 nGlueAnz=pGPL->GetCount();
843                     sal_uInt16 nAnz=(sal_uInt16)pMrkGlue->GetCount();
844                     for (sal_uInt16 nNum=0; nNum<nAnz; nNum++)
845                     {
846                         sal_uInt16 nId=pMrkGlue->GetObject(nNum);
847                         //nNum changed to nNumGP because already used in for loop
848                         sal_uInt16 nNumGP=pGPL->FindGluePoint(nId);
849                         if (nNumGP!=SDRGLUEPOINT_NOTFOUND)
850                         {
851                             const SdrGluePoint& rGP=(*pGPL)[nNumGP];
852                             Point aPos(rGP.GetAbsolutePos(*pObj));
853                             SdrHdl* pGlueHdl=new SdrHdl(aPos,HDL_GLUE);
854                             pGlueHdl->SetObj(pObj);
855                             pGlueHdl->SetPageView(pPV);
856                             pGlueHdl->SetObjHdlNum(nId);
857                             aHdl.AddHdl(pGlueHdl);
858                         }
859                     }
860                 }
861             }
862         }
863 
864         // Drehpunkt/Spiegelachse
865         AddDragModeHdl(eDragMode);
866 
867         // add custom handles (used by other apps, e.g. AnchorPos)
868         AddCustomHdl();
869 
870         // sort handles
871         aHdl.Sort();
872 
873         // #105722# try to restore focus handle index from remembered values
874         if(bSaveOldFocus)
875         {
876             for(sal_uInt32 a(0); a < aHdl.GetHdlCount(); a++)
877             {
878                 SdrHdl* pCandidate = aHdl.GetHdl(a);
879 
880                 if(pCandidate->GetObj()
881                     && pCandidate->GetObj() == pSaveObj
882                     && pCandidate->GetKind() == eSaveKind
883                     && pCandidate->GetPolyNum() == nSavePolyNum
884                     && pCandidate->GetPointNum() == nSavePointNum)
885                 {
886                     aHdl.SetFocusHdl(pCandidate);
887                     break;
888                 }
889             }
890         }
891     }
892 }
893 
894 void SdrMarkView::AddCustomHdl()
895 {
896     // add custom handles (used by other apps, e.g. AnchorPos)
897 }
898 
899 void SdrMarkView::SetDragMode(SdrDragMode eMode)
900 {
901     SdrDragMode eMode0=eDragMode;
902     eDragMode=eMode;
903     if (eDragMode==SDRDRAG_RESIZE) eDragMode=SDRDRAG_MOVE;
904     if (eDragMode!=eMode0) {
905         //HMHBOOL bVis=IsMarkHdlShown();
906         //HMHif (bVis) HideMarkHdl();
907         ForceRefToMarked();
908         SetMarkHandles();
909         //HMHif (bVis) ShowMarkHdl();
910         {
911             if (AreObjectsMarked()) MarkListHasChanged();
912         }
913     }
914 }
915 
916 void SdrMarkView::AddDragModeHdl(SdrDragMode eMode)
917 {
918     switch(eMode)
919     {
920         case SDRDRAG_ROTATE:
921         {
922             // add rotation center
923             SdrHdl* pHdl = new SdrHdl(aRef1, HDL_REF1);
924 
925             aHdl.AddHdl(pHdl);
926 
927             break;
928         }
929         case SDRDRAG_MIRROR:
930         {
931             // add mirror axis
932             SdrHdl* pHdl3 = new SdrHdl(aRef2, HDL_REF2);
933             SdrHdl* pHdl2 = new SdrHdl(aRef1, HDL_REF1);
934             SdrHdl* pHdl1 = new SdrHdlLine(*pHdl2, *pHdl3, HDL_MIRX);
935 
936             pHdl1->SetObjHdlNum(1); // fuer Sortierung
937             pHdl2->SetObjHdlNum(2); // fuer Sortierung
938             pHdl3->SetObjHdlNum(3); // fuer Sortierung
939 
940             aHdl.AddHdl(pHdl1); // Linie als erstes, damit als letztes im HitTest
941             aHdl.AddHdl(pHdl2);
942             aHdl.AddHdl(pHdl3);
943 
944             break;
945         }
946         case SDRDRAG_TRANSPARENCE:
947         {
948             // add interactive transparence handle
949             sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
950             if(nMarkAnz == 1)
951             {
952                 SdrObject* pObj = GetMarkedObjectByIndex(0);
953                 SdrModel* pModel = GetModel();
954                 const SfxItemSet& rSet = pObj->GetMergedItemSet();
955 
956                 if(SFX_ITEM_SET != rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, sal_False))
957                 {
958                     // add this item, it's not yet there
959                     XFillFloatTransparenceItem aNewItem(
960                         (const XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE));
961                     XGradient aGrad = aNewItem.GetGradientValue();
962 
963                     aNewItem.SetEnabled(sal_True);
964                     aGrad.SetStartIntens(100);
965                     aGrad.SetEndIntens(100);
966                     aNewItem.SetGradientValue(aGrad);
967 
968                     // add undo to allow user to take back this step
969                     if( pModel->IsUndoEnabled() )
970                     {
971                         pModel->BegUndo(SVX_RESSTR(SIP_XA_FILLTRANSPARENCE));
972                         pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
973                         pModel->EndUndo();
974                     }
975 
976                     //pObj->SetItemAndBroadcast(aNewItem);
977                     SfxItemSet aNewSet(pModel->GetItemPool());
978                     aNewSet.Put(aNewItem);
979                     pObj->SetMergedItemSetAndBroadcast(aNewSet);
980                 }
981 
982                 // set values and transform to vector set
983                 GradTransformer aGradTransformer;
984                 GradTransVector aGradTransVector;
985                 GradTransGradient aGradTransGradient;
986 
987                 aGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
988                 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
989 
990                 // build handles
991                 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
992                 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
993                 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True);
994                 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True);
995                 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_False);
996                 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!");
997 
998                 // link them
999                 pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
1000                 pGradHdl->SetObj(pObj);
1001                 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1002                 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1003 
1004                 // insert them
1005                 aHdl.AddHdl(pColHdl1);
1006                 aHdl.AddHdl(pColHdl2);
1007                 aHdl.AddHdl(pGradHdl);
1008             }
1009             break;
1010         }
1011         case SDRDRAG_GRADIENT:
1012         {
1013             // add interactive gradient handle
1014             sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
1015             if(nMarkAnz == 1)
1016             {
1017                 SdrObject* pObj = GetMarkedObjectByIndex(0);
1018                 const SfxItemSet& rSet = pObj->GetMergedItemSet();
1019                 XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
1020 
1021                 if(eFillStyle == XFILL_GRADIENT)
1022                 {
1023                     // set values and transform to vector set
1024                     GradTransformer aGradTransformer;
1025                     GradTransVector aGradTransVector;
1026                     GradTransGradient aGradTransGradient;
1027                     Size aHdlSize(15, 15);
1028 
1029                     aGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
1030                     aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
1031 
1032                     // build handles
1033                     const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
1034                     const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
1035                     SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, sal_False);
1036                     SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, sal_False);
1037                     SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_True);
1038                     DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!");
1039 
1040                     // link them
1041                     pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
1042                     pGradHdl->SetObj(pObj);
1043                     pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1044                     pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1045 
1046                     // insert them
1047                     aHdl.AddHdl(pColHdl1);
1048                     aHdl.AddHdl(pColHdl2);
1049                     aHdl.AddHdl(pGradHdl);
1050                 }
1051             }
1052             break;
1053         }
1054         case SDRDRAG_CROP:
1055         {
1056             // todo
1057             break;
1058         }
1059         default: break;
1060     }
1061 }
1062 
1063 /** handle mouse over effects for handles */
1064 sal_Bool SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
1065 {
1066     if(aHdl.GetHdlCount())
1067     {
1068         SdrHdl* pMouseOverHdl = 0;
1069         if( !rMEvt.IsLeaveWindow() && pWin )
1070         {
1071             Point aMDPos( pWin->PixelToLogic( rMEvt.GetPosPixel() ) );
1072             pMouseOverHdl = PickHandle(aMDPos);
1073         }
1074 
1075         // notify last mouse over handle that he lost the mouse
1076         const sal_uIntPtr nHdlCount = aHdl.GetHdlCount();
1077 
1078         for(sal_uIntPtr nHdl = 0; nHdl < nHdlCount; nHdl++ )
1079         {
1080             SdrHdl* pCurrentHdl = GetHdl(nHdl);
1081             if( pCurrentHdl->mbMouseOver )
1082             {
1083                 if( pCurrentHdl != pMouseOverHdl )
1084                 {
1085                     pCurrentHdl->mbMouseOver = false;
1086                     pCurrentHdl->onMouseLeave();
1087                 }
1088                 break;
1089             }
1090         }
1091 
1092         // notify current mouse over handle
1093         if( pMouseOverHdl /* && !pMouseOverHdl->mbMouseOver */ )
1094         {
1095             pMouseOverHdl->mbMouseOver = true;
1096             pMouseOverHdl->onMouseEnter(rMEvt);
1097         }
1098     }
1099     return SdrSnapView::MouseMove(rMEvt, pWin);
1100 }
1101 
1102 void SdrMarkView::ForceRefToMarked()
1103 {
1104     switch(eDragMode)
1105     {
1106         case SDRDRAG_ROTATE:
1107         {
1108             Rectangle aR(GetMarkedObjRect());
1109             aRef1 = aR.Center();
1110 
1111             break;
1112         }
1113 
1114         case SDRDRAG_MIRROR:
1115         {
1116             // Erstmal die laenge der Spiegelachsenlinie berechnen
1117             long nOutMin=0;
1118             long nOutMax=0;
1119             long nMinLen=0;
1120             long nObjDst=0;
1121             long nOutHgt=0;
1122             OutputDevice* pOut=GetFirstOutputDevice();
1123             //OutputDevice* pOut=GetWin(0);
1124             if (pOut!=NULL) {
1125                 // Mindestlaenge 50 Pixel
1126                 nMinLen=pOut->PixelToLogic(Size(0,50)).Height();
1127                 // 20 Pixel fuer RefPt-Abstand vom Obj
1128                 nObjDst=pOut->PixelToLogic(Size(0,20)).Height();
1129                 // MinY/MaxY
1130                 // Abstand zum Rand = Mindestlaenge = 10 Pixel
1131                 long nDst=pOut->PixelToLogic(Size(0,10)).Height();
1132                 nOutMin=-pOut->GetMapMode().GetOrigin().Y();
1133                 nOutMax=pOut->GetOutputSize().Height()-1+nOutMin;
1134                 nOutMin+=nDst;
1135                 nOutMax-=nDst;
1136                 // Absolute Mindestlaenge jedoch 10 Pixel
1137                 if (nOutMax-nOutMin<nDst) {
1138                     nOutMin+=nOutMax+1;
1139                     nOutMin/=2;
1140                     nOutMin-=(nDst+1)/2;
1141                     nOutMax=nOutMin+nDst;
1142                 }
1143                 nOutHgt=nOutMax-nOutMin;
1144                 // Sonst Mindestlaenge = 1/4 OutHgt
1145                 long nTemp=nOutHgt/4;
1146                 if (nTemp>nMinLen) nMinLen=nTemp;
1147             }
1148 
1149             Rectangle aR(GetMarkedObjBoundRect());
1150             Point aCenter(aR.Center());
1151             long nMarkHgt=aR.GetHeight()-1;
1152             long nHgt=nMarkHgt+nObjDst*2;       // 20 Pixel obej und unten ueberstehend
1153             if (nHgt<nMinLen) nHgt=nMinLen;     // Mindestlaenge 50 Pixel bzw. 1/4 OutHgt
1154 
1155             long nY1=aCenter.Y()-(nHgt+1)/2;
1156             long nY2=nY1+nHgt;
1157 
1158             if (pOut!=NULL && nMinLen>nOutHgt) nMinLen=nOutHgt; // evtl. noch etwas verkuerzen
1159 
1160             if (pOut!=NULL) { // nun vollstaendig in den sichtbaren Bereich schieben
1161                 if (nY1<nOutMin) {
1162                     nY1=nOutMin;
1163                     if (nY2<nY1+nMinLen) nY2=nY1+nMinLen;
1164                 }
1165                 if (nY2>nOutMax) {
1166                     nY2=nOutMax;
1167                     if (nY1>nY2-nMinLen) nY1=nY2-nMinLen;
1168                 }
1169             }
1170 
1171             aRef1.X()=aCenter.X();
1172             aRef1.Y()=nY1;
1173             aRef2.X()=aCenter.X();
1174             aRef2.Y()=nY2;
1175 
1176             break;
1177         }
1178 
1179         case SDRDRAG_TRANSPARENCE:
1180         case SDRDRAG_GRADIENT:
1181         case SDRDRAG_CROP:
1182         {
1183             Rectangle aRect(GetMarkedObjBoundRect());
1184             aRef1 = aRect.TopLeft();
1185             aRef2 = aRect.BottomRight();
1186             break;
1187         }
1188         default: break;
1189     }
1190 }
1191 
1192 void SdrMarkView::SetRef1(const Point& rPt)
1193 {
1194     if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
1195     {
1196         aRef1 = rPt;
1197         SdrHdl* pH = aHdl.GetHdl(HDL_REF1);
1198         if(pH)
1199             pH->SetPos(rPt);
1200         //HMHShowMarkHdl();
1201     }
1202 }
1203 
1204 void SdrMarkView::SetRef2(const Point& rPt)
1205 {
1206     if(eDragMode == SDRDRAG_MIRROR)
1207     {
1208         aRef2 = rPt;
1209         SdrHdl* pH = aHdl.GetHdl(HDL_REF2);
1210         if(pH)
1211             pH->SetPos(rPt);
1212         //HMHShowMarkHdl();
1213     }
1214 }
1215 
1216 void SdrMarkView::CheckMarked()
1217 {
1218     for (sal_uIntPtr nm=GetMarkedObjectCount(); nm>0;) {
1219         nm--;
1220         SdrMark* pM=GetSdrMarkByIndex(nm);
1221         SdrObject* pObj=pM->GetMarkedSdrObj();
1222         SdrPageView* pPV=pM->GetPageView();
1223         SdrLayerID nLay=pObj->GetLayer();
1224         sal_Bool bRaus=!pObj->IsInserted(); // Obj geloescht?
1225         if (!pObj->Is3DObj()) {
1226             bRaus=bRaus || pObj->GetPage()!=pPV->GetPage();   // Obj ploetzlich in anderer Page oder Group
1227         }
1228         bRaus=bRaus || pPV->GetLockedLayers().IsSet(nLay) ||  // Layer gesperrt?
1229                        !pPV->GetVisibleLayers().IsSet(nLay);  // Layer nicht sichtbar?
1230 
1231         if( !bRaus )
1232             bRaus = !pObj->IsVisible(); // not visible objects can not be marked
1233 
1234         if (!bRaus) {
1235             // Joe am 9.3.1997: Gruppierte Objekten koennen nun auch
1236             // markiert werden. Nach EnterGroup muessen aber die Objekte
1237             // der hoeheren Ebene deselektiert werden.
1238             const SdrObjList* pOOL=pObj->GetObjList();
1239             const SdrObjList* pVOL=pPV->GetObjList();
1240             while (pOOL!=NULL && pOOL!=pVOL) {
1241                 pOOL=pOOL->GetUpList();
1242             }
1243             bRaus=pOOL!=pVOL;
1244         }
1245 
1246         if (bRaus)
1247         {
1248             GetMarkedObjectListWriteAccess().DeleteMark(nm);
1249         }
1250         else
1251         {
1252             if (!IsGluePointEditMode()) { // Markierte GluePoints nur im GlueEditMode
1253                 SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1254                 if (pPts!=NULL && pPts->GetCount()!=0) {
1255                     pPts->Clear();
1256                 }
1257             }
1258         }
1259     }
1260 
1261     // #97995# at least reset the remembered BoundRect to prevent handle
1262     // generation if bForceFrameHandles is TRUE.
1263     bMarkedObjRectDirty = sal_True;
1264 }
1265 
1266 void SdrMarkView::SetMarkRects()
1267 {
1268     SdrPageView* pPV = GetSdrPageView();
1269 
1270     if(pPV)
1271     {
1272         pPV->SetHasMarkedObj(GetSnapRectFromMarkedObjects(pPV, pPV->MarkSnap()));
1273         GetBoundRectFromMarkedObjects(pPV, pPV->MarkBound());
1274     }
1275 }
1276 
1277 void SdrMarkView::SetFrameHandles(sal_Bool bOn)
1278 {
1279     if (bOn!=bForceFrameHandles) {
1280         sal_Bool bOld=ImpIsFrameHandles();
1281         bForceFrameHandles=bOn;
1282         sal_Bool bNew=ImpIsFrameHandles();
1283         if (bNew!=bOld) {
1284             AdjustMarkHdl(); //HMHTRUE);
1285             MarkListHasChanged();
1286         }
1287     }
1288 }
1289 
1290 void SdrMarkView::SetEditMode(SdrViewEditMode eMode)
1291 {
1292     if (eMode!=eEditMode) {
1293         sal_Bool bGlue0=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1294         sal_Bool bEdge0=((SdrCreateView*)this)->IsEdgeTool();
1295         eEditMode0=eEditMode;
1296         eEditMode=eMode;
1297         sal_Bool bGlue1=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1298         sal_Bool bEdge1=((SdrCreateView*)this)->IsEdgeTool();
1299         // etwas Aufwand um Flackern zu verhindern beim Umschalten
1300         // zwischen GlueEdit und EdgeTool
1301         if (bGlue1 && !bGlue0) ImpSetGlueVisible2(bGlue1);
1302         if (bEdge1!=bEdge0) ImpSetGlueVisible3(bEdge1);
1303         if (!bGlue1 && bGlue0) ImpSetGlueVisible2(bGlue1);
1304         if (bGlue0 && !bGlue1) UnmarkAllGluePoints();
1305     }
1306 }
1307 
1308 ////////////////////////////////////////////////////////////////////////////////////////////////////
1309 
1310 sal_Bool SdrMarkView::IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const
1311 {
1312     if (pObj)
1313     {
1314         if (pObj->IsMarkProtect() ||
1315             (!bDesignMode && pObj->IsUnoObj()))
1316         {
1317             // Objekt nicht selektierbar oder
1318             // SdrUnoObj nicht im DesignMode
1319             return sal_False;
1320         }
1321     }
1322     return pPV!=NULL ? pPV->IsObjMarkable(pObj) : sal_True;
1323 }
1324 
1325 sal_Bool SdrMarkView::IsMarkedObjHit(const Point& rPnt, short nTol) const
1326 {
1327     sal_Bool bRet=sal_False;
1328     nTol=ImpGetHitTolLogic(nTol,NULL);
1329     Point aPt(rPnt);
1330     for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount() && !bRet; nm++) {
1331         SdrMark* pM=GetSdrMarkByIndex(nm);
1332         bRet = 0 != CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0);
1333     }
1334     return bRet;
1335 }
1336 
1337 SdrHdl* SdrMarkView::PickHandle(const Point& rPnt, sal_uIntPtr nOptions, SdrHdl* pHdl0) const
1338 {
1339     if (bSomeObjChgdFlag) { // ggf. Handles neu berechnen lassen!
1340         FlushComeBackTimer();
1341     }
1342     sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1343     sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0;
1344     Point aPt(rPnt);
1345     return aHdl.IsHdlListHit(aPt,bBack,bNext,pHdl0);
1346 }
1347 
1348 sal_Bool SdrMarkView::MarkObj(const Point& rPnt, short nTol, sal_Bool bToggle, sal_Bool bDeep)
1349 {
1350     SdrObject* pObj;
1351     SdrPageView* pPV;
1352     nTol=ImpGetHitTolLogic(nTol,NULL);
1353     sal_uIntPtr nOptions=SDRSEARCH_PICKMARKABLE;
1354     if (bDeep) nOptions=nOptions|SDRSEARCH_DEEP;
1355     sal_Bool bRet=PickObj(rPnt,(sal_uInt16)nTol,pObj,pPV,nOptions);
1356     if (bRet) {
1357         sal_Bool bUnmark=bToggle && IsObjMarked(pObj);
1358         MarkObj(pObj,pPV,bUnmark);
1359     }
1360     return bRet;
1361 }
1362 
1363 sal_Bool SdrMarkView::MarkNextObj(sal_Bool bPrev)
1364 {
1365     SdrPageView* pPageView = GetSdrPageView();
1366 
1367     if(!pPageView)
1368     {
1369         return sal_False;
1370     }
1371 
1372     SortMarkedObjects();
1373     sal_uIntPtr  nMarkAnz=GetMarkedObjectCount();
1374     sal_uIntPtr  nChgMarkNum = ULONG_MAX; // Nummer des zu ersetzenden MarkEntries
1375     sal_uIntPtr  nSearchObjNum = bPrev ? 0 : ULONG_MAX;
1376     if (nMarkAnz!=0) {
1377         nChgMarkNum=bPrev ? 0 : sal_uIntPtr(nMarkAnz-1);
1378         SdrMark* pM=GetSdrMarkByIndex(nChgMarkNum);
1379         OSL_ASSERT(pM!=NULL);
1380         if (pM->GetMarkedSdrObj() != NULL)
1381             nSearchObjNum = pM->GetMarkedSdrObj()->GetNavigationPosition();
1382     }
1383 
1384     SdrObject* pMarkObj=NULL;
1385     SdrObjList* pSearchObjList=pPageView->GetObjList();
1386     sal_uIntPtr nObjAnz=pSearchObjList->GetObjCount();
1387     if (nObjAnz!=0) {
1388         if (nSearchObjNum>nObjAnz) nSearchObjNum=nObjAnz;
1389         while (pMarkObj==NULL && ((!bPrev && nSearchObjNum>0) || (bPrev && nSearchObjNum<nObjAnz)))
1390         {
1391             if (!bPrev)
1392                 nSearchObjNum--;
1393             SdrObject* pSearchObj = pSearchObjList->GetObjectForNavigationPosition(nSearchObjNum);
1394             if (IsObjMarkable(pSearchObj,pPageView))
1395             {
1396                 if (TryToFindMarkedObject(pSearchObj)==CONTAINER_ENTRY_NOTFOUND)
1397                 {
1398                     pMarkObj=pSearchObj;
1399                 }
1400             }
1401             if (bPrev) nSearchObjNum++;
1402         }
1403     }
1404 
1405     if(!pMarkObj)
1406     {
1407         return sal_False;
1408     }
1409 
1410     if (nChgMarkNum!=ULONG_MAX)
1411     {
1412         GetMarkedObjectListWriteAccess().DeleteMark(nChgMarkNum);
1413     }
1414     MarkObj(pMarkObj,pPageView); // ruft auch MarkListHasChanged(), AdjustMarkHdl()
1415     return sal_True;
1416 }
1417 
1418 sal_Bool SdrMarkView::MarkNextObj(const Point& rPnt, short nTol, sal_Bool bPrev)
1419 {
1420     SortMarkedObjects();
1421     nTol=ImpGetHitTolLogic(nTol,NULL);
1422     Point aPt(rPnt);
1423     SdrMark* pTopMarkHit=NULL;
1424     SdrMark* pBtmMarkHit=NULL;
1425     sal_uIntPtr nTopMarkHit=0;
1426     sal_uIntPtr nBtmMarkHit=0;
1427     // oberstes der markierten Objekte suchen, das von rPnt getroffen wird
1428     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1429     sal_uIntPtr nm=0;
1430     for (nm=nMarkAnz; nm>0 && pTopMarkHit==NULL;) {
1431         nm--;
1432         SdrMark* pM=GetSdrMarkByIndex(nm);
1433         if(CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0))
1434         {
1435             pTopMarkHit=pM;
1436             nTopMarkHit=nm;
1437         }
1438     }
1439     // Nichts gefunden, dann ganz normal ein Obj markieren.
1440     if (pTopMarkHit==NULL) return MarkObj(rPnt,sal_uInt16(nTol),sal_False);
1441 
1442     SdrObject* pTopObjHit=pTopMarkHit->GetMarkedSdrObj();
1443     SdrObjList* pObjList=pTopObjHit->GetObjList();
1444     SdrPageView* pPV=pTopMarkHit->GetPageView();
1445     // unterstes der markierten Objekte suchen, das von rPnt getroffen wird
1446     // und auf der gleichen PageView liegt wie pTopMarkHit
1447     for (nm=0; nm<nMarkAnz && pBtmMarkHit==NULL; nm++) {
1448         SdrMark* pM=GetSdrMarkByIndex(nm);
1449         SdrPageView* pPV2=pM->GetPageView();
1450         if (pPV2==pPV && CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pPV2,0,0))
1451         {
1452             pBtmMarkHit=pM;
1453             nBtmMarkHit=nm;
1454         }
1455     }
1456     if (pBtmMarkHit==NULL) { pBtmMarkHit=pTopMarkHit; nBtmMarkHit=nTopMarkHit; }
1457     SdrObject* pBtmObjHit=pBtmMarkHit->GetMarkedSdrObj();
1458     sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1459 
1460     // #110988#
1461     //sal_uIntPtr nSearchBeg=bPrev ? pBtmObjHit->GetOrdNum()+1 : pTopObjHit->GetOrdNum();
1462     sal_uInt32 nSearchBeg;
1463     E3dScene* pScene = NULL;
1464     SdrObject* pObjHit = (bPrev) ? pBtmObjHit : pTopObjHit;
1465     sal_Bool bRemap = pObjHit->ISA(E3dCompoundObject)
1466         ? ((E3dCompoundObject*)pObjHit)->IsAOrdNumRemapCandidate(pScene)
1467         : sal_False;
1468 
1469     if(bPrev)
1470     {
1471         sal_uInt32 nOrdNumBtm(pBtmObjHit->GetOrdNum());
1472 
1473         if(bRemap)
1474         {
1475             nOrdNumBtm = pScene->RemapOrdNum(nOrdNumBtm);
1476         }
1477 
1478         nSearchBeg = nOrdNumBtm + 1;
1479     }
1480     else
1481     {
1482         sal_uInt32 nOrdNumTop(pTopObjHit->GetOrdNum());
1483 
1484         if(bRemap)
1485         {
1486             nOrdNumTop = pScene->RemapOrdNum(nOrdNumTop);
1487         }
1488 
1489         nSearchBeg = nOrdNumTop;
1490     }
1491 
1492     sal_uIntPtr no=nSearchBeg;
1493     SdrObject* pFndObj=NULL;
1494     //SdrObject* pAktObj=NULL;
1495     while (pFndObj==NULL && ((!bPrev && no>0) || (bPrev && no<nObjAnz))) {
1496         if (!bPrev) no--;
1497         SdrObject* pObj;
1498 
1499         if(bRemap)
1500         {
1501             pObj = pObjList->GetObj(pScene->RemapOrdNum(no));
1502         }
1503         else
1504         {
1505             pObj = pObjList->GetObj(no);
1506         }
1507 
1508         if (CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_TESTMARKABLE,0))
1509         {
1510             if (TryToFindMarkedObject(pObj)==CONTAINER_ENTRY_NOTFOUND) {
1511                 pFndObj=pObj;
1512             } else {
1513                 // hier wg. Performance ggf. noch no auf Top bzw. auf Btm stellen
1514             }
1515         }
1516         if (bPrev) no++;
1517     }
1518     if (pFndObj!=NULL)
1519     {
1520         GetMarkedObjectListWriteAccess().DeleteMark(bPrev?nBtmMarkHit:nTopMarkHit);
1521         GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pFndObj,pPV));
1522         MarkListHasChanged();
1523         AdjustMarkHdl(); //HMHTRUE);
1524     }
1525     return pFndObj!=NULL;
1526 }
1527 
1528 sal_Bool SdrMarkView::MarkObj(const Rectangle& rRect, sal_Bool bUnmark)
1529 {
1530     sal_Bool bFnd=sal_False;
1531     Rectangle aR(rRect);
1532     SdrObject* pObj;
1533     SdrObjList* pObjList;
1534     BrkAction();
1535     SdrPageView* pPV = GetSdrPageView();
1536 
1537     if(pPV)
1538     {
1539         pObjList=pPV->GetObjList();
1540         Rectangle aFrm1(aR);
1541         sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1542         for (sal_uIntPtr nO=0; nO<nObjAnz; nO++) {
1543             pObj=pObjList->GetObj(nO);
1544             Rectangle aRect(pObj->GetCurrentBoundRect());
1545             if (aFrm1.IsInside(aRect)) {
1546                 if (!bUnmark) {
1547                     if (IsObjMarkable(pObj,pPV))
1548                     {
1549                         GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1550                         bFnd=sal_True;
1551                     }
1552                 } else {
1553                     sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1554                     if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1555                     {
1556                         GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1557                         bFnd=sal_True;
1558                     }
1559                 }
1560             }
1561         }
1562     }
1563     if (bFnd) {
1564         SortMarkedObjects();
1565         MarkListHasChanged();
1566         AdjustMarkHdl(); //HMHTRUE);
1567         //HMHShowMarkHdl();
1568     }
1569     return bFnd;
1570 }
1571 
1572 void SdrMarkView::MarkObj(SdrObject* pObj, SdrPageView* pPV, sal_Bool bUnmark, sal_Bool bImpNoSetMarkHdl)
1573 {
1574     if (pObj!=NULL && pPV!=NULL && IsObjMarkable(pObj, pPV)) {
1575         BrkAction();
1576         if (!bUnmark)
1577         {
1578             GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1579         }
1580         else
1581         {
1582             sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1583             if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1584             {
1585                 GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1586             }
1587         }
1588         if (!bImpNoSetMarkHdl) {
1589             MarkListHasChanged();
1590             AdjustMarkHdl(); //HMHTRUE);
1591             //HMHif (!bSomeObjChgdFlag) {
1592                 // ShowMarkHdl kommt sonst mit dem AfterPaintTimer
1593                 //HMHShowMarkHdl();
1594             //HMH}
1595         }
1596     }
1597 }
1598 
1599 sal_Bool SdrMarkView::IsObjMarked(SdrObject* pObj) const
1600 {
1601     // nicht so ganz die feine Art: Da FindObject() nicht const ist
1602     // muss ich mich hier auf non-const casten.
1603     sal_uIntPtr nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj);
1604     return nPos!=CONTAINER_ENTRY_NOTFOUND;
1605 }
1606 
1607 sal_uInt16 SdrMarkView::GetMarkHdlSizePixel() const
1608 {
1609     return aHdl.GetHdlSize()*2+1;
1610 }
1611 
1612 void SdrMarkView::SetSolidMarkHdl(sal_Bool bOn)
1613 {
1614     if (bOn!=aHdl.IsFineHdl()) {
1615         //HMHBOOL bMerk=IsMarkHdlShown();
1616         //HMHif (bMerk) HideMarkHdl();
1617         aHdl.SetFineHdl(bOn);
1618         //HMHif (bMerk) ShowMarkHdl();
1619     }
1620 }
1621 
1622 void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz)
1623 {
1624     if (nSiz<3) nSiz=3;
1625     nSiz/=2;
1626     if (nSiz!=aHdl.GetHdlSize()) {
1627         //HMHBOOL bMerk=IsMarkHdlShown();
1628         //HMHif (bMerk) HideMarkHdl();
1629         aHdl.SetHdlSize(nSiz);
1630         //HMHif (bMerk) ShowMarkHdl();
1631     }
1632 }
1633 
1634 #define SDRSEARCH_IMPISMASTER 0x80000000 /* MasterPage wird gerade durchsucht */
1635 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay) const
1636 {
1637     if(((nOptions & SDRSEARCH_IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible()))
1638     {
1639         return NULL;
1640     }
1641 
1642     const bool bCheckIfMarkable(nOptions & SDRSEARCH_TESTMARKABLE);
1643     const bool bDeep(nOptions & SDRSEARCH_DEEP);
1644     const bool bOLE(pObj->ISA(SdrOle2Obj));
1645     const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame());
1646     SdrObject* pRet=NULL;
1647     Rectangle aRect(pObj->GetCurrentBoundRect());
1648     sal_uInt16 nTol2(nTol);
1649 
1650     // double tolerance for OLE, text frames and objects in
1651     // active text edit
1652     if(bOLE || bTXT || pObj==((SdrObjEditView*)this)->GetTextEditObject())
1653     {
1654         nTol2*=2;
1655     }
1656 
1657     aRect.Left  ()-=nTol2; // Einmal Toleranz drauf fuer alle Objekte
1658     aRect.Top   ()-=nTol2;
1659     aRect.Right ()+=nTol2;
1660     aRect.Bottom()+=nTol2;
1661 
1662     if (aRect.IsInside(rPnt))
1663     {
1664         if ((!bCheckIfMarkable || IsObjMarkable(pObj,pPV)))
1665         {
1666             SdrObjList* pOL=pObj->GetSubList();
1667 
1668             if (pOL!=NULL && pOL->GetObjCount()!=0)
1669             {
1670                 SdrObject* pTmpObj;
1671                 // OD 30.06.2003 #108784# - adjustment hit point for virtual
1672                 // objects.
1673                 Point aPnt( rPnt );
1674 
1675                 if ( pObj->ISA(SdrVirtObj) )
1676                 {
1677                     Point aOffset = static_cast<SdrVirtObj*>(pObj)->GetOffset();
1678                     aPnt.Move( -aOffset.X(), -aOffset.Y() );
1679                 }
1680 
1681                 pRet=CheckSingleSdrObjectHit(aPnt,nTol,pOL,pPV,nOptions,pMVisLay,pTmpObj);
1682             }
1683             else
1684             {
1685                 if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer()))
1686                 {
1687                     pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false);
1688                 }
1689             }
1690         }
1691     }
1692 
1693     if (!bDeep && pRet!=NULL)
1694     {
1695         pRet=pObj;
1696     }
1697 
1698     return pRet;
1699 }
1700 
1701 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList* pOL, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj) const
1702 {
1703     sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD)!=0;
1704     SdrObject* pRet=NULL;
1705     rpRootObj=NULL;
1706     if (pOL!=NULL)
1707     {
1708         // #110988#
1709         sal_Bool bRemap(pOL->GetOwnerObj() && pOL->GetOwnerObj()->ISA(E3dScene));
1710         E3dScene* pRemapScene = (bRemap ? (E3dScene*)pOL->GetOwnerObj() : 0L);
1711 
1712         sal_uIntPtr nObjAnz=pOL->GetObjCount();
1713         sal_uIntPtr nObjNum=bBack ? 0 : nObjAnz;
1714         while (pRet==NULL && (bBack ? nObjNum<nObjAnz : nObjNum>0)) {
1715             if (!bBack) nObjNum--;
1716             SdrObject* pObj;
1717 
1718             // #110988#
1719             if(bRemap)
1720             {
1721                 pObj = pOL->GetObj(pRemapScene->RemapOrdNum(nObjNum));
1722             }
1723             else
1724             {
1725                 pObj = pOL->GetObj(nObjNum);
1726             }
1727 
1728             pRet=CheckSingleSdrObjectHit(rPnt,nTol,pObj,pPV,nOptions,pMVisLay);
1729             if (pRet!=NULL) rpRootObj=pObj;
1730             if (bBack) nObjNum++;
1731         }
1732     }
1733     return pRet;
1734 }
1735 
1736 sal_Bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions) const
1737 {
1738     return PickObj(rPnt,nTol,rpObj,rpPV,nOptions,NULL,NULL,NULL);
1739 }
1740 
1741 sal_Bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions, SdrObject** ppRootObj, sal_uIntPtr* pnMarkNum, sal_uInt16* pnPassNum) const
1742 { // Fehlt noch Pass2,Pass3
1743     SortMarkedObjects();
1744     if (ppRootObj!=NULL) *ppRootObj=NULL;
1745     if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1746     if (pnPassNum!=NULL) *pnPassNum=0;
1747     rpObj=NULL;
1748     rpPV=NULL;
1749     sal_Bool bWholePage=(nOptions & SDRSEARCH_WHOLEPAGE) !=0;
1750     sal_Bool bMarked=(nOptions & SDRSEARCH_MARKED) !=0;
1751     sal_Bool bMasters=!bMarked && (nOptions & SDRSEARCH_ALSOONMASTER) !=0;
1752     sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1753 #if OSL_DEBUG_LEVEL > 0
1754     sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0; (void)bNext; // n.i.
1755     sal_Bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; (void)bBoundCheckOn2ndPass;// n.i.
1756     sal_Bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; (void)bCheckNearestOn3rdPass;// n.i.
1757 #endif
1758     if (nTol<0) nTol=ImpGetHitTolLogic(nTol,NULL);
1759     Point aPt(rPnt);
1760     SdrObject* pObj=NULL;
1761     SdrObject* pHitObj=NULL;
1762     SdrPageView* pPV=NULL;
1763     if (!bBack && ((SdrObjEditView*)this)->IsTextEditFrameHit(rPnt)) {
1764         pObj=((SdrObjEditView*)this)->GetTextEditObject();
1765         pHitObj=pObj;
1766         pPV=((SdrObjEditView*)this)->GetTextEditPageView();
1767     }
1768     if (bMarked) {
1769         sal_uIntPtr nMrkAnz=GetMarkedObjectCount();
1770         sal_uIntPtr nMrkNum=bBack ? 0 : nMrkAnz;
1771         while (pHitObj==NULL && (bBack ? nMrkNum<nMrkAnz : nMrkNum>0)) {
1772             if (!bBack) nMrkNum--;
1773             SdrMark* pM=GetSdrMarkByIndex(nMrkNum);
1774             pObj=pM->GetMarkedSdrObj();
1775             pPV=pM->GetPageView();
1776             pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,nOptions,NULL);
1777             if (bBack) nMrkNum++;
1778         }
1779     }
1780     else
1781     {
1782         pPV = GetSdrPageView();
1783 
1784         if(pPV)
1785         {
1786             SdrPage* pPage=pPV->GetPage();
1787             sal_uInt16 nPgAnz=1;
1788 
1789             if(bMasters && pPage->TRG_HasMasterPage())
1790             {
1791                 nPgAnz++;
1792             }
1793 
1794             sal_Bool bExtraPassForWholePage=bWholePage && pPage!=pPV->GetObjList();
1795             if (bExtraPassForWholePage) nPgAnz++; // Suche erst in AktObjList, dann auf der gesamten Page
1796             sal_uInt16 nPgNum=bBack ? 0 : nPgAnz;
1797             while (pHitObj==NULL && (bBack ? nPgNum<nPgAnz : nPgNum>0)) {
1798                 sal_uIntPtr nTmpOptions=nOptions;
1799                 if (!bBack) nPgNum--;
1800                 const SetOfByte* pMVisLay=NULL;
1801                 SdrObjList* pObjList=NULL;
1802                 if (pnPassNum!=NULL) *pnPassNum&=~(SDRSEARCHPASS_MASTERPAGE|SDRSEARCHPASS_INACTIVELIST);
1803                 if (nPgNum>=nPgAnz-1 || (bExtraPassForWholePage && nPgNum>=nPgAnz-2))
1804                 {
1805                     pObjList=pPV->GetObjList();
1806                     if (bExtraPassForWholePage && nPgNum==nPgAnz-2) {
1807                         pObjList=pPage;
1808                         if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_INACTIVELIST;
1809                     }
1810                 }
1811                 else
1812                 {
1813                     // sonst MasterPage
1814                     SdrPage& rMasterPage = pPage->TRG_GetMasterPage();
1815                     pMVisLay = &pPage->TRG_GetMasterPageVisibleLayers();
1816                     pObjList = &rMasterPage;
1817 
1818                     if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_MASTERPAGE;
1819                     nTmpOptions=nTmpOptions | SDRSEARCH_IMPISMASTER;
1820                 }
1821                 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObjList,pPV,nTmpOptions,pMVisLay,pObj);
1822                 if (bBack) nPgNum++;
1823             }
1824         }
1825     }
1826     if (pHitObj!=NULL) {
1827         if (ppRootObj!=NULL) *ppRootObj=pObj;
1828         if ((nOptions & SDRSEARCH_DEEP) !=0) pObj=pHitObj;
1829         if ((nOptions & SDRSEARCH_TESTTEXTEDIT) !=0) {
1830             if (!pObj->HasTextEdit() || pPV->GetLockedLayers().IsSet(pObj->GetLayer())) {
1831                 pObj=NULL;
1832             }
1833         }
1834         if (pObj!=NULL && (nOptions & SDRSEARCH_TESTMACRO) !=0) {
1835             SdrObjMacroHitRec aHitRec;
1836             aHitRec.aPos=aPt;
1837             aHitRec.aDownPos=aPt;
1838             aHitRec.nTol=nTol;
1839             aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
1840             aHitRec.pPageView=pPV;
1841             if (!pObj->HasMacro() || !pObj->IsMacroHit(aHitRec)) pObj=NULL;
1842         }
1843         if (pObj!=NULL && (nOptions & SDRSEARCH_WITHTEXT) !=0 && pObj->GetOutlinerParaObject()==NULL) pObj=NULL;
1844         if (pObj!=NULL && (nOptions & SDRSEARCH_TESTTEXTAREA) !=0)
1845         {
1846             if(!SdrObjectPrimitiveHit(*pObj, aPt, 0, *pPV, 0, true))
1847             {
1848                 pObj = 0;
1849             }
1850         }
1851         if (pObj!=NULL) {
1852             rpObj=pObj;
1853             rpPV=pPV;
1854             if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_DIRECT;
1855         }
1856     }
1857     return rpObj!=NULL;
1858 }
1859 
1860 sal_Bool SdrMarkView::PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr* pnMarkNum, sal_uIntPtr nOptions) const
1861 {
1862     SortMarkedObjects();
1863     sal_Bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0;
1864     sal_Bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0;
1865     rpObj=NULL;
1866     rpPV=NULL;
1867     if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1868     Point aPt(rPnt);
1869     sal_uInt16 nTol=(sal_uInt16)nHitTolLog;
1870     sal_Bool bFnd=sal_False;
1871     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1872     sal_uIntPtr nMarkNum;
1873     for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1874         nMarkNum--;
1875         SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1876         SdrPageView* pPV=pM->GetPageView();
1877         SdrObject* pObj=pM->GetMarkedSdrObj();
1878         bFnd = 0 != CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,SDRSEARCH_TESTMARKABLE,0);
1879         if (bFnd) {
1880             rpObj=pObj;
1881             rpPV=pPV;
1882             if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1883         }
1884     }
1885     if ((bBoundCheckOn2ndPass || bCheckNearestOn3rdPass) && !bFnd) {
1886         SdrObject* pBestObj=NULL;
1887         SdrPageView* pBestPV=NULL;
1888         sal_uIntPtr nBestMarkNum=0;
1889         sal_uIntPtr nBestDist=ULONG_MAX;
1890         for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1891             nMarkNum--;
1892             SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1893             SdrPageView* pPV=pM->GetPageView();
1894             SdrObject* pObj=pM->GetMarkedSdrObj();
1895             Rectangle aRect(pObj->GetCurrentBoundRect());
1896             aRect.Left  ()-=nTol;
1897             aRect.Top   ()-=nTol;
1898             aRect.Right ()+=nTol;
1899             aRect.Bottom()+=nTol;
1900             if (aRect.IsInside(aPt)) {
1901                 bFnd=sal_True;
1902                 rpObj=pObj;
1903                 rpPV=pPV;
1904                 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1905             } else if (bCheckNearestOn3rdPass) {
1906                 sal_uIntPtr nDist=0;
1907                 if (aPt.X()<aRect.Left())   nDist+=aRect.Left()-aPt.X();
1908                 if (aPt.X()>aRect.Right())  nDist+=aPt.X()-aRect.Right();
1909                 if (aPt.Y()<aRect.Top())    nDist+=aRect.Top()-aPt.Y();
1910                 if (aPt.Y()>aRect.Bottom()) nDist+=aPt.Y()-aRect.Bottom();
1911                 if (nDist<nBestDist) {
1912                     pBestObj=pObj;
1913                     pBestPV=pPV;
1914                     nBestMarkNum=nMarkNum;
1915                 }
1916             }
1917         }
1918         if (bCheckNearestOn3rdPass && !bFnd) {
1919             rpObj=pBestObj;
1920             rpPV=pBestPV;
1921             if (pnMarkNum!=NULL) *pnMarkNum=nBestMarkNum;
1922             bFnd=pBestObj!=NULL;
1923         }
1924     }
1925     return bFnd;
1926 }
1927 
1928 SdrHitKind SdrMarkView::PickSomething(const Point& rPnt, short nTol) const
1929 {
1930     nTol=ImpGetHitTolLogic(nTol,NULL);
1931     SdrHitKind eRet=SDRHIT_NONE;
1932     Point aPt(rPnt);
1933     SdrObject* pObj=NULL;
1934     SdrPageView* pPV=NULL;
1935     if (eRet==SDRHIT_NONE && PickObj(rPnt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_PICKMARKABLE)) {
1936         Rectangle aRct1(aPt-Point(nTol,nTol),aPt+Point(nTol,nTol)); // HitRect fuer Toleranz
1937         Rectangle aBR(pObj->GetCurrentBoundRect());
1938         if      (aRct1.IsInside(aBR.TopLeft()))      eRet=SDRHIT_BOUNDTL;
1939         else if (aRct1.IsInside(aBR.TopCenter()))    eRet=SDRHIT_BOUNDTC;
1940         else if (aRct1.IsInside(aBR.TopRight()))     eRet=SDRHIT_BOUNDTR;
1941         else if (aRct1.IsInside(aBR.LeftCenter()))   eRet=SDRHIT_BOUNDCL;
1942         else if (aRct1.IsInside(aBR.RightCenter()))  eRet=SDRHIT_BOUNDCR;
1943         else if (aRct1.IsInside(aBR.BottomLeft()))   eRet=SDRHIT_BOUNDBL;
1944         else if (aRct1.IsInside(aBR.BottomCenter())) eRet=SDRHIT_BOUNDBC;
1945         else if (aRct1.IsInside(aBR.BottomRight()))  eRet=SDRHIT_BOUNDBR;
1946         else eRet=SDRHIT_OBJECT;
1947     }
1948     return eRet;
1949 }
1950 
1951 void SdrMarkView::UnmarkAllObj(SdrPageView* pPV)
1952 {
1953     if (GetMarkedObjectCount()!=0) {
1954         BrkAction();
1955         //HMHBOOL bVis=bHdlShown;
1956         //HMHif (bVis) HideMarkHdl();
1957         if (pPV!=NULL)
1958         {
1959             GetMarkedObjectListWriteAccess().DeletePageView(*pPV);
1960         }
1961         else
1962         {
1963             GetMarkedObjectListWriteAccess().Clear();
1964         }
1965         pMarkedObj=NULL;
1966         pMarkedPV=NULL;
1967         MarkListHasChanged();
1968         AdjustMarkHdl(); //HMHTRUE);
1969         //HMHif (bVis) ShowMarkHdl(); // ggf. fuer die RefPoints
1970     }
1971 }
1972 
1973 void SdrMarkView::MarkAllObj(SdrPageView* _pPV)
1974 {
1975     BrkAction();
1976     //HMHHideMarkHdl();
1977 
1978     if(!_pPV)
1979     {
1980         _pPV = GetSdrPageView();
1981     }
1982 
1983     // #i69171# _pPV may still be NULL if there is no SDrPageView (!), e.g. when inserting
1984     // other files
1985     if(_pPV)
1986     {
1987         const bool bMarkChg(GetMarkedObjectListWriteAccess().InsertPageView(*_pPV));
1988 
1989         if(bMarkChg)
1990         {
1991             MarkListHasChanged();
1992         }
1993     }
1994 
1995     if(GetMarkedObjectCount())
1996     {
1997         AdjustMarkHdl(); //HMHTRUE);
1998         //HMHShowMarkHdl();
1999     }
2000 }
2001 
2002 void SdrMarkView::AdjustMarkHdl() //HMHBOOL bRestraintPaint)
2003 {
2004     //HMHBOOL bVis=bHdlShown;
2005     //HMHif (bVis) HideMarkHdl();
2006     CheckMarked();
2007     SetMarkRects();
2008     SetMarkHandles();
2009     //HMHif(bRestraintPaint && bVis)
2010     //HMH{
2011     //HMH   ShowMarkHdl();
2012     //HMH}
2013 }
2014 
2015 Rectangle SdrMarkView::GetMarkedObjBoundRect() const
2016 {
2017     Rectangle aRect;
2018     for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
2019         SdrMark* pM=GetSdrMarkByIndex(nm);
2020         SdrObject* pO=pM->GetMarkedSdrObj();
2021         Rectangle aR1(pO->GetCurrentBoundRect());
2022         if (aRect.IsEmpty()) aRect=aR1;
2023         else aRect.Union(aR1);
2024     }
2025     return aRect;
2026 }
2027 
2028 const Rectangle& SdrMarkView::GetMarkedObjRect() const
2029 {
2030     if (bMarkedObjRectDirty) {
2031         ((SdrMarkView*)this)->bMarkedObjRectDirty=sal_False;
2032         Rectangle aRect;
2033         for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
2034             SdrMark* pM=GetSdrMarkByIndex(nm);
2035             SdrObject* pO=pM->GetMarkedSdrObj();
2036             Rectangle aR1(pO->GetSnapRect());
2037             if (aRect.IsEmpty()) aRect=aR1;
2038             else aRect.Union(aR1);
2039         }
2040         ((SdrMarkView*)this)->aMarkedObjRect=aRect;
2041     }
2042     return aMarkedObjRect;
2043 }
2044 
2045 ////////////////////////////////////////////////////////////////////////////////////////////////////
2046 
2047 void SdrMarkView::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal, sal_uInt16 nOpt) const
2048 {
2049     rStr = ImpGetResStr(nStrCacheID);
2050     xub_StrLen nPos = rStr.SearchAscii("%1");
2051 
2052     if(nPos != STRING_NOTFOUND)
2053     {
2054         rStr.Erase(nPos, 2);
2055 
2056         if(nOpt == IMPSDR_POINTSDESCRIPTION)
2057         {
2058             rStr.Insert(GetDescriptionOfMarkedPoints(), nPos);
2059         }
2060         else if(nOpt == IMPSDR_GLUEPOINTSDESCRIPTION)
2061         {
2062             rStr.Insert(GetDescriptionOfMarkedGluePoints(), nPos);
2063         }
2064         else
2065         {
2066             rStr.Insert(GetDescriptionOfMarkedObjects(), nPos);
2067         }
2068     }
2069 
2070     nPos = rStr.SearchAscii("%2");
2071 
2072     if(nPos != STRING_NOTFOUND)
2073     {
2074         rStr.Erase(nPos, 2);
2075         rStr.Insert(UniString::CreateFromInt32(nVal), nPos);
2076     }
2077 }
2078 
2079 ////////////////////////////////////////////////////////////////////////////////////////////////////
2080 
2081 sal_Bool SdrMarkView::EnterMarkedGroup()
2082 {
2083     sal_Bool bRet=sal_False;
2084     // Es wird nur die erste gefundene Gruppe (also nur in einer PageView) geentert
2085     // Weil PageView::EnterGroup ein AdjustMarkHdl ruft.
2086     // Das muss ich per Flag mal unterbinden  vvvvvvvv
2087     SdrPageView* pPV = GetSdrPageView();
2088 
2089     if(pPV)
2090     {
2091         sal_Bool bEnter=sal_False;
2092         for (sal_uInt32 nm(GetMarkedObjectCount()); nm > 0 && !bEnter;)
2093         {
2094             nm--;
2095             SdrMark* pM=GetSdrMarkByIndex(nm);
2096             if (pM->GetPageView()==pPV) {
2097                 SdrObject* pObj=pM->GetMarkedSdrObj();
2098                 if (pObj->IsGroupObject()) {
2099                     if (pPV->EnterGroup(pObj)) {
2100                         bRet=sal_True;
2101                         bEnter=sal_True;
2102                     }
2103                 }
2104             }
2105         }
2106     }
2107     return bRet;
2108 }
2109 
2110 ////////////////////////////////////////////////////////////////////////////////////////////////////
2111 
2112 void SdrMarkView::MarkListHasChanged()
2113 {
2114     GetMarkedObjectListWriteAccess().SetNameDirty();
2115     SetEdgesOfMarkedNodesDirty(); // bEdgesOfMarkedNodesDirty=sal_True;
2116 
2117     bMarkedObjRectDirty=sal_True;
2118     bMarkedPointsRectsDirty=sal_True;
2119 #ifdef DBG_UTIL
2120     if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
2121 #endif
2122     sal_Bool bOneEdgeMarked=sal_False;
2123     if (GetMarkedObjectCount()==1) {
2124         const SdrObject* pObj=GetMarkedObjectByIndex(0);
2125         if (pObj->GetObjInventor()==SdrInventor) {
2126             sal_uInt16 nIdent=pObj->GetObjIdentifier();
2127             bOneEdgeMarked=nIdent==OBJ_EDGE;
2128         }
2129     }
2130     ImpSetGlueVisible4(bOneEdgeMarked);
2131 }
2132 
2133 ////////////////////////////////////////////////////////////////////////////////////////////////////
2134 
2135 void SdrMarkView::SetMoveOutside(sal_Bool bOn)
2136 {
2137     aHdl.SetMoveOutside(bOn);
2138 }
2139 
2140 sal_Bool SdrMarkView::IsMoveOutside() const
2141 {
2142     return aHdl.IsMoveOutside();
2143 }
2144 
2145 void SdrMarkView::SetDesignMode( sal_Bool _bOn )
2146 {
2147     if ( bDesignMode != _bOn )
2148     {
2149         bDesignMode = _bOn;
2150         SdrPageView* pPageView = GetSdrPageView();
2151         if ( pPageView )
2152             pPageView->SetDesignMode( _bOn );
2153     }
2154 }
2155 
2156 // MarkHandles Objektaenderung:
2157 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2158 // - Bei Notify mit HINT_OBJCHG (oder so) werden die Handles erstmal versteckt
2159 //   (wenn nicht schon wegen Dragging versteckt).
2160 // - XorHdl: Bei ModelHasChanged() werden sie dann wieder angezeigt.
2161 // - PaintEvents kommen nun durch.
2162 //   - Die XorHandles werden z.T. wieder uebermalt.
2163 //   - Xor:  Nach dem Painten werden die Handles im (vom PaintHandler gerufenen)
2164 //           CompleteRedraw per ToggleShownXor bei gesetzter ClipRegion nochmal gemalt
2165 //           und damit ist alles in Butter.
2166 //   - ToggleShownXor macht bei SolidHdl nix weil bHdlShown=FALSE
2167 //   - Der AfterPaintTimer wird gestartet.
2168 // - SolidHdl: Im AfterPaintHandler wird ShowMarkHdl gerufen.
2169 //   Da die Handles zu diesem Zeitpunkt nicht angezeigt sind wird:
2170 //   - SaveBackground durchgefuehrt.
2171 //   - DrawMarkHdl gerufen und bHdlShown gesetzt.
2172 //
2173 // MarkHandles bei sonstigem Invalidate:
2174 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2175 // In diesem Fall bekomme ich kein Notify und beim Aufruf des
2176 // PaintHandlers->CompleteRedraw() sind auch die SolidHandles sichtbar.
2177 
2178