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