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