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