Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / svdraw / svdmrkv.cxx
blob230cceb516bf9b3f0b8a237b08b51adb7c69ebb7
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 "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 <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>
51 #include <svx/svdograf.hxx>
53 #include <editeng/editdata.hxx>
56 // Migrate Marking of Objects, Points and GluePoints
58 class ImplMarkingOverlay
60 // The OverlayObjects
61 ::sdr::overlay::OverlayObjectList maObjects;
63 // The remembered second position in logical coordinates
64 basegfx::B2DPoint maSecondPosition;
66 // bitfield
67 // A flag to remember if the action is for unmarking.
68 bool mbUnmarking : 1;
70 public:
71 ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, bool bUnmarking = false);
72 ~ImplMarkingOverlay();
74 void SetSecondPosition(const basegfx::B2DPoint& rNewPosition);
75 bool IsUnmarking() const { return mbUnmarking; }
78 ImplMarkingOverlay::ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, bool bUnmarking)
79 : maSecondPosition(rStartPos),
80 mbUnmarking(bUnmarking)
82 for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
84 SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
85 rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
87 if (xTargetOverlay.is())
89 ::sdr::overlay::OverlayRollingRectangleStriped* pNew = new ::sdr::overlay::OverlayRollingRectangleStriped(
90 rStartPos, rStartPos, false);
91 xTargetOverlay->add(*pNew);
92 maObjects.append(*pNew);
97 ImplMarkingOverlay::~ImplMarkingOverlay()
99 // The OverlayObjects are cleared using the destructor of OverlayObjectList.
100 // That destructor calls clear() at the list which removes all objects from the
101 // OverlayManager and deletes them.
104 void ImplMarkingOverlay::SetSecondPosition(const basegfx::B2DPoint& rNewPosition)
106 if(rNewPosition != maSecondPosition)
108 // apply to OverlayObjects
109 for(sal_uInt32 a(0L); a < maObjects.count(); a++)
111 ::sdr::overlay::OverlayRollingRectangleStriped& rCandidate = (::sdr::overlay::OverlayRollingRectangleStriped&)maObjects.getOverlayObject(a);
112 rCandidate.setSecondPosition(rNewPosition);
115 // remember new position
116 maSecondPosition = rNewPosition;
122 // MarkView
126 void SdrMarkView::ImpClearVars()
128 eDragMode=SDRDRAG_MOVE;
129 bRefHdlShownOnly=false;
130 eEditMode=SDREDITMODE_EDIT;
131 eEditMode0=SDREDITMODE_EDIT;
132 bDesignMode=false;
133 pMarkedObj=NULL;
134 pMarkedPV=NULL;
135 bForceFrameHandles=false;
136 bPlusHdlAlways=false;
137 nFrameHandlesLimit=50;
138 bInsPolyPoint=false;
139 mnInsPointNum = 0L;
140 bMarkedObjRectDirty=false;
141 bMarkedPointsRectsDirty=false;
142 mbMarkHandlesHidden = false;
143 bMrkPntDirty=false;
144 bMarkHdlWhenTextEdit=false;
145 bMarkableObjCountDirty=false; // not yet implemented
146 nMarkableObjCount=0; // not yet implemented
148 // Migrate selections
149 BrkMarkObj();
150 BrkMarkPoints();
151 BrkMarkGluePoints();
154 SdrMarkView::SdrMarkView(SdrModel* pModel1, OutputDevice* pOut)
155 : SdrSnapView(pModel1,pOut),
156 mpMarkObjOverlay(0L),
157 mpMarkPointsOverlay(0L),
158 mpMarkGluePointsOverlay(0L),
159 aHdl(this),
160 mpSdrViewSelection(new sdr::ViewSelection())
162 ImpClearVars();
163 StartListening(*pModel1);
166 SdrMarkView::~SdrMarkView()
168 // Migrate selections
169 BrkMarkObj();
170 BrkMarkPoints();
171 BrkMarkGluePoints();
172 delete mpSdrViewSelection;
175 void SdrMarkView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
177 SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
178 if (pSdrHint!=NULL)
180 SdrHintKind eKind=pSdrHint->GetKind();
182 if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED)
184 bMarkedObjRectDirty=true;
185 bMarkedPointsRectsDirty=true;
188 SdrSnapView::Notify(rBC,rHint);
191 void SdrMarkView::ModelHasChanged()
193 SdrPaintView::ModelHasChanged();
194 GetMarkedObjectListWriteAccess().SetNameDirty();
195 bMarkedObjRectDirty=true;
196 bMarkedPointsRectsDirty=true;
197 // Example: Obj is selected and maMarkedObjectList is sorted.
198 // In another View 2, the ObjOrder is changed (e. g. MovToTop())
199 // Then we need to re-sort MarkList.
200 GetMarkedObjectListWriteAccess().SetUnsorted();
201 SortMarkedObjects();
202 bMrkPntDirty=true;
203 UndirtyMrkPnt();
204 SdrView* pV=(SdrView*)this;
205 if (pV!=NULL && !pV->IsDragObj() && !pV->IsInsObjPoint()) {
206 AdjustMarkHdl();
212 bool SdrMarkView::IsAction() const
214 return SdrSnapView::IsAction() || IsMarkObj() || IsMarkPoints() || IsMarkGluePoints();
217 void SdrMarkView::MovAction(const Point& rPnt)
219 SdrSnapView::MovAction(rPnt);
221 if(IsMarkObj())
223 MovMarkObj(rPnt);
225 else if(IsMarkPoints())
227 MovMarkPoints(rPnt);
229 else if(IsMarkGluePoints())
231 MovMarkGluePoints(rPnt);
235 void SdrMarkView::EndAction()
237 if(IsMarkObj())
239 EndMarkObj();
241 else if(IsMarkPoints())
243 EndMarkPoints();
245 else if(IsMarkGluePoints())
247 EndMarkGluePoints();
250 SdrSnapView::EndAction();
253 void SdrMarkView::BckAction()
255 SdrSnapView::BckAction();
256 BrkMarkObj();
257 BrkMarkPoints();
258 BrkMarkGluePoints();
261 void SdrMarkView::BrkAction()
263 SdrSnapView::BrkAction();
264 BrkMarkObj();
265 BrkMarkPoints();
266 BrkMarkGluePoints();
269 void SdrMarkView::TakeActionRect(Rectangle& rRect) const
271 if(IsMarkObj() || IsMarkPoints() || IsMarkGluePoints())
273 rRect = Rectangle(aDragStat.GetStart(), aDragStat.GetNow());
275 else
277 SdrSnapView::TakeActionRect(rRect);
283 void SdrMarkView::ClearPageView()
285 UnmarkAllObj();
286 SdrSnapView::ClearPageView();
289 void SdrMarkView::HideSdrPage()
291 bool bMrkChg(false);
293 SdrPageView* pPageView = GetSdrPageView();
294 if (pPageView)
296 // break all creation actions when hiding page (#75081#)
297 BrkAction();
299 // Discard all selections on this page
300 bMrkChg = GetMarkedObjectListWriteAccess().DeletePageView(*pPageView);
303 SdrSnapView::HideSdrPage();
305 if(bMrkChg)
307 MarkListHasChanged();
308 AdjustMarkHdl();
314 bool SdrMarkView::BegMarkObj(const Point& rPnt, bool bUnmark)
316 BrkAction();
318 DBG_ASSERT(0L == mpMarkObjOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkObjOverlay (!)");
319 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
320 mpMarkObjOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
322 aDragStat.Reset(rPnt);
323 aDragStat.NextPoint();
324 aDragStat.SetMinMove(nMinMovLog);
326 return true;
329 void SdrMarkView::MovMarkObj(const Point& rPnt)
331 if(IsMarkObj() && aDragStat.CheckMinMoved(rPnt))
333 aDragStat.NextMove(rPnt);
334 DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
335 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
336 mpMarkObjOverlay->SetSecondPosition(aNewPos);
340 bool SdrMarkView::EndMarkObj()
342 bool bRetval(false);
344 if(IsMarkObj())
346 if(aDragStat.IsMinMoved())
348 Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
349 aRect.Justify();
350 MarkObj(aRect, mpMarkObjOverlay->IsUnmarking());
351 bRetval = true;
354 // cleanup
355 BrkMarkObj();
358 return bRetval;
361 void SdrMarkView::BrkMarkObj()
363 if(IsMarkObj())
365 DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
366 delete mpMarkObjOverlay;
367 mpMarkObjOverlay = 0L;
373 bool SdrMarkView::BegMarkPoints(const Point& rPnt, bool bUnmark)
375 if(HasMarkablePoints())
377 BrkAction();
379 DBG_ASSERT(0L == mpMarkPointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkPointsOverlay (!)");
380 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
381 mpMarkPointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
383 aDragStat.Reset(rPnt);
384 aDragStat.NextPoint();
385 aDragStat.SetMinMove(nMinMovLog);
387 return true;
390 return false;
393 void SdrMarkView::MovMarkPoints(const Point& rPnt)
395 if(IsMarkPoints() && aDragStat.CheckMinMoved(rPnt))
397 aDragStat.NextMove(rPnt);
399 DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
400 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
401 mpMarkPointsOverlay->SetSecondPosition(aNewPos);
405 bool SdrMarkView::EndMarkPoints()
407 bool bRetval(false);
409 if(IsMarkPoints())
411 if(aDragStat.IsMinMoved())
413 Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
414 aRect.Justify();
415 MarkPoints(aRect, mpMarkPointsOverlay->IsUnmarking());
417 bRetval = true;
420 // cleanup
421 BrkMarkPoints();
424 return bRetval;
427 void SdrMarkView::BrkMarkPoints()
429 if(IsMarkPoints())
431 DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
432 delete mpMarkPointsOverlay;
433 mpMarkPointsOverlay = 0L;
439 bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, bool bUnmark)
441 if(HasMarkableGluePoints())
443 BrkAction();
445 DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)");
447 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
448 mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
449 aDragStat.Reset(rPnt);
450 aDragStat.NextPoint();
451 aDragStat.SetMinMove(nMinMovLog);
453 return true;
456 return false;
459 void SdrMarkView::MovMarkGluePoints(const Point& rPnt)
461 if(IsMarkGluePoints() && aDragStat.CheckMinMoved(rPnt))
463 aDragStat.NextMove(rPnt);
465 DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
466 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
467 mpMarkGluePointsOverlay->SetSecondPosition(aNewPos);
471 bool SdrMarkView::EndMarkGluePoints()
473 bool bRetval(false);
475 if(IsMarkGluePoints())
477 if(aDragStat.IsMinMoved())
479 Rectangle aRect(aDragStat.GetStart(),aDragStat.GetNow());
480 aRect.Justify();
481 MarkGluePoints(&aRect, mpMarkGluePointsOverlay->IsUnmarking());
483 bRetval = true;
486 // cleanup
487 BrkMarkGluePoints();
490 return bRetval;
493 void SdrMarkView::BrkMarkGluePoints()
495 if(IsMarkGluePoints())
497 DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
498 delete mpMarkGluePointsOverlay;
499 mpMarkGluePointsOverlay = 0L;
503 sal_uIntPtr SdrMarkView::GetMarkableObjCount() const
505 sal_uIntPtr nCount=0;
506 SdrPageView* pPV = GetSdrPageView();
508 if(pPV)
510 SdrObjList* pOL=pPV->GetObjList();
511 sal_uIntPtr nObjAnz=pOL->GetObjCount();
512 for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
513 SdrObject* pObj=pOL->GetObj(nObjNum);
514 if (IsObjMarkable(pObj,pPV)) {
515 nCount++;
519 return nCount;
522 bool SdrMarkView::HasMarkableObj() const
524 sal_uIntPtr nCount=0;
526 SdrPageView* pPV = GetSdrPageView();
527 if(pPV)
529 SdrObjList* pOL=pPV->GetObjList();
530 sal_uIntPtr nObjAnz=pOL->GetObjCount();
531 for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz && nCount==0; nObjNum++) {
532 SdrObject* pObj=pOL->GetObj(nObjNum);
533 if (IsObjMarkable(pObj,pPV)) {
534 nCount++;
538 return nCount!=0;
541 void SdrMarkView::hideMarkHandles()
543 if(!mbMarkHandlesHidden)
545 mbMarkHandlesHidden = true;
546 AdjustMarkHdl();
550 void SdrMarkView::showMarkHandles()
552 if(mbMarkHandlesHidden)
554 mbMarkHandlesHidden = false;
555 AdjustMarkHdl();
559 bool SdrMarkView::ImpIsFrameHandles() const
561 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
562 bool bFrmHdl=nMarkAnz>nFrameHandlesLimit || bForceFrameHandles;
563 bool bStdDrag=eDragMode==SDRDRAG_MOVE;
564 if (nMarkAnz==1 && bStdDrag && bFrmHdl)
566 const SdrObject* pObj=GetMarkedObjectByIndex(0);
567 if (pObj->GetObjInventor()==SdrInventor)
569 sal_uInt16 nIdent=pObj->GetObjIdentifier();
570 if (nIdent==OBJ_LINE || nIdent==OBJ_EDGE || nIdent==OBJ_CAPTION || nIdent==OBJ_MEASURE || nIdent==OBJ_CUSTOMSHAPE || nIdent==OBJ_TABLE )
572 bFrmHdl=false;
576 if (!bStdDrag && !bFrmHdl) {
577 // all other drag modes only with FrameHandles
578 bFrmHdl=true;
579 if (eDragMode==SDRDRAG_ROTATE) {
580 // when rotating, use ObjOwn drag, if there's at least 1 PolyObj
581 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && bFrmHdl; nMarkNum++) {
582 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
583 const SdrObject* pObj=pM->GetMarkedSdrObj();
584 bFrmHdl=!pObj->IsPolyObj();
588 if (!bFrmHdl) {
589 // FrameHandles, if at least 1 Obj can't do SpecialDrag
590 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bFrmHdl; nMarkNum++) {
591 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
592 const SdrObject* pObj=pM->GetMarkedSdrObj();
593 bFrmHdl=!pObj->hasSpecialDrag();
597 // no FrameHdl for crop
598 if(bFrmHdl && SDRDRAG_CROP == eDragMode)
600 bFrmHdl = false;
603 return bFrmHdl;
606 void SdrMarkView::SetMarkHandles()
608 // remember old focus handle values to search for it again
609 const SdrHdl* pSaveOldFocusHdl = aHdl.GetFocusHdl();
610 bool bSaveOldFocus(false);
611 sal_uInt32 nSavePolyNum(0L), nSavePointNum(0L);
612 SdrHdlKind eSaveKind(HDL_MOVE);
613 SdrObject* pSaveObj = NULL;
615 if(pSaveOldFocusHdl
616 && pSaveOldFocusHdl->GetObj()
617 && pSaveOldFocusHdl->GetObj()->ISA(SdrPathObj)
618 && (pSaveOldFocusHdl->GetKind() == HDL_POLY || pSaveOldFocusHdl->GetKind() == HDL_BWGT))
620 bSaveOldFocus = true;
621 nSavePolyNum = pSaveOldFocusHdl->GetPolyNum();
622 nSavePointNum = pSaveOldFocusHdl->GetPointNum();
623 pSaveObj = pSaveOldFocusHdl->GetObj();
624 eSaveKind = pSaveOldFocusHdl->GetKind();
627 // delete/clear all handles. This will always be done, even with areMarkHandlesHidden()
628 aHdl.Clear();
629 aHdl.SetRotateShear(eDragMode==SDRDRAG_ROTATE);
630 aHdl.SetDistortShear(eDragMode==SDRDRAG_SHEAR);
631 pMarkedObj=NULL;
632 pMarkedPV=NULL;
634 // are handles enabled at all? Create only then
635 if(!areMarkHandlesHidden())
637 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
638 bool bStdDrag=eDragMode==SDRDRAG_MOVE;
639 bool bSingleTextObjMark=false;
641 if (nMarkAnz==1)
643 pMarkedObj=GetMarkedObjectByIndex(0);
644 bSingleTextObjMark =
645 pMarkedObj &&
646 pMarkedObj->ISA(SdrTextObj) &&
647 static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame();
650 bool bFrmHdl=ImpIsFrameHandles();
652 if (nMarkAnz>0)
654 pMarkedPV=GetSdrPageViewOfMarkedByIndex(0);
656 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && (pMarkedPV!=NULL || !bFrmHdl); nMarkNum++)
658 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
660 if (pMarkedPV!=pM->GetPageView())
662 pMarkedPV=NULL;
667 // apply calc offset to marked object rect
668 // ( necessary for handles to be displayed in
669 // correct position )
670 Point aGridOff = GetGridOffset();
672 // check if text edit or ole is active and handles need to be suppressed. This may be the case
673 // when a single object is selected
674 // Using a strict return statement is okay here; no handles means *no* handles.
675 if(pMarkedObj)
677 // formally #i33755#: If TextEdit is active the EditEngine will directly paint
678 // to the window, so suppress Overlay and handles completely; a text frame for
679 // the active text edit will be painted by the repaitnt mechanism in
680 // SdrObjEditView::ImpPaintOutlinerView in this case. This needs to be reworked
681 // in the future
682 // Also formally #122142#: Pretty much the same for SdrCaptionObj's in calc.
683 if(((SdrView*)this)->IsTextEdit())
685 const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pMarkedObj);
687 if(pSdrTextObj && pSdrTextObj->IsInEditMode())
689 return;
693 // formally #i118524#: if inplace activated OLE is selected, suppress handles
694 const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pMarkedObj);
696 if(pSdrOle2Obj && (pSdrOle2Obj->isInplaceActive() || pSdrOle2Obj->isUiActive()))
698 return;
702 if (bFrmHdl)
704 Rectangle aRect(GetMarkedObjRect());
706 if(!aRect.IsEmpty())
707 { // otherwise nothing is found
708 if( bSingleTextObjMark )
710 const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
711 pMarkedObj->AddToHdlList(aHdl);
712 const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
713 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
715 SdrHdl* pHdl=aHdl.GetHdl(i);
716 pHdl->SetObj(pMarkedObj);
717 pHdl->SetPos( pHdl->GetPos() + aGridOff );
718 pHdl->SetPageView(pMarkedPV);
719 pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
722 else
724 bool bWdt0=aRect.Left()==aRect.Right();
725 bool bHgt0=aRect.Top()==aRect.Bottom();
726 if (bWdt0 && bHgt0)
728 aHdl.AddHdl(new SdrHdl(aRect.TopLeft(),HDL_UPLFT));
730 else if (!bStdDrag && (bWdt0 || bHgt0))
732 aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
733 aHdl.AddHdl(new SdrHdl(aRect.BottomRight(),HDL_LWRGT));
735 else
737 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
738 if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopCenter() ,HDL_UPPER));
739 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopRight() ,HDL_UPRGT));
740 if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.LeftCenter() ,HDL_LEFT ));
741 if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.RightCenter() ,HDL_RIGHT));
742 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomLeft() ,HDL_LWLFT));
743 if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomCenter(),HDL_LOWER));
744 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomRight() ,HDL_LWRGT));
749 else
751 bool bDone(false);
753 // moved crop handling to non-frame part and the handle creation to SdrGrafObj
754 if(1 == nMarkAnz && pMarkedObj && SDRDRAG_CROP == eDragMode)
756 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pMarkedObj);
758 if(pSdrGrafObj)
760 pSdrGrafObj->addCropHandles(aHdl);
761 bDone = true;
765 if(!bDone)
767 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
769 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
770 SdrObject* pObj=pM->GetMarkedSdrObj();
771 SdrPageView* pPV=pM->GetPageView();
772 const sal_uIntPtr nSiz0=aHdl.GetHdlCount();
773 pObj->AddToHdlList(aHdl);
774 const sal_uIntPtr nSiz1=aHdl.GetHdlCount();
775 bool bPoly=pObj->IsPolyObj();
776 const SdrUShortCont* pMrkPnts=pM->GetMarkedPoints();
777 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++)
779 SdrHdl* pHdl=aHdl.GetHdl(i);
780 pHdl->SetPos( pHdl->GetPos() + aGridOff );
781 pHdl->SetObj(pObj);
782 pHdl->SetPageView(pPV);
783 pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
785 if (bPoly)
787 bool bSelected=pMrkPnts!=NULL
788 && pMrkPnts->find( sal_uInt16(i-nSiz0) ) != pMrkPnts->end();
789 pHdl->SetSelected(bSelected);
790 if (bPlusHdlAlways || bSelected)
792 sal_uInt32 nPlusAnz=pObj->GetPlusHdlCount(*pHdl);
793 for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
795 SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,nPlusNum);
796 if (pPlusHdl!=NULL)
798 pPlusHdl->SetObj(pObj);
799 pPlusHdl->SetPageView(pPV);
800 pPlusHdl->SetPlusHdl(true);
801 aHdl.AddHdl(pPlusHdl);
811 // GluePoint handles
812 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
814 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
815 SdrObject* pObj=pM->GetMarkedSdrObj();
816 SdrPageView* pPV=pM->GetPageView();
817 const SdrUShortCont* pMrkGlue=pM->GetMarkedGluePoints();
818 if (pMrkGlue!=NULL)
820 const SdrGluePointList* pGPL=pObj->GetGluePointList();
821 if (pGPL!=NULL)
823 for(SdrUShortCont::const_iterator it = pMrkGlue->begin(); it != pMrkGlue->end(); ++it)
825 sal_uInt16 nId=*it;
826 //nNum changed to nNumGP because already used in for loop
827 sal_uInt16 nNumGP=pGPL->FindGluePoint(nId);
828 if (nNumGP!=SDRGLUEPOINT_NOTFOUND)
830 const SdrGluePoint& rGP=(*pGPL)[nNumGP];
831 Point aPos(rGP.GetAbsolutePos(*pObj));
832 SdrHdl* pGlueHdl=new SdrHdl(aPos,HDL_GLUE);
833 pGlueHdl->SetObj(pObj);
834 pGlueHdl->SetPageView(pPV);
835 pGlueHdl->SetObjHdlNum(nId);
836 aHdl.AddHdl(pGlueHdl);
843 // rotation point/axis of reflection
844 AddDragModeHdl(eDragMode);
846 // sort handles
847 aHdl.Sort();
849 // add custom handles (used by other apps, e.g. AnchorPos)
850 AddCustomHdl();
852 // try to restore focus handle index from remembered values
853 if(bSaveOldFocus)
855 for(sal_uInt32 a(0); a < aHdl.GetHdlCount(); a++)
857 SdrHdl* pCandidate = aHdl.GetHdl(a);
859 if(pCandidate->GetObj()
860 && pCandidate->GetObj() == pSaveObj
861 && pCandidate->GetKind() == eSaveKind
862 && pCandidate->GetPolyNum() == nSavePolyNum
863 && pCandidate->GetPointNum() == nSavePointNum)
865 aHdl.SetFocusHdl(pCandidate);
866 break;
873 void SdrMarkView::AddCustomHdl()
875 // add custom handles (used by other apps, e.g. AnchorPos)
878 void SdrMarkView::SetDragMode(SdrDragMode eMode)
880 SdrDragMode eMode0=eDragMode;
881 eDragMode=eMode;
882 if (eDragMode==SDRDRAG_RESIZE) eDragMode=SDRDRAG_MOVE;
883 if (eDragMode!=eMode0) {
884 ForceRefToMarked();
885 SetMarkHandles();
887 if (AreObjectsMarked()) MarkListHasChanged();
892 void SdrMarkView::AddDragModeHdl(SdrDragMode eMode)
894 switch(eMode)
896 case SDRDRAG_ROTATE:
898 // add rotation center
899 SdrHdl* pHdl = new SdrHdl(aRef1, HDL_REF1);
901 aHdl.AddHdl(pHdl);
903 break;
905 case SDRDRAG_MIRROR:
907 // add axis of reflection
908 SdrHdl* pHdl3 = new SdrHdl(aRef2, HDL_REF2);
909 SdrHdl* pHdl2 = new SdrHdl(aRef1, HDL_REF1);
910 SdrHdl* pHdl1 = new SdrHdlLine(*pHdl2, *pHdl3, HDL_MIRX);
912 pHdl1->SetObjHdlNum(1); // for sorting
913 pHdl2->SetObjHdlNum(2); // for sorting
914 pHdl3->SetObjHdlNum(3); // for sorting
916 aHdl.AddHdl(pHdl1); // line comes first, so it is the last in HitTest
917 aHdl.AddHdl(pHdl2);
918 aHdl.AddHdl(pHdl3);
920 break;
922 case SDRDRAG_TRANSPARENCE:
924 // add interactive transparency handle
925 sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
926 if(nMarkAnz == 1)
928 SdrObject* pObj = GetMarkedObjectByIndex(0);
929 SdrModel* pModel = GetModel();
930 const SfxItemSet& rSet = pObj->GetMergedItemSet();
932 if(SFX_ITEM_SET != rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, false))
934 // add this item, it's not yet there
935 XFillFloatTransparenceItem aNewItem(
936 (const XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE));
937 XGradient aGrad = aNewItem.GetGradientValue();
939 aNewItem.SetEnabled(true);
940 aGrad.SetStartIntens(100);
941 aGrad.SetEndIntens(100);
942 aNewItem.SetGradientValue(aGrad);
944 // add undo to allow user to take back this step
945 if( pModel->IsUndoEnabled() )
947 pModel->BegUndo(SVX_RESSTR(SIP_XA_FILLTRANSPARENCE));
948 pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
949 pModel->EndUndo();
952 SfxItemSet aNewSet(pModel->GetItemPool());
953 aNewSet.Put(aNewItem);
954 pObj->SetMergedItemSetAndBroadcast(aNewSet);
957 // set values and transform to vector set
958 GradTransformer aGradTransformer;
959 GradTransVector aGradTransVector;
960 GradTransGradient aGradTransGradient;
962 aGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
963 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
965 // build handles
966 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
967 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
968 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, true);
969 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, true);
970 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, false);
971 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Could not get all necessary handles!");
973 // link them
974 pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
975 pGradHdl->SetObj(pObj);
976 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
977 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
979 // insert them
980 aHdl.AddHdl(pColHdl1);
981 aHdl.AddHdl(pColHdl2);
982 aHdl.AddHdl(pGradHdl);
984 break;
986 case SDRDRAG_GRADIENT:
988 // add interactive gradient handle
989 sal_uIntPtr nMarkAnz = GetMarkedObjectCount();
990 if(nMarkAnz == 1)
992 SdrObject* pObj = GetMarkedObjectByIndex(0);
993 const SfxItemSet& rSet = pObj->GetMergedItemSet();
994 XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
996 if(eFillStyle == XFILL_GRADIENT)
998 // set values and transform to vector set
999 GradTransformer aGradTransformer;
1000 GradTransVector aGradTransVector;
1001 GradTransGradient aGradTransGradient;
1002 Size aHdlSize(15, 15);
1004 aGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
1005 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
1007 // build handles
1008 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
1009 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
1010 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, false);
1011 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, false);
1012 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, true);
1013 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Could not get all necessary handles!");
1015 // link them
1016 pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
1017 pGradHdl->SetObj(pObj);
1018 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1019 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1021 // insert them
1022 aHdl.AddHdl(pColHdl1);
1023 aHdl.AddHdl(pColHdl2);
1024 aHdl.AddHdl(pGradHdl);
1027 break;
1029 case SDRDRAG_CROP:
1031 // TODO
1032 break;
1034 default: break;
1038 /** handle mouse over effects for handles */
1039 bool SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
1041 if(aHdl.GetHdlCount())
1043 SdrHdl* pMouseOverHdl = 0;
1044 if( !rMEvt.IsLeaveWindow() && pWin )
1046 Point aMDPos( pWin->PixelToLogic( rMEvt.GetPosPixel() ) );
1047 pMouseOverHdl = PickHandle(aMDPos);
1050 // notify last mouse over handle that he lost the mouse
1051 const sal_uIntPtr nHdlCount = aHdl.GetHdlCount();
1053 for(sal_uIntPtr nHdl = 0; nHdl < nHdlCount; nHdl++ )
1055 SdrHdl* pCurrentHdl = GetHdl(nHdl);
1056 if( pCurrentHdl->mbMouseOver )
1058 if( pCurrentHdl != pMouseOverHdl )
1060 pCurrentHdl->mbMouseOver = false;
1061 pCurrentHdl->onMouseLeave();
1063 break;
1067 // notify current mouse over handle
1068 if( pMouseOverHdl )
1070 pMouseOverHdl->mbMouseOver = true;
1071 pMouseOverHdl->onMouseEnter(rMEvt);
1074 return SdrSnapView::MouseMove(rMEvt, pWin);
1077 void SdrMarkView::ForceRefToMarked()
1079 switch(eDragMode)
1081 case SDRDRAG_ROTATE:
1083 Rectangle aR(GetMarkedObjRect());
1084 aRef1 = aR.Center();
1086 break;
1089 case SDRDRAG_MIRROR:
1091 // first calculate the length of the axis of reflection
1092 long nOutMin=0;
1093 long nOutMax=0;
1094 long nMinLen=0;
1095 long nObjDst=0;
1096 long nOutHgt=0;
1097 OutputDevice* pOut=GetFirstOutputDevice();
1098 if (pOut!=NULL) {
1099 // minimum length: 50 pixels
1100 nMinLen=pOut->PixelToLogic(Size(0,50)).Height();
1101 // 20 pixels distance to the Obj for the reference point
1102 nObjDst=pOut->PixelToLogic(Size(0,20)).Height();
1103 // MinY/MaxY
1104 // margin = minimum length = 10 pixels
1105 long nDst=pOut->PixelToLogic(Size(0,10)).Height();
1106 nOutMin=-pOut->GetMapMode().GetOrigin().Y();
1107 nOutMax=pOut->GetOutputSize().Height()-1+nOutMin;
1108 nOutMin+=nDst;
1109 nOutMax-=nDst;
1110 // absolute minimum length, however, is 10 pixels
1111 if (nOutMax-nOutMin<nDst) {
1112 nOutMin+=nOutMax+1;
1113 nOutMin/=2;
1114 nOutMin-=(nDst+1)/2;
1115 nOutMax=nOutMin+nDst;
1117 nOutHgt=nOutMax-nOutMin;
1118 // otherwise minimum length = 1/4 OutHgt
1119 long nTemp=nOutHgt/4;
1120 if (nTemp>nMinLen) nMinLen=nTemp;
1123 Rectangle aR(GetMarkedObjBoundRect());
1124 Point aCenter(aR.Center());
1125 long nMarkHgt=aR.GetHeight()-1;
1126 long nHgt=nMarkHgt+nObjDst*2; // 20 pixels overlapping above and below
1127 if (nHgt<nMinLen) nHgt=nMinLen; // minimum length 50 pixels or 1/4 OutHgt, respectively
1129 long nY1=aCenter.Y()-(nHgt+1)/2;
1130 long nY2=nY1+nHgt;
1132 if (pOut!=NULL && nMinLen>nOutHgt) nMinLen=nOutHgt; // TODO: maybe shorten this a little
1134 if (pOut!=NULL) { // now move completely into the visible area
1135 if (nY1<nOutMin) {
1136 nY1=nOutMin;
1137 if (nY2<nY1+nMinLen) nY2=nY1+nMinLen;
1139 if (nY2>nOutMax) {
1140 nY2=nOutMax;
1141 if (nY1>nY2-nMinLen) nY1=nY2-nMinLen;
1145 aRef1.X()=aCenter.X();
1146 aRef1.Y()=nY1;
1147 aRef2.X()=aCenter.X();
1148 aRef2.Y()=nY2;
1150 break;
1153 case SDRDRAG_TRANSPARENCE:
1154 case SDRDRAG_GRADIENT:
1155 case SDRDRAG_CROP:
1157 Rectangle aRect(GetMarkedObjBoundRect());
1158 aRef1 = aRect.TopLeft();
1159 aRef2 = aRect.BottomRight();
1160 break;
1162 default: break;
1166 void SdrMarkView::SetRef1(const Point& rPt)
1168 if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
1170 aRef1 = rPt;
1171 SdrHdl* pH = aHdl.GetHdl(HDL_REF1);
1172 if(pH)
1173 pH->SetPos(rPt);
1177 void SdrMarkView::SetRef2(const Point& rPt)
1179 if(eDragMode == SDRDRAG_MIRROR)
1181 aRef2 = rPt;
1182 SdrHdl* pH = aHdl.GetHdl(HDL_REF2);
1183 if(pH)
1184 pH->SetPos(rPt);
1188 void SdrMarkView::CheckMarked()
1190 for (sal_uIntPtr nm=GetMarkedObjectCount(); nm>0;) {
1191 nm--;
1192 SdrMark* pM=GetSdrMarkByIndex(nm);
1193 SdrObject* pObj=pM->GetMarkedSdrObj();
1194 SdrPageView* pPV=pM->GetPageView();
1195 SdrLayerID nLay=pObj->GetLayer();
1196 bool bRaus=!pObj->IsInserted(); // Obj deleted?
1197 if (!pObj->Is3DObj()) {
1198 bRaus=bRaus || pObj->GetPage()!=pPV->GetPage(); // Obj suddenly in different Page or Group
1200 bRaus=bRaus || pPV->GetLockedLayers().IsSet(nLay) || // Layer locked?
1201 !pPV->GetVisibleLayers().IsSet(nLay); // Layer invisible?
1203 if( !bRaus )
1204 bRaus = !pObj->IsVisible(); // invisible objects can not be selected
1206 if (!bRaus) {
1207 // Grouped objects can now be selected.
1208 // After EnterGroup the higher-level objects,
1209 // have to be deselected, though.
1210 const SdrObjList* pOOL=pObj->GetObjList();
1211 const SdrObjList* pVOL=pPV->GetObjList();
1212 while (pOOL!=NULL && pOOL!=pVOL) {
1213 pOOL=pOOL->GetUpList();
1215 bRaus=pOOL!=pVOL;
1218 if (bRaus)
1220 GetMarkedObjectListWriteAccess().DeleteMark(nm);
1222 else
1224 if (!IsGluePointEditMode()) { // selected glue points only in GlueEditMode
1225 SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1226 if (pPts!=NULL) {
1227 pPts->clear();
1233 // at least reset the remembered BoundRect to prevent handle
1234 // generation if bForceFrameHandles is TRUE.
1235 bMarkedObjRectDirty = true;
1238 void SdrMarkView::SetMarkRects()
1240 SdrPageView* pPV = GetSdrPageView();
1242 if(pPV)
1244 pPV->SetHasMarkedObj(GetSnapRectFromMarkedObjects(pPV, pPV->MarkSnap()));
1245 GetBoundRectFromMarkedObjects(pPV, pPV->MarkBound());
1249 void SdrMarkView::SetFrameHandles(bool bOn)
1251 if (bOn!=bForceFrameHandles) {
1252 bool bOld=ImpIsFrameHandles();
1253 bForceFrameHandles=bOn;
1254 bool bNew=ImpIsFrameHandles();
1255 if (bNew!=bOld) {
1256 AdjustMarkHdl();
1257 MarkListHasChanged();
1262 void SdrMarkView::SetEditMode(SdrViewEditMode eMode)
1264 if (eMode!=eEditMode) {
1265 bool bGlue0=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1266 bool bEdge0=((SdrCreateView*)this)->IsEdgeTool();
1267 eEditMode0=eEditMode;
1268 eEditMode=eMode;
1269 bool bGlue1=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1270 bool bEdge1=((SdrCreateView*)this)->IsEdgeTool();
1271 // avoid flickering when switching between GlueEdit and EdgeTool
1272 if (bGlue1 && !bGlue0) ImpSetGlueVisible2(bGlue1);
1273 if (bEdge1!=bEdge0) ImpSetGlueVisible3(bEdge1);
1274 if (!bGlue1 && bGlue0) ImpSetGlueVisible2(bGlue1);
1275 if (bGlue0 && !bGlue1) UnmarkAllGluePoints();
1281 bool SdrMarkView::IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const
1283 if (pObj)
1285 if (pObj->IsMarkProtect() ||
1286 (!bDesignMode && pObj->IsUnoObj()))
1288 // object not selectable or
1289 // SdrUnoObj not in DesignMode
1290 return false;
1293 return pPV==NULL || pPV->IsObjMarkable(pObj);
1296 bool SdrMarkView::IsMarkedObjHit(const Point& rPnt, short nTol) const
1298 bool bRet=false;
1299 nTol=ImpGetHitTolLogic(nTol,NULL);
1300 Point aPt(rPnt);
1301 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount() && !bRet; nm++) {
1302 SdrMark* pM=GetSdrMarkByIndex(nm);
1303 bRet = 0 != CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0);
1305 return bRet;
1308 SdrHdl* SdrMarkView::PickHandle(const Point& rPnt, sal_uIntPtr nOptions, SdrHdl* pHdl0) const
1310 if (bSomeObjChgdFlag) { // recalculate handles, if necessary
1311 FlushComeBackTimer();
1313 bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1314 bool bNext=(nOptions & SDRSEARCH_NEXT) !=0;
1315 Point aPt(rPnt);
1316 return aHdl.IsHdlListHit(aPt,bBack,bNext,pHdl0);
1319 bool SdrMarkView::MarkObj(const Point& rPnt, short nTol, bool bToggle, bool bDeep)
1321 SdrObject* pObj;
1322 SdrPageView* pPV;
1323 nTol=ImpGetHitTolLogic(nTol,NULL);
1324 sal_uIntPtr nOptions=SDRSEARCH_PICKMARKABLE;
1325 if (bDeep) nOptions=nOptions|SDRSEARCH_DEEP;
1326 bool bRet=PickObj(rPnt,(sal_uInt16)nTol,pObj,pPV,nOptions);
1327 if (bRet) {
1328 bool bUnmark=bToggle && IsObjMarked(pObj);
1329 MarkObj(pObj,pPV,bUnmark);
1331 return bRet;
1334 bool SdrMarkView::MarkNextObj(bool bPrev)
1336 SdrPageView* pPageView = GetSdrPageView();
1338 if(!pPageView)
1340 return false;
1343 SortMarkedObjects();
1344 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1345 sal_uIntPtr nChgMarkNum = ULONG_MAX; // number of the MarkEntry we want to replace
1346 sal_uIntPtr nSearchObjNum = bPrev ? 0 : ULONG_MAX;
1347 if (nMarkAnz!=0) {
1348 nChgMarkNum=bPrev ? 0 : sal_uIntPtr(nMarkAnz-1);
1349 SdrMark* pM=GetSdrMarkByIndex(nChgMarkNum);
1350 OSL_ASSERT(pM!=NULL);
1351 if (pM->GetMarkedSdrObj() != NULL)
1352 nSearchObjNum = pM->GetMarkedSdrObj()->GetNavigationPosition();
1355 SdrObject* pMarkObj=NULL;
1356 SdrObjList* pSearchObjList=pPageView->GetObjList();
1357 sal_uIntPtr nObjAnz=pSearchObjList->GetObjCount();
1358 if (nObjAnz!=0) {
1359 if (nSearchObjNum>nObjAnz) nSearchObjNum=nObjAnz;
1360 while (pMarkObj==NULL && ((!bPrev && nSearchObjNum>0) || (bPrev && nSearchObjNum<nObjAnz)))
1362 if (!bPrev)
1363 nSearchObjNum--;
1364 SdrObject* pSearchObj = pSearchObjList->GetObjectForNavigationPosition(nSearchObjNum);
1365 if (IsObjMarkable(pSearchObj,pPageView))
1367 if (TryToFindMarkedObject(pSearchObj)==CONTAINER_ENTRY_NOTFOUND)
1369 pMarkObj=pSearchObj;
1372 if (bPrev) nSearchObjNum++;
1376 if(!pMarkObj)
1378 return false;
1381 if (nChgMarkNum!=ULONG_MAX)
1383 GetMarkedObjectListWriteAccess().DeleteMark(nChgMarkNum);
1385 MarkObj(pMarkObj,pPageView); // also calls MarkListHasChanged(), AdjustMarkHdl()
1386 return true;
1389 bool SdrMarkView::MarkNextObj(const Point& rPnt, short nTol, bool bPrev)
1391 SortMarkedObjects();
1392 nTol=ImpGetHitTolLogic(nTol,NULL);
1393 Point aPt(rPnt);
1394 SdrMark* pTopMarkHit=NULL;
1395 SdrMark* pBtmMarkHit=NULL;
1396 sal_uIntPtr nTopMarkHit=0;
1397 sal_uIntPtr nBtmMarkHit=0;
1398 // find topmost of the selected objects that is hit by rPnt
1399 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1400 sal_uIntPtr nm=0;
1401 for (nm=nMarkAnz; nm>0 && pTopMarkHit==NULL;) {
1402 nm--;
1403 SdrMark* pM=GetSdrMarkByIndex(nm);
1404 if(CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0))
1406 pTopMarkHit=pM;
1407 nTopMarkHit=nm;
1410 // nothing found, in this case, just select an object
1411 if (pTopMarkHit==NULL) return MarkObj(rPnt,sal_uInt16(nTol),false);
1413 SdrObject* pTopObjHit=pTopMarkHit->GetMarkedSdrObj();
1414 SdrObjList* pObjList=pTopObjHit->GetObjList();
1415 SdrPageView* pPV=pTopMarkHit->GetPageView();
1416 // find lowermost of the selected objects that is hit by rPnt
1417 // and is placed on the same PageView as pTopMarkHit
1418 for (nm=0; nm<nMarkAnz && pBtmMarkHit==NULL; nm++) {
1419 SdrMark* pM=GetSdrMarkByIndex(nm);
1420 SdrPageView* pPV2=pM->GetPageView();
1421 if (pPV2==pPV && CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pPV2,0,0))
1423 pBtmMarkHit=pM;
1424 nBtmMarkHit=nm;
1427 if (pBtmMarkHit==NULL) { pBtmMarkHit=pTopMarkHit; nBtmMarkHit=nTopMarkHit; }
1428 SdrObject* pBtmObjHit=pBtmMarkHit->GetMarkedSdrObj();
1429 sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1431 sal_uInt32 nSearchBeg;
1432 E3dScene* pScene = NULL;
1433 SdrObject* pObjHit = (bPrev) ? pBtmObjHit : pTopObjHit;
1434 bool bRemap = pObjHit->ISA(E3dCompoundObject)
1435 ? ((E3dCompoundObject*)pObjHit)->IsAOrdNumRemapCandidate(pScene)
1436 : false;
1438 if(bPrev)
1440 sal_uInt32 nOrdNumBtm(pBtmObjHit->GetOrdNum());
1442 if(bRemap)
1444 nOrdNumBtm = pScene->RemapOrdNum(nOrdNumBtm);
1447 nSearchBeg = nOrdNumBtm + 1;
1449 else
1451 sal_uInt32 nOrdNumTop(pTopObjHit->GetOrdNum());
1453 if(bRemap)
1455 nOrdNumTop = pScene->RemapOrdNum(nOrdNumTop);
1458 nSearchBeg = nOrdNumTop;
1461 sal_uIntPtr no=nSearchBeg;
1462 SdrObject* pFndObj=NULL;
1463 while (pFndObj==NULL && ((!bPrev && no>0) || (bPrev && no<nObjAnz))) {
1464 if (!bPrev) no--;
1465 SdrObject* pObj;
1467 if(bRemap)
1469 pObj = pObjList->GetObj(pScene->RemapOrdNum(no));
1471 else
1473 pObj = pObjList->GetObj(no);
1476 if (CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_TESTMARKABLE,0))
1478 if (TryToFindMarkedObject(pObj)==CONTAINER_ENTRY_NOTFOUND) {
1479 pFndObj=pObj;
1480 } else {
1481 // TODO: for performance reasons set on to Top or Btm, if necessary
1484 if (bPrev) no++;
1486 if (pFndObj!=NULL)
1488 GetMarkedObjectListWriteAccess().DeleteMark(bPrev?nBtmMarkHit:nTopMarkHit);
1489 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pFndObj,pPV));
1490 MarkListHasChanged();
1491 AdjustMarkHdl();
1493 return pFndObj!=NULL;
1496 bool SdrMarkView::MarkObj(const Rectangle& rRect, bool bUnmark)
1498 bool bFnd=false;
1499 Rectangle aR(rRect);
1500 SdrObjList* pObjList;
1501 BrkAction();
1502 SdrPageView* pPV = GetSdrPageView();
1504 if(pPV)
1506 pObjList=pPV->GetObjList();
1507 Rectangle aFrm1(aR);
1508 sal_uIntPtr nObjAnz=pObjList->GetObjCount();
1509 SdrObject* pObj;
1510 for (sal_uIntPtr nO=0; nO<nObjAnz; nO++) {
1511 pObj=pObjList->GetObj(nO);
1512 Rectangle aRect(pObj->GetCurrentBoundRect());
1513 if (aFrm1.IsInside(aRect)) {
1514 if (!bUnmark) {
1515 if (IsObjMarkable(pObj,pPV))
1517 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1518 bFnd=true;
1520 } else {
1521 sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1522 if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1524 GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1525 bFnd=true;
1531 if (bFnd) {
1532 SortMarkedObjects();
1533 MarkListHasChanged();
1534 AdjustMarkHdl();
1536 return bFnd;
1539 void SdrMarkView::MarkObj(SdrObject* pObj, SdrPageView* pPV, bool bUnmark, bool bImpNoSetMarkHdl)
1541 if (pObj!=NULL && pPV!=NULL && IsObjMarkable(pObj, pPV)) {
1542 BrkAction();
1543 if (!bUnmark)
1545 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1547 else
1549 sal_uIntPtr nPos=TryToFindMarkedObject(pObj);
1550 if (nPos!=CONTAINER_ENTRY_NOTFOUND)
1552 GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1555 if (!bImpNoSetMarkHdl) {
1556 MarkListHasChanged();
1557 AdjustMarkHdl();
1562 bool SdrMarkView::IsObjMarked(SdrObject* pObj) const
1564 // Hack: Because FindObject() is not const,
1565 // I have to cast myself to non-const.
1566 sal_uIntPtr nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj);
1567 return nPos!=CONTAINER_ENTRY_NOTFOUND;
1570 sal_uInt16 SdrMarkView::GetMarkHdlSizePixel() const
1572 return aHdl.GetHdlSize()*2+1;
1575 void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz)
1577 if (nSiz<3) nSiz=3;
1578 nSiz/=2;
1579 if (nSiz!=aHdl.GetHdlSize()) {
1580 aHdl.SetHdlSize(nSiz);
1584 #define SDRSEARCH_IMPISMASTER 0x80000000 /* MasterPage is being searched right now */
1585 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay) const
1587 if(((nOptions & SDRSEARCH_IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible()))
1589 return NULL;
1592 const bool bCheckIfMarkable(nOptions & SDRSEARCH_TESTMARKABLE);
1593 const bool bDeep(nOptions & SDRSEARCH_DEEP);
1594 const bool bOLE(pObj->ISA(SdrOle2Obj));
1595 const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame());
1596 SdrObject* pRet=NULL;
1597 Rectangle aRect(pObj->GetCurrentBoundRect());
1598 // hack for calc grid sync
1599 aRect += pObj->GetGridOffset();
1600 sal_uInt16 nTol2(nTol);
1602 // double tolerance for OLE, text frames and objects in
1603 // active text edit
1604 if(bOLE || bTXT || pObj==((SdrObjEditView*)this)->GetTextEditObject())
1606 nTol2*=2;
1609 aRect.Left ()-=nTol2; // add 1 tolerance for all objects
1610 aRect.Top ()-=nTol2;
1611 aRect.Right ()+=nTol2;
1612 aRect.Bottom()+=nTol2;
1614 if (aRect.IsInside(rPnt))
1616 if ((!bCheckIfMarkable || IsObjMarkable(pObj,pPV)))
1618 SdrObjList* pOL=pObj->GetSubList();
1620 if (pOL!=NULL && pOL->GetObjCount()!=0)
1622 SdrObject* pTmpObj;
1623 // adjustment hit point for virtual objects
1624 Point aPnt( rPnt );
1626 if ( pObj->ISA(SdrVirtObj) )
1628 Point aOffset = static_cast<SdrVirtObj*>(pObj)->GetOffset();
1629 aPnt.Move( -aOffset.X(), -aOffset.Y() );
1632 pRet=CheckSingleSdrObjectHit(aPnt,nTol,pOL,pPV,nOptions,pMVisLay,pTmpObj);
1634 else
1636 if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer()))
1638 pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false);
1644 if (!bDeep && pRet!=NULL)
1646 pRet=pObj;
1649 return pRet;
1652 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList* pOL, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj) const
1654 return (*this).CheckSingleSdrObjectHit(rPnt,nTol,pOL,pPV,nOptions,pMVisLay,rpRootObj,NULL);
1656 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
1658 bool bBack=(nOptions & SDRSEARCH_BACKWARD)!=0;
1659 bool bBefMrk=(nOptions & SDRSEARCH_BEFOREMARK)!=0;
1660 SdrObject* pRet=NULL;
1661 rpRootObj=NULL;
1662 if (pOL!=NULL)
1664 bool bRemap(pOL->GetOwnerObj() && pOL->GetOwnerObj()->ISA(E3dScene));
1665 E3dScene* pRemapScene = (bRemap ? (E3dScene*)pOL->GetOwnerObj() : 0L);
1667 sal_uIntPtr nObjAnz=pOL->GetObjCount();
1668 sal_uIntPtr nObjNum=bBack ? 0 : nObjAnz;
1669 while (pRet==NULL && (bBack ? nObjNum<nObjAnz : nObjNum>0)) {
1670 if (!bBack) nObjNum--;
1671 SdrObject* pObj;
1673 if(bRemap)
1675 pObj = pOL->GetObj(pRemapScene->RemapOrdNum(nObjNum));
1677 else
1679 pObj = pOL->GetObj(nObjNum);
1681 if (bBefMrk)
1683 if ((pMarkList)!=NULL)
1685 if ((*pMarkList).FindObject(pObj)!=CONTAINER_ENTRY_NOTFOUND)
1687 return NULL;
1691 pRet=CheckSingleSdrObjectHit(rPnt,nTol,pObj,pPV,nOptions,pMVisLay);
1692 if (pRet!=NULL) rpRootObj=pObj;
1693 if (bBack) nObjNum++;
1696 return pRet;
1699 bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions) const
1701 return PickObj(rPnt,nTol,rpObj,rpPV,nOptions,NULL,NULL,NULL);
1704 bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions, SdrObject** ppRootObj, sal_uIntPtr* pnMarkNum, sal_uInt16* pnPassNum) const
1705 { // TODO: lacks a Pass2,Pass3
1706 SortMarkedObjects();
1707 if (ppRootObj!=NULL) *ppRootObj=NULL;
1708 if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1709 if (pnPassNum!=NULL) *pnPassNum=0;
1710 rpObj=NULL;
1711 rpPV=NULL;
1712 bool bWholePage=(nOptions & SDRSEARCH_WHOLEPAGE) !=0;
1713 bool bMarked=(nOptions & SDRSEARCH_MARKED) !=0;
1714 bool bMasters=!bMarked && (nOptions & SDRSEARCH_ALSOONMASTER) !=0;
1715 bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1716 #if OSL_DEBUG_LEVEL > 0
1717 bool bNext=(nOptions & SDRSEARCH_NEXT) !=0; (void)bNext; // n.i.
1718 bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; (void)bBoundCheckOn2ndPass;// n.i.
1719 bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; (void)bCheckNearestOn3rdPass;// n.i.
1720 #endif
1721 if (nTol<0) nTol=ImpGetHitTolLogic(nTol,NULL);
1722 Point aPt(rPnt);
1723 SdrObject* pObj=NULL;
1724 SdrObject* pHitObj=NULL;
1725 SdrPageView* pPV=NULL;
1726 if (!bBack && ((SdrObjEditView*)this)->IsTextEditFrameHit(rPnt)) {
1727 pObj=((SdrObjEditView*)this)->GetTextEditObject();
1728 pHitObj=pObj;
1729 pPV=((SdrObjEditView*)this)->GetTextEditPageView();
1731 if (bMarked) {
1732 sal_uIntPtr nMrkAnz=GetMarkedObjectCount();
1733 sal_uIntPtr nMrkNum=bBack ? 0 : nMrkAnz;
1734 while (pHitObj==NULL && (bBack ? nMrkNum<nMrkAnz : nMrkNum>0)) {
1735 if (!bBack) nMrkNum--;
1736 SdrMark* pM=GetSdrMarkByIndex(nMrkNum);
1737 pObj=pM->GetMarkedSdrObj();
1738 pPV=pM->GetPageView();
1739 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,nOptions,NULL);
1740 if (bBack) nMrkNum++;
1743 else
1745 pPV = GetSdrPageView();
1747 if(pPV)
1749 SdrPage* pPage=pPV->GetPage();
1750 sal_uInt16 nPgAnz=1;
1752 if(bMasters && pPage->TRG_HasMasterPage())
1754 nPgAnz++;
1757 bool bExtraPassForWholePage=bWholePage && pPage!=pPV->GetObjList();
1758 if (bExtraPassForWholePage) nPgAnz++; // First search in AktObjList, then on the entire page
1759 sal_uInt16 nPgNum=bBack ? 0 : nPgAnz;
1760 while (pHitObj==NULL && (bBack ? nPgNum<nPgAnz : nPgNum>0)) {
1761 sal_uIntPtr nTmpOptions=nOptions;
1762 if (!bBack) nPgNum--;
1763 const SetOfByte* pMVisLay=NULL;
1764 SdrObjList* pObjList=NULL;
1765 if (pnPassNum!=NULL) *pnPassNum&=~(SDRSEARCHPASS_MASTERPAGE|SDRSEARCHPASS_INACTIVELIST);
1766 if (nPgNum>=nPgAnz-1 || (bExtraPassForWholePage && nPgNum>=nPgAnz-2))
1768 pObjList=pPV->GetObjList();
1769 if (bExtraPassForWholePage && nPgNum==nPgAnz-2) {
1770 pObjList=pPage;
1771 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_INACTIVELIST;
1774 else
1776 // otherwise MasterPage
1777 SdrPage& rMasterPage = pPage->TRG_GetMasterPage();
1778 pMVisLay = &pPage->TRG_GetMasterPageVisibleLayers();
1779 pObjList = &rMasterPage;
1781 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_MASTERPAGE;
1782 nTmpOptions=nTmpOptions | SDRSEARCH_IMPISMASTER;
1784 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObjList,pPV,nTmpOptions,pMVisLay,pObj,&(GetMarkedObjectList()));
1785 if (bBack) nPgNum++;
1789 if (pHitObj!=NULL) {
1790 if (ppRootObj!=NULL) *ppRootObj=pObj;
1791 if ((nOptions & SDRSEARCH_DEEP) !=0) pObj=pHitObj;
1792 if ((nOptions & SDRSEARCH_TESTTEXTEDIT) !=0) {
1793 if (!pObj->HasTextEdit() || pPV->GetLockedLayers().IsSet(pObj->GetLayer())) {
1794 pObj=NULL;
1797 if (pObj!=NULL && (nOptions & SDRSEARCH_TESTMACRO) !=0) {
1798 SdrObjMacroHitRec aHitRec;
1799 aHitRec.aPos=aPt;
1800 aHitRec.aDownPos=aPt;
1801 aHitRec.nTol=nTol;
1802 aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
1803 aHitRec.pPageView=pPV;
1804 if (!pObj->HasMacro() || !pObj->IsMacroHit(aHitRec)) pObj=NULL;
1806 if (pObj!=NULL && (nOptions & SDRSEARCH_WITHTEXT) !=0 && pObj->GetOutlinerParaObject()==NULL) pObj=NULL;
1807 if (pObj!=NULL && (nOptions & SDRSEARCH_TESTTEXTAREA) !=0 && pPV)
1809 if(!SdrObjectPrimitiveHit(*pObj, aPt, 0, *pPV, 0, true))
1811 pObj = 0;
1814 if (pObj!=NULL) {
1815 rpObj=pObj;
1816 rpPV=pPV;
1817 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_DIRECT;
1820 return rpObj!=NULL;
1823 bool SdrMarkView::PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr* pnMarkNum, sal_uIntPtr nOptions) const
1825 SortMarkedObjects();
1826 bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0;
1827 bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0;
1828 rpObj=NULL;
1829 rpPV=NULL;
1830 if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
1831 Point aPt(rPnt);
1832 sal_uInt16 nTol=(sal_uInt16)nHitTolLog;
1833 bool bFnd=false;
1834 sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1835 sal_uIntPtr nMarkNum;
1836 for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1837 nMarkNum--;
1838 SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1839 SdrPageView* pPV=pM->GetPageView();
1840 SdrObject* pObj=pM->GetMarkedSdrObj();
1841 bFnd = 0 != CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,SDRSEARCH_TESTMARKABLE,0);
1842 if (bFnd) {
1843 rpObj=pObj;
1844 rpPV=pPV;
1845 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1848 if ((bBoundCheckOn2ndPass || bCheckNearestOn3rdPass) && !bFnd) {
1849 SdrObject* pBestObj=NULL;
1850 SdrPageView* pBestPV=NULL;
1851 sal_uIntPtr nBestMarkNum=0;
1852 sal_uIntPtr nBestDist=ULONG_MAX;
1853 for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1854 nMarkNum--;
1855 SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1856 SdrPageView* pPV=pM->GetPageView();
1857 SdrObject* pObj=pM->GetMarkedSdrObj();
1858 Rectangle aRect(pObj->GetCurrentBoundRect());
1859 aRect.Left ()-=nTol;
1860 aRect.Top ()-=nTol;
1861 aRect.Right ()+=nTol;
1862 aRect.Bottom()+=nTol;
1863 if (aRect.IsInside(aPt)) {
1864 bFnd=true;
1865 rpObj=pObj;
1866 rpPV=pPV;
1867 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
1868 } else if (bCheckNearestOn3rdPass) {
1869 sal_uIntPtr nDist=0;
1870 if (aPt.X()<aRect.Left()) nDist+=aRect.Left()-aPt.X();
1871 if (aPt.X()>aRect.Right()) nDist+=aPt.X()-aRect.Right();
1872 if (aPt.Y()<aRect.Top()) nDist+=aRect.Top()-aPt.Y();
1873 if (aPt.Y()>aRect.Bottom()) nDist+=aPt.Y()-aRect.Bottom();
1874 if (nDist<nBestDist) {
1875 pBestObj=pObj;
1876 pBestPV=pPV;
1877 nBestMarkNum=nMarkNum;
1881 if (bCheckNearestOn3rdPass && !bFnd) {
1882 rpObj=pBestObj;
1883 rpPV=pBestPV;
1884 if (pnMarkNum!=NULL) *pnMarkNum=nBestMarkNum;
1885 bFnd=pBestObj!=NULL;
1888 return bFnd;
1892 void SdrMarkView::UnmarkAllObj(SdrPageView* pPV)
1894 if (GetMarkedObjectCount()!=0) {
1895 BrkAction();
1896 if (pPV!=NULL)
1898 GetMarkedObjectListWriteAccess().DeletePageView(*pPV);
1900 else
1902 GetMarkedObjectListWriteAccess().Clear();
1904 pMarkedObj=NULL;
1905 pMarkedPV=NULL;
1906 MarkListHasChanged();
1907 AdjustMarkHdl();
1911 void SdrMarkView::MarkAllObj(SdrPageView* _pPV)
1913 BrkAction();
1915 if(!_pPV)
1917 _pPV = GetSdrPageView();
1920 // #i69171# _pPV may still be NULL if there is no SDrPageView (!), e.g. when inserting
1921 // other files
1922 if(_pPV)
1924 const bool bMarkChg(GetMarkedObjectListWriteAccess().InsertPageView(*_pPV));
1926 if(bMarkChg)
1928 MarkListHasChanged();
1932 if(GetMarkedObjectCount())
1934 AdjustMarkHdl();
1938 void SdrMarkView::AdjustMarkHdl()
1940 CheckMarked();
1941 SetMarkRects();
1942 SetMarkHandles();
1945 Rectangle SdrMarkView::GetMarkedObjBoundRect() const
1947 Rectangle aRect;
1948 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
1949 SdrMark* pM=GetSdrMarkByIndex(nm);
1950 SdrObject* pO=pM->GetMarkedSdrObj();
1951 Rectangle aR1(pO->GetCurrentBoundRect());
1952 // Ensure marked area includes the calc offset
1953 // ( if applicable ) to sync to grid
1954 aR1 += pO->GetGridOffset();
1955 if (aRect.IsEmpty()) aRect=aR1;
1956 else aRect.Union(aR1);
1958 return aRect;
1961 Point SdrMarkView::GetGridOffset() const
1963 Point aOffset;
1964 // calculate the area occupied by the union of each marked object
1965 // ( synced to grid ) and compare to the same unsynced area to calculate
1966 // the offset. Hopefully that's the sensible thing to do
1967 const Rectangle& aGroupSyncedRect = GetMarkedObjRect();
1968 aOffset = aGroupSyncedRect.TopLeft() - aMarkedObjRectNoOffset.TopLeft();
1969 return aOffset;
1972 const Rectangle& SdrMarkView::GetMarkedObjRect() const
1974 if (bMarkedObjRectDirty) {
1975 ((SdrMarkView*)this)->bMarkedObjRectDirty=false;
1976 Rectangle aRect;
1977 Rectangle aRect2;
1978 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
1979 SdrMark* pM=GetSdrMarkByIndex(nm);
1980 SdrObject* pO=pM->GetMarkedSdrObj();
1981 Rectangle aR1(pO->GetSnapRect());
1982 // apply calc offset to marked object rect
1983 // ( necessary for handles to be displayed in
1984 // correct position )
1985 if (aRect2.IsEmpty()) aRect2=aR1;
1986 else aRect2.Union( aR1 );
1987 aR1 += pO->GetGridOffset();
1988 if (aRect.IsEmpty()) aRect=aR1;
1989 else aRect.Union(aR1);
1991 ((SdrMarkView*)this)->aMarkedObjRect=aRect;
1992 ((SdrMarkView*)this)->aMarkedObjRectNoOffset=aRect2;
1994 return aMarkedObjRect;
1999 void SdrMarkView::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, OUString& rStr, sal_uInt16 nVal, sal_uInt16 nOpt) const
2001 rStr = ImpGetResStr(nStrCacheID);
2002 sal_Int32 nPos = rStr.indexOf("%1");
2004 if(nPos != -1)
2006 if(nOpt == IMPSDR_POINTSDESCRIPTION)
2008 rStr = rStr.replaceAt(nPos, 2, GetDescriptionOfMarkedPoints());
2010 else if(nOpt == IMPSDR_GLUEPOINTSDESCRIPTION)
2012 rStr = rStr.replaceAt(nPos, 2, GetDescriptionOfMarkedGluePoints());
2014 else
2016 rStr = rStr.replaceAt(nPos, 2, GetDescriptionOfMarkedObjects());
2020 rStr = rStr.replaceFirst("%2", OUString::number( nVal ));
2025 bool SdrMarkView::EnterMarkedGroup()
2027 bool bRet=false;
2028 // We enter only the first group found (in only one PageView), because
2029 // PageView::EnterGroup calls an AdjustMarkHdl.
2030 // TODO: I'll have to prevent that via a flag.
2031 SdrPageView* pPV = GetSdrPageView();
2033 if(pPV)
2035 bool bEnter=false;
2036 for (sal_uInt32 nm(GetMarkedObjectCount()); nm > 0 && !bEnter;)
2038 nm--;
2039 SdrMark* pM=GetSdrMarkByIndex(nm);
2040 if (pM->GetPageView()==pPV) {
2041 SdrObject* pObj=pM->GetMarkedSdrObj();
2042 if (pObj->IsGroupObject()) {
2043 if (pPV->EnterGroup(pObj)) {
2044 bRet=true;
2045 bEnter=true;
2051 return bRet;
2056 void SdrMarkView::MarkListHasChanged()
2058 GetMarkedObjectListWriteAccess().SetNameDirty();
2059 SetEdgesOfMarkedNodesDirty();
2061 bMarkedObjRectDirty=true;
2062 bMarkedPointsRectsDirty=true;
2063 #ifdef DBG_UTIL
2064 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
2065 #endif
2066 bool bOneEdgeMarked=false;
2067 if (GetMarkedObjectCount()==1) {
2068 const SdrObject* pObj=GetMarkedObjectByIndex(0);
2069 if (pObj->GetObjInventor()==SdrInventor) {
2070 sal_uInt16 nIdent=pObj->GetObjIdentifier();
2071 bOneEdgeMarked=nIdent==OBJ_EDGE;
2074 ImpSetGlueVisible4(bOneEdgeMarked);
2079 void SdrMarkView::SetMoveOutside(bool bOn)
2081 aHdl.SetMoveOutside(bOn);
2084 void SdrMarkView::SetDesignMode( bool _bOn )
2086 if ( bDesignMode != _bOn )
2088 bDesignMode = _bOn;
2089 SdrPageView* pPageView = GetSdrPageView();
2090 if ( pPageView )
2091 pPageView->SetDesignMode( _bOn );
2095 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */