bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / svdraw / svdmrkv.cxx
blobff27728c1d09dcd764667a0e726ef5ae9ceada80
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svx/svdmrkv.hxx>
22 #include <svx/svdetc.hxx>
23 #include <svx/svdoedge.hxx>
24 #include "svx/svdglob.hxx"
25 #include <svx/svdview.hxx>
26 #include <svx/svdpagv.hxx>
27 #include <svx/svdpage.hxx>
28 #include "svddrgm1.hxx"
30 #ifdef DBG_UTIL
31 #include <svdibrow.hxx>
32 #endif
34 #include <svx/svdoole2.hxx>
35 #include <svx/xgrad.hxx>
36 #include <svx/xflgrit.hxx>
37 #include "gradtrns.hxx"
38 #include <svx/xflftrit.hxx>
39 #include <svx/dialmgr.hxx>
40 #include "svx/svdstr.hrc"
41 #include <svx/svdundo.hxx>
42 #include <svx/svdopath.hxx>
43 #include <svx/scene3d.hxx>
44 #include <svx/svdovirt.hxx>
45 #include <svx/sdr/overlay/overlayrollingrectangle.hxx>
46 #include <svx/sdr/overlay/overlaymanager.hxx>
47 #include <svx/sdrpaintwindow.hxx>
48 #include <svx/sdrpagewindow.hxx>
49 #include <svx/sdrhittesthelper.hxx>
50 #include <svx/svdocapt.hxx>
52 #include <editeng/editdata.hxx>
54 ////////////////////////////////////////////////////////////////////////////////////////////////////
55 // Migrate Marking of Objects, Points and GluePoints
57 class ImplMarkingOverlay
59 // The OverlayObjects
60 ::sdr::overlay::OverlayObjectList maObjects;
62 // The remembered second position in logical coordinates
63 basegfx::B2DPoint maSecondPosition;
65 // bitfield
66 // A flag to remember if the action is for unmarking.
67 unsigned mbUnmarking : 1;
69 public:
70 ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking = sal_False);
71 ~ImplMarkingOverlay();
73 void SetSecondPosition(const basegfx::B2DPoint& rNewPosition);
74 sal_Bool IsUnmarking() const { return mbUnmarking; }
77 ImplMarkingOverlay::ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking)
78 : maSecondPosition(rStartPos),
79 mbUnmarking(bUnmarking)
81 for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
83 SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
84 rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
86 if (xTargetOverlay.is())
88 ::sdr::overlay::OverlayRollingRectangleStriped* pNew = new ::sdr::overlay::OverlayRollingRectangleStriped(
89 rStartPos, rStartPos, false);
90 xTargetOverlay->add(*pNew);
91 maObjects.append(*pNew);
96 ImplMarkingOverlay::~ImplMarkingOverlay()
98 // The OverlayObjects are cleared using the destructor of OverlayObjectList.
99 // That destructor calls clear() at the list which removes all objects from the
100 // OverlayManager and deletes them.
103 void ImplMarkingOverlay::SetSecondPosition(const basegfx::B2DPoint& rNewPosition)
105 if(rNewPosition != maSecondPosition)
107 // apply to OverlayObjects
108 for(sal_uInt32 a(0L); a < maObjects.count(); a++)
110 ::sdr::overlay::OverlayRollingRectangleStriped& rCandidate = (::sdr::overlay::OverlayRollingRectangleStriped&)maObjects.getOverlayObject(a);
111 rCandidate.setSecondPosition(rNewPosition);
114 // remember new position
115 maSecondPosition = rNewPosition;
119 ////////////////////////////////////////////////////////////////////////////////////////////////////
120 ////////////////////////////////////////////////////////////////////////////////////////////////////
121 // MarkView
122 ////////////////////////////////////////////////////////////////////////////////////////////////////
123 ////////////////////////////////////////////////////////////////////////////////////////////////////
125 void SdrMarkView::ImpClearVars()
127 eDragMode=SDRDRAG_MOVE;
128 bRefHdlShownOnly=sal_False;
129 eEditMode=SDREDITMODE_EDIT;
130 eEditMode0=SDREDITMODE_EDIT;
131 bDesignMode=sal_False;
132 pMarkedObj=NULL;
133 pMarkedPV=NULL;
134 bForceFrameHandles=sal_False;
135 bPlusHdlAlways=sal_False;
136 nFrameHandlesLimit=50;
137 bInsPolyPoint=sal_False;
138 mnInsPointNum = 0L;
139 bMarkedObjRectDirty=sal_False;
140 bMarkedPointsRectsDirty=sal_False;
141 mbMarkHandlesHidden = false;
142 bMrkPntDirty=sal_False;
143 bMarkHdlWhenTextEdit=sal_False;
144 bMarkableObjCountDirty=sal_False; // not yet implemented
145 nMarkableObjCount=0; // not yet implemented
147 // Migrate selections
148 BrkMarkObj();
149 BrkMarkPoints();
150 BrkMarkGluePoints();
153 SdrMarkView::SdrMarkView(SdrModel* pModel1, OutputDevice* pOut)
154 : SdrSnapView(pModel1,pOut),
155 mpMarkObjOverlay(0L),
156 mpMarkPointsOverlay(0L),
157 mpMarkGluePointsOverlay(0L),
158 aHdl(this),
159 mpSdrViewSelection(new sdr::ViewSelection())
161 ImpClearVars();
162 StartListening(*pModel1);
165 SdrMarkView::~SdrMarkView()
167 // Migrate selections
168 BrkMarkObj();
169 BrkMarkPoints();
170 BrkMarkGluePoints();
171 delete mpSdrViewSelection;
174 void SdrMarkView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
176 SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
177 if (pSdrHint!=NULL)
179 SdrHintKind eKind=pSdrHint->GetKind();
181 if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED)
183 bMarkedObjRectDirty=sal_True;
184 bMarkedPointsRectsDirty=sal_True;
187 SdrSnapView::Notify(rBC,rHint);
190 void SdrMarkView::ModelHasChanged()
192 SdrPaintView::ModelHasChanged();
193 GetMarkedObjectListWriteAccess().SetNameDirty();
194 bMarkedObjRectDirty=sal_True;
195 bMarkedPointsRectsDirty=sal_True;
196 // Example: Obj is selected and maMarkedObjectList is sorted.
197 // In another View 2, the ObjOrder is changed (e. g. MovToTop())
198 // Then we need to re-sort MarkList.
199 GetMarkedObjectListWriteAccess().SetUnsorted();
200 SortMarkedObjects();
201 bMrkPntDirty=sal_True;
202 UndirtyMrkPnt();
203 SdrView* pV=(SdrView*)this;
204 if (pV!=NULL && !pV->IsDragObj() && !pV->IsInsObjPoint()) {
205 AdjustMarkHdl();
209 ////////////////////////////////////////////////////////////////////////////////////////////////////
211 sal_Bool SdrMarkView::IsAction() const
213 return SdrSnapView::IsAction() || IsMarkObj() || IsMarkPoints() || IsMarkGluePoints();
216 void SdrMarkView::MovAction(const Point& rPnt)
218 SdrSnapView::MovAction(rPnt);
220 if(IsMarkObj())
222 MovMarkObj(rPnt);
224 else if(IsMarkPoints())
226 MovMarkPoints(rPnt);
228 else if(IsMarkGluePoints())
230 MovMarkGluePoints(rPnt);
234 void SdrMarkView::EndAction()
236 if(IsMarkObj())
238 EndMarkObj();
240 else if(IsMarkPoints())
242 EndMarkPoints();
244 else if(IsMarkGluePoints())
246 EndMarkGluePoints();
249 SdrSnapView::EndAction();
252 void SdrMarkView::BckAction()
254 SdrSnapView::BckAction();
255 BrkMarkObj();
256 BrkMarkPoints();
257 BrkMarkGluePoints();
260 void SdrMarkView::BrkAction()
262 SdrSnapView::BrkAction();
263 BrkMarkObj();
264 BrkMarkPoints();
265 BrkMarkGluePoints();
268 void SdrMarkView::TakeActionRect(Rectangle& rRect) const
270 if(IsMarkObj() || IsMarkPoints() || IsMarkGluePoints())
272 rRect = Rectangle(aDragStat.GetStart(), aDragStat.GetNow());
274 else
276 SdrSnapView::TakeActionRect(rRect);
280 ////////////////////////////////////////////////////////////////////////////////////////////////////
282 void SdrMarkView::ClearPageView()
284 UnmarkAllObj();
285 SdrSnapView::ClearPageView();
288 void SdrMarkView::HideSdrPage()
290 bool bMrkChg(false);
292 SdrPageView* pPageView = GetSdrPageView();
293 if (pPageView)
295 // break all creation actions when hiding page (#75081#)
296 BrkAction();
298 // Discard all selections on this page
299 bMrkChg = GetMarkedObjectListWriteAccess().DeletePageView(*pPageView);
302 SdrSnapView::HideSdrPage();
304 if(bMrkChg)
306 MarkListHasChanged();
307 AdjustMarkHdl();
311 ////////////////////////////////////////////////////////////////////////////////////////////////////
313 sal_Bool SdrMarkView::BegMarkObj(const Point& rPnt, sal_Bool bUnmark)
315 BrkAction();
317 DBG_ASSERT(0L == mpMarkObjOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkObjOverlay (!)");
318 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
319 mpMarkObjOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
321 aDragStat.Reset(rPnt);
322 aDragStat.NextPoint();
323 aDragStat.SetMinMove(nMinMovLog);
325 return sal_True;
328 void SdrMarkView::MovMarkObj(const Point& rPnt)
330 if(IsMarkObj() && aDragStat.CheckMinMoved(rPnt))
332 aDragStat.NextMove(rPnt);
333 DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
334 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
335 mpMarkObjOverlay->SetSecondPosition(aNewPos);
339 sal_Bool SdrMarkView::EndMarkObj()
341 sal_Bool bRetval(sal_False);
343 if(IsMarkObj())
345 if(aDragStat.IsMinMoved())
347 Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
348 aRect.Justify();
349 MarkObj(aRect, mpMarkObjOverlay->IsUnmarking());
350 bRetval = sal_True;
353 // cleanup
354 BrkMarkObj();
357 return bRetval;
360 void SdrMarkView::BrkMarkObj()
362 if(IsMarkObj())
364 DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
365 delete mpMarkObjOverlay;
366 mpMarkObjOverlay = 0L;
370 ////////////////////////////////////////////////////////////////////////////////////////////////////
372 sal_Bool SdrMarkView::BegMarkPoints(const Point& rPnt, sal_Bool bUnmark)
374 if(HasMarkablePoints())
376 BrkAction();
378 DBG_ASSERT(0L == mpMarkPointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkPointsOverlay (!)");
379 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
380 mpMarkPointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
382 aDragStat.Reset(rPnt);
383 aDragStat.NextPoint();
384 aDragStat.SetMinMove(nMinMovLog);
386 return sal_True;
389 return sal_False;
392 void SdrMarkView::MovMarkPoints(const Point& rPnt)
394 if(IsMarkPoints() && aDragStat.CheckMinMoved(rPnt))
396 aDragStat.NextMove(rPnt);
398 DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
399 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
400 mpMarkPointsOverlay->SetSecondPosition(aNewPos);
404 sal_Bool SdrMarkView::EndMarkPoints()
406 sal_Bool bRetval(sal_False);
408 if(IsMarkPoints())
410 if(aDragStat.IsMinMoved())
412 Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
413 aRect.Justify();
414 MarkPoints(aRect, mpMarkPointsOverlay->IsUnmarking());
416 bRetval = sal_True;
419 // cleanup
420 BrkMarkPoints();
423 return bRetval;
426 void SdrMarkView::BrkMarkPoints()
428 if(IsMarkPoints())
430 DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
431 delete mpMarkPointsOverlay;
432 mpMarkPointsOverlay = 0L;
436 ////////////////////////////////////////////////////////////////////////////////////////////////////
438 sal_Bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, sal_Bool bUnmark)
440 if(HasMarkableGluePoints())
442 BrkAction();
444 DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)");
446 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
447 mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
448 aDragStat.Reset(rPnt);
449 aDragStat.NextPoint();
450 aDragStat.SetMinMove(nMinMovLog);
452 return sal_True;
455 return sal_False;
458 void SdrMarkView::MovMarkGluePoints(const Point& rPnt)
460 if(IsMarkGluePoints() && aDragStat.CheckMinMoved(rPnt))
462 aDragStat.NextMove(rPnt);
464 DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
465 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
466 mpMarkGluePointsOverlay->SetSecondPosition(aNewPos);
470 sal_Bool SdrMarkView::EndMarkGluePoints()
472 sal_Bool bRetval(sal_False);
474 if(IsMarkGluePoints())
476 if(aDragStat.IsMinMoved())
478 Rectangle aRect(aDragStat.GetStart(),aDragStat.GetNow());
479 aRect.Justify();
480 MarkGluePoints(&aRect, mpMarkGluePointsOverlay->IsUnmarking());
482 bRetval = sal_True;
485 // cleanup
486 BrkMarkGluePoints();
489 return bRetval;
492 void SdrMarkView::BrkMarkGluePoints()
494 if(IsMarkGluePoints())
496 DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
497 delete mpMarkGluePointsOverlay;
498 mpMarkGluePointsOverlay = 0L;
502 void SdrMarkView::hideMarkHandles()
504 if(!mbMarkHandlesHidden)
506 mbMarkHandlesHidden = true;
507 AdjustMarkHdl();
511 void SdrMarkView::showMarkHandles()
513 if(mbMarkHandlesHidden)
515 mbMarkHandlesHidden = false;
516 AdjustMarkHdl();
520 sal_Bool SdrMarkView::ImpIsFrameHandles() const
522 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
523 sal_Bool bFrmHdl=nMarkAnz>nFrameHandlesLimit || bForceFrameHandles;
524 bool bStdDrag=eDragMode==SDRDRAG_MOVE;
525 if (nMarkAnz==1 && bStdDrag && bFrmHdl)
527 const SdrObject* pObj=GetMarkedObjectByIndex(0);
528 if (pObj->GetObjInventor()==SdrInventor)
530 sal_uInt16 nIdent=pObj->GetObjIdentifier();
531 if (nIdent==OBJ_LINE || nIdent==OBJ_EDGE || nIdent==OBJ_CAPTION || nIdent==OBJ_MEASURE || nIdent==OBJ_CUSTOMSHAPE || nIdent==OBJ_TABLE )
533 bFrmHdl=sal_False;
537 if (!bStdDrag && !bFrmHdl) {
538 // all other drag modes only with FrameHandles
539 bFrmHdl=sal_True;
540 if (eDragMode==SDRDRAG_ROTATE) {
541 // when rotating, use ObjOwn drag, if there's at least 1 PolyObj
542 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && bFrmHdl; nMarkNum++) {
543 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
544 const SdrObject* pObj=pM->GetMarkedSdrObj();
545 bFrmHdl=!pObj->IsPolyObj();
549 if (!bFrmHdl) {
550 // FrameHandles, if at least 1 Obj can't do SpecialDrag
551 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bFrmHdl; nMarkNum++) {
552 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
553 const SdrObject* pObj=pM->GetMarkedSdrObj();
554 bFrmHdl=!pObj->hasSpecialDrag();
557 return bFrmHdl;
560 void SdrMarkView::SetMarkHandles()
562 // remember old focus handle values to search for it again
563 const SdrHdl* pSaveOldFocusHdl = aHdl.GetFocusHdl();
564 bool bSaveOldFocus(false);
565 sal_uInt32 nSavePolyNum(0L), nSavePointNum(0L);
566 SdrHdlKind eSaveKind(HDL_MOVE);
567 SdrObject* pSaveObj = NULL;
569 if(pSaveOldFocusHdl
570 && pSaveOldFocusHdl->GetObj()
571 && pSaveOldFocusHdl->GetObj()->ISA(SdrPathObj)
572 && (pSaveOldFocusHdl->GetKind() == HDL_POLY || pSaveOldFocusHdl->GetKind() == HDL_BWGT))
574 bSaveOldFocus = true;
575 nSavePolyNum = pSaveOldFocusHdl->GetPolyNum();
576 nSavePointNum = pSaveOldFocusHdl->GetPointNum();
577 pSaveObj = pSaveOldFocusHdl->GetObj();
578 eSaveKind = pSaveOldFocusHdl->GetKind();
581 // delete/clear all handles. This will always be done, even with areMarkHandlesHidden()
582 aHdl.Clear();
583 aHdl.SetRotateShear(eDragMode==SDRDRAG_ROTATE);
584 aHdl.SetDistortShear(eDragMode==SDRDRAG_SHEAR);
585 pMarkedObj=NULL;
586 pMarkedPV=NULL;
588 // are handles enabled at all? Create only then
589 if(!areMarkHandlesHidden())
591 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
592 bool bStdDrag=eDragMode==SDRDRAG_MOVE;
593 bool bSingleTextObjMark=false;
595 if (nMarkAnz==1)
597 pMarkedObj=GetMarkedObjectByIndex(0);
598 bSingleTextObjMark =
599 pMarkedObj &&
600 pMarkedObj->ISA(SdrTextObj) &&
601 static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame();
604 sal_Bool bFrmHdl=ImpIsFrameHandles();
606 if (nMarkAnz>0)
608 pMarkedPV=GetSdrPageViewOfMarkedByIndex(0);
610 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && (pMarkedPV!=NULL || !bFrmHdl); nMarkNum++)
612 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
614 if (pMarkedPV!=pM->GetPageView())
616 pMarkedPV=NULL;
621 // apply calc offset to marked object rect
622 // ( necessary for handles to be displayed in
623 // correct position )
624 Point aGridOff = GetGridOffset();
626 // #i122142# for captions in TextEdit, force to FrameHdls to get the special text selection
627 if(!bFrmHdl && pMarkedObj && bSingleTextObjMark && dynamic_cast< SdrCaptionObj* >(pMarkedObj))
629 bFrmHdl = true;
632 if (bFrmHdl)
634 Rectangle aRect(GetMarkedObjRect());
635 // #i33755#
636 const bool bHideHandlesWhenInTextEdit(
637 ((SdrView*)this)->IsTextEdit()
638 && pMarkedObj
639 && pMarkedObj->ISA(SdrTextObj)
640 && ((SdrTextObj*)pMarkedObj)->IsInEditMode());
642 // #i118524# if inplace activated OLE is selected,
643 // suppress handles
644 bool bHideHandlesWhenOleActive(false);
645 const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pMarkedObj);
647 if(pSdrOle2Obj && (pSdrOle2Obj->isInplaceActive() || pSdrOle2Obj->isUiActive()))
649 bHideHandlesWhenOleActive = true;
652 if(!aRect.IsEmpty() && !bHideHandlesWhenInTextEdit && !bHideHandlesWhenOleActive)
653 { // otherwise nothing is found
654 if( bSingleTextObjMark )
656 const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
657 pMarkedObj->AddToHdlList(aHdl);
658 const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
659 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
661 SdrHdl* pHdl=aHdl.GetHdl(i);
662 pHdl->SetObj(pMarkedObj);
663 pHdl->SetPos( pHdl->GetPos() + aGridOff );
664 pHdl->SetPageView(pMarkedPV);
665 pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
668 else if( eDragMode==SDRDRAG_CROP )
670 aHdl.AddHdl(new SdrCropHdl(aRect.TopLeft() ,HDL_UPLFT));
671 aHdl.AddHdl(new SdrCropHdl(aRect.TopCenter() ,HDL_UPPER));
672 aHdl.AddHdl(new SdrCropHdl(aRect.TopRight() ,HDL_UPRGT));
673 aHdl.AddHdl(new SdrCropHdl(aRect.LeftCenter() ,HDL_LEFT ));
674 aHdl.AddHdl(new SdrCropHdl(aRect.RightCenter() ,HDL_RIGHT));
675 aHdl.AddHdl(new SdrCropHdl(aRect.BottomLeft() ,HDL_LWLFT));
676 aHdl.AddHdl(new SdrCropHdl(aRect.BottomCenter(),HDL_LOWER));
677 aHdl.AddHdl(new SdrCropHdl(aRect.BottomRight() ,HDL_LWRGT));
679 else
681 bool bWdt0=aRect.Left()==aRect.Right();
682 bool bHgt0=aRect.Top()==aRect.Bottom();
683 if (bWdt0 && bHgt0)
685 aHdl.AddHdl(new SdrHdl(aRect.TopLeft(),HDL_UPLFT));
687 else if (!bStdDrag && (bWdt0 || bHgt0))
689 aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
690 aHdl.AddHdl(new SdrHdl(aRect.BottomRight(),HDL_LWRGT));
692 else
694 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
695 if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopCenter() ,HDL_UPPER));
696 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopRight() ,HDL_UPRGT));
697 if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.LeftCenter() ,HDL_LEFT ));
698 if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.RightCenter() ,HDL_RIGHT));
699 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomLeft() ,HDL_LWLFT));
700 if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomCenter(),HDL_LOWER));
701 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomRight() ,HDL_LWRGT));
706 else
708 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
710 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
711 SdrObject* pObj=pM->GetMarkedSdrObj();
712 SdrPageView* pPV=pM->GetPageView();
713 const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
714 pObj->AddToHdlList(aHdl);
715 const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
716 bool bPoly=pObj->IsPolyObj();
717 const SdrUShortCont* pMrkPnts=pM->GetMarkedPoints();
718 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
720 SdrHdl* pHdl=aHdl.GetHdl(i);
721 pHdl->SetPos( pHdl->GetPos() + aGridOff );
722 pHdl->SetObj(pObj);
723 pHdl->SetPageView(pPV);
724 pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
725 if (bPoly)
727 sal_Bool bSelected=pMrkPnts!=NULL
728 && pMrkPnts->find( sal_uInt16(i-nSiz0) ) != pMrkPnts->end();
729 pHdl->SetSelected(bSelected);
730 if (bPlusHdlAlways || bSelected)
732 sal_uInt32 nPlusAnz=pObj->GetPlusHdlCount(*pHdl);
733 for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
735 SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,nPlusNum);
736 if (pPlusHdl!=NULL)
738 pPlusHdl->SetObj(pObj);
739 pPlusHdl->SetPageView(pPV);
740 pPlusHdl->SetPlusHdl(sal_True);
741 aHdl.AddHdl(pPlusHdl);
747 } // for nMarkNum
748 } // if bFrmHdl else
750 // GluePoint handles
751 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
753 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
754 SdrObject* pObj=pM->GetMarkedSdrObj();
755 SdrPageView* pPV=pM->GetPageView();
756 const SdrUShortCont* pMrkGlue=pM->GetMarkedGluePoints();
757 if (pMrkGlue!=NULL)
759 const SdrGluePointList* pGPL=pObj->GetGluePointList();
760 if (pGPL!=NULL)
762 for(SdrUShortCont::const_iterator it = pMrkGlue->begin(); it != pMrkGlue->end(); ++it)
764 sal_uInt16 nId=*it;
765 //nNum changed to nNumGP because already used in for loop
766 sal_uInt16 nNumGP=pGPL->FindGluePoint(nId);
767 if (nNumGP!=SDRGLUEPOINT_NOTFOUND)
769 const SdrGluePoint& rGP=(*pGPL)[nNumGP];
770 Point aPos(rGP.GetAbsolutePos(*pObj));
771 SdrHdl* pGlueHdl=new SdrHdl(aPos,HDL_GLUE);
772 pGlueHdl->SetObj(pObj);
773 pGlueHdl->SetPageView(pPV);
774 pGlueHdl->SetObjHdlNum(nId);
775 aHdl.AddHdl(pGlueHdl);
782 // rotation point/axis of reflection
783 AddDragModeHdl(eDragMode);
785 // sort handles
786 aHdl.Sort();
788 // add custom handles (used by other apps, e.g. AnchorPos)
789 AddCustomHdl();
791 // try to restore focus handle index from remembered values
792 if(bSaveOldFocus)
794 for(sal_uInt32 a(0); a < aHdl.GetHdlCount(); a++)
796 SdrHdl* pCandidate = aHdl.GetHdl(a);
798 if(pCandidate->GetObj()
799 && pCandidate->GetObj() == pSaveObj
800 && pCandidate->GetKind() == eSaveKind
801 && pCandidate->GetPolyNum() == nSavePolyNum
802 && pCandidate->GetPointNum() == nSavePointNum)
804 aHdl.SetFocusHdl(pCandidate);
805 break;
812 void SdrMarkView::AddCustomHdl()
814 // add custom handles (used by other apps, e.g. AnchorPos)
817 void SdrMarkView::SetDragMode(SdrDragMode eMode)
819 SdrDragMode eMode0=eDragMode;
820 eDragMode=eMode;
821 if (eDragMode==SDRDRAG_RESIZE) eDragMode=SDRDRAG_MOVE;
822 if (eDragMode!=eMode0) {
823 ForceRefToMarked();
824 SetMarkHandles();
826 if (AreObjectsMarked()) MarkListHasChanged();
831 void SdrMarkView::AddDragModeHdl(SdrDragMode eMode)
833 switch(eMode)
835 case SDRDRAG_ROTATE:
837 // add rotation center
838 SdrHdl* pHdl = new SdrHdl(aRef1, HDL_REF1);
840 aHdl.AddHdl(pHdl);
842 break;
844 case SDRDRAG_MIRROR:
846 // add axis of reflection
847 SdrHdl* pHdl3 = new SdrHdl(aRef2, HDL_REF2);
848 SdrHdl* pHdl2 = new SdrHdl(aRef1, HDL_REF1);
849 SdrHdl* pHdl1 = new SdrHdlLine(*pHdl2, *pHdl3, HDL_MIRX);
851 pHdl1->SetObjHdlNum(1); // for sorting
852 pHdl2->SetObjHdlNum(2); // for sorting
853 pHdl3->SetObjHdlNum(3); // for sorting
855 aHdl.AddHdl(pHdl1); // line comes first, so it is the last in HitTest
856 aHdl.AddHdl(pHdl2);
857 aHdl.AddHdl(pHdl3);
859 break;
861 case SDRDRAG_TRANSPARENCE:
863 // add interactive transparency handle
864 sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
865 if(nMarkAnz == 1)
867 SdrObject* pObj = GetMarkedObjectByIndex(0);
868 SdrModel* pModel = GetModel();
869 const SfxItemSet& rSet = pObj->GetMergedItemSet();
871 if(SFX_ITEM_SET != rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, sal_False))
873 // add this item, it's not yet there
874 XFillFloatTransparenceItem aNewItem(
875 (const XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE));
876 XGradient aGrad = aNewItem.GetGradientValue();
878 aNewItem.SetEnabled(sal_True);
879 aGrad.SetStartIntens(100);
880 aGrad.SetEndIntens(100);
881 aNewItem.SetGradientValue(aGrad);
883 // add undo to allow user to take back this step
884 if( pModel->IsUndoEnabled() )
886 pModel->BegUndo(SVX_RESSTR(SIP_XA_FILLTRANSPARENCE));
887 pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
888 pModel->EndUndo();
891 SfxItemSet aNewSet(pModel->GetItemPool());
892 aNewSet.Put(aNewItem);
893 pObj->SetMergedItemSetAndBroadcast(aNewSet);
896 // set values and transform to vector set
897 GradTransformer aGradTransformer;
898 GradTransVector aGradTransVector;
899 GradTransGradient aGradTransGradient;
901 aGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
902 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
904 // build handles
905 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
906 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
907 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True);
908 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True);
909 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_False);
910 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Could not get all necessary handles!");
912 // link them
913 pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
914 pGradHdl->SetObj(pObj);
915 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
916 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
918 // insert them
919 aHdl.AddHdl(pColHdl1);
920 aHdl.AddHdl(pColHdl2);
921 aHdl.AddHdl(pGradHdl);
923 break;
925 case SDRDRAG_GRADIENT:
927 // add interactive gradient handle
928 sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
929 if(nMarkAnz == 1)
931 SdrObject* pObj = GetMarkedObjectByIndex(0);
932 const SfxItemSet& rSet = pObj->GetMergedItemSet();
933 XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
935 if(eFillStyle == XFILL_GRADIENT)
937 // set values and transform to vector set
938 GradTransformer aGradTransformer;
939 GradTransVector aGradTransVector;
940 GradTransGradient aGradTransGradient;
941 Size aHdlSize(15, 15);
943 aGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
944 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
946 // build handles
947 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
948 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
949 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, sal_False);
950 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, sal_False);
951 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_True);
952 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Could not get all necessary handles!");
954 // link them
955 pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
956 pGradHdl->SetObj(pObj);
957 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
958 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
960 // insert them
961 aHdl.AddHdl(pColHdl1);
962 aHdl.AddHdl(pColHdl2);
963 aHdl.AddHdl(pGradHdl);
966 break;
968 case SDRDRAG_CROP:
970 // TODO
971 break;
973 default: break;
977 /** handle mouse over effects for handles */
978 sal_Bool SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
980 if(aHdl.GetHdlCount())
982 SdrHdl* pMouseOverHdl = 0;
983 if( !rMEvt.IsLeaveWindow() && pWin )
985 Point aMDPos( pWin->PixelToLogic( rMEvt.GetPosPixel() ) );
986 pMouseOverHdl = PickHandle(aMDPos);
989 // notify last mouse over handle that he lost the mouse
990 const sal_uIntPtr nHdlCount = aHdl.GetHdlCount();
992 for(sal_uIntPtr nHdl = 0; nHdl < nHdlCount; nHdl++ )
994 SdrHdl* pCurrentHdl = GetHdl(nHdl);
995 if( pCurrentHdl->mbMouseOver )
997 if( pCurrentHdl != pMouseOverHdl )
999 pCurrentHdl->mbMouseOver = false;
1000 pCurrentHdl->onMouseLeave();
1002 break;
1006 // notify current mouse over handle
1007 if( pMouseOverHdl )
1009 pMouseOverHdl->mbMouseOver = true;
1010 pMouseOverHdl->onMouseEnter(rMEvt);
1013 return SdrSnapView::MouseMove(rMEvt, pWin);
1016 void SdrMarkView::ForceRefToMarked()
1018 switch(eDragMode)
1020 case SDRDRAG_ROTATE:
1022 Rectangle aR(GetMarkedObjRect());
1023 aRef1 = aR.Center();
1025 break;
1028 case SDRDRAG_MIRROR:
1030 // first calculate the length of the axis of reflection
1031 long nOutMin=0;
1032 long nOutMax=0;
1033 long nMinLen=0;
1034 long nObjDst=0;
1035 long nOutHgt=0;
1036 OutputDevice* pOut=GetFirstOutputDevice();
1037 if (pOut!=NULL) {
1038 // minimum length: 50 pixels
1039 nMinLen=pOut->PixelToLogic(Size(0,50)).Height();
1040 // 20 pixels distance to the Obj for the reference point
1041 nObjDst=pOut->PixelToLogic(Size(0,20)).Height();
1042 // MinY/MaxY
1043 // margin = minimum length = 10 pixels
1044 long nDst=pOut->PixelToLogic(Size(0,10)).Height();
1045 nOutMin=-pOut->GetMapMode().GetOrigin().Y();
1046 nOutMax=pOut->GetOutputSize().Height()-1+nOutMin;
1047 nOutMin+=nDst;
1048 nOutMax-=nDst;
1049 // absolute minimum length, however, is 10 pixels
1050 if (nOutMax-nOutMin<nDst) {
1051 nOutMin+=nOutMax+1;
1052 nOutMin/=2;
1053 nOutMin-=(nDst+1)/2;
1054 nOutMax=nOutMin+nDst;
1056 nOutHgt=nOutMax-nOutMin;
1057 // otherwise minimum length = 1/4 OutHgt
1058 long nTemp=nOutHgt/4;
1059 if (nTemp>nMinLen) nMinLen=nTemp;
1062 Rectangle aR(GetMarkedObjBoundRect());
1063 Point aCenter(aR.Center());
1064 long nMarkHgt=aR.GetHeight()-1;
1065 long nHgt=nMarkHgt+nObjDst*2; // 20 pixels overlapping above and below
1066 if (nHgt<nMinLen) nHgt=nMinLen; // minimum length 50 pixels or 1/4 OutHgt, respectively
1068 long nY1=aCenter.Y()-(nHgt+1)/2;
1069 long nY2=nY1+nHgt;
1071 if (pOut!=NULL && nMinLen>nOutHgt) nMinLen=nOutHgt; // TODO: maybe shorten this a little
1073 if (pOut!=NULL) { // now move completely into the visible area
1074 if (nY1<nOutMin) {
1075 nY1=nOutMin;
1076 if (nY2<nY1+nMinLen) nY2=nY1+nMinLen;
1078 if (nY2>nOutMax) {
1079 nY2=nOutMax;
1080 if (nY1>nY2-nMinLen) nY1=nY2-nMinLen;
1084 aRef1.X()=aCenter.X();
1085 aRef1.Y()=nY1;
1086 aRef2.X()=aCenter.X();
1087 aRef2.Y()=nY2;
1089 break;
1092 case SDRDRAG_TRANSPARENCE:
1093 case SDRDRAG_GRADIENT:
1094 case SDRDRAG_CROP:
1096 Rectangle aRect(GetMarkedObjBoundRect());
1097 aRef1 = aRect.TopLeft();
1098 aRef2 = aRect.BottomRight();
1099 break;
1101 default: break;
1105 void SdrMarkView::SetRef1(const Point& rPt)
1107 if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
1109 aRef1 = rPt;
1110 SdrHdl* pH = aHdl.GetHdl(HDL_REF1);
1111 if(pH)
1112 pH->SetPos(rPt);
1116 void SdrMarkView::SetRef2(const Point& rPt)
1118 if(eDragMode == SDRDRAG_MIRROR)
1120 aRef2 = rPt;
1121 SdrHdl* pH = aHdl.GetHdl(HDL_REF2);
1122 if(pH)
1123 pH->SetPos(rPt);
1127 void SdrMarkView::CheckMarked()
1129 for (sal_uIntPtr nm=GetMarkedObjectCount(); nm>0;) {
1130 nm--;
1131 SdrMark* pM=GetSdrMarkByIndex(nm);
1132 SdrObject* pObj=pM->GetMarkedSdrObj();
1133 SdrPageView* pPV=pM->GetPageView();
1134 SdrLayerID nLay=pObj->GetLayer();
1135 bool bRaus=!pObj->IsInserted(); // Obj deleted?
1136 if (!pObj->Is3DObj()) {
1137 bRaus=bRaus || pObj->GetPage()!=pPV->GetPage(); // Obj suddenly in different Page or Group
1139 bRaus=bRaus || pPV->GetLockedLayers().IsSet(nLay) || // Layer locked?
1140 !pPV->GetVisibleLayers().IsSet(nLay); // Layer invisible?
1142 if( !bRaus )
1143 bRaus = !pObj->IsVisible(); // invisible objects can not be selected
1145 if (!bRaus) {
1146 // Grouped objects can now be selected.
1147 // After EnterGroup the higher-level objects,
1148 // have to be deselected, though.
1149 const SdrObjList* pOOL=pObj->GetObjList();
1150 const SdrObjList* pVOL=pPV->GetObjList();
1151 while (pOOL!=NULL && pOOL!=pVOL) {
1152 pOOL=pOOL->GetUpList();
1154 bRaus=pOOL!=pVOL;
1157 if (bRaus)
1159 GetMarkedObjectListWriteAccess().DeleteMark(nm);
1161 else
1163 if (!IsGluePointEditMode()) { // selected glue points only in GlueEditMode
1164 SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1165 if (pPts!=NULL) {
1166 pPts->clear();
1172 // at least reset the remembered BoundRect to prevent handle
1173 // generation if bForceFrameHandles is TRUE.
1174 bMarkedObjRectDirty = sal_True;
1177 void SdrMarkView::SetMarkRects()
1179 SdrPageView* pPV = GetSdrPageView();
1181 if(pPV)
1183 pPV->SetHasMarkedObj(GetSnapRectFromMarkedObjects(pPV, pPV->MarkSnap()));
1184 GetBoundRectFromMarkedObjects(pPV, pPV->MarkBound());
1188 void SdrMarkView::SetFrameHandles(sal_Bool bOn)
1190 if (bOn!=bForceFrameHandles) {
1191 sal_Bool bOld=ImpIsFrameHandles();
1192 bForceFrameHandles=bOn;
1193 sal_Bool bNew=ImpIsFrameHandles();
1194 if (bNew!=bOld) {
1195 AdjustMarkHdl();
1196 MarkListHasChanged();
1201 void SdrMarkView::SetEditMode(SdrViewEditMode eMode)
1203 if (eMode!=eEditMode) {
1204 bool bGlue0=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1205 bool bEdge0=((SdrCreateView*)this)->IsEdgeTool();
1206 eEditMode0=eEditMode;
1207 eEditMode=eMode;
1208 bool bGlue1=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1209 bool bEdge1=((SdrCreateView*)this)->IsEdgeTool();
1210 // avoid flickering when switching between GlueEdit and EdgeTool
1211 if (bGlue1 && !bGlue0) ImpSetGlueVisible2(bGlue1);
1212 if (bEdge1!=bEdge0) ImpSetGlueVisible3(bEdge1);
1213 if (!bGlue1 && bGlue0) ImpSetGlueVisible2(bGlue1);
1214 if (bGlue0 && !bGlue1) UnmarkAllGluePoints();
1218 ////////////////////////////////////////////////////////////////////////////////////////////////////
1220 sal_Bool SdrMarkView::IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const
1222 if (pObj)
1224 if (pObj->IsMarkProtect() ||
1225 (!bDesignMode && pObj->IsUnoObj()))
1227 // object not selectable or
1228 // SdrUnoObj not in DesignMode
1229 return sal_False;
1232 return pPV!=NULL ? pPV->IsObjMarkable(pObj) : sal_True;
1235 sal_Bool SdrMarkView::IsMarkedObjHit(const Point& rPnt, short nTol) const
1237 sal_Bool bRet=sal_False;
1238 nTol=ImpGetHitTolLogic(nTol,NULL);
1239 Point aPt(rPnt);
1240 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount() && !bRet; nm++) {
1241 SdrMark* pM=GetSdrMarkByIndex(nm);
1242 bRet = 0 != CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0);
1244 return bRet;
1247 SdrHdl* SdrMarkView::PickHandle(const Point& rPnt, sal_uIntPtr nOptions, SdrHdl* pHdl0) const
1249 if (bSomeObjChgdFlag) { // recalculate handles, if necessary
1250 FlushComeBackTimer();
1252 sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1253 sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0;
1254 Point aPt(rPnt);
1255 return aHdl.IsHdlListHit(aPt,bBack,bNext,pHdl0);
1258 sal_Bool SdrMarkView::MarkObj(const Point& rPnt, short nTol, sal_Bool bToggle, sal_Bool bDeep)
1260 SdrObject* pObj;
1261 SdrPageView* pPV;
1262 nTol=ImpGetHitTolLogic(nTol,NULL);
1263 sal_uIntPtr nOptions=SDRSEARCH_PICKMARKABLE;
1264 if (bDeep) nOptions=nOptions|SDRSEARCH_DEEP;
1265 sal_Bool bRet=PickObj(rPnt,(sal_uInt16)nTol,pObj,pPV,nOptions);
1266 if (bRet) {
1267 sal_Bool bUnmark=bToggle && IsObjMarked(pObj);
1268 MarkObj(pObj,pPV,bUnmark);
1270 return bRet;
1273 sal_Bool SdrMarkView::MarkNextObj(sal_Bool bPrev)
1275 SdrPageView* pPageView = GetSdrPageView();
1277 if(!pPageView)
1279 return sal_False;
1282 SortMarkedObjects();
1283 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1284 sal_uIntPtr nChgMarkNum = ULONG_MAX; // number of the MarkEntry we want to replace
1285 sal_uIntPtr nSearchObjNum = bPrev ? 0 : ULONG_MAX;
1286 if (nMarkAnz!=0) {
1287 nChgMarkNum=bPrev ? 0 : sal_uIntPtr(nMarkAnz-1);
1288 SdrMark* pM=GetSdrMarkByIndex(nChgMarkNum);
1289 OSL_ASSERT(pM!=NULL);
1290 if (pM->GetMarkedSdrObj() != NULL)
1291 nSearchObjNum = pM->GetMarkedSdrObj()->GetNavigationPosition();
1294 SdrObject* pMarkObj=NULL;
1295 SdrObjList* pSearchObjList=pPageView->GetObjList();
1296 sal_uIntPtr nObjAnz=pSearchObjList->GetObjCount();
1297 if (nObjAnz!=0) {
1298 if (nSearchObjNum>nObjAnz) nSearchObjNum=nObjAnz;
1299 while (pMarkObj==NULL && ((!bPrev && nSearchObjNum>0) || (bPrev && nSearchObjNum<nObjAnz)))
1301 if (!bPrev)
1302 nSearchObjNum--;
1303 SdrObject* pSearchObj = pSearchObjList->GetObjectForNavigationPosition(nSearchObjNum);
1304 if (IsObjMarkable(pSearchObj,pPageView))
1306 if (TryToFindMarkedObject(pSearchObj)==CONTAINER_ENTRY_NOTFOUND)
1308 pMarkObj=pSearchObj;
1311 if (bPrev) nSearchObjNum++;
1315 if(!pMarkObj)
1317 return sal_False;
1320 if (nChgMarkNum!=ULONG_MAX)
1322 GetMarkedObjectListWriteAccess().DeleteMark(nChgMarkNum);
1324 MarkObj(pMarkObj,pPageView); // also calls MarkListHasChanged(), AdjustMarkHdl()
1325 return sal_True;
1328 sal_Bool SdrMarkView::MarkNextObj(const Point& rPnt, short nTol, sal_Bool bPrev)
1330 SortMarkedObjects();
1331 nTol=ImpGetHitTolLogic(nTol,NULL);
1332 Point aPt(rPnt);
1333 SdrMark* pTopMarkHit=NULL;
1334 SdrMark* pBtmMarkHit=NULL;
1335 sal_uIntPtr nTopMarkHit=0;
1336 sal_uIntPtr nBtmMarkHit=0;
1337 // find topmost of the selected objects that is hit by rPnt
1338 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1339 sal_uIntPtr nm=0;
1340 for (nm=nMarkAnz; nm>0 && pTopMarkHit==NULL;) {
1341 nm--;
1342 SdrMark* pM=GetSdrMarkByIndex(nm);
1343 if(CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0))
1345 pTopMarkHit=pM;
1346 nTopMarkHit=nm;
1349 // nothing found, in this case, just select an object
1350 if (pTopMarkHit==NULL) return MarkObj(rPnt,sal_uInt16(nTol),sal_False);
1352 SdrObject* pTopObjHit=pTopMarkHit->GetMarkedSdrObj();
1353 SdrObjList* pObjList=pTopObjHit->GetObjList();
1354 SdrPageView* pPV=pTopMarkHit->GetPageView();
1355 // find lowermost of the selected objects that is hit by rPnt
1356 // and is placed on the same PageView as pTopMarkHit
1357 for (nm=0; nm<nMarkAnz && pBtmMarkHit==NULL; nm++) {
1358 SdrMark* pM=GetSdrMarkByIndex(nm);
1359 SdrPageView* pPV2=pM->GetPageView();
1360 if (pPV2==pPV && CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pPV2,0,0))
1362 pBtmMarkHit=pM;
1363 nBtmMarkHit=nm;
1366 if (pBtmMarkHit==NULL) { pBtmMarkHit=pTopMarkHit; nBtmMarkHit=nTopMarkHit; }
1367 SdrObject* pBtmObjHit=pBtmMarkHit->GetMarkedSdrObj();
1368 sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1370 sal_uInt32 nSearchBeg;
1371 E3dScene* pScene = NULL;
1372 SdrObject* pObjHit = (bPrev) ? pBtmObjHit : pTopObjHit;
1373 bool bRemap = pObjHit->ISA(E3dCompoundObject)
1374 ? ((E3dCompoundObject*)pObjHit)->IsAOrdNumRemapCandidate(pScene)
1375 : false;
1377 if(bPrev)
1379 sal_uInt32 nOrdNumBtm(pBtmObjHit->GetOrdNum());
1381 if(bRemap)
1383 nOrdNumBtm = pScene->RemapOrdNum(nOrdNumBtm);
1386 nSearchBeg = nOrdNumBtm + 1;
1388 else
1390 sal_uInt32 nOrdNumTop(pTopObjHit->GetOrdNum());
1392 if(bRemap)
1394 nOrdNumTop = pScene->RemapOrdNum(nOrdNumTop);
1397 nSearchBeg = nOrdNumTop;
1400 sal_uIntPtr no=nSearchBeg;
1401 SdrObject* pFndObj=NULL;
1402 while (pFndObj==NULL && ((!bPrev && no>0) || (bPrev && no<nObjAnz))) {
1403 if (!bPrev) no--;
1404 SdrObject* pObj;
1406 if(bRemap)
1408 pObj = pObjList->GetObj(pScene->RemapOrdNum(no));
1410 else
1412 pObj = pObjList->GetObj(no);
1415 if (CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_TESTMARKABLE,0))
1417 if (TryToFindMarkedObject(pObj)==CONTAINER_ENTRY_NOTFOUND) {
1418 pFndObj=pObj;
1419 } else {
1420 // TODO: for performance reasons set on to Top or Btm, if necessary
1423 if (bPrev) no++;
1425 if (pFndObj!=NULL)
1427 GetMarkedObjectListWriteAccess().DeleteMark(bPrev?nBtmMarkHit:nTopMarkHit);
1428 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pFndObj,pPV));
1429 MarkListHasChanged();
1430 AdjustMarkHdl();
1432 return pFndObj!=NULL;
1435 sal_Bool SdrMarkView::MarkObj(const Rectangle& rRect, sal_Bool bUnmark)
1437 sal_Bool bFnd=sal_False;
1438 Rectangle aR(rRect);
1439 SdrObjList* pObjList;
1440 BrkAction();
1441 SdrPageView* pPV = GetSdrPageView();
1443 if(pPV)
1445 pObjList=pPV->GetObjList();
1446 Rectangle aFrm1(aR);
1447 sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1448 SdrObject* pObj;
1449 for (sal_uIntPtr nO=0; nO<nObjAnz; nO++) {
1450 pObj=pObjList->GetObj(nO);
1451 Rectangle aRect(pObj->GetCurrentBoundRect());
1452 if (aFrm1.IsInside(aRect)) {
1453 if (!bUnmark) {
1454 if (IsObjMarkable(pObj,pPV))
1456 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1457 bFnd=sal_True;
1459 } else {
1460 sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1461 if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1463 GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1464 bFnd=sal_True;
1470 if (bFnd) {
1471 SortMarkedObjects();
1472 MarkListHasChanged();
1473 AdjustMarkHdl();
1475 return bFnd;
1478 void SdrMarkView::MarkObj(SdrObject* pObj, SdrPageView* pPV, sal_Bool bUnmark, sal_Bool bImpNoSetMarkHdl)
1480 if (pObj!=NULL && pPV!=NULL && IsObjMarkable(pObj, pPV)) {
1481 BrkAction();
1482 if (!bUnmark)
1484 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1486 else
1488 sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1489 if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1491 GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1494 if (!bImpNoSetMarkHdl) {
1495 MarkListHasChanged();
1496 AdjustMarkHdl();
1501 sal_Bool SdrMarkView::IsObjMarked(SdrObject* pObj) const
1503 // Hack: Because FindObject() is not const,
1504 // I have to cast myself to non-const.
1505 sal_uIntPtr nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj);
1506 return nPos!=CONTAINER_ENTRY_NOTFOUND;
1509 sal_uInt16 SdrMarkView::GetMarkHdlSizePixel() const
1511 return aHdl.GetHdlSize()*2+1;
1514 void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz)
1516 if (nSiz<3) nSiz=3;
1517 nSiz/=2;
1518 if (nSiz!=aHdl.GetHdlSize()) {
1519 aHdl.SetHdlSize(nSiz);
1523 #define SDRSEARCH_IMPISMASTER 0x80000000 /* MasterPage is being searched right now */
1524 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay) const
1526 if(((nOptions & SDRSEARCH_IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible()))
1528 return NULL;
1531 const bool bCheckIfMarkable(nOptions & SDRSEARCH_TESTMARKABLE);
1532 const bool bDeep(nOptions & SDRSEARCH_DEEP);
1533 const bool bOLE(pObj->ISA(SdrOle2Obj));
1534 const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame());
1535 SdrObject* pRet=NULL;
1536 Rectangle aRect(pObj->GetCurrentBoundRect());
1537 // hack for calc grid sync
1538 aRect += pObj->GetGridOffset();
1539 sal_uInt16 nTol2(nTol);
1541 // double tolerance for OLE, text frames and objects in
1542 // active text edit
1543 if(bOLE || bTXT || pObj==((SdrObjEditView*)this)->GetTextEditObject())
1545 nTol2*=2;
1548 aRect.Left ()-=nTol2; // add 1 tolerance for all objects
1549 aRect.Top ()-=nTol2;
1550 aRect.Right ()+=nTol2;
1551 aRect.Bottom()+=nTol2;
1553 if (aRect.IsInside(rPnt))
1555 if ((!bCheckIfMarkable || IsObjMarkable(pObj,pPV)))
1557 SdrObjList* pOL=pObj->GetSubList();
1559 if (pOL!=NULL && pOL->GetObjCount()!=0)
1561 SdrObject* pTmpObj;
1562 // adjustment hit point for virtual objects
1563 Point aPnt( rPnt );
1565 if ( pObj->ISA(SdrVirtObj) )
1567 Point aOffset = static_cast<SdrVirtObj*>(pObj)->GetOffset();
1568 aPnt.Move( -aOffset.X(), -aOffset.Y() );
1571 pRet=CheckSingleSdrObjectHit(aPnt,nTol,pOL,pPV,nOptions,pMVisLay,pTmpObj);
1573 else
1575 if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer()))
1577 pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false);
1583 if (!bDeep && pRet!=NULL)
1585 pRet=pObj;
1588 return pRet;
1591 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList* pOL, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj) const
1593 return (*this).CheckSingleSdrObjectHit(rPnt,nTol,pOL,pPV,nOptions,pMVisLay,rpRootObj,NULL);
1595 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList* pOL, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj,const SdrMarkList * pMarkList) const
1597 bool bBack=(nOptions & SDRSEARCH_BACKWARD)!=0;
1598 bool bBefMrk=(nOptions & SDRSEARCH_BEFOREMARK)!=0;
1599 SdrObject* pRet=NULL;
1600 rpRootObj=NULL;
1601 if (pOL!=NULL)
1603 bool bRemap(pOL->GetOwnerObj() && pOL->GetOwnerObj()->ISA(E3dScene));
1604 E3dScene* pRemapScene = (bRemap ? (E3dScene*)pOL->GetOwnerObj() : 0L);
1606 sal_uIntPtr nObjAnz=pOL->GetObjCount();
1607 sal_uIntPtr nObjNum=bBack ? 0 : nObjAnz;
1608 while (pRet==NULL && (bBack ? nObjNum<nObjAnz : nObjNum>0)) {
1609 if (!bBack) nObjNum--;
1610 SdrObject* pObj;
1612 if(bRemap)
1614 pObj = pOL->GetObj(pRemapScene->RemapOrdNum(nObjNum));
1616 else
1618 pObj = pOL->GetObj(nObjNum);
1620 if (bBefMrk)
1622 if ((pMarkList)!=NULL)
1624 if ((*pMarkList).FindObject(pObj)!=CONTAINER_ENTRY_NOTFOUND)
1626 return NULL;
1630 pRet=CheckSingleSdrObjectHit(rPnt,nTol,pObj,pPV,nOptions,pMVisLay);
1631 if (pRet!=NULL) rpRootObj=pObj;
1632 if (bBack) nObjNum++;
1635 return pRet;
1638 sal_Bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions) const
1640 return PickObj(rPnt,nTol,rpObj,rpPV,nOptions,NULL,NULL,NULL);
1643 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
1644 { // TODO: lacks a Pass2,Pass3
1645 SortMarkedObjects();
1646 if (ppRootObj!=NULL) *ppRootObj=NULL;
1647 if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1648 if (pnPassNum!=NULL) *pnPassNum=0;
1649 rpObj=NULL;
1650 rpPV=NULL;
1651 bool bWholePage=(nOptions & SDRSEARCH_WHOLEPAGE) !=0;
1652 bool bMarked=(nOptions & SDRSEARCH_MARKED) !=0;
1653 bool bMasters=!bMarked && (nOptions & SDRSEARCH_ALSOONMASTER) !=0;
1654 bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1655 #if OSL_DEBUG_LEVEL > 0
1656 bool bNext=(nOptions & SDRSEARCH_NEXT) !=0; (void)bNext; // n.i.
1657 bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; (void)bBoundCheckOn2ndPass;// n.i.
1658 bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; (void)bCheckNearestOn3rdPass;// n.i.
1659 #endif
1660 if (nTol<0) nTol=ImpGetHitTolLogic(nTol,NULL);
1661 Point aPt(rPnt);
1662 SdrObject* pObj=NULL;
1663 SdrObject* pHitObj=NULL;
1664 SdrPageView* pPV=NULL;
1665 if (!bBack && ((SdrObjEditView*)this)->IsTextEditFrameHit(rPnt)) {
1666 pObj=((SdrObjEditView*)this)->GetTextEditObject();
1667 pHitObj=pObj;
1668 pPV=((SdrObjEditView*)this)->GetTextEditPageView();
1670 if (bMarked) {
1671 sal_uIntPtr nMrkAnz=GetMarkedObjectCount();
1672 sal_uIntPtr nMrkNum=bBack ? 0 : nMrkAnz;
1673 while (pHitObj==NULL && (bBack ? nMrkNum<nMrkAnz : nMrkNum>0)) {
1674 if (!bBack) nMrkNum--;
1675 SdrMark* pM=GetSdrMarkByIndex(nMrkNum);
1676 pObj=pM->GetMarkedSdrObj();
1677 pPV=pM->GetPageView();
1678 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,nOptions,NULL);
1679 if (bBack) nMrkNum++;
1682 else
1684 pPV = GetSdrPageView();
1686 if(pPV)
1688 SdrPage* pPage=pPV->GetPage();
1689 sal_uInt16 nPgAnz=1;
1691 if(bMasters && pPage->TRG_HasMasterPage())
1693 nPgAnz++;
1696 bool bExtraPassForWholePage=bWholePage && pPage!=pPV->GetObjList();
1697 if (bExtraPassForWholePage) nPgAnz++; // First search in AktObjList, then on the entire page
1698 sal_uInt16 nPgNum=bBack ? 0 : nPgAnz;
1699 while (pHitObj==NULL && (bBack ? nPgNum<nPgAnz : nPgNum>0)) {
1700 sal_uIntPtr nTmpOptions=nOptions;
1701 if (!bBack) nPgNum--;
1702 const SetOfByte* pMVisLay=NULL;
1703 SdrObjList* pObjList=NULL;
1704 if (pnPassNum!=NULL) *pnPassNum&=~(SDRSEARCHPASS_MASTERPAGE|SDRSEARCHPASS_INACTIVELIST);
1705 if (nPgNum>=nPgAnz-1 || (bExtraPassForWholePage && nPgNum>=nPgAnz-2))
1707 pObjList=pPV->GetObjList();
1708 if (bExtraPassForWholePage && nPgNum==nPgAnz-2) {
1709 pObjList=pPage;
1710 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_INACTIVELIST;
1713 else
1715 // otherwise MasterPage
1716 SdrPage& rMasterPage = pPage->TRG_GetMasterPage();
1717 pMVisLay = &pPage->TRG_GetMasterPageVisibleLayers();
1718 pObjList = &rMasterPage;
1720 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_MASTERPAGE;
1721 nTmpOptions=nTmpOptions | SDRSEARCH_IMPISMASTER;
1723 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObjList,pPV,nTmpOptions,pMVisLay,pObj,&(GetMarkedObjectList()));
1724 if (bBack) nPgNum++;
1728 if (pHitObj!=NULL) {
1729 if (ppRootObj!=NULL) *ppRootObj=pObj;
1730 if ((nOptions & SDRSEARCH_DEEP) !=0) pObj=pHitObj;
1731 if ((nOptions & SDRSEARCH_TESTTEXTEDIT) !=0) {
1732 if (!pObj->HasTextEdit() || pPV->GetLockedLayers().IsSet(pObj->GetLayer())) {
1733 pObj=NULL;
1736 if (pObj!=NULL && (nOptions & SDRSEARCH_TESTMACRO) !=0) {
1737 SdrObjMacroHitRec aHitRec;
1738 aHitRec.aPos=aPt;
1739 aHitRec.aDownPos=aPt;
1740 aHitRec.nTol=nTol;
1741 aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
1742 aHitRec.pPageView=pPV;
1743 if (!pObj->HasMacro() || !pObj->IsMacroHit(aHitRec)) pObj=NULL;
1745 if (pObj!=NULL && (nOptions & SDRSEARCH_WITHTEXT) !=0 && pObj->GetOutlinerParaObject()==NULL) pObj=NULL;
1746 if (pObj!=NULL && (nOptions & SDRSEARCH_TESTTEXTAREA) !=0)
1748 if(!SdrObjectPrimitiveHit(*pObj, aPt, 0, *pPV, 0, true))
1750 pObj = 0;
1753 if (pObj!=NULL) {
1754 rpObj=pObj;
1755 rpPV=pPV;
1756 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_DIRECT;
1759 return rpObj!=NULL;
1762 sal_Bool SdrMarkView::PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr* pnMarkNum, sal_uIntPtr nOptions) const
1764 SortMarkedObjects();
1765 bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0;
1766 bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0;
1767 rpObj=NULL;
1768 rpPV=NULL;
1769 if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1770 Point aPt(rPnt);
1771 sal_uInt16 nTol=(sal_uInt16)nHitTolLog;
1772 sal_Bool bFnd=sal_False;
1773 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1774 sal_uIntPtr nMarkNum;
1775 for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1776 nMarkNum--;
1777 SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1778 SdrPageView* pPV=pM->GetPageView();
1779 SdrObject* pObj=pM->GetMarkedSdrObj();
1780 bFnd = 0 != CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,SDRSEARCH_TESTMARKABLE,0);
1781 if (bFnd) {
1782 rpObj=pObj;
1783 rpPV=pPV;
1784 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1787 if ((bBoundCheckOn2ndPass || bCheckNearestOn3rdPass) && !bFnd) {
1788 SdrObject* pBestObj=NULL;
1789 SdrPageView* pBestPV=NULL;
1790 sal_uIntPtr nBestMarkNum=0;
1791 sal_uIntPtr nBestDist=ULONG_MAX;
1792 for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1793 nMarkNum--;
1794 SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1795 SdrPageView* pPV=pM->GetPageView();
1796 SdrObject* pObj=pM->GetMarkedSdrObj();
1797 Rectangle aRect(pObj->GetCurrentBoundRect());
1798 aRect.Left ()-=nTol;
1799 aRect.Top ()-=nTol;
1800 aRect.Right ()+=nTol;
1801 aRect.Bottom()+=nTol;
1802 if (aRect.IsInside(aPt)) {
1803 bFnd=sal_True;
1804 rpObj=pObj;
1805 rpPV=pPV;
1806 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1807 } else if (bCheckNearestOn3rdPass) {
1808 sal_uIntPtr nDist=0;
1809 if (aPt.X()<aRect.Left()) nDist+=aRect.Left()-aPt.X();
1810 if (aPt.X()>aRect.Right()) nDist+=aPt.X()-aRect.Right();
1811 if (aPt.Y()<aRect.Top()) nDist+=aRect.Top()-aPt.Y();
1812 if (aPt.Y()>aRect.Bottom()) nDist+=aPt.Y()-aRect.Bottom();
1813 if (nDist<nBestDist) {
1814 pBestObj=pObj;
1815 pBestPV=pPV;
1816 nBestMarkNum=nMarkNum;
1820 if (bCheckNearestOn3rdPass && !bFnd) {
1821 rpObj=pBestObj;
1822 rpPV=pBestPV;
1823 if (pnMarkNum!=NULL) *pnMarkNum=nBestMarkNum;
1824 bFnd=pBestObj!=NULL;
1827 return bFnd;
1831 void SdrMarkView::UnmarkAllObj(SdrPageView* pPV)
1833 if (GetMarkedObjectCount()!=0) {
1834 BrkAction();
1835 if (pPV!=NULL)
1837 GetMarkedObjectListWriteAccess().DeletePageView(*pPV);
1839 else
1841 GetMarkedObjectListWriteAccess().Clear();
1843 pMarkedObj=NULL;
1844 pMarkedPV=NULL;
1845 MarkListHasChanged();
1846 AdjustMarkHdl();
1850 void SdrMarkView::MarkAllObj(SdrPageView* _pPV)
1852 BrkAction();
1854 if(!_pPV)
1856 _pPV = GetSdrPageView();
1859 // #i69171# _pPV may still be NULL if there is no SDrPageView (!), e.g. when inserting
1860 // other files
1861 if(_pPV)
1863 const bool bMarkChg(GetMarkedObjectListWriteAccess().InsertPageView(*_pPV));
1865 if(bMarkChg)
1867 MarkListHasChanged();
1871 if(GetMarkedObjectCount())
1873 AdjustMarkHdl();
1877 void SdrMarkView::AdjustMarkHdl()
1879 CheckMarked();
1880 SetMarkRects();
1881 SetMarkHandles();
1884 Rectangle SdrMarkView::GetMarkedObjBoundRect() const
1886 Rectangle aRect;
1887 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
1888 SdrMark* pM=GetSdrMarkByIndex(nm);
1889 SdrObject* pO=pM->GetMarkedSdrObj();
1890 Rectangle aR1(pO->GetCurrentBoundRect());
1891 // Ensure marked area includes the calc offset
1892 // ( if applicable ) to sync to grid
1893 aR1 += pO->GetGridOffset();
1894 if (aRect.IsEmpty()) aRect=aR1;
1895 else aRect.Union(aR1);
1897 return aRect;
1900 Point SdrMarkView::GetGridOffset() const
1902 Point aOffset;
1903 // calculate the area occupied by the union of each marked object
1904 // ( synced to grid ) and compare to the same unsynced area to calculate
1905 // the offset. Hopefully that's the sensible thing to do
1906 const Rectangle& aGroupSyncedRect = GetMarkedObjRect();
1907 aOffset = aGroupSyncedRect.TopLeft() - aMarkedObjRectNoOffset.TopLeft();
1908 return aOffset;
1911 const Rectangle& SdrMarkView::GetMarkedObjRect() const
1913 if (bMarkedObjRectDirty) {
1914 ((SdrMarkView*)this)->bMarkedObjRectDirty=sal_False;
1915 Rectangle aRect;
1916 Rectangle aRect2;
1917 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
1918 SdrMark* pM=GetSdrMarkByIndex(nm);
1919 SdrObject* pO=pM->GetMarkedSdrObj();
1920 Rectangle aR1(pO->GetSnapRect());
1921 // apply calc offset to marked object rect
1922 // ( necessary for handles to be displayed in
1923 // correct position )
1924 if (aRect2.IsEmpty()) aRect2=aR1;
1925 else aRect2.Union( aR1 );
1926 aR1 += pO->GetGridOffset();
1927 if (aRect.IsEmpty()) aRect=aR1;
1928 else aRect.Union(aR1);
1930 ((SdrMarkView*)this)->aMarkedObjRect=aRect;
1931 ((SdrMarkView*)this)->aMarkedObjRectNoOffset=aRect2;
1933 return aMarkedObjRect;
1936 ////////////////////////////////////////////////////////////////////////////////////////////////////
1938 void SdrMarkView::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal, sal_uInt16 nOpt) const
1940 rStr = ImpGetResStr(nStrCacheID);
1941 xub_StrLen nPos = rStr.SearchAscii("%1");
1943 if(nPos != STRING_NOTFOUND)
1945 rStr.Erase(nPos, 2);
1947 if(nOpt == IMPSDR_POINTSDESCRIPTION)
1949 rStr.Insert(GetDescriptionOfMarkedPoints(), nPos);
1951 else if(nOpt == IMPSDR_GLUEPOINTSDESCRIPTION)
1953 rStr.Insert(GetDescriptionOfMarkedGluePoints(), nPos);
1955 else
1957 rStr.Insert(GetDescriptionOfMarkedObjects(), nPos);
1961 nPos = rStr.SearchAscii("%2");
1963 if(nPos != STRING_NOTFOUND)
1965 rStr.Erase(nPos, 2);
1966 rStr.Insert(OUString::number( nVal ), nPos);
1970 ////////////////////////////////////////////////////////////////////////////////////////////////////
1972 sal_Bool SdrMarkView::EnterMarkedGroup()
1974 sal_Bool bRet=sal_False;
1975 // We enter only the first group found (in only one PageView), because
1976 // PageView::EnterGroup calls an AdjustMarkHdl.
1977 // TODO: I'll have to prevent that via a flag.
1978 SdrPageView* pPV = GetSdrPageView();
1980 if(pPV)
1982 bool bEnter=false;
1983 for (sal_uInt32 nm(GetMarkedObjectCount()); nm > 0 && !bEnter;)
1985 nm--;
1986 SdrMark* pM=GetSdrMarkByIndex(nm);
1987 if (pM->GetPageView()==pPV) {
1988 SdrObject* pObj=pM->GetMarkedSdrObj();
1989 if (pObj->IsGroupObject()) {
1990 if (pPV->EnterGroup(pObj)) {
1991 bRet=sal_True;
1992 bEnter=true;
1998 return bRet;
2001 ////////////////////////////////////////////////////////////////////////////////////////////////////
2003 void SdrMarkView::MarkListHasChanged()
2005 GetMarkedObjectListWriteAccess().SetNameDirty();
2006 SetEdgesOfMarkedNodesDirty();
2008 bMarkedObjRectDirty=sal_True;
2009 bMarkedPointsRectsDirty=sal_True;
2010 #ifdef DBG_UTIL
2011 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
2012 #endif
2013 sal_Bool bOneEdgeMarked=sal_False;
2014 if (GetMarkedObjectCount()==1) {
2015 const SdrObject* pObj=GetMarkedObjectByIndex(0);
2016 if (pObj->GetObjInventor()==SdrInventor) {
2017 sal_uInt16 nIdent=pObj->GetObjIdentifier();
2018 bOneEdgeMarked=nIdent==OBJ_EDGE;
2021 ImpSetGlueVisible4(bOneEdgeMarked);
2024 ////////////////////////////////////////////////////////////////////////////////////////////////////
2026 void SdrMarkView::SetMoveOutside(sal_Bool bOn)
2028 aHdl.SetMoveOutside(bOn);
2031 void SdrMarkView::SetDesignMode( sal_Bool _bOn )
2033 if ( bDesignMode != _bOn )
2035 bDesignMode = _bOn;
2036 SdrPageView* pPageView = GetSdrPageView();
2037 if ( pPageView )
2038 pPageView->SetDesignMode( _bOn );
2042 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */