xref: /trunk/main/svx/source/svdraw/svdmrkv.cxx (revision a5b190bfa3e1bed4623e2958a8877664a3b5506c)
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             // #i118524# if inplace activated OLE is selected,
735             // suppress handles
736             bool bHideHandlesWhenOleActive(false);
737             const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pMarkedObj);
738 
739             if(pSdrOle2Obj && (pSdrOle2Obj->isInplaceActive() || pSdrOle2Obj->isUiActive()))
740             {
741                 bHideHandlesWhenOleActive = true;
742             }
743 
744             if(!aRect.IsEmpty() && !bHideHandlesWhenInTextEdit && !bHideHandlesWhenOleActive)
745             { // sonst nix gefunden
746                 if( bSingleTextObjMark )
747                 {
748                     const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
749                     pMarkedObj->AddToHdlList(aHdl);
750                     const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
751                     for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
752                     {
753                         SdrHdl* pHdl=aHdl.GetHdl(i);
754                         pHdl->SetObj(pMarkedObj);
755                         pHdl->SetPageView(pMarkedPV);
756                         pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
757                     }
758                 }
759                 else if( eDragMode==SDRDRAG_CROP )
760                 {
761                     aHdl.AddHdl(new SdrCropHdl(aRect.TopLeft()     ,HDL_UPLFT));
762                     aHdl.AddHdl(new SdrCropHdl(aRect.TopCenter()   ,HDL_UPPER));
763                     aHdl.AddHdl(new SdrCropHdl(aRect.TopRight()    ,HDL_UPRGT));
764                     aHdl.AddHdl(new SdrCropHdl(aRect.LeftCenter()  ,HDL_LEFT ));
765                     aHdl.AddHdl(new SdrCropHdl(aRect.RightCenter() ,HDL_RIGHT));
766                     aHdl.AddHdl(new SdrCropHdl(aRect.BottomLeft()  ,HDL_LWLFT));
767                     aHdl.AddHdl(new SdrCropHdl(aRect.BottomCenter(),HDL_LOWER));
768                     aHdl.AddHdl(new SdrCropHdl(aRect.BottomRight() ,HDL_LWRGT));
769                 }
770                 else
771                 {
772                     sal_Bool bWdt0=aRect.Left()==aRect.Right();
773                     sal_Bool bHgt0=aRect.Top()==aRect.Bottom();
774                     if (bWdt0 && bHgt0)
775                     {
776                         aHdl.AddHdl(new SdrHdl(aRect.TopLeft(),HDL_UPLFT));
777                     }
778                     else if (!bStdDrag && (bWdt0 || bHgt0))
779                     {
780                         aHdl.AddHdl(new SdrHdl(aRect.TopLeft()    ,HDL_UPLFT));
781                         aHdl.AddHdl(new SdrHdl(aRect.BottomRight(),HDL_LWRGT));
782                     }
783                     else
784                     {
785                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopLeft()     ,HDL_UPLFT));
786                         if (          !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopCenter()   ,HDL_UPPER));
787                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopRight()    ,HDL_UPRGT));
788                         if (!bWdt0          ) aHdl.AddHdl(new SdrHdl(aRect.LeftCenter()  ,HDL_LEFT ));
789                         if (!bWdt0          ) aHdl.AddHdl(new SdrHdl(aRect.RightCenter() ,HDL_RIGHT));
790                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomLeft()  ,HDL_LWLFT));
791                         if (          !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomCenter(),HDL_LOWER));
792                         if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomRight() ,HDL_LWRGT));
793                     }
794                 }
795             }
796         }
797         else
798         {
799             for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
800             {
801                 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
802                 SdrObject* pObj=pM->GetMarkedSdrObj();
803                 SdrPageView* pPV=pM->GetPageView();
804                 const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
805                 pObj->AddToHdlList(aHdl);
806                 const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
807                 bool bPoly=pObj->IsPolyObj();
808                 const SdrUShortCont* pMrkPnts=pM->GetMarkedPoints();
809                 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
810                 {
811                     SdrHdl* pHdl=aHdl.GetHdl(i);
812                     pHdl->SetObj(pObj);
813                     pHdl->SetPageView(pPV);
814                     pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
815                     if (bPoly)
816                     {
817                         sal_Bool bSelected=pMrkPnts!=NULL && pMrkPnts->Exist(sal_uInt16(i-nSiz0));
818                         pHdl->SetSelected(bSelected);
819                         //sal_Bool bPlus=bPlusHdlAlways;
820                         if (bPlusHdlAlways || bSelected)
821                         {
822                             sal_uInt32 nPlusAnz=pObj->GetPlusHdlCount(*pHdl);
823                             for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
824                             {
825                                 SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,nPlusNum);
826                                 if (pPlusHdl!=NULL)
827                                 {
828                                     pPlusHdl->SetObj(pObj);
829                                     pPlusHdl->SetPageView(pPV);
830                                     pPlusHdl->SetPlusHdl(sal_True);
831                                     aHdl.AddHdl(pPlusHdl);
832                                 }
833                             }
834                         }
835                     }
836                 }
837             } // for nMarkNum
838         } // if bFrmHdl else
839 
840         // GluePoint-Handles
841         for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
842         {
843             const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
844             SdrObject* pObj=pM->GetMarkedSdrObj();
845             SdrPageView* pPV=pM->GetPageView();
846             const SdrUShortCont* pMrkGlue=pM->GetMarkedGluePoints();
847             if (pMrkGlue!=NULL)
848             {
849                 const SdrGluePointList* pGPL=pObj->GetGluePointList();
850                 if (pGPL!=NULL)
851                 {
852                     //sal_uInt16 nGlueAnz=pGPL->GetCount();
853                     sal_uInt16 nAnz=(sal_uInt16)pMrkGlue->GetCount();
854                     for (sal_uInt16 nNum=0; nNum<nAnz; nNum++)
855                     {
856                         sal_uInt16 nId=pMrkGlue->GetObject(nNum);
857                         //nNum changed to nNumGP because already used in for loop
858                         sal_uInt16 nNumGP=pGPL->FindGluePoint(nId);
859                         if (nNumGP!=SDRGLUEPOINT_NOTFOUND)
860                         {
861                             const SdrGluePoint& rGP=(*pGPL)[nNumGP];
862                             Point aPos(rGP.GetAbsolutePos(*pObj));
863                             SdrHdl* pGlueHdl=new SdrHdl(aPos,HDL_GLUE);
864                             pGlueHdl->SetObj(pObj);
865                             pGlueHdl->SetPageView(pPV);
866                             pGlueHdl->SetObjHdlNum(nId);
867                             aHdl.AddHdl(pGlueHdl);
868                         }
869                     }
870                 }
871             }
872         }
873 
874         // Drehpunkt/Spiegelachse
875         AddDragModeHdl(eDragMode);
876 
877         // add custom handles (used by other apps, e.g. AnchorPos)
878         AddCustomHdl();
879 
880         // sort handles
881         aHdl.Sort();
882 
883         // #105722# try to restore focus handle index from remembered values
884         if(bSaveOldFocus)
885         {
886             for(sal_uInt32 a(0); a < aHdl.GetHdlCount(); a++)
887             {
888                 SdrHdl* pCandidate = aHdl.GetHdl(a);
889 
890                 if(pCandidate->GetObj()
891                     && pCandidate->GetObj() == pSaveObj
892                     && pCandidate->GetKind() == eSaveKind
893                     && pCandidate->GetPolyNum() == nSavePolyNum
894                     && pCandidate->GetPointNum() == nSavePointNum)
895                 {
896                     aHdl.SetFocusHdl(pCandidate);
897                     break;
898                 }
899             }
900         }
901     }
902 }
903 
904 void SdrMarkView::AddCustomHdl()
905 {
906     // add custom handles (used by other apps, e.g. AnchorPos)
907 }
908 
909 void SdrMarkView::SetDragMode(SdrDragMode eMode)
910 {
911     SdrDragMode eMode0=eDragMode;
912     eDragMode=eMode;
913     if (eDragMode==SDRDRAG_RESIZE) eDragMode=SDRDRAG_MOVE;
914     if (eDragMode!=eMode0) {
915         //HMHBOOL bVis=IsMarkHdlShown();
916         //HMHif (bVis) HideMarkHdl();
917         ForceRefToMarked();
918         SetMarkHandles();
919         //HMHif (bVis) ShowMarkHdl();
920         {
921             if (AreObjectsMarked()) MarkListHasChanged();
922         }
923     }
924 }
925 
926 void SdrMarkView::AddDragModeHdl(SdrDragMode eMode)
927 {
928     switch(eMode)
929     {
930         case SDRDRAG_ROTATE:
931         {
932             // add rotation center
933             SdrHdl* pHdl = new SdrHdl(aRef1, HDL_REF1);
934 
935             aHdl.AddHdl(pHdl);
936 
937             break;
938         }
939         case SDRDRAG_MIRROR:
940         {
941             // add mirror axis
942             SdrHdl* pHdl3 = new SdrHdl(aRef2, HDL_REF2);
943             SdrHdl* pHdl2 = new SdrHdl(aRef1, HDL_REF1);
944             SdrHdl* pHdl1 = new SdrHdlLine(*pHdl2, *pHdl3, HDL_MIRX);
945 
946             pHdl1->SetObjHdlNum(1); // fuer Sortierung
947             pHdl2->SetObjHdlNum(2); // fuer Sortierung
948             pHdl3->SetObjHdlNum(3); // fuer Sortierung
949 
950             aHdl.AddHdl(pHdl1); // Linie als erstes, damit als letztes im HitTest
951             aHdl.AddHdl(pHdl2);
952             aHdl.AddHdl(pHdl3);
953 
954             break;
955         }
956         case SDRDRAG_TRANSPARENCE:
957         {
958             // add interactive transparence handle
959             sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
960             if(nMarkAnz == 1)
961             {
962                 SdrObject* pObj = GetMarkedObjectByIndex(0);
963                 SdrModel* pModel = GetModel();
964                 const SfxItemSet& rSet = pObj->GetMergedItemSet();
965 
966                 if(SFX_ITEM_SET != rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, sal_False))
967                 {
968                     // add this item, it's not yet there
969                     XFillFloatTransparenceItem aNewItem(
970                         (const XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE));
971                     XGradient aGrad = aNewItem.GetGradientValue();
972 
973                     aNewItem.SetEnabled(sal_True);
974                     aGrad.SetStartIntens(100);
975                     aGrad.SetEndIntens(100);
976                     aNewItem.SetGradientValue(aGrad);
977 
978                     // add undo to allow user to take back this step
979                     if( pModel->IsUndoEnabled() )
980                     {
981                         pModel->BegUndo(SVX_RESSTR(SIP_XA_FILLTRANSPARENCE));
982                         pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
983                         pModel->EndUndo();
984                     }
985 
986                     //pObj->SetItemAndBroadcast(aNewItem);
987                     SfxItemSet aNewSet(pModel->GetItemPool());
988                     aNewSet.Put(aNewItem);
989                     pObj->SetMergedItemSetAndBroadcast(aNewSet);
990                 }
991 
992                 // set values and transform to vector set
993                 GradTransformer aGradTransformer;
994                 GradTransVector aGradTransVector;
995                 GradTransGradient aGradTransGradient;
996 
997                 aGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
998                 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
999 
1000                 // build handles
1001                 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
1002                 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
1003                 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True);
1004                 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True);
1005                 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_False);
1006                 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!");
1007 
1008                 // link them
1009                 pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
1010                 pGradHdl->SetObj(pObj);
1011                 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1012                 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1013 
1014                 // insert them
1015                 aHdl.AddHdl(pColHdl1);
1016                 aHdl.AddHdl(pColHdl2);
1017                 aHdl.AddHdl(pGradHdl);
1018             }
1019             break;
1020         }
1021         case SDRDRAG_GRADIENT:
1022         {
1023             // add interactive gradient handle
1024             sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
1025             if(nMarkAnz == 1)
1026             {
1027                 SdrObject* pObj = GetMarkedObjectByIndex(0);
1028                 const SfxItemSet& rSet = pObj->GetMergedItemSet();
1029                 XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
1030 
1031                 if(eFillStyle == XFILL_GRADIENT)
1032                 {
1033                     // set values and transform to vector set
1034                     GradTransformer aGradTransformer;
1035                     GradTransVector aGradTransVector;
1036                     GradTransGradient aGradTransGradient;
1037                     Size aHdlSize(15, 15);
1038 
1039                     aGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
1040                     aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
1041 
1042                     // build handles
1043                     const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
1044                     const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
1045                     SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, sal_False);
1046                     SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, sal_False);
1047                     SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_True);
1048                     DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!");
1049 
1050                     // link them
1051                     pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
1052                     pGradHdl->SetObj(pObj);
1053                     pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1054                     pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1055 
1056                     // insert them
1057                     aHdl.AddHdl(pColHdl1);
1058                     aHdl.AddHdl(pColHdl2);
1059                     aHdl.AddHdl(pGradHdl);
1060                 }
1061             }
1062             break;
1063         }
1064         case SDRDRAG_CROP:
1065         {
1066             // todo
1067             break;
1068         }
1069         default: break;
1070     }
1071 }
1072 
1073 /** handle mouse over effects for handles */
1074 sal_Bool SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
1075 {
1076     if(aHdl.GetHdlCount())
1077     {
1078         SdrHdl* pMouseOverHdl = 0;
1079         if( !rMEvt.IsLeaveWindow() && pWin )
1080         {
1081             Point aMDPos( pWin->PixelToLogic( rMEvt.GetPosPixel() ) );
1082             pMouseOverHdl = PickHandle(aMDPos);
1083         }
1084 
1085         // notify last mouse over handle that he lost the mouse
1086         const sal_uIntPtr nHdlCount = aHdl.GetHdlCount();
1087 
1088         for(sal_uIntPtr nHdl = 0; nHdl < nHdlCount; nHdl++ )
1089         {
1090             SdrHdl* pCurrentHdl = GetHdl(nHdl);
1091             if( pCurrentHdl->mbMouseOver )
1092             {
1093                 if( pCurrentHdl != pMouseOverHdl )
1094                 {
1095                     pCurrentHdl->mbMouseOver = false;
1096                     pCurrentHdl->onMouseLeave();
1097                 }
1098                 break;
1099             }
1100         }
1101 
1102         // notify current mouse over handle
1103         if( pMouseOverHdl /* && !pMouseOverHdl->mbMouseOver */ )
1104         {
1105             pMouseOverHdl->mbMouseOver = true;
1106             pMouseOverHdl->onMouseEnter(rMEvt);
1107         }
1108     }
1109     return SdrSnapView::MouseMove(rMEvt, pWin);
1110 }
1111 
1112 void SdrMarkView::ForceRefToMarked()
1113 {
1114     switch(eDragMode)
1115     {
1116         case SDRDRAG_ROTATE:
1117         {
1118             Rectangle aR(GetMarkedObjRect());
1119             aRef1 = aR.Center();
1120 
1121             break;
1122         }
1123 
1124         case SDRDRAG_MIRROR:
1125         {
1126             // Erstmal die laenge der Spiegelachsenlinie berechnen
1127             long nOutMin=0;
1128             long nOutMax=0;
1129             long nMinLen=0;
1130             long nObjDst=0;
1131             long nOutHgt=0;
1132             OutputDevice* pOut=GetFirstOutputDevice();
1133             //OutputDevice* pOut=GetWin(0);
1134             if (pOut!=NULL) {
1135                 // Mindestlaenge 50 Pixel
1136                 nMinLen=pOut->PixelToLogic(Size(0,50)).Height();
1137                 // 20 Pixel fuer RefPt-Abstand vom Obj
1138                 nObjDst=pOut->PixelToLogic(Size(0,20)).Height();
1139                 // MinY/MaxY
1140                 // Abstand zum Rand = Mindestlaenge = 10 Pixel
1141                 long nDst=pOut->PixelToLogic(Size(0,10)).Height();
1142                 nOutMin=-pOut->GetMapMode().GetOrigin().Y();
1143                 nOutMax=pOut->GetOutputSize().Height()-1+nOutMin;
1144                 nOutMin+=nDst;
1145                 nOutMax-=nDst;
1146                 // Absolute Mindestlaenge jedoch 10 Pixel
1147                 if (nOutMax-nOutMin<nDst) {
1148                     nOutMin+=nOutMax+1;
1149                     nOutMin/=2;
1150                     nOutMin-=(nDst+1)/2;
1151                     nOutMax=nOutMin+nDst;
1152                 }
1153                 nOutHgt=nOutMax-nOutMin;
1154                 // Sonst Mindestlaenge = 1/4 OutHgt
1155                 long nTemp=nOutHgt/4;
1156                 if (nTemp>nMinLen) nMinLen=nTemp;
1157             }
1158 
1159             Rectangle aR(GetMarkedObjBoundRect());
1160             Point aCenter(aR.Center());
1161             long nMarkHgt=aR.GetHeight()-1;
1162             long nHgt=nMarkHgt+nObjDst*2;       // 20 Pixel obej und unten ueberstehend
1163             if (nHgt<nMinLen) nHgt=nMinLen;     // Mindestlaenge 50 Pixel bzw. 1/4 OutHgt
1164 
1165             long nY1=aCenter.Y()-(nHgt+1)/2;
1166             long nY2=nY1+nHgt;
1167 
1168             if (pOut!=NULL && nMinLen>nOutHgt) nMinLen=nOutHgt; // evtl. noch etwas verkuerzen
1169 
1170             if (pOut!=NULL) { // nun vollstaendig in den sichtbaren Bereich schieben
1171                 if (nY1<nOutMin) {
1172                     nY1=nOutMin;
1173                     if (nY2<nY1+nMinLen) nY2=nY1+nMinLen;
1174                 }
1175                 if (nY2>nOutMax) {
1176                     nY2=nOutMax;
1177                     if (nY1>nY2-nMinLen) nY1=nY2-nMinLen;
1178                 }
1179             }
1180 
1181             aRef1.X()=aCenter.X();
1182             aRef1.Y()=nY1;
1183             aRef2.X()=aCenter.X();
1184             aRef2.Y()=nY2;
1185 
1186             break;
1187         }
1188 
1189         case SDRDRAG_TRANSPARENCE:
1190         case SDRDRAG_GRADIENT:
1191         case SDRDRAG_CROP:
1192         {
1193             Rectangle aRect(GetMarkedObjBoundRect());
1194             aRef1 = aRect.TopLeft();
1195             aRef2 = aRect.BottomRight();
1196             break;
1197         }
1198         default: break;
1199     }
1200 }
1201 
1202 void SdrMarkView::SetRef1(const Point& rPt)
1203 {
1204     if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
1205     {
1206         aRef1 = rPt;
1207         SdrHdl* pH = aHdl.GetHdl(HDL_REF1);
1208         if(pH)
1209             pH->SetPos(rPt);
1210         //HMHShowMarkHdl();
1211     }
1212 }
1213 
1214 void SdrMarkView::SetRef2(const Point& rPt)
1215 {
1216     if(eDragMode == SDRDRAG_MIRROR)
1217     {
1218         aRef2 = rPt;
1219         SdrHdl* pH = aHdl.GetHdl(HDL_REF2);
1220         if(pH)
1221             pH->SetPos(rPt);
1222         //HMHShowMarkHdl();
1223     }
1224 }
1225 
1226 void SdrMarkView::CheckMarked()
1227 {
1228     for (sal_uIntPtr nm=GetMarkedObjectCount(); nm>0;) {
1229         nm--;
1230         SdrMark* pM=GetSdrMarkByIndex(nm);
1231         SdrObject* pObj=pM->GetMarkedSdrObj();
1232         SdrPageView* pPV=pM->GetPageView();
1233         SdrLayerID nLay=pObj->GetLayer();
1234         sal_Bool bRaus=!pObj->IsInserted(); // Obj geloescht?
1235         if (!pObj->Is3DObj()) {
1236             bRaus=bRaus || pObj->GetPage()!=pPV->GetPage();   // Obj ploetzlich in anderer Page oder Group
1237         }
1238         bRaus=bRaus || pPV->GetLockedLayers().IsSet(nLay) ||  // Layer gesperrt?
1239                        !pPV->GetVisibleLayers().IsSet(nLay);  // Layer nicht sichtbar?
1240 
1241         if( !bRaus )
1242             bRaus = !pObj->IsVisible(); // not visible objects can not be marked
1243 
1244         if (!bRaus) {
1245             // Joe am 9.3.1997: Gruppierte Objekten koennen nun auch
1246             // markiert werden. Nach EnterGroup muessen aber die Objekte
1247             // der hoeheren Ebene deselektiert werden.
1248             const SdrObjList* pOOL=pObj->GetObjList();
1249             const SdrObjList* pVOL=pPV->GetObjList();
1250             while (pOOL!=NULL && pOOL!=pVOL) {
1251                 pOOL=pOOL->GetUpList();
1252             }
1253             bRaus=pOOL!=pVOL;
1254         }
1255 
1256         if (bRaus)
1257         {
1258             GetMarkedObjectListWriteAccess().DeleteMark(nm);
1259         }
1260         else
1261         {
1262             if (!IsGluePointEditMode()) { // Markierte GluePoints nur im GlueEditMode
1263                 SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1264                 if (pPts!=NULL && pPts->GetCount()!=0) {
1265                     pPts->Clear();
1266                 }
1267             }
1268         }
1269     }
1270 
1271     // #97995# at least reset the remembered BoundRect to prevent handle
1272     // generation if bForceFrameHandles is TRUE.
1273     bMarkedObjRectDirty = sal_True;
1274 }
1275 
1276 void SdrMarkView::SetMarkRects()
1277 {
1278     SdrPageView* pPV = GetSdrPageView();
1279 
1280     if(pPV)
1281     {
1282         pPV->SetHasMarkedObj(GetSnapRectFromMarkedObjects(pPV, pPV->MarkSnap()));
1283         GetBoundRectFromMarkedObjects(pPV, pPV->MarkBound());
1284     }
1285 }
1286 
1287 void SdrMarkView::SetFrameHandles(sal_Bool bOn)
1288 {
1289     if (bOn!=bForceFrameHandles) {
1290         sal_Bool bOld=ImpIsFrameHandles();
1291         bForceFrameHandles=bOn;
1292         sal_Bool bNew=ImpIsFrameHandles();
1293         if (bNew!=bOld) {
1294             AdjustMarkHdl(); //HMHTRUE);
1295             MarkListHasChanged();
1296         }
1297     }
1298 }
1299 
1300 void SdrMarkView::SetEditMode(SdrViewEditMode eMode)
1301 {
1302     if (eMode!=eEditMode) {
1303         sal_Bool bGlue0=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1304         sal_Bool bEdge0=((SdrCreateView*)this)->IsEdgeTool();
1305         eEditMode0=eEditMode;
1306         eEditMode=eMode;
1307         sal_Bool bGlue1=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1308         sal_Bool bEdge1=((SdrCreateView*)this)->IsEdgeTool();
1309         // etwas Aufwand um Flackern zu verhindern beim Umschalten
1310         // zwischen GlueEdit und EdgeTool
1311         if (bGlue1 && !bGlue0) ImpSetGlueVisible2(bGlue1);
1312         if (bEdge1!=bEdge0) ImpSetGlueVisible3(bEdge1);
1313         if (!bGlue1 && bGlue0) ImpSetGlueVisible2(bGlue1);
1314         if (bGlue0 && !bGlue1) UnmarkAllGluePoints();
1315     }
1316 }
1317 
1318 ////////////////////////////////////////////////////////////////////////////////////////////////////
1319 
1320 sal_Bool SdrMarkView::IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const
1321 {
1322     if (pObj)
1323     {
1324         if (pObj->IsMarkProtect() ||
1325             (!bDesignMode && pObj->IsUnoObj()))
1326         {
1327             // Objekt nicht selektierbar oder
1328             // SdrUnoObj nicht im DesignMode
1329             return sal_False;
1330         }
1331     }
1332     return pPV!=NULL ? pPV->IsObjMarkable(pObj) : sal_True;
1333 }
1334 
1335 sal_Bool SdrMarkView::IsMarkedObjHit(const Point& rPnt, short nTol) const
1336 {
1337     sal_Bool bRet=sal_False;
1338     nTol=ImpGetHitTolLogic(nTol,NULL);
1339     Point aPt(rPnt);
1340     for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount() && !bRet; nm++) {
1341         SdrMark* pM=GetSdrMarkByIndex(nm);
1342         bRet = 0 != CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0);
1343     }
1344     return bRet;
1345 }
1346 
1347 SdrHdl* SdrMarkView::PickHandle(const Point& rPnt, sal_uIntPtr nOptions, SdrHdl* pHdl0) const
1348 {
1349     if (bSomeObjChgdFlag) { // ggf. Handles neu berechnen lassen!
1350         FlushComeBackTimer();
1351     }
1352     sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1353     sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0;
1354     Point aPt(rPnt);
1355     return aHdl.IsHdlListHit(aPt,bBack,bNext,pHdl0);
1356 }
1357 
1358 sal_Bool SdrMarkView::MarkObj(const Point& rPnt, short nTol, sal_Bool bToggle, sal_Bool bDeep)
1359 {
1360     SdrObject* pObj;
1361     SdrPageView* pPV;
1362     nTol=ImpGetHitTolLogic(nTol,NULL);
1363     sal_uIntPtr nOptions=SDRSEARCH_PICKMARKABLE;
1364     if (bDeep) nOptions=nOptions|SDRSEARCH_DEEP;
1365     sal_Bool bRet=PickObj(rPnt,(sal_uInt16)nTol,pObj,pPV,nOptions);
1366     if (bRet) {
1367         sal_Bool bUnmark=bToggle && IsObjMarked(pObj);
1368         MarkObj(pObj,pPV,bUnmark);
1369     }
1370     return bRet;
1371 }
1372 
1373 sal_Bool SdrMarkView::MarkNextObj(sal_Bool bPrev)
1374 {
1375     SdrPageView* pPageView = GetSdrPageView();
1376 
1377     if(!pPageView)
1378     {
1379         return sal_False;
1380     }
1381 
1382     SortMarkedObjects();
1383     sal_uIntPtr  nMarkAnz=GetMarkedObjectCount();
1384     sal_uIntPtr  nChgMarkNum = ULONG_MAX; // Nummer des zu ersetzenden MarkEntries
1385     sal_uIntPtr  nSearchObjNum = bPrev ? 0 : ULONG_MAX;
1386     if (nMarkAnz!=0) {
1387         nChgMarkNum=bPrev ? 0 : sal_uIntPtr(nMarkAnz-1);
1388         SdrMark* pM=GetSdrMarkByIndex(nChgMarkNum);
1389         OSL_ASSERT(pM!=NULL);
1390         if (pM->GetMarkedSdrObj() != NULL)
1391             nSearchObjNum = pM->GetMarkedSdrObj()->GetNavigationPosition();
1392     }
1393 
1394     SdrObject* pMarkObj=NULL;
1395     SdrObjList* pSearchObjList=pPageView->GetObjList();
1396     sal_uIntPtr nObjAnz=pSearchObjList->GetObjCount();
1397     if (nObjAnz!=0) {
1398         if (nSearchObjNum>nObjAnz) nSearchObjNum=nObjAnz;
1399         while (pMarkObj==NULL && ((!bPrev && nSearchObjNum>0) || (bPrev && nSearchObjNum<nObjAnz)))
1400         {
1401             if (!bPrev)
1402                 nSearchObjNum--;
1403             SdrObject* pSearchObj = pSearchObjList->GetObjectForNavigationPosition(nSearchObjNum);
1404             if (IsObjMarkable(pSearchObj,pPageView))
1405             {
1406                 if (TryToFindMarkedObject(pSearchObj)==CONTAINER_ENTRY_NOTFOUND)
1407                 {
1408                     pMarkObj=pSearchObj;
1409                 }
1410             }
1411             if (bPrev) nSearchObjNum++;
1412         }
1413     }
1414 
1415     if(!pMarkObj)
1416     {
1417         return sal_False;
1418     }
1419 
1420     if (nChgMarkNum!=ULONG_MAX)
1421     {
1422         GetMarkedObjectListWriteAccess().DeleteMark(nChgMarkNum);
1423     }
1424     MarkObj(pMarkObj,pPageView); // ruft auch MarkListHasChanged(), AdjustMarkHdl()
1425     return sal_True;
1426 }
1427 
1428 sal_Bool SdrMarkView::MarkNextObj(const Point& rPnt, short nTol, sal_Bool bPrev)
1429 {
1430     SortMarkedObjects();
1431     nTol=ImpGetHitTolLogic(nTol,NULL);
1432     Point aPt(rPnt);
1433     SdrMark* pTopMarkHit=NULL;
1434     SdrMark* pBtmMarkHit=NULL;
1435     sal_uIntPtr nTopMarkHit=0;
1436     sal_uIntPtr nBtmMarkHit=0;
1437     // oberstes der markierten Objekte suchen, das von rPnt getroffen wird
1438     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1439     sal_uIntPtr nm=0;
1440     for (nm=nMarkAnz; nm>0 && pTopMarkHit==NULL;) {
1441         nm--;
1442         SdrMark* pM=GetSdrMarkByIndex(nm);
1443         if(CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0))
1444         {
1445             pTopMarkHit=pM;
1446             nTopMarkHit=nm;
1447         }
1448     }
1449     // Nichts gefunden, dann ganz normal ein Obj markieren.
1450     if (pTopMarkHit==NULL) return MarkObj(rPnt,sal_uInt16(nTol),sal_False);
1451 
1452     SdrObject* pTopObjHit=pTopMarkHit->GetMarkedSdrObj();
1453     SdrObjList* pObjList=pTopObjHit->GetObjList();
1454     SdrPageView* pPV=pTopMarkHit->GetPageView();
1455     // unterstes der markierten Objekte suchen, das von rPnt getroffen wird
1456     // und auf der gleichen PageView liegt wie pTopMarkHit
1457     for (nm=0; nm<nMarkAnz && pBtmMarkHit==NULL; nm++) {
1458         SdrMark* pM=GetSdrMarkByIndex(nm);
1459         SdrPageView* pPV2=pM->GetPageView();
1460         if (pPV2==pPV && CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pPV2,0,0))
1461         {
1462             pBtmMarkHit=pM;
1463             nBtmMarkHit=nm;
1464         }
1465     }
1466     if (pBtmMarkHit==NULL) { pBtmMarkHit=pTopMarkHit; nBtmMarkHit=nTopMarkHit; }
1467     SdrObject* pBtmObjHit=pBtmMarkHit->GetMarkedSdrObj();
1468     sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1469 
1470     // #110988#
1471     //sal_uIntPtr nSearchBeg=bPrev ? pBtmObjHit->GetOrdNum()+1 : pTopObjHit->GetOrdNum();
1472     sal_uInt32 nSearchBeg;
1473     E3dScene* pScene = NULL;
1474     SdrObject* pObjHit = (bPrev) ? pBtmObjHit : pTopObjHit;
1475     sal_Bool bRemap = pObjHit->ISA(E3dCompoundObject)
1476         ? ((E3dCompoundObject*)pObjHit)->IsAOrdNumRemapCandidate(pScene)
1477         : sal_False;
1478 
1479     if(bPrev)
1480     {
1481         sal_uInt32 nOrdNumBtm(pBtmObjHit->GetOrdNum());
1482 
1483         if(bRemap)
1484         {
1485             nOrdNumBtm = pScene->RemapOrdNum(nOrdNumBtm);
1486         }
1487 
1488         nSearchBeg = nOrdNumBtm + 1;
1489     }
1490     else
1491     {
1492         sal_uInt32 nOrdNumTop(pTopObjHit->GetOrdNum());
1493 
1494         if(bRemap)
1495         {
1496             nOrdNumTop = pScene->RemapOrdNum(nOrdNumTop);
1497         }
1498 
1499         nSearchBeg = nOrdNumTop;
1500     }
1501 
1502     sal_uIntPtr no=nSearchBeg;
1503     SdrObject* pFndObj=NULL;
1504     //SdrObject* pAktObj=NULL;
1505     while (pFndObj==NULL && ((!bPrev && no>0) || (bPrev && no<nObjAnz))) {
1506         if (!bPrev) no--;
1507         SdrObject* pObj;
1508 
1509         if(bRemap)
1510         {
1511             pObj = pObjList->GetObj(pScene->RemapOrdNum(no));
1512         }
1513         else
1514         {
1515             pObj = pObjList->GetObj(no);
1516         }
1517 
1518         if (CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_TESTMARKABLE,0))
1519         {
1520             if (TryToFindMarkedObject(pObj)==CONTAINER_ENTRY_NOTFOUND) {
1521                 pFndObj=pObj;
1522             } else {
1523                 // hier wg. Performance ggf. noch no auf Top bzw. auf Btm stellen
1524             }
1525         }
1526         if (bPrev) no++;
1527     }
1528     if (pFndObj!=NULL)
1529     {
1530         GetMarkedObjectListWriteAccess().DeleteMark(bPrev?nBtmMarkHit:nTopMarkHit);
1531         GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pFndObj,pPV));
1532         MarkListHasChanged();
1533         AdjustMarkHdl(); //HMHTRUE);
1534     }
1535     return pFndObj!=NULL;
1536 }
1537 
1538 sal_Bool SdrMarkView::MarkObj(const Rectangle& rRect, sal_Bool bUnmark)
1539 {
1540     sal_Bool bFnd=sal_False;
1541     Rectangle aR(rRect);
1542     SdrObject* pObj;
1543     SdrObjList* pObjList;
1544     BrkAction();
1545     SdrPageView* pPV = GetSdrPageView();
1546 
1547     if(pPV)
1548     {
1549         pObjList=pPV->GetObjList();
1550         Rectangle aFrm1(aR);
1551         sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1552         for (sal_uIntPtr nO=0; nO<nObjAnz; nO++) {
1553             pObj=pObjList->GetObj(nO);
1554             Rectangle aRect(pObj->GetCurrentBoundRect());
1555             if (aFrm1.IsInside(aRect)) {
1556                 if (!bUnmark) {
1557                     if (IsObjMarkable(pObj,pPV))
1558                     {
1559                         GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1560                         bFnd=sal_True;
1561                     }
1562                 } else {
1563                     sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1564                     if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1565                     {
1566                         GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1567                         bFnd=sal_True;
1568                     }
1569                 }
1570             }
1571         }
1572     }
1573     if (bFnd) {
1574         SortMarkedObjects();
1575         MarkListHasChanged();
1576         AdjustMarkHdl(); //HMHTRUE);
1577         //HMHShowMarkHdl();
1578     }
1579     return bFnd;
1580 }
1581 
1582 void SdrMarkView::MarkObj(SdrObject* pObj, SdrPageView* pPV, sal_Bool bUnmark, sal_Bool bImpNoSetMarkHdl)
1583 {
1584     if (pObj!=NULL && pPV!=NULL && IsObjMarkable(pObj, pPV)) {
1585         BrkAction();
1586         if (!bUnmark)
1587         {
1588             GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1589         }
1590         else
1591         {
1592             sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1593             if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1594             {
1595                 GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1596             }
1597         }
1598         if (!bImpNoSetMarkHdl) {
1599             MarkListHasChanged();
1600             AdjustMarkHdl(); //HMHTRUE);
1601             //HMHif (!bSomeObjChgdFlag) {
1602                 // ShowMarkHdl kommt sonst mit dem AfterPaintTimer
1603                 //HMHShowMarkHdl();
1604             //HMH}
1605         }
1606     }
1607 }
1608 
1609 sal_Bool SdrMarkView::IsObjMarked(SdrObject* pObj) const
1610 {
1611     // nicht so ganz die feine Art: Da FindObject() nicht const ist
1612     // muss ich mich hier auf non-const casten.
1613     sal_uIntPtr nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj);
1614     return nPos!=CONTAINER_ENTRY_NOTFOUND;
1615 }
1616 
1617 sal_uInt16 SdrMarkView::GetMarkHdlSizePixel() const
1618 {
1619     return aHdl.GetHdlSize()*2+1;
1620 }
1621 
1622 void SdrMarkView::SetSolidMarkHdl(sal_Bool bOn)
1623 {
1624     if (bOn!=aHdl.IsFineHdl()) {
1625         //HMHBOOL bMerk=IsMarkHdlShown();
1626         //HMHif (bMerk) HideMarkHdl();
1627         aHdl.SetFineHdl(bOn);
1628         //HMHif (bMerk) ShowMarkHdl();
1629     }
1630 }
1631 
1632 void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz)
1633 {
1634     if (nSiz<3) nSiz=3;
1635     nSiz/=2;
1636     if (nSiz!=aHdl.GetHdlSize()) {
1637         //HMHBOOL bMerk=IsMarkHdlShown();
1638         //HMHif (bMerk) HideMarkHdl();
1639         aHdl.SetHdlSize(nSiz);
1640         //HMHif (bMerk) ShowMarkHdl();
1641     }
1642 }
1643 
1644 #define SDRSEARCH_IMPISMASTER 0x80000000 /* MasterPage wird gerade durchsucht */
1645 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay) const
1646 {
1647     if(((nOptions & SDRSEARCH_IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible()))
1648     {
1649         return NULL;
1650     }
1651 
1652     const bool bCheckIfMarkable(nOptions & SDRSEARCH_TESTMARKABLE);
1653     const bool bDeep(nOptions & SDRSEARCH_DEEP);
1654     const bool bOLE(pObj->ISA(SdrOle2Obj));
1655     const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame());
1656     SdrObject* pRet=NULL;
1657     Rectangle aRect(pObj->GetCurrentBoundRect());
1658     sal_uInt16 nTol2(nTol);
1659 
1660     // double tolerance for OLE, text frames and objects in
1661     // active text edit
1662     if(bOLE || bTXT || pObj==((SdrObjEditView*)this)->GetTextEditObject())
1663     {
1664         nTol2*=2;
1665     }
1666 
1667     aRect.Left  ()-=nTol2; // Einmal Toleranz drauf fuer alle Objekte
1668     aRect.Top   ()-=nTol2;
1669     aRect.Right ()+=nTol2;
1670     aRect.Bottom()+=nTol2;
1671 
1672     if (aRect.IsInside(rPnt))
1673     {
1674         if ((!bCheckIfMarkable || IsObjMarkable(pObj,pPV)))
1675         {
1676             SdrObjList* pOL=pObj->GetSubList();
1677 
1678             if (pOL!=NULL && pOL->GetObjCount()!=0)
1679             {
1680                 SdrObject* pTmpObj;
1681                 // OD 30.06.2003 #108784# - adjustment hit point for virtual
1682                 // objects.
1683                 Point aPnt( rPnt );
1684 
1685                 if ( pObj->ISA(SdrVirtObj) )
1686                 {
1687                     Point aOffset = static_cast<SdrVirtObj*>(pObj)->GetOffset();
1688                     aPnt.Move( -aOffset.X(), -aOffset.Y() );
1689                 }
1690 
1691                 pRet=CheckSingleSdrObjectHit(aPnt,nTol,pOL,pPV,nOptions,pMVisLay,pTmpObj);
1692             }
1693             else
1694             {
1695                 if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer()))
1696                 {
1697                     pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false);
1698                 }
1699             }
1700         }
1701     }
1702 
1703     if (!bDeep && pRet!=NULL)
1704     {
1705         pRet=pObj;
1706     }
1707 
1708     return pRet;
1709 }
1710 
1711 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList* pOL, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj) const
1712 {
1713     sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD)!=0;
1714     SdrObject* pRet=NULL;
1715     rpRootObj=NULL;
1716     if (pOL!=NULL)
1717     {
1718         // #110988#
1719         sal_Bool bRemap(pOL->GetOwnerObj() && pOL->GetOwnerObj()->ISA(E3dScene));
1720         E3dScene* pRemapScene = (bRemap ? (E3dScene*)pOL->GetOwnerObj() : 0L);
1721 
1722         sal_uIntPtr nObjAnz=pOL->GetObjCount();
1723         sal_uIntPtr nObjNum=bBack ? 0 : nObjAnz;
1724         while (pRet==NULL && (bBack ? nObjNum<nObjAnz : nObjNum>0)) {
1725             if (!bBack) nObjNum--;
1726             SdrObject* pObj;
1727 
1728             // #110988#
1729             if(bRemap)
1730             {
1731                 pObj = pOL->GetObj(pRemapScene->RemapOrdNum(nObjNum));
1732             }
1733             else
1734             {
1735                 pObj = pOL->GetObj(nObjNum);
1736             }
1737 
1738             pRet=CheckSingleSdrObjectHit(rPnt,nTol,pObj,pPV,nOptions,pMVisLay);
1739             if (pRet!=NULL) rpRootObj=pObj;
1740             if (bBack) nObjNum++;
1741         }
1742     }
1743     return pRet;
1744 }
1745 
1746 sal_Bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions) const
1747 {
1748     return PickObj(rPnt,nTol,rpObj,rpPV,nOptions,NULL,NULL,NULL);
1749 }
1750 
1751 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
1752 { // Fehlt noch Pass2,Pass3
1753     SortMarkedObjects();
1754     if (ppRootObj!=NULL) *ppRootObj=NULL;
1755     if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1756     if (pnPassNum!=NULL) *pnPassNum=0;
1757     rpObj=NULL;
1758     rpPV=NULL;
1759     sal_Bool bWholePage=(nOptions & SDRSEARCH_WHOLEPAGE) !=0;
1760     sal_Bool bMarked=(nOptions & SDRSEARCH_MARKED) !=0;
1761     sal_Bool bMasters=!bMarked && (nOptions & SDRSEARCH_ALSOONMASTER) !=0;
1762     sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1763 #if OSL_DEBUG_LEVEL > 0
1764     sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0; (void)bNext; // n.i.
1765     sal_Bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; (void)bBoundCheckOn2ndPass;// n.i.
1766     sal_Bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; (void)bCheckNearestOn3rdPass;// n.i.
1767 #endif
1768     if (nTol<0) nTol=ImpGetHitTolLogic(nTol,NULL);
1769     Point aPt(rPnt);
1770     SdrObject* pObj=NULL;
1771     SdrObject* pHitObj=NULL;
1772     SdrPageView* pPV=NULL;
1773     if (!bBack && ((SdrObjEditView*)this)->IsTextEditFrameHit(rPnt)) {
1774         pObj=((SdrObjEditView*)this)->GetTextEditObject();
1775         pHitObj=pObj;
1776         pPV=((SdrObjEditView*)this)->GetTextEditPageView();
1777     }
1778     if (bMarked) {
1779         sal_uIntPtr nMrkAnz=GetMarkedObjectCount();
1780         sal_uIntPtr nMrkNum=bBack ? 0 : nMrkAnz;
1781         while (pHitObj==NULL && (bBack ? nMrkNum<nMrkAnz : nMrkNum>0)) {
1782             if (!bBack) nMrkNum--;
1783             SdrMark* pM=GetSdrMarkByIndex(nMrkNum);
1784             pObj=pM->GetMarkedSdrObj();
1785             pPV=pM->GetPageView();
1786             pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,nOptions,NULL);
1787             if (bBack) nMrkNum++;
1788         }
1789     }
1790     else
1791     {
1792         pPV = GetSdrPageView();
1793 
1794         if(pPV)
1795         {
1796             SdrPage* pPage=pPV->GetPage();
1797             sal_uInt16 nPgAnz=1;
1798 
1799             if(bMasters && pPage->TRG_HasMasterPage())
1800             {
1801                 nPgAnz++;
1802             }
1803 
1804             sal_Bool bExtraPassForWholePage=bWholePage && pPage!=pPV->GetObjList();
1805             if (bExtraPassForWholePage) nPgAnz++; // Suche erst in AktObjList, dann auf der gesamten Page
1806             sal_uInt16 nPgNum=bBack ? 0 : nPgAnz;
1807             while (pHitObj==NULL && (bBack ? nPgNum<nPgAnz : nPgNum>0)) {
1808                 sal_uIntPtr nTmpOptions=nOptions;
1809                 if (!bBack) nPgNum--;
1810                 const SetOfByte* pMVisLay=NULL;
1811                 SdrObjList* pObjList=NULL;
1812                 if (pnPassNum!=NULL) *pnPassNum&=~(SDRSEARCHPASS_MASTERPAGE|SDRSEARCHPASS_INACTIVELIST);
1813                 if (nPgNum>=nPgAnz-1 || (bExtraPassForWholePage && nPgNum>=nPgAnz-2))
1814                 {
1815                     pObjList=pPV->GetObjList();
1816                     if (bExtraPassForWholePage && nPgNum==nPgAnz-2) {
1817                         pObjList=pPage;
1818                         if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_INACTIVELIST;
1819                     }
1820                 }
1821                 else
1822                 {
1823                     // sonst MasterPage
1824                     SdrPage& rMasterPage = pPage->TRG_GetMasterPage();
1825                     pMVisLay = &pPage->TRG_GetMasterPageVisibleLayers();
1826                     pObjList = &rMasterPage;
1827 
1828                     if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_MASTERPAGE;
1829                     nTmpOptions=nTmpOptions | SDRSEARCH_IMPISMASTER;
1830                 }
1831                 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObjList,pPV,nTmpOptions,pMVisLay,pObj);
1832                 if (bBack) nPgNum++;
1833             }
1834         }
1835     }
1836     if (pHitObj!=NULL) {
1837         if (ppRootObj!=NULL) *ppRootObj=pObj;
1838         if ((nOptions & SDRSEARCH_DEEP) !=0) pObj=pHitObj;
1839         if ((nOptions & SDRSEARCH_TESTTEXTEDIT) !=0) {
1840             if (!pObj->HasTextEdit() || pPV->GetLockedLayers().IsSet(pObj->GetLayer())) {
1841                 pObj=NULL;
1842             }
1843         }
1844         if (pObj!=NULL && (nOptions & SDRSEARCH_TESTMACRO) !=0) {
1845             SdrObjMacroHitRec aHitRec;
1846             aHitRec.aPos=aPt;
1847             aHitRec.aDownPos=aPt;
1848             aHitRec.nTol=nTol;
1849             aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
1850             aHitRec.pPageView=pPV;
1851             if (!pObj->HasMacro() || !pObj->IsMacroHit(aHitRec)) pObj=NULL;
1852         }
1853         if (pObj!=NULL && (nOptions & SDRSEARCH_WITHTEXT) !=0 && pObj->GetOutlinerParaObject()==NULL) pObj=NULL;
1854         if (pObj!=NULL && (nOptions & SDRSEARCH_TESTTEXTAREA) !=0)
1855         {
1856             if(!SdrObjectPrimitiveHit(*pObj, aPt, 0, *pPV, 0, true))
1857             {
1858                 pObj = 0;
1859             }
1860         }
1861         if (pObj!=NULL) {
1862             rpObj=pObj;
1863             rpPV=pPV;
1864             if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_DIRECT;
1865         }
1866     }
1867     return rpObj!=NULL;
1868 }
1869 
1870 sal_Bool SdrMarkView::PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr* pnMarkNum, sal_uIntPtr nOptions) const
1871 {
1872     SortMarkedObjects();
1873     sal_Bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0;
1874     sal_Bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0;
1875     rpObj=NULL;
1876     rpPV=NULL;
1877     if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1878     Point aPt(rPnt);
1879     sal_uInt16 nTol=(sal_uInt16)nHitTolLog;
1880     sal_Bool bFnd=sal_False;
1881     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1882     sal_uIntPtr nMarkNum;
1883     for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1884         nMarkNum--;
1885         SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1886         SdrPageView* pPV=pM->GetPageView();
1887         SdrObject* pObj=pM->GetMarkedSdrObj();
1888         bFnd = 0 != CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,SDRSEARCH_TESTMARKABLE,0);
1889         if (bFnd) {
1890             rpObj=pObj;
1891             rpPV=pPV;
1892             if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1893         }
1894     }
1895     if ((bBoundCheckOn2ndPass || bCheckNearestOn3rdPass) && !bFnd) {
1896         SdrObject* pBestObj=NULL;
1897         SdrPageView* pBestPV=NULL;
1898         sal_uIntPtr nBestMarkNum=0;
1899         sal_uIntPtr nBestDist=ULONG_MAX;
1900         for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1901             nMarkNum--;
1902             SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1903             SdrPageView* pPV=pM->GetPageView();
1904             SdrObject* pObj=pM->GetMarkedSdrObj();
1905             Rectangle aRect(pObj->GetCurrentBoundRect());
1906             aRect.Left  ()-=nTol;
1907             aRect.Top   ()-=nTol;
1908             aRect.Right ()+=nTol;
1909             aRect.Bottom()+=nTol;
1910             if (aRect.IsInside(aPt)) {
1911                 bFnd=sal_True;
1912                 rpObj=pObj;
1913                 rpPV=pPV;
1914                 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1915             } else if (bCheckNearestOn3rdPass) {
1916                 sal_uIntPtr nDist=0;
1917                 if (aPt.X()<aRect.Left())   nDist+=aRect.Left()-aPt.X();
1918                 if (aPt.X()>aRect.Right())  nDist+=aPt.X()-aRect.Right();
1919                 if (aPt.Y()<aRect.Top())    nDist+=aRect.Top()-aPt.Y();
1920                 if (aPt.Y()>aRect.Bottom()) nDist+=aPt.Y()-aRect.Bottom();
1921                 if (nDist<nBestDist) {
1922                     pBestObj=pObj;
1923                     pBestPV=pPV;
1924                     nBestMarkNum=nMarkNum;
1925                 }
1926             }
1927         }
1928         if (bCheckNearestOn3rdPass && !bFnd) {
1929             rpObj=pBestObj;
1930             rpPV=pBestPV;
1931             if (pnMarkNum!=NULL) *pnMarkNum=nBestMarkNum;
1932             bFnd=pBestObj!=NULL;
1933         }
1934     }
1935     return bFnd;
1936 }
1937 
1938 SdrHitKind SdrMarkView::PickSomething(const Point& rPnt, short nTol) const
1939 {
1940     nTol=ImpGetHitTolLogic(nTol,NULL);
1941     SdrHitKind eRet=SDRHIT_NONE;
1942     Point aPt(rPnt);
1943     SdrObject* pObj=NULL;
1944     SdrPageView* pPV=NULL;
1945     if (eRet==SDRHIT_NONE && PickObj(rPnt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_PICKMARKABLE)) {
1946         Rectangle aRct1(aPt-Point(nTol,nTol),aPt+Point(nTol,nTol)); // HitRect fuer Toleranz
1947         Rectangle aBR(pObj->GetCurrentBoundRect());
1948         if      (aRct1.IsInside(aBR.TopLeft()))      eRet=SDRHIT_BOUNDTL;
1949         else if (aRct1.IsInside(aBR.TopCenter()))    eRet=SDRHIT_BOUNDTC;
1950         else if (aRct1.IsInside(aBR.TopRight()))     eRet=SDRHIT_BOUNDTR;
1951         else if (aRct1.IsInside(aBR.LeftCenter()))   eRet=SDRHIT_BOUNDCL;
1952         else if (aRct1.IsInside(aBR.RightCenter()))  eRet=SDRHIT_BOUNDCR;
1953         else if (aRct1.IsInside(aBR.BottomLeft()))   eRet=SDRHIT_BOUNDBL;
1954         else if (aRct1.IsInside(aBR.BottomCenter())) eRet=SDRHIT_BOUNDBC;
1955         else if (aRct1.IsInside(aBR.BottomRight()))  eRet=SDRHIT_BOUNDBR;
1956         else eRet=SDRHIT_OBJECT;
1957     }
1958     return eRet;
1959 }
1960 
1961 void SdrMarkView::UnmarkAllObj(SdrPageView* pPV)
1962 {
1963     if (GetMarkedObjectCount()!=0) {
1964         BrkAction();
1965         //HMHBOOL bVis=bHdlShown;
1966         //HMHif (bVis) HideMarkHdl();
1967         if (pPV!=NULL)
1968         {
1969             GetMarkedObjectListWriteAccess().DeletePageView(*pPV);
1970         }
1971         else
1972         {
1973             GetMarkedObjectListWriteAccess().Clear();
1974         }
1975         pMarkedObj=NULL;
1976         pMarkedPV=NULL;
1977         MarkListHasChanged();
1978         AdjustMarkHdl(); //HMHTRUE);
1979         //HMHif (bVis) ShowMarkHdl(); // ggf. fuer die RefPoints
1980     }
1981 }
1982 
1983 void SdrMarkView::MarkAllObj(SdrPageView* _pPV)
1984 {
1985     BrkAction();
1986     //HMHHideMarkHdl();
1987 
1988     if(!_pPV)
1989     {
1990         _pPV = GetSdrPageView();
1991     }
1992 
1993     // #i69171# _pPV may still be NULL if there is no SDrPageView (!), e.g. when inserting
1994     // other files
1995     if(_pPV)
1996     {
1997         const bool bMarkChg(GetMarkedObjectListWriteAccess().InsertPageView(*_pPV));
1998 
1999         if(bMarkChg)
2000         {
2001             MarkListHasChanged();
2002         }
2003     }
2004 
2005     if(GetMarkedObjectCount())
2006     {
2007         AdjustMarkHdl(); //HMHTRUE);
2008         //HMHShowMarkHdl();
2009     }
2010 }
2011 
2012 void SdrMarkView::AdjustMarkHdl() //HMHBOOL bRestraintPaint)
2013 {
2014     //HMHBOOL bVis=bHdlShown;
2015     //HMHif (bVis) HideMarkHdl();
2016     CheckMarked();
2017     SetMarkRects();
2018     SetMarkHandles();
2019     //HMHif(bRestraintPaint && bVis)
2020     //HMH{
2021     //HMH   ShowMarkHdl();
2022     //HMH}
2023 }
2024 
2025 Rectangle SdrMarkView::GetMarkedObjBoundRect() const
2026 {
2027     Rectangle aRect;
2028     for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
2029         SdrMark* pM=GetSdrMarkByIndex(nm);
2030         SdrObject* pO=pM->GetMarkedSdrObj();
2031         Rectangle aR1(pO->GetCurrentBoundRect());
2032         if (aRect.IsEmpty()) aRect=aR1;
2033         else aRect.Union(aR1);
2034     }
2035     return aRect;
2036 }
2037 
2038 const Rectangle& SdrMarkView::GetMarkedObjRect() const
2039 {
2040     if (bMarkedObjRectDirty) {
2041         ((SdrMarkView*)this)->bMarkedObjRectDirty=sal_False;
2042         Rectangle aRect;
2043         for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
2044             SdrMark* pM=GetSdrMarkByIndex(nm);
2045             SdrObject* pO=pM->GetMarkedSdrObj();
2046             Rectangle aR1(pO->GetSnapRect());
2047             if (aRect.IsEmpty()) aRect=aR1;
2048             else aRect.Union(aR1);
2049         }
2050         ((SdrMarkView*)this)->aMarkedObjRect=aRect;
2051     }
2052     return aMarkedObjRect;
2053 }
2054 
2055 ////////////////////////////////////////////////////////////////////////////////////////////////////
2056 
2057 void SdrMarkView::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal, sal_uInt16 nOpt) const
2058 {
2059     rStr = ImpGetResStr(nStrCacheID);
2060     xub_StrLen nPos = rStr.SearchAscii("%1");
2061 
2062     if(nPos != STRING_NOTFOUND)
2063     {
2064         rStr.Erase(nPos, 2);
2065 
2066         if(nOpt == IMPSDR_POINTSDESCRIPTION)
2067         {
2068             rStr.Insert(GetDescriptionOfMarkedPoints(), nPos);
2069         }
2070         else if(nOpt == IMPSDR_GLUEPOINTSDESCRIPTION)
2071         {
2072             rStr.Insert(GetDescriptionOfMarkedGluePoints(), nPos);
2073         }
2074         else
2075         {
2076             rStr.Insert(GetDescriptionOfMarkedObjects(), nPos);
2077         }
2078     }
2079 
2080     nPos = rStr.SearchAscii("%2");
2081 
2082     if(nPos != STRING_NOTFOUND)
2083     {
2084         rStr.Erase(nPos, 2);
2085         rStr.Insert(UniString::CreateFromInt32(nVal), nPos);
2086     }
2087 }
2088 
2089 ////////////////////////////////////////////////////////////////////////////////////////////////////
2090 
2091 sal_Bool SdrMarkView::EnterMarkedGroup()
2092 {
2093     sal_Bool bRet=sal_False;
2094     // Es wird nur die erste gefundene Gruppe (also nur in einer PageView) geentert
2095     // Weil PageView::EnterGroup ein AdjustMarkHdl ruft.
2096     // Das muss ich per Flag mal unterbinden  vvvvvvvv
2097     SdrPageView* pPV = GetSdrPageView();
2098 
2099     if(pPV)
2100     {
2101         sal_Bool bEnter=sal_False;
2102         for (sal_uInt32 nm(GetMarkedObjectCount()); nm > 0 && !bEnter;)
2103         {
2104             nm--;
2105             SdrMark* pM=GetSdrMarkByIndex(nm);
2106             if (pM->GetPageView()==pPV) {
2107                 SdrObject* pObj=pM->GetMarkedSdrObj();
2108                 if (pObj->IsGroupObject()) {
2109                     if (pPV->EnterGroup(pObj)) {
2110                         bRet=sal_True;
2111                         bEnter=sal_True;
2112                     }
2113                 }
2114             }
2115         }
2116     }
2117     return bRet;
2118 }
2119 
2120 ////////////////////////////////////////////////////////////////////////////////////////////////////
2121 
2122 void SdrMarkView::MarkListHasChanged()
2123 {
2124     GetMarkedObjectListWriteAccess().SetNameDirty();
2125     SetEdgesOfMarkedNodesDirty(); // bEdgesOfMarkedNodesDirty=sal_True;
2126 
2127     bMarkedObjRectDirty=sal_True;
2128     bMarkedPointsRectsDirty=sal_True;
2129 #ifdef DBG_UTIL
2130     if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
2131 #endif
2132     sal_Bool bOneEdgeMarked=sal_False;
2133     if (GetMarkedObjectCount()==1) {
2134         const SdrObject* pObj=GetMarkedObjectByIndex(0);
2135         if (pObj->GetObjInventor()==SdrInventor) {
2136             sal_uInt16 nIdent=pObj->GetObjIdentifier();
2137             bOneEdgeMarked=nIdent==OBJ_EDGE;
2138         }
2139     }
2140     ImpSetGlueVisible4(bOneEdgeMarked);
2141 }
2142 
2143 ////////////////////////////////////////////////////////////////////////////////////////////////////
2144 
2145 void SdrMarkView::SetMoveOutside(sal_Bool bOn)
2146 {
2147     aHdl.SetMoveOutside(bOn);
2148 }
2149 
2150 sal_Bool SdrMarkView::IsMoveOutside() const
2151 {
2152     return aHdl.IsMoveOutside();
2153 }
2154 
2155 void SdrMarkView::SetDesignMode( sal_Bool _bOn )
2156 {
2157     if ( bDesignMode != _bOn )
2158     {
2159         bDesignMode = _bOn;
2160         SdrPageView* pPageView = GetSdrPageView();
2161         if ( pPageView )
2162             pPageView->SetDesignMode( _bOn );
2163     }
2164 }
2165 
2166 // MarkHandles Objektaenderung:
2167 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2168 // - Bei Notify mit HINT_OBJCHG (oder so) werden die Handles erstmal versteckt
2169 //   (wenn nicht schon wegen Dragging versteckt).
2170 // - XorHdl: Bei ModelHasChanged() werden sie dann wieder angezeigt.
2171 // - PaintEvents kommen nun durch.
2172 //   - Die XorHandles werden z.T. wieder uebermalt.
2173 //   - Xor:  Nach dem Painten werden die Handles im (vom PaintHandler gerufenen)
2174 //           CompleteRedraw per ToggleShownXor bei gesetzter ClipRegion nochmal gemalt
2175 //           und damit ist alles in Butter.
2176 //   - ToggleShownXor macht bei SolidHdl nix weil bHdlShown=FALSE
2177 //   - Der AfterPaintTimer wird gestartet.
2178 // - SolidHdl: Im AfterPaintHandler wird ShowMarkHdl gerufen.
2179 //   Da die Handles zu diesem Zeitpunkt nicht angezeigt sind wird:
2180 //   - SaveBackground durchgefuehrt.
2181 //   - DrawMarkHdl gerufen und bHdlShown gesetzt.
2182 //
2183 // MarkHandles bei sonstigem Invalidate:
2184 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2185 // In diesem Fall bekomme ich kein Notify und beim Aufruf des
2186 // PaintHandlers->CompleteRedraw() sind auch die SolidHandles sichtbar.
2187 
2188