Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
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"
29 :
30 : #ifdef DBG_UTIL
31 : #include <svdibrow.hxx>
32 : #endif
33 :
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>
52 :
53 : #include <editeng/editdata.hxx>
54 :
55 : using namespace com::sun::star;
56 :
57 : // Migrate Marking of Objects, Points and GluePoints
58 :
59 : class ImplMarkingOverlay
60 : {
61 : // The OverlayObjects
62 : ::sdr::overlay::OverlayObjectList maObjects;
63 :
64 : // The remembered second position in logical coordinates
65 : basegfx::B2DPoint maSecondPosition;
66 :
67 : // bitfield
68 : // A flag to remember if the action is for unmarking.
69 : bool mbUnmarking : 1;
70 :
71 : public:
72 : ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, bool bUnmarking = false);
73 : ~ImplMarkingOverlay();
74 :
75 : void SetSecondPosition(const basegfx::B2DPoint& rNewPosition);
76 0 : bool IsUnmarking() const { return mbUnmarking; }
77 : };
78 :
79 0 : ImplMarkingOverlay::ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, bool bUnmarking)
80 : : maSecondPosition(rStartPos),
81 0 : mbUnmarking(bUnmarking)
82 : {
83 0 : for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
84 : {
85 0 : SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
86 0 : rtl::Reference< ::sdr::overlay::OverlayManager > xTargetOverlay = pCandidate->GetOverlayManager();
87 :
88 0 : if (xTargetOverlay.is())
89 : {
90 : ::sdr::overlay::OverlayRollingRectangleStriped* pNew = new ::sdr::overlay::OverlayRollingRectangleStriped(
91 0 : rStartPos, rStartPos, false);
92 0 : xTargetOverlay->add(*pNew);
93 0 : maObjects.append(*pNew);
94 : }
95 0 : }
96 0 : }
97 :
98 0 : ImplMarkingOverlay::~ImplMarkingOverlay()
99 : {
100 : // The OverlayObjects are cleared using the destructor of OverlayObjectList.
101 : // That destructor calls clear() at the list which removes all objects from the
102 : // OverlayManager and deletes them.
103 0 : }
104 :
105 0 : void ImplMarkingOverlay::SetSecondPosition(const basegfx::B2DPoint& rNewPosition)
106 : {
107 0 : if(rNewPosition != maSecondPosition)
108 : {
109 : // apply to OverlayObjects
110 0 : for(sal_uInt32 a(0L); a < maObjects.count(); a++)
111 : {
112 0 : ::sdr::overlay::OverlayRollingRectangleStriped& rCandidate = static_cast< ::sdr::overlay::OverlayRollingRectangleStriped&>(maObjects.getOverlayObject(a));
113 0 : rCandidate.setSecondPosition(rNewPosition);
114 : }
115 :
116 : // remember new position
117 0 : maSecondPosition = rNewPosition;
118 : }
119 0 : }
120 :
121 :
122 :
123 : // MarkView
124 :
125 :
126 :
127 15989 : void SdrMarkView::ImpClearVars()
128 : {
129 15989 : eDragMode=SDRDRAG_MOVE;
130 15989 : bRefHdlShownOnly=false;
131 15989 : eEditMode=SDREDITMODE_EDIT;
132 15989 : eEditMode0=SDREDITMODE_EDIT;
133 15989 : bDesignMode=false;
134 15989 : pMarkedObj=NULL;
135 15989 : pMarkedPV=NULL;
136 15989 : bForceFrameHandles=false;
137 15989 : bPlusHdlAlways=false;
138 15989 : nFrameHandlesLimit=50;
139 15989 : bInsPolyPoint=false;
140 15989 : mnInsPointNum = 0L;
141 15989 : bMarkedObjRectDirty=false;
142 15989 : bMarkedPointsRectsDirty=false;
143 15989 : mbMarkHandlesHidden = false;
144 15989 : bMrkPntDirty=false;
145 15989 : bMarkHdlWhenTextEdit=false;
146 15989 : bMarkableObjCountDirty=false; // not yet implemented
147 15989 : nMarkableObjCount=0; // not yet implemented
148 :
149 : // Migrate selections
150 15989 : BrkMarkObj();
151 15989 : BrkMarkPoints();
152 15989 : BrkMarkGluePoints();
153 15989 : }
154 :
155 15989 : SdrMarkView::SdrMarkView(SdrModel* pModel1, OutputDevice* pOut)
156 : : SdrSnapView(pModel1,pOut),
157 : mpMarkObjOverlay(0L),
158 : mpMarkPointsOverlay(0L),
159 : mpMarkGluePointsOverlay(0L),
160 : aHdl(this),
161 15989 : mpSdrViewSelection(new sdr::ViewSelection())
162 : {
163 15989 : ImpClearVars();
164 15989 : StartListening(*pModel1);
165 15989 : }
166 :
167 31838 : SdrMarkView::~SdrMarkView()
168 : {
169 : // Migrate selections
170 15919 : BrkMarkObj();
171 15919 : BrkMarkPoints();
172 15919 : BrkMarkGluePoints();
173 15919 : delete mpSdrViewSelection;
174 15919 : }
175 :
176 480398 : void SdrMarkView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
177 : {
178 480398 : const SdrHint* pSdrHint = dynamic_cast<const SdrHint*>(&rHint);
179 480398 : if (pSdrHint)
180 : {
181 471484 : SdrHintKind eKind=pSdrHint->GetKind();
182 :
183 471484 : if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED)
184 : {
185 404629 : bMarkedObjRectDirty=true;
186 404629 : bMarkedPointsRectsDirty=true;
187 : }
188 : }
189 480398 : SdrSnapView::Notify(rBC,rHint);
190 480398 : }
191 :
192 8129 : void SdrMarkView::ModelHasChanged()
193 : {
194 8129 : SdrPaintView::ModelHasChanged();
195 8129 : GetMarkedObjectListWriteAccess().SetNameDirty();
196 8129 : bMarkedObjRectDirty=true;
197 8129 : bMarkedPointsRectsDirty=true;
198 : // Example: Obj is selected and maMarkedObjectList is sorted.
199 : // In another View 2, the ObjOrder is changed (e. g. MovToTop())
200 : // Then we need to re-sort MarkList.
201 8129 : GetMarkedObjectListWriteAccess().SetUnsorted();
202 8129 : SortMarkedObjects();
203 8129 : bMrkPntDirty=true;
204 8129 : UndirtyMrkPnt();
205 8129 : SdrView* pV=static_cast<SdrView*>(this);
206 8129 : if (pV!=NULL && !pV->IsDragObj() && !pV->IsInsObjPoint()) {
207 8129 : AdjustMarkHdl();
208 : }
209 8129 : }
210 :
211 :
212 :
213 3423 : bool SdrMarkView::IsAction() const
214 : {
215 3423 : return SdrSnapView::IsAction() || IsMarkObj() || IsMarkPoints() || IsMarkGluePoints();
216 : }
217 :
218 0 : void SdrMarkView::MovAction(const Point& rPnt)
219 : {
220 0 : SdrSnapView::MovAction(rPnt);
221 :
222 0 : if(IsMarkObj())
223 : {
224 0 : MovMarkObj(rPnt);
225 : }
226 0 : else if(IsMarkPoints())
227 : {
228 0 : MovMarkPoints(rPnt);
229 : }
230 0 : else if(IsMarkGluePoints())
231 : {
232 0 : MovMarkGluePoints(rPnt);
233 : }
234 0 : }
235 :
236 0 : void SdrMarkView::EndAction()
237 : {
238 0 : if(IsMarkObj())
239 : {
240 0 : EndMarkObj();
241 : }
242 0 : else if(IsMarkPoints())
243 : {
244 0 : EndMarkPoints();
245 : }
246 0 : else if(IsMarkGluePoints())
247 : {
248 0 : EndMarkGluePoints();
249 : }
250 :
251 0 : SdrSnapView::EndAction();
252 0 : }
253 :
254 0 : void SdrMarkView::BckAction()
255 : {
256 0 : SdrSnapView::BckAction();
257 0 : BrkMarkObj();
258 0 : BrkMarkPoints();
259 0 : BrkMarkGluePoints();
260 0 : }
261 :
262 8919 : void SdrMarkView::BrkAction()
263 : {
264 8919 : SdrSnapView::BrkAction();
265 8919 : BrkMarkObj();
266 8919 : BrkMarkPoints();
267 8919 : BrkMarkGluePoints();
268 8919 : }
269 :
270 0 : void SdrMarkView::TakeActionRect(Rectangle& rRect) const
271 : {
272 0 : if(IsMarkObj() || IsMarkPoints() || IsMarkGluePoints())
273 : {
274 0 : rRect = Rectangle(aDragStat.GetStart(), aDragStat.GetNow());
275 : }
276 : else
277 : {
278 0 : SdrSnapView::TakeActionRect(rRect);
279 : }
280 0 : }
281 :
282 :
283 :
284 0 : void SdrMarkView::ClearPageView()
285 : {
286 0 : UnmarkAllObj();
287 0 : SdrSnapView::ClearPageView();
288 0 : }
289 :
290 7503 : void SdrMarkView::HideSdrPage()
291 : {
292 7503 : bool bMrkChg(false);
293 :
294 7503 : SdrPageView* pPageView = GetSdrPageView();
295 7503 : if (pPageView)
296 : {
297 : // break all creation actions when hiding page (#75081#)
298 7131 : BrkAction();
299 :
300 : // Discard all selections on this page
301 7131 : bMrkChg = GetMarkedObjectListWriteAccess().DeletePageView(*pPageView);
302 : }
303 :
304 7503 : SdrSnapView::HideSdrPage();
305 :
306 7503 : if(bMrkChg)
307 : {
308 106 : MarkListHasChanged();
309 106 : AdjustMarkHdl();
310 : }
311 7503 : }
312 :
313 :
314 :
315 0 : bool SdrMarkView::BegMarkObj(const Point& rPnt, bool bUnmark)
316 : {
317 0 : BrkAction();
318 :
319 : DBG_ASSERT(0L == mpMarkObjOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkObjOverlay (!)");
320 0 : basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
321 0 : mpMarkObjOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
322 :
323 0 : aDragStat.Reset(rPnt);
324 0 : aDragStat.NextPoint();
325 0 : aDragStat.SetMinMove(nMinMovLog);
326 :
327 0 : return true;
328 : }
329 :
330 0 : void SdrMarkView::MovMarkObj(const Point& rPnt)
331 : {
332 0 : if(IsMarkObj() && aDragStat.CheckMinMoved(rPnt))
333 : {
334 0 : aDragStat.NextMove(rPnt);
335 : DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
336 0 : basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
337 0 : mpMarkObjOverlay->SetSecondPosition(aNewPos);
338 : }
339 0 : }
340 :
341 0 : bool SdrMarkView::EndMarkObj()
342 : {
343 0 : bool bRetval(false);
344 :
345 0 : if(IsMarkObj())
346 : {
347 0 : if(aDragStat.IsMinMoved())
348 : {
349 0 : Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
350 0 : aRect.Justify();
351 0 : MarkObj(aRect, mpMarkObjOverlay->IsUnmarking());
352 0 : bRetval = true;
353 : }
354 :
355 : // cleanup
356 0 : BrkMarkObj();
357 : }
358 :
359 0 : return bRetval;
360 : }
361 :
362 40827 : void SdrMarkView::BrkMarkObj()
363 : {
364 40827 : if(IsMarkObj())
365 : {
366 : DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
367 0 : delete mpMarkObjOverlay;
368 0 : mpMarkObjOverlay = 0L;
369 : }
370 40827 : }
371 :
372 :
373 :
374 0 : bool SdrMarkView::BegMarkPoints(const Point& rPnt, bool bUnmark)
375 : {
376 0 : if(HasMarkablePoints())
377 : {
378 0 : BrkAction();
379 :
380 : DBG_ASSERT(0L == mpMarkPointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkPointsOverlay (!)");
381 0 : basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
382 0 : mpMarkPointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
383 :
384 0 : aDragStat.Reset(rPnt);
385 0 : aDragStat.NextPoint();
386 0 : aDragStat.SetMinMove(nMinMovLog);
387 :
388 0 : return true;
389 : }
390 :
391 0 : return false;
392 : }
393 :
394 0 : void SdrMarkView::MovMarkPoints(const Point& rPnt)
395 : {
396 0 : if(IsMarkPoints() && aDragStat.CheckMinMoved(rPnt))
397 : {
398 0 : aDragStat.NextMove(rPnt);
399 :
400 : DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
401 0 : basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
402 0 : mpMarkPointsOverlay->SetSecondPosition(aNewPos);
403 : }
404 0 : }
405 :
406 0 : bool SdrMarkView::EndMarkPoints()
407 : {
408 0 : bool bRetval(false);
409 :
410 0 : if(IsMarkPoints())
411 : {
412 0 : if(aDragStat.IsMinMoved())
413 : {
414 0 : Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
415 0 : aRect.Justify();
416 0 : MarkPoints(aRect, mpMarkPointsOverlay->IsUnmarking());
417 :
418 0 : bRetval = true;
419 : }
420 :
421 : // cleanup
422 0 : BrkMarkPoints();
423 : }
424 :
425 0 : return bRetval;
426 : }
427 :
428 40827 : void SdrMarkView::BrkMarkPoints()
429 : {
430 40827 : if(IsMarkPoints())
431 : {
432 : DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
433 0 : delete mpMarkPointsOverlay;
434 0 : mpMarkPointsOverlay = 0L;
435 : }
436 40827 : }
437 :
438 :
439 :
440 0 : bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, bool bUnmark)
441 : {
442 0 : if(HasMarkableGluePoints())
443 : {
444 0 : BrkAction();
445 :
446 : DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)");
447 :
448 0 : basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
449 0 : mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
450 0 : aDragStat.Reset(rPnt);
451 0 : aDragStat.NextPoint();
452 0 : aDragStat.SetMinMove(nMinMovLog);
453 :
454 0 : return true;
455 : }
456 :
457 0 : return false;
458 : }
459 :
460 0 : void SdrMarkView::MovMarkGluePoints(const Point& rPnt)
461 : {
462 0 : if(IsMarkGluePoints() && aDragStat.CheckMinMoved(rPnt))
463 : {
464 0 : aDragStat.NextMove(rPnt);
465 :
466 : DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
467 0 : basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
468 0 : mpMarkGluePointsOverlay->SetSecondPosition(aNewPos);
469 : }
470 0 : }
471 :
472 0 : bool SdrMarkView::EndMarkGluePoints()
473 : {
474 0 : bool bRetval(false);
475 :
476 0 : if(IsMarkGluePoints())
477 : {
478 0 : if(aDragStat.IsMinMoved())
479 : {
480 0 : Rectangle aRect(aDragStat.GetStart(),aDragStat.GetNow());
481 0 : aRect.Justify();
482 0 : MarkGluePoints(&aRect, mpMarkGluePointsOverlay->IsUnmarking());
483 :
484 0 : bRetval = true;
485 : }
486 :
487 : // cleanup
488 0 : BrkMarkGluePoints();
489 : }
490 :
491 0 : return bRetval;
492 : }
493 :
494 40827 : void SdrMarkView::BrkMarkGluePoints()
495 : {
496 40827 : if(IsMarkGluePoints())
497 : {
498 : DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
499 0 : delete mpMarkGluePointsOverlay;
500 0 : mpMarkGluePointsOverlay = 0L;
501 : }
502 40827 : }
503 :
504 0 : sal_uIntPtr SdrMarkView::GetMarkableObjCount() const
505 : {
506 0 : sal_uIntPtr nCount=0;
507 0 : SdrPageView* pPV = GetSdrPageView();
508 :
509 0 : if(pPV)
510 : {
511 0 : SdrObjList* pOL=pPV->GetObjList();
512 0 : const size_t nObjAnz = pOL->GetObjCount();
513 0 : for (size_t nObjNum=0; nObjNum<nObjAnz; ++nObjNum) {
514 0 : SdrObject* pObj=pOL->GetObj(nObjNum);
515 0 : if (IsObjMarkable(pObj,pPV)) {
516 0 : nCount++;
517 : }
518 : }
519 : }
520 0 : return nCount;
521 : }
522 :
523 0 : bool SdrMarkView::HasMarkableObj() const
524 : {
525 0 : SdrPageView* pPV = GetSdrPageView();
526 0 : if(pPV)
527 : {
528 0 : SdrObjList* pOL=pPV->GetObjList();
529 0 : const size_t nObjAnz = pOL->GetObjCount();
530 0 : for (size_t nObjNum = 0; nObjNum<nObjAnz; ++nObjNum) {
531 0 : SdrObject* pObj=pOL->GetObj(nObjNum);
532 0 : if (IsObjMarkable(pObj,pPV)) {
533 0 : return true;
534 : }
535 : }
536 : }
537 0 : return false;
538 : }
539 :
540 25186 : void SdrMarkView::hideMarkHandles()
541 : {
542 25186 : if(!mbMarkHandlesHidden)
543 : {
544 25186 : mbMarkHandlesHidden = true;
545 25186 : AdjustMarkHdl();
546 : }
547 25186 : }
548 :
549 29316 : void SdrMarkView::showMarkHandles()
550 : {
551 29316 : if(mbMarkHandlesHidden)
552 : {
553 24666 : mbMarkHandlesHidden = false;
554 24666 : AdjustMarkHdl();
555 : }
556 29316 : }
557 :
558 78431 : bool SdrMarkView::ImpIsFrameHandles() const
559 : {
560 78431 : const size_t nMarkAnz=GetMarkedObjectCount();
561 78431 : bool bFrmHdl=nMarkAnz>static_cast<size_t>(nFrameHandlesLimit) || bForceFrameHandles;
562 78431 : bool bStdDrag=eDragMode==SDRDRAG_MOVE;
563 78431 : if (nMarkAnz==1 && bStdDrag && bFrmHdl)
564 : {
565 49 : const SdrObject* pObj=GetMarkedObjectByIndex(0);
566 49 : if (pObj->GetObjInventor()==SdrInventor)
567 : {
568 45 : sal_uInt16 nIdent=pObj->GetObjIdentifier();
569 45 : if (nIdent==OBJ_LINE || nIdent==OBJ_EDGE || nIdent==OBJ_CAPTION || nIdent==OBJ_MEASURE || nIdent==OBJ_CUSTOMSHAPE || nIdent==OBJ_TABLE )
570 : {
571 10 : bFrmHdl=false;
572 : }
573 : }
574 : }
575 78431 : if (!bStdDrag && !bFrmHdl) {
576 : // all other drag modes only with FrameHandles
577 0 : bFrmHdl=true;
578 0 : if (eDragMode==SDRDRAG_ROTATE) {
579 : // when rotating, use ObjOwn drag, if there's at least 1 PolyObj
580 0 : for (size_t nMarkNum=0; nMarkNum<nMarkAnz && bFrmHdl; ++nMarkNum) {
581 0 : const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
582 0 : const SdrObject* pObj=pM->GetMarkedSdrObj();
583 0 : bFrmHdl=!pObj->IsPolyObj();
584 : }
585 : }
586 : }
587 78431 : if (!bFrmHdl) {
588 : // FrameHandles, if at least 1 Obj can't do SpecialDrag
589 14169 : for (size_t nMarkNum=0; nMarkNum<nMarkAnz && !bFrmHdl; ++nMarkNum) {
590 1132 : const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
591 1132 : const SdrObject* pObj=pM->GetMarkedSdrObj();
592 1132 : bFrmHdl=!pObj->hasSpecialDrag();
593 : }
594 : }
595 :
596 : // no FrameHdl for crop
597 78431 : if(bFrmHdl && SDRDRAG_CROP == eDragMode)
598 : {
599 0 : bFrmHdl = false;
600 : }
601 :
602 78431 : return bFrmHdl;
603 : }
604 :
605 86459 : void SdrMarkView::SetMarkHandles()
606 : {
607 : // remember old focus handle values to search for it again
608 86459 : const SdrHdl* pSaveOldFocusHdl = aHdl.GetFocusHdl();
609 86459 : bool bSaveOldFocus(false);
610 86459 : sal_uInt32 nSavePolyNum(0L), nSavePointNum(0L);
611 86459 : SdrHdlKind eSaveKind(HDL_MOVE);
612 86459 : SdrObject* pSaveObj = NULL;
613 :
614 86459 : if(pSaveOldFocusHdl
615 0 : && pSaveOldFocusHdl->GetObj()
616 0 : && pSaveOldFocusHdl->GetObj()->ISA(SdrPathObj)
617 86459 : && (pSaveOldFocusHdl->GetKind() == HDL_POLY || pSaveOldFocusHdl->GetKind() == HDL_BWGT))
618 : {
619 0 : bSaveOldFocus = true;
620 0 : nSavePolyNum = pSaveOldFocusHdl->GetPolyNum();
621 0 : nSavePointNum = pSaveOldFocusHdl->GetPointNum();
622 0 : pSaveObj = pSaveOldFocusHdl->GetObj();
623 0 : eSaveKind = pSaveOldFocusHdl->GetKind();
624 : }
625 :
626 : // delete/clear all handles. This will always be done, even with areMarkHandlesHidden()
627 86459 : aHdl.Clear();
628 86459 : aHdl.SetRotateShear(eDragMode==SDRDRAG_ROTATE);
629 86459 : aHdl.SetDistortShear(eDragMode==SDRDRAG_SHEAR);
630 86459 : pMarkedObj=NULL;
631 86459 : pMarkedPV=NULL;
632 :
633 : // are handles enabled at all? Create only then
634 86459 : if(!areMarkHandlesHidden())
635 : {
636 60219 : const size_t nMarkAnz=GetMarkedObjectCount();
637 60219 : bool bStdDrag=eDragMode==SDRDRAG_MOVE;
638 60219 : bool bSingleTextObjMark=false;
639 :
640 60219 : if (nMarkAnz==1)
641 : {
642 197 : pMarkedObj=GetMarkedObjectByIndex(0);
643 : bSingleTextObjMark =
644 197 : pMarkedObj &&
645 288 : pMarkedObj->ISA(SdrTextObj) &&
646 288 : static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame();
647 : }
648 :
649 60219 : bool bFrmHdl=ImpIsFrameHandles();
650 :
651 60219 : if (nMarkAnz>0)
652 : {
653 474 : pMarkedPV=GetSdrPageViewOfMarkedByIndex(0);
654 :
655 1527 : for (size_t nMarkNum=0; nMarkNum<nMarkAnz && (pMarkedPV!=NULL || !bFrmHdl); ++nMarkNum)
656 : {
657 1053 : const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
658 :
659 1053 : if (pMarkedPV!=pM->GetPageView())
660 : {
661 0 : pMarkedPV=NULL;
662 : }
663 : }
664 : }
665 :
666 : // apply calc offset to marked object rect
667 : // ( necessary for handles to be displayed in
668 : // correct position )
669 60219 : Point aGridOff = GetGridOffset();
670 :
671 : // check if text edit or ole is active and handles need to be suppressed. This may be the case
672 : // when a single object is selected
673 : // Using a strict return statement is okay here; no handles means *no* handles.
674 60219 : if(pMarkedObj)
675 : {
676 : // formally #i33755#: If TextEdit is active the EditEngine will directly paint
677 : // to the window, so suppress Overlay and handles completely; a text frame for
678 : // the active text edit will be painted by the repaitnt mechanism in
679 : // SdrObjEditView::ImpPaintOutlinerView in this case. This needs to be reworked
680 : // in the future
681 : // Also formally #122142#: Pretty much the same for SdrCaptionObj's in calc.
682 197 : if(static_cast<SdrView*>(this)->IsTextEdit())
683 : {
684 0 : const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pMarkedObj);
685 :
686 0 : if(pSdrTextObj && pSdrTextObj->IsInEditMode())
687 : {
688 0 : return;
689 : }
690 : }
691 :
692 : // formally #i118524#: if inplace activated OLE is selected, suppress handles
693 197 : const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pMarkedObj);
694 :
695 197 : if(pSdrOle2Obj && (pSdrOle2Obj->isInplaceActive() || pSdrOle2Obj->isUiActive()))
696 : {
697 0 : return;
698 : }
699 : }
700 :
701 60219 : if (bFrmHdl)
702 : {
703 54620 : Rectangle aRect(GetMarkedObjRect());
704 :
705 54620 : if(!aRect.IsEmpty())
706 : { // otherwise nothing is found
707 282 : if( bSingleTextObjMark )
708 : {
709 0 : const size_t nSiz0=aHdl.GetHdlCount();
710 0 : pMarkedObj->AddToHdlList(aHdl);
711 0 : const size_t nSiz1=aHdl.GetHdlCount();
712 0 : for (size_t i=nSiz0; i<nSiz1; ++i)
713 : {
714 0 : SdrHdl* pHdl=aHdl.GetHdl(i);
715 0 : pHdl->SetObj(pMarkedObj);
716 0 : pHdl->SetPos( pHdl->GetPos() + aGridOff );
717 0 : pHdl->SetPageView(pMarkedPV);
718 0 : pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
719 : }
720 : }
721 : else
722 : {
723 282 : bool bWdt0=aRect.Left()==aRect.Right();
724 282 : bool bHgt0=aRect.Top()==aRect.Bottom();
725 282 : if (bWdt0 && bHgt0)
726 : {
727 0 : aHdl.AddHdl(new SdrHdl(aRect.TopLeft(),HDL_UPLFT));
728 : }
729 282 : else if (!bStdDrag && (bWdt0 || bHgt0))
730 : {
731 0 : aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
732 0 : aHdl.AddHdl(new SdrHdl(aRect.BottomRight(),HDL_LWRGT));
733 : }
734 : else
735 : {
736 282 : if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
737 282 : if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopCenter() ,HDL_UPPER));
738 282 : if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopRight() ,HDL_UPRGT));
739 282 : if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.LeftCenter() ,HDL_LEFT ));
740 282 : if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.RightCenter() ,HDL_RIGHT));
741 282 : if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomLeft() ,HDL_LWLFT));
742 282 : if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomCenter(),HDL_LOWER));
743 282 : if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomRight() ,HDL_LWRGT));
744 : }
745 : }
746 : }
747 : }
748 : else
749 : {
750 5599 : bool bDone(false);
751 :
752 : // moved crop handling to non-frame part and the handle creation to SdrGrafObj
753 5599 : if(1 == nMarkAnz && pMarkedObj && SDRDRAG_CROP == eDragMode)
754 : {
755 0 : const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pMarkedObj);
756 :
757 0 : if(pSdrGrafObj)
758 : {
759 0 : pSdrGrafObj->addCropHandles(aHdl);
760 0 : bDone = true;
761 : }
762 : }
763 :
764 5599 : if(!bDone)
765 : {
766 5967 : for (size_t nMarkNum=0; nMarkNum<nMarkAnz; ++nMarkNum)
767 : {
768 368 : const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
769 368 : SdrObject* pObj=pM->GetMarkedSdrObj();
770 368 : SdrPageView* pPV=pM->GetPageView();
771 368 : const size_t nSiz0=aHdl.GetHdlCount();
772 368 : pObj->AddToHdlList(aHdl);
773 368 : const size_t nSiz1=aHdl.GetHdlCount();
774 368 : bool bPoly=pObj->IsPolyObj();
775 368 : const SdrUShortCont* pMrkPnts=pM->GetMarkedPoints();
776 2242 : for (size_t i=nSiz0; i<nSiz1; ++i)
777 : {
778 1874 : SdrHdl* pHdl=aHdl.GetHdl(i);
779 1874 : pHdl->SetPos( pHdl->GetPos() + aGridOff );
780 1874 : pHdl->SetObj(pObj);
781 1874 : pHdl->SetPageView(pPV);
782 1874 : pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
783 :
784 1874 : if (bPoly)
785 : {
786 : bool bSelected=pMrkPnts!=NULL
787 1402 : && pMrkPnts->find( sal_uInt16(i-nSiz0) ) != pMrkPnts->end();
788 1402 : pHdl->SetSelected(bSelected);
789 1402 : if (bPlusHdlAlways || bSelected)
790 : {
791 0 : sal_uInt32 nPlusAnz=pObj->GetPlusHdlCount(*pHdl);
792 0 : for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
793 : {
794 0 : SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,nPlusNum);
795 0 : if (pPlusHdl!=NULL)
796 : {
797 0 : pPlusHdl->SetObj(pObj);
798 0 : pPlusHdl->SetPageView(pPV);
799 0 : pPlusHdl->SetPlusHdl(true);
800 0 : aHdl.AddHdl(pPlusHdl);
801 : }
802 : }
803 : }
804 : }
805 : }
806 : }
807 : }
808 : }
809 :
810 : // GluePoint handles
811 61272 : for (size_t nMarkNum=0; nMarkNum<nMarkAnz; ++nMarkNum)
812 : {
813 1053 : const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
814 1053 : SdrObject* pObj=pM->GetMarkedSdrObj();
815 1053 : SdrPageView* pPV=pM->GetPageView();
816 1053 : const SdrUShortCont* pMrkGlue=pM->GetMarkedGluePoints();
817 1053 : if (pMrkGlue!=NULL)
818 : {
819 0 : const SdrGluePointList* pGPL=pObj->GetGluePointList();
820 0 : if (pGPL!=NULL)
821 : {
822 0 : for(SdrUShortCont::const_iterator it = pMrkGlue->begin(); it != pMrkGlue->end(); ++it)
823 : {
824 0 : sal_uInt16 nId=*it;
825 : //nNum changed to nNumGP because already used in for loop
826 0 : sal_uInt16 nNumGP=pGPL->FindGluePoint(nId);
827 0 : if (nNumGP!=SDRGLUEPOINT_NOTFOUND)
828 : {
829 0 : const SdrGluePoint& rGP=(*pGPL)[nNumGP];
830 0 : Point aPos(rGP.GetAbsolutePos(*pObj));
831 0 : SdrHdl* pGlueHdl=new SdrHdl(aPos,HDL_GLUE);
832 0 : pGlueHdl->SetObj(pObj);
833 0 : pGlueHdl->SetPageView(pPV);
834 0 : pGlueHdl->SetObjHdlNum(nId);
835 0 : aHdl.AddHdl(pGlueHdl);
836 : }
837 : }
838 : }
839 : }
840 : }
841 :
842 : // rotation point/axis of reflection
843 60219 : AddDragModeHdl(eDragMode);
844 :
845 : // sort handles
846 60219 : aHdl.Sort();
847 :
848 : // add custom handles (used by other apps, e.g. AnchorPos)
849 60219 : AddCustomHdl();
850 :
851 : // try to restore focus handle index from remembered values
852 60219 : if(bSaveOldFocus)
853 : {
854 0 : for(size_t a = 0; a < aHdl.GetHdlCount(); ++a)
855 : {
856 0 : SdrHdl* pCandidate = aHdl.GetHdl(a);
857 :
858 0 : if(pCandidate->GetObj()
859 0 : && pCandidate->GetObj() == pSaveObj
860 0 : && pCandidate->GetKind() == eSaveKind
861 0 : && pCandidate->GetPolyNum() == nSavePolyNum
862 0 : && pCandidate->GetPointNum() == nSavePointNum)
863 : {
864 0 : aHdl.SetFocusHdl(pCandidate);
865 0 : break;
866 : }
867 : }
868 : }
869 : }
870 : }
871 :
872 5840 : void SdrMarkView::AddCustomHdl()
873 : {
874 : // add custom handles (used by other apps, e.g. AnchorPos)
875 5840 : }
876 :
877 1642 : void SdrMarkView::SetDragMode(SdrDragMode eMode)
878 : {
879 1642 : SdrDragMode eMode0=eDragMode;
880 1642 : eDragMode=eMode;
881 1642 : if (eDragMode==SDRDRAG_RESIZE) eDragMode=SDRDRAG_MOVE;
882 1642 : if (eDragMode!=eMode0) {
883 0 : ForceRefToMarked();
884 0 : SetMarkHandles();
885 : {
886 0 : if (AreObjectsMarked()) MarkListHasChanged();
887 : }
888 : }
889 1642 : }
890 :
891 60219 : void SdrMarkView::AddDragModeHdl(SdrDragMode eMode)
892 : {
893 60219 : switch(eMode)
894 : {
895 : case SDRDRAG_ROTATE:
896 : {
897 : // add rotation center
898 0 : SdrHdl* pHdl = new SdrHdl(aRef1, HDL_REF1);
899 :
900 0 : aHdl.AddHdl(pHdl);
901 :
902 0 : break;
903 : }
904 : case SDRDRAG_MIRROR:
905 : {
906 : // add axis of reflection
907 0 : SdrHdl* pHdl3 = new SdrHdl(aRef2, HDL_REF2);
908 0 : SdrHdl* pHdl2 = new SdrHdl(aRef1, HDL_REF1);
909 0 : SdrHdl* pHdl1 = new SdrHdlLine(*pHdl2, *pHdl3, HDL_MIRX);
910 :
911 0 : pHdl1->SetObjHdlNum(1); // for sorting
912 0 : pHdl2->SetObjHdlNum(2); // for sorting
913 0 : pHdl3->SetObjHdlNum(3); // for sorting
914 :
915 0 : aHdl.AddHdl(pHdl1); // line comes first, so it is the last in HitTest
916 0 : aHdl.AddHdl(pHdl2);
917 0 : aHdl.AddHdl(pHdl3);
918 :
919 0 : break;
920 : }
921 : case SDRDRAG_TRANSPARENCE:
922 : {
923 : // add interactive transparency handle
924 0 : const size_t nMarkAnz = GetMarkedObjectCount();
925 0 : if(nMarkAnz == 1)
926 : {
927 0 : SdrObject* pObj = GetMarkedObjectByIndex(0);
928 0 : SdrModel* pModel = GetModel();
929 0 : const SfxItemSet& rSet = pObj->GetMergedItemSet();
930 :
931 0 : if(SfxItemState::SET != rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, false))
932 : {
933 : // add this item, it's not yet there
934 : XFillFloatTransparenceItem aNewItem(
935 0 : static_cast<const XFillFloatTransparenceItem&>(rSet.Get(XATTR_FILLFLOATTRANSPARENCE)));
936 0 : XGradient aGrad = aNewItem.GetGradientValue();
937 :
938 0 : aNewItem.SetEnabled(true);
939 0 : aGrad.SetStartIntens(100);
940 0 : aGrad.SetEndIntens(100);
941 0 : aNewItem.SetGradientValue(aGrad);
942 :
943 : // add undo to allow user to take back this step
944 0 : if( pModel->IsUndoEnabled() )
945 : {
946 0 : pModel->BegUndo(SVX_RESSTR(SIP_XA_FILLTRANSPARENCE));
947 0 : pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
948 0 : pModel->EndUndo();
949 : }
950 :
951 0 : SfxItemSet aNewSet(pModel->GetItemPool());
952 0 : aNewSet.Put(aNewItem);
953 0 : pObj->SetMergedItemSetAndBroadcast(aNewSet);
954 : }
955 :
956 : // set values and transform to vector set
957 0 : GradTransformer aGradTransformer;
958 0 : GradTransVector aGradTransVector;
959 0 : GradTransGradient aGradTransGradient;
960 :
961 0 : aGradTransGradient.aGradient = static_cast<const XFillFloatTransparenceItem&>(rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
962 0 : aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
963 :
964 : // build handles
965 0 : const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
966 0 : const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
967 0 : SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, true);
968 0 : SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, true);
969 0 : SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, false);
970 : DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Could not get all necessary handles!");
971 :
972 : // link them
973 0 : pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
974 0 : pGradHdl->SetObj(pObj);
975 0 : pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
976 0 : pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
977 :
978 : // insert them
979 0 : aHdl.AddHdl(pColHdl1);
980 0 : aHdl.AddHdl(pColHdl2);
981 0 : aHdl.AddHdl(pGradHdl);
982 : }
983 0 : break;
984 : }
985 : case SDRDRAG_GRADIENT:
986 : {
987 : // add interactive gradient handle
988 0 : const size_t nMarkAnz = GetMarkedObjectCount();
989 0 : if(nMarkAnz == 1)
990 : {
991 0 : SdrObject* pObj = GetMarkedObjectByIndex(0);
992 0 : const SfxItemSet& rSet = pObj->GetMergedItemSet();
993 0 : drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(rSet.Get(XATTR_FILLSTYLE)).GetValue();
994 :
995 0 : if(eFillStyle == drawing::FillStyle_GRADIENT)
996 : {
997 : // set values and transform to vector set
998 0 : GradTransformer aGradTransformer;
999 0 : GradTransVector aGradTransVector;
1000 0 : GradTransGradient aGradTransGradient;
1001 0 : Size aHdlSize(15, 15);
1002 :
1003 0 : aGradTransGradient.aGradient = static_cast<const XFillGradientItem&>(rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
1004 0 : aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
1005 :
1006 : // build handles
1007 0 : const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
1008 0 : const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
1009 0 : SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, false);
1010 0 : SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, false);
1011 0 : SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, true);
1012 : DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Could not get all necessary handles!");
1013 :
1014 : // link them
1015 0 : pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
1016 0 : pGradHdl->SetObj(pObj);
1017 0 : pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1018 0 : pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
1019 :
1020 : // insert them
1021 0 : aHdl.AddHdl(pColHdl1);
1022 0 : aHdl.AddHdl(pColHdl2);
1023 0 : aHdl.AddHdl(pGradHdl);
1024 : }
1025 : }
1026 0 : break;
1027 : }
1028 : case SDRDRAG_CROP:
1029 : {
1030 : // TODO
1031 0 : break;
1032 : }
1033 60219 : default: break;
1034 : }
1035 60219 : }
1036 :
1037 : /** handle mouse over effects for handles */
1038 0 : bool SdrMarkView::MouseMove(const MouseEvent& rMEvt, vcl::Window* pWin)
1039 : {
1040 0 : if(aHdl.GetHdlCount())
1041 : {
1042 0 : SdrHdl* pMouseOverHdl = 0;
1043 0 : if( !rMEvt.IsLeaveWindow() && pWin )
1044 : {
1045 0 : Point aMDPos( pWin->PixelToLogic( rMEvt.GetPosPixel() ) );
1046 0 : pMouseOverHdl = PickHandle(aMDPos);
1047 : }
1048 :
1049 : // notify last mouse over handle that he lost the mouse
1050 0 : const size_t nHdlCount = aHdl.GetHdlCount();
1051 :
1052 0 : for(size_t nHdl = 0; nHdl < nHdlCount; ++nHdl)
1053 : {
1054 0 : SdrHdl* pCurrentHdl = GetHdl(nHdl);
1055 0 : if( pCurrentHdl->mbMouseOver )
1056 : {
1057 0 : if( pCurrentHdl != pMouseOverHdl )
1058 : {
1059 0 : pCurrentHdl->mbMouseOver = false;
1060 0 : pCurrentHdl->onMouseLeave();
1061 : }
1062 0 : break;
1063 : }
1064 : }
1065 :
1066 : // notify current mouse over handle
1067 0 : if( pMouseOverHdl )
1068 : {
1069 0 : pMouseOverHdl->mbMouseOver = true;
1070 0 : pMouseOverHdl->onMouseEnter(rMEvt);
1071 : }
1072 : }
1073 0 : return SdrSnapView::MouseMove(rMEvt, pWin);
1074 : }
1075 :
1076 0 : void SdrMarkView::ForceRefToMarked()
1077 : {
1078 0 : switch(eDragMode)
1079 : {
1080 : case SDRDRAG_ROTATE:
1081 : {
1082 0 : Rectangle aR(GetMarkedObjRect());
1083 0 : aRef1 = aR.Center();
1084 :
1085 0 : break;
1086 : }
1087 :
1088 : case SDRDRAG_MIRROR:
1089 : {
1090 : // first calculate the length of the axis of reflection
1091 0 : long nOutMin=0;
1092 0 : long nOutMax=0;
1093 0 : long nMinLen=0;
1094 0 : long nObjDst=0;
1095 0 : long nOutHgt=0;
1096 0 : OutputDevice* pOut=GetFirstOutputDevice();
1097 0 : if (pOut!=NULL) {
1098 : // minimum length: 50 pixels
1099 0 : nMinLen=pOut->PixelToLogic(Size(0,50)).Height();
1100 : // 20 pixels distance to the Obj for the reference point
1101 0 : nObjDst=pOut->PixelToLogic(Size(0,20)).Height();
1102 : // MinY/MaxY
1103 : // margin = minimum length = 10 pixels
1104 0 : long nDst=pOut->PixelToLogic(Size(0,10)).Height();
1105 0 : nOutMin=-pOut->GetMapMode().GetOrigin().Y();
1106 0 : nOutMax=pOut->GetOutputSize().Height()-1+nOutMin;
1107 0 : nOutMin+=nDst;
1108 0 : nOutMax-=nDst;
1109 : // absolute minimum length, however, is 10 pixels
1110 0 : if (nOutMax-nOutMin<nDst) {
1111 0 : nOutMin+=nOutMax+1;
1112 0 : nOutMin/=2;
1113 0 : nOutMin-=(nDst+1)/2;
1114 0 : nOutMax=nOutMin+nDst;
1115 : }
1116 0 : nOutHgt=nOutMax-nOutMin;
1117 : // otherwise minimum length = 1/4 OutHgt
1118 0 : long nTemp=nOutHgt/4;
1119 0 : if (nTemp>nMinLen) nMinLen=nTemp;
1120 : }
1121 :
1122 0 : Rectangle aR(GetMarkedObjBoundRect());
1123 0 : Point aCenter(aR.Center());
1124 0 : long nMarkHgt=aR.GetHeight()-1;
1125 0 : long nHgt=nMarkHgt+nObjDst*2; // 20 pixels overlapping above and below
1126 0 : if (nHgt<nMinLen) nHgt=nMinLen; // minimum length 50 pixels or 1/4 OutHgt, respectively
1127 :
1128 0 : long nY1=aCenter.Y()-(nHgt+1)/2;
1129 0 : long nY2=nY1+nHgt;
1130 :
1131 0 : if (pOut!=NULL && nMinLen>nOutHgt) nMinLen=nOutHgt; // TODO: maybe shorten this a little
1132 :
1133 0 : if (pOut!=NULL) { // now move completely into the visible area
1134 0 : if (nY1<nOutMin) {
1135 0 : nY1=nOutMin;
1136 0 : if (nY2<nY1+nMinLen) nY2=nY1+nMinLen;
1137 : }
1138 0 : if (nY2>nOutMax) {
1139 0 : nY2=nOutMax;
1140 0 : if (nY1>nY2-nMinLen) nY1=nY2-nMinLen;
1141 : }
1142 : }
1143 :
1144 0 : aRef1.X()=aCenter.X();
1145 0 : aRef1.Y()=nY1;
1146 0 : aRef2.X()=aCenter.X();
1147 0 : aRef2.Y()=nY2;
1148 :
1149 0 : break;
1150 : }
1151 :
1152 : case SDRDRAG_TRANSPARENCE:
1153 : case SDRDRAG_GRADIENT:
1154 : case SDRDRAG_CROP:
1155 : {
1156 0 : Rectangle aRect(GetMarkedObjBoundRect());
1157 0 : aRef1 = aRect.TopLeft();
1158 0 : aRef2 = aRect.BottomRight();
1159 0 : break;
1160 : }
1161 0 : default: break;
1162 : }
1163 0 : }
1164 :
1165 0 : void SdrMarkView::SetRef1(const Point& rPt)
1166 : {
1167 0 : if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
1168 : {
1169 0 : aRef1 = rPt;
1170 0 : SdrHdl* pH = aHdl.GetHdl(HDL_REF1);
1171 0 : if(pH)
1172 0 : pH->SetPos(rPt);
1173 : }
1174 0 : }
1175 :
1176 0 : void SdrMarkView::SetRef2(const Point& rPt)
1177 : {
1178 0 : if(eDragMode == SDRDRAG_MIRROR)
1179 : {
1180 0 : aRef2 = rPt;
1181 0 : SdrHdl* pH = aHdl.GetHdl(HDL_REF2);
1182 0 : if(pH)
1183 0 : pH->SetPos(rPt);
1184 : }
1185 0 : }
1186 :
1187 90021 : void SdrMarkView::CheckMarked()
1188 : {
1189 181617 : for (size_t nm=GetMarkedObjectCount(); nm>0;) {
1190 1575 : --nm;
1191 1575 : SdrMark* pM=GetSdrMarkByIndex(nm);
1192 1575 : SdrObject* pObj=pM->GetMarkedSdrObj();
1193 1575 : SdrPageView* pPV=pM->GetPageView();
1194 1575 : SdrLayerID nLay=pObj->GetLayer();
1195 1575 : bool bRaus=!pObj->IsInserted(); // Obj deleted?
1196 1575 : if (!pObj->Is3DObj()) {
1197 1575 : bRaus=bRaus || pObj->GetPage()!=pPV->GetPage(); // Obj suddenly in different Page or Group
1198 : }
1199 3150 : bRaus=bRaus || pPV->GetLockedLayers().IsSet(nLay) || // Layer locked?
1200 3150 : !pPV->GetVisibleLayers().IsSet(nLay); // Layer invisible?
1201 :
1202 1575 : if( !bRaus )
1203 1575 : bRaus = !pObj->IsVisible(); // invisible objects can not be selected
1204 :
1205 1575 : if (!bRaus) {
1206 : // Grouped objects can now be selected.
1207 : // After EnterGroup the higher-level objects,
1208 : // have to be deselected, though.
1209 1575 : const SdrObjList* pOOL=pObj->GetObjList();
1210 1575 : const SdrObjList* pVOL=pPV->GetObjList();
1211 3150 : while (pOOL!=NULL && pOOL!=pVOL) {
1212 0 : pOOL=pOOL->GetUpList();
1213 : }
1214 1575 : bRaus=pOOL!=pVOL;
1215 : }
1216 :
1217 1575 : if (bRaus)
1218 : {
1219 0 : GetMarkedObjectListWriteAccess().DeleteMark(nm);
1220 : }
1221 : else
1222 : {
1223 1575 : if (!IsGluePointEditMode()) { // selected glue points only in GlueEditMode
1224 1575 : SdrUShortCont* pPts=pM->GetMarkedGluePoints();
1225 1575 : if (pPts!=NULL) {
1226 0 : pPts->clear();
1227 : }
1228 : }
1229 : }
1230 : }
1231 :
1232 : // at least reset the remembered BoundRect to prevent handle
1233 : // generation if bForceFrameHandles is TRUE.
1234 90021 : bMarkedObjRectDirty = true;
1235 90021 : }
1236 :
1237 86459 : void SdrMarkView::SetMarkRects()
1238 : {
1239 86459 : SdrPageView* pPV = GetSdrPageView();
1240 :
1241 86459 : if(pPV)
1242 : {
1243 74506 : pPV->SetHasMarkedObj(GetSnapRectFromMarkedObjects(pPV, pPV->MarkSnap()));
1244 74506 : GetBoundRectFromMarkedObjects(pPV, pPV->MarkBound());
1245 : }
1246 86459 : }
1247 :
1248 8238 : void SdrMarkView::SetFrameHandles(bool bOn)
1249 : {
1250 8238 : if (bOn!=bForceFrameHandles) {
1251 6462 : bool bOld=ImpIsFrameHandles();
1252 6462 : bForceFrameHandles=bOn;
1253 6462 : bool bNew=ImpIsFrameHandles();
1254 6462 : if (bNew!=bOld) {
1255 6462 : AdjustMarkHdl();
1256 6462 : MarkListHasChanged();
1257 : }
1258 : }
1259 8238 : }
1260 :
1261 550 : void SdrMarkView::SetEditMode(SdrViewEditMode eMode)
1262 : {
1263 550 : if (eMode!=eEditMode) {
1264 0 : bool bGlue0=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1265 0 : bool bEdge0=static_cast<SdrCreateView*>(this)->IsEdgeTool();
1266 0 : eEditMode0=eEditMode;
1267 0 : eEditMode=eMode;
1268 0 : bool bGlue1=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
1269 0 : bool bEdge1=static_cast<SdrCreateView*>(this)->IsEdgeTool();
1270 : // avoid flickering when switching between GlueEdit and EdgeTool
1271 0 : if (bGlue1 && !bGlue0) ImpSetGlueVisible2(bGlue1);
1272 0 : if (bEdge1!=bEdge0) ImpSetGlueVisible3(bEdge1);
1273 0 : if (!bGlue1 && bGlue0) ImpSetGlueVisible2(bGlue1);
1274 0 : if (bGlue0 && !bGlue1) UnmarkAllGluePoints();
1275 : }
1276 550 : }
1277 :
1278 :
1279 :
1280 1228 : bool SdrMarkView::IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const
1281 : {
1282 1228 : if (pObj)
1283 : {
1284 2458 : if (pObj->IsMarkProtect() ||
1285 1772 : (!bDesignMode && pObj->IsUnoObj()))
1286 : {
1287 : // object not selectable or
1288 : // SdrUnoObj not in DesignMode
1289 2 : return false;
1290 : }
1291 : }
1292 1226 : return pPV==NULL || pPV->IsObjMarkable(pObj);
1293 : }
1294 :
1295 0 : bool SdrMarkView::IsMarkedObjHit(const Point& rPnt, short nTol) const
1296 : {
1297 0 : bool bRet=false;
1298 0 : nTol=ImpGetHitTolLogic(nTol,NULL);
1299 0 : Point aPt(rPnt);
1300 0 : for (size_t nm=0; nm<GetMarkedObjectCount() && !bRet; ++nm) {
1301 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
1302 0 : bRet = 0 != CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0);
1303 : }
1304 0 : return bRet;
1305 : }
1306 :
1307 4738 : SdrHdl* SdrMarkView::PickHandle(const Point& rPnt, sal_uIntPtr nOptions, SdrHdl* pHdl0) const
1308 : {
1309 4738 : if (bSomeObjChgdFlag) { // recalculate handles, if necessary
1310 1933 : FlushComeBackTimer();
1311 : }
1312 4738 : bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1313 4738 : bool bNext=(nOptions & SDRSEARCH_NEXT) !=0;
1314 4738 : Point aPt(rPnt);
1315 4738 : return aHdl.IsHdlListHit(aPt,bBack,bNext,pHdl0);
1316 : }
1317 :
1318 0 : bool SdrMarkView::MarkObj(const Point& rPnt, short nTol, bool bToggle, bool bDeep)
1319 : {
1320 : SdrObject* pObj;
1321 : SdrPageView* pPV;
1322 0 : nTol=ImpGetHitTolLogic(nTol,NULL);
1323 0 : sal_uIntPtr nOptions=SDRSEARCH_PICKMARKABLE;
1324 0 : if (bDeep) nOptions=nOptions|SDRSEARCH_DEEP;
1325 0 : bool bRet=PickObj(rPnt,(sal_uInt16)nTol,pObj,pPV,nOptions);
1326 0 : if (bRet) {
1327 0 : bool bUnmark=bToggle && IsObjMarked(pObj);
1328 0 : MarkObj(pObj,pPV,bUnmark);
1329 : }
1330 0 : return bRet;
1331 : }
1332 :
1333 0 : bool SdrMarkView::MarkNextObj(bool bPrev)
1334 : {
1335 0 : SdrPageView* pPageView = GetSdrPageView();
1336 :
1337 0 : if(!pPageView)
1338 : {
1339 0 : return false;
1340 : }
1341 :
1342 0 : SortMarkedObjects();
1343 0 : const size_t nMarkAnz=GetMarkedObjectCount();
1344 0 : size_t nChgMarkNum = SAL_MAX_SIZE; // number of the MarkEntry we want to replace
1345 0 : size_t nSearchObjNum = bPrev ? 0 : SAL_MAX_SIZE;
1346 0 : if (nMarkAnz!=0) {
1347 0 : nChgMarkNum=bPrev ? 0 : nMarkAnz-1;
1348 0 : SdrMark* pM=GetSdrMarkByIndex(nChgMarkNum);
1349 : OSL_ASSERT(pM!=NULL);
1350 0 : if (pM->GetMarkedSdrObj() != NULL)
1351 0 : nSearchObjNum = pM->GetMarkedSdrObj()->GetNavigationPosition();
1352 : }
1353 :
1354 0 : SdrObject* pMarkObj=NULL;
1355 0 : SdrObjList* pSearchObjList=pPageView->GetObjList();
1356 0 : const size_t nObjAnz = pSearchObjList->GetObjCount();
1357 0 : if (nObjAnz!=0) {
1358 0 : if (nSearchObjNum>nObjAnz) nSearchObjNum=nObjAnz;
1359 0 : while (pMarkObj==NULL && ((!bPrev && nSearchObjNum>0) || (bPrev && nSearchObjNum<nObjAnz)))
1360 : {
1361 0 : if (!bPrev)
1362 0 : nSearchObjNum--;
1363 0 : SdrObject* pSearchObj = pSearchObjList->GetObjectForNavigationPosition(nSearchObjNum);
1364 0 : if (IsObjMarkable(pSearchObj,pPageView))
1365 : {
1366 0 : if (TryToFindMarkedObject(pSearchObj)==SAL_MAX_SIZE)
1367 : {
1368 0 : pMarkObj=pSearchObj;
1369 : }
1370 : }
1371 0 : if (bPrev) nSearchObjNum++;
1372 : }
1373 : }
1374 :
1375 0 : if(!pMarkObj)
1376 : {
1377 0 : return false;
1378 : }
1379 :
1380 0 : if (nChgMarkNum!=SAL_MAX_SIZE)
1381 : {
1382 0 : GetMarkedObjectListWriteAccess().DeleteMark(nChgMarkNum);
1383 : }
1384 0 : MarkObj(pMarkObj,pPageView); // also calls MarkListHasChanged(), AdjustMarkHdl()
1385 0 : return true;
1386 : }
1387 :
1388 0 : bool SdrMarkView::MarkNextObj(const Point& rPnt, short nTol, bool bPrev)
1389 : {
1390 0 : SortMarkedObjects();
1391 0 : nTol=ImpGetHitTolLogic(nTol,NULL);
1392 0 : Point aPt(rPnt);
1393 0 : SdrMark* pTopMarkHit=NULL;
1394 0 : SdrMark* pBtmMarkHit=NULL;
1395 0 : size_t nTopMarkHit=0;
1396 0 : size_t nBtmMarkHit=0;
1397 : // find topmost of the selected objects that is hit by rPnt
1398 0 : const size_t nMarkAnz=GetMarkedObjectCount();
1399 0 : for (size_t nm=nMarkAnz; nm>0 && pTopMarkHit==NULL;) {
1400 0 : --nm;
1401 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
1402 0 : if(CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0))
1403 : {
1404 0 : pTopMarkHit=pM;
1405 0 : nTopMarkHit=nm;
1406 : }
1407 : }
1408 : // nothing found, in this case, just select an object
1409 0 : if (pTopMarkHit==NULL) return MarkObj(rPnt,sal_uInt16(nTol),false);
1410 :
1411 0 : SdrObject* pTopObjHit=pTopMarkHit->GetMarkedSdrObj();
1412 0 : SdrObjList* pObjList=pTopObjHit->GetObjList();
1413 0 : SdrPageView* pPV=pTopMarkHit->GetPageView();
1414 : // find lowermost of the selected objects that is hit by rPnt
1415 : // and is placed on the same PageView as pTopMarkHit
1416 0 : for (size_t nm=0; nm<nMarkAnz && pBtmMarkHit==NULL; ++nm) {
1417 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
1418 0 : SdrPageView* pPV2=pM->GetPageView();
1419 0 : if (pPV2==pPV && CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pPV2,0,0))
1420 : {
1421 0 : pBtmMarkHit=pM;
1422 0 : nBtmMarkHit=nm;
1423 : }
1424 : }
1425 0 : if (pBtmMarkHit==NULL) { pBtmMarkHit=pTopMarkHit; nBtmMarkHit=nTopMarkHit; }
1426 0 : SdrObject* pBtmObjHit=pBtmMarkHit->GetMarkedSdrObj();
1427 0 : const size_t nObjAnz = pObjList->GetObjCount();
1428 :
1429 0 : size_t nSearchBeg = 0;
1430 0 : E3dScene* pScene = NULL;
1431 0 : SdrObject* pObjHit = (bPrev) ? pBtmObjHit : pTopObjHit;
1432 0 : bool bRemap = pObjHit->ISA(E3dCompoundObject)
1433 : ? static_cast<E3dCompoundObject*>(pObjHit)->IsAOrdNumRemapCandidate(pScene)
1434 0 : : false;
1435 :
1436 0 : if(bPrev)
1437 : {
1438 0 : sal_uInt32 nOrdNumBtm(pBtmObjHit->GetOrdNum());
1439 :
1440 0 : if(bRemap)
1441 : {
1442 0 : nOrdNumBtm = pScene->RemapOrdNum(nOrdNumBtm);
1443 : }
1444 :
1445 0 : nSearchBeg = nOrdNumBtm + 1;
1446 : }
1447 : else
1448 : {
1449 0 : sal_uInt32 nOrdNumTop(pTopObjHit->GetOrdNum());
1450 :
1451 0 : if(bRemap)
1452 : {
1453 0 : nOrdNumTop = pScene->RemapOrdNum(nOrdNumTop);
1454 : }
1455 :
1456 0 : nSearchBeg = nOrdNumTop;
1457 : }
1458 :
1459 0 : size_t no=nSearchBeg;
1460 0 : SdrObject* pFndObj=NULL;
1461 0 : while (pFndObj==NULL && ((!bPrev && no>0) || (bPrev && no<nObjAnz))) {
1462 0 : if (!bPrev) no--;
1463 : SdrObject* pObj;
1464 :
1465 0 : if(bRemap)
1466 : {
1467 0 : pObj = pObjList->GetObj(pScene->RemapOrdNum(no));
1468 : }
1469 : else
1470 : {
1471 0 : pObj = pObjList->GetObj(no);
1472 : }
1473 :
1474 0 : if (CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_TESTMARKABLE,0))
1475 : {
1476 0 : if (TryToFindMarkedObject(pObj)==SAL_MAX_SIZE) {
1477 0 : pFndObj=pObj;
1478 : } else {
1479 : // TODO: for performance reasons set on to Top or Btm, if necessary
1480 : }
1481 : }
1482 0 : if (bPrev) no++;
1483 : }
1484 0 : if (pFndObj!=NULL)
1485 : {
1486 0 : GetMarkedObjectListWriteAccess().DeleteMark(bPrev?nBtmMarkHit:nTopMarkHit);
1487 0 : GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pFndObj,pPV));
1488 0 : MarkListHasChanged();
1489 0 : AdjustMarkHdl();
1490 : }
1491 0 : return pFndObj!=NULL;
1492 : }
1493 :
1494 0 : bool SdrMarkView::MarkObj(const Rectangle& rRect, bool bUnmark)
1495 : {
1496 0 : bool bFnd=false;
1497 0 : Rectangle aR(rRect);
1498 : SdrObjList* pObjList;
1499 0 : BrkAction();
1500 0 : SdrPageView* pPV = GetSdrPageView();
1501 :
1502 0 : if(pPV)
1503 : {
1504 0 : pObjList=pPV->GetObjList();
1505 0 : Rectangle aFrm1(aR);
1506 0 : const size_t nObjAnz = pObjList->GetObjCount();
1507 : SdrObject* pObj;
1508 0 : for (size_t nO=0; nO<nObjAnz; ++nO) {
1509 0 : pObj=pObjList->GetObj(nO);
1510 0 : Rectangle aRect(pObj->GetCurrentBoundRect());
1511 0 : if (aFrm1.IsInside(aRect)) {
1512 0 : if (!bUnmark) {
1513 0 : if (IsObjMarkable(pObj,pPV))
1514 : {
1515 0 : GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1516 0 : bFnd=true;
1517 : }
1518 : } else {
1519 0 : const size_t nPos=TryToFindMarkedObject(pObj);
1520 0 : if (nPos!=SAL_MAX_SIZE)
1521 : {
1522 0 : GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1523 0 : bFnd=true;
1524 : }
1525 : }
1526 : }
1527 : }
1528 : }
1529 0 : if (bFnd) {
1530 0 : SortMarkedObjects();
1531 0 : MarkListHasChanged();
1532 0 : AdjustMarkHdl();
1533 : }
1534 0 : return bFnd;
1535 : }
1536 :
1537 1038 : void SdrMarkView::MarkObj(SdrObject* pObj, SdrPageView* pPV, bool bUnmark, bool bImpNoSetMarkHdl)
1538 : {
1539 1038 : if (pObj!=NULL && pPV!=NULL && IsObjMarkable(pObj, pPV)) {
1540 1038 : BrkAction();
1541 1038 : if (!bUnmark)
1542 : {
1543 1016 : GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
1544 : }
1545 : else
1546 : {
1547 22 : const size_t nPos=TryToFindMarkedObject(pObj);
1548 22 : if (nPos!=SAL_MAX_SIZE)
1549 : {
1550 0 : GetMarkedObjectListWriteAccess().DeleteMark(nPos);
1551 : }
1552 : }
1553 1038 : if (!bImpNoSetMarkHdl) {
1554 884 : MarkListHasChanged();
1555 884 : AdjustMarkHdl();
1556 : }
1557 : }
1558 1038 : }
1559 :
1560 8 : bool SdrMarkView::IsObjMarked(SdrObject* pObj) const
1561 : {
1562 8 : return TryToFindMarkedObject(pObj)!=SAL_MAX_SIZE;
1563 : }
1564 :
1565 14842 : sal_uInt16 SdrMarkView::GetMarkHdlSizePixel() const
1566 : {
1567 14842 : return aHdl.GetHdlSize()*2+1;
1568 : }
1569 :
1570 8022 : void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz)
1571 : {
1572 8022 : if (nSiz<3) nSiz=3;
1573 8022 : nSiz/=2;
1574 8022 : if (nSiz!=aHdl.GetHdlSize()) {
1575 6110 : aHdl.SetHdlSize(nSiz);
1576 : }
1577 8022 : }
1578 :
1579 : #define SDRSEARCH_IMPISMASTER 0x80000000 /* MasterPage is being searched right now */
1580 7222 : SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay) const
1581 : {
1582 7222 : if(((nOptions & SDRSEARCH_IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible()))
1583 : {
1584 480 : return NULL;
1585 : }
1586 :
1587 6742 : const bool bCheckIfMarkable(nOptions & SDRSEARCH_TESTMARKABLE);
1588 6742 : const bool bDeep(nOptions & SDRSEARCH_DEEP);
1589 6742 : const bool bOLE(pObj->ISA(SdrOle2Obj));
1590 6742 : const bool bTXT(pObj->ISA(SdrTextObj) && static_cast<SdrTextObj*>(pObj)->IsTextFrame());
1591 6742 : SdrObject* pRet=NULL;
1592 6742 : Rectangle aRect(pObj->GetCurrentBoundRect());
1593 : // hack for calc grid sync
1594 6742 : aRect += pObj->GetGridOffset();
1595 6742 : sal_uInt16 nTol2(nTol);
1596 :
1597 : // double tolerance for OLE, text frames and objects in
1598 : // active text edit
1599 6742 : if(bOLE || bTXT || pObj==static_cast<const SdrObjEditView*>(this)->GetTextEditObject())
1600 : {
1601 1400 : nTol2*=2;
1602 : }
1603 :
1604 6742 : aRect.Left ()-=nTol2; // add 1 tolerance for all objects
1605 6742 : aRect.Top ()-=nTol2;
1606 6742 : aRect.Right ()+=nTol2;
1607 6742 : aRect.Bottom()+=nTol2;
1608 :
1609 6742 : if (aRect.IsInside(rPnt))
1610 : {
1611 186 : if ((!bCheckIfMarkable || IsObjMarkable(pObj,pPV)))
1612 : {
1613 102 : SdrObjList* pOL=pObj->GetSubList();
1614 :
1615 102 : if (pOL!=NULL && pOL->GetObjCount()!=0)
1616 : {
1617 : SdrObject* pTmpObj;
1618 : // adjustment hit point for virtual objects
1619 4 : Point aPnt( rPnt );
1620 :
1621 4 : if ( pObj->ISA(SdrVirtObj) )
1622 : {
1623 0 : Point aOffset = static_cast<SdrVirtObj*>(pObj)->GetOffset();
1624 0 : aPnt.Move( -aOffset.X(), -aOffset.Y() );
1625 : }
1626 :
1627 4 : pRet=CheckSingleSdrObjectHit(aPnt,nTol,pOL,pPV,nOptions,pMVisLay,pTmpObj);
1628 : }
1629 : else
1630 : {
1631 98 : if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer()))
1632 : {
1633 98 : pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false);
1634 : }
1635 : }
1636 : }
1637 : }
1638 :
1639 6742 : if (!bDeep && pRet!=NULL)
1640 : {
1641 10 : pRet=pObj;
1642 : }
1643 :
1644 6742 : return pRet;
1645 : }
1646 :
1647 4 : SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList* pOL, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj) const
1648 : {
1649 4 : return (*this).CheckSingleSdrObjectHit(rPnt,nTol,pOL,pPV,nOptions,pMVisLay,rpRootObj,NULL);
1650 : }
1651 5862 : 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
1652 : {
1653 5862 : bool bBack=(nOptions & SDRSEARCH_BACKWARD)!=0;
1654 5862 : bool bBefMrk=(nOptions & SDRSEARCH_BEFOREMARK)!=0;
1655 5862 : SdrObject* pRet=NULL;
1656 5862 : rpRootObj=NULL;
1657 5862 : if (pOL!=NULL)
1658 : {
1659 5862 : bool bRemap(pOL->GetOwnerObj() && pOL->GetOwnerObj()->ISA(E3dScene));
1660 5862 : E3dScene* pRemapScene = (bRemap ? static_cast<E3dScene*>(pOL->GetOwnerObj()) : 0L);
1661 :
1662 5862 : const size_t nObjAnz=pOL->GetObjCount();
1663 5862 : size_t nObjNum=bBack ? 0 : nObjAnz;
1664 18946 : while (pRet==NULL && (bBack ? nObjNum<nObjAnz : nObjNum>0)) {
1665 7222 : if (!bBack) nObjNum--;
1666 : SdrObject* pObj;
1667 :
1668 7222 : if(bRemap)
1669 : {
1670 0 : pObj = pOL->GetObj(pRemapScene->RemapOrdNum(nObjNum));
1671 : }
1672 : else
1673 : {
1674 7222 : pObj = pOL->GetObj(nObjNum);
1675 : }
1676 7222 : if (bBefMrk)
1677 : {
1678 0 : if ((pMarkList)!=NULL)
1679 : {
1680 0 : if ((*pMarkList).FindObject(pObj)!=SAL_MAX_SIZE)
1681 : {
1682 0 : return NULL;
1683 : }
1684 : }
1685 : }
1686 7222 : pRet=CheckSingleSdrObjectHit(rPnt,nTol,pObj,pPV,nOptions,pMVisLay);
1687 7222 : if (pRet!=NULL) rpRootObj=pObj;
1688 7222 : if (bBack) nObjNum++;
1689 : }
1690 : }
1691 5862 : return pRet;
1692 : }
1693 :
1694 4208 : bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions) const
1695 : {
1696 4208 : return PickObj(rPnt,nTol,rpObj,rpPV,nOptions,NULL,NULL);
1697 : }
1698 :
1699 5308 : bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions, SdrObject** ppRootObj, sal_uInt16* pnPassNum) const
1700 : { // TODO: lacks a Pass2,Pass3
1701 5308 : SortMarkedObjects();
1702 5308 : if (ppRootObj!=NULL) *ppRootObj=NULL;
1703 5308 : if (pnPassNum!=NULL) *pnPassNum=0;
1704 5308 : rpObj=NULL;
1705 5308 : rpPV=NULL;
1706 5308 : bool bWholePage=(nOptions & SDRSEARCH_WHOLEPAGE) !=0;
1707 5308 : bool bMarked=(nOptions & SDRSEARCH_MARKED) !=0;
1708 5308 : bool bMasters=!bMarked && (nOptions & SDRSEARCH_ALSOONMASTER) !=0;
1709 5308 : bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
1710 : #if OSL_DEBUG_LEVEL > 0
1711 : bool bNext=(nOptions & SDRSEARCH_NEXT) !=0; (void)bNext; // n.i.
1712 : bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; (void)bBoundCheckOn2ndPass;// n.i.
1713 : bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; (void)bCheckNearestOn3rdPass;// n.i.
1714 : #endif
1715 5308 : if (nTol<0) nTol=ImpGetHitTolLogic(nTol,NULL);
1716 5308 : Point aPt(rPnt);
1717 5308 : SdrObject* pObj=NULL;
1718 5308 : SdrObject* pHitObj=NULL;
1719 5308 : SdrPageView* pPV=NULL;
1720 5308 : if (!bBack && static_cast<const SdrObjEditView*>(this)->IsTextEditFrameHit(rPnt)) {
1721 0 : pObj=static_cast<const SdrObjEditView*>(this)->GetTextEditObject();
1722 0 : pHitObj=pObj;
1723 0 : pPV=static_cast<const SdrObjEditView*>(this)->GetTextEditPageView();
1724 : }
1725 5308 : if (bMarked) {
1726 550 : const size_t nMrkAnz=GetMarkedObjectCount();
1727 550 : size_t nMrkNum=bBack ? 0 : nMrkAnz;
1728 1100 : while (pHitObj==NULL && (bBack ? nMrkNum<nMrkAnz : nMrkNum>0)) {
1729 0 : if (!bBack) nMrkNum--;
1730 0 : SdrMark* pM=GetSdrMarkByIndex(nMrkNum);
1731 0 : pObj=pM->GetMarkedSdrObj();
1732 0 : pPV=pM->GetPageView();
1733 0 : pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,nOptions,NULL);
1734 0 : if (bBack) nMrkNum++;
1735 : }
1736 : }
1737 : else
1738 : {
1739 4758 : pPV = GetSdrPageView();
1740 :
1741 4758 : if(pPV)
1742 : {
1743 4758 : SdrPage* pPage=pPV->GetPage();
1744 4758 : sal_uInt16 nPgAnz=1;
1745 :
1746 4758 : if(bMasters && pPage->TRG_HasMasterPage())
1747 : {
1748 1100 : nPgAnz++;
1749 : }
1750 :
1751 4758 : bool bExtraPassForWholePage=bWholePage && pPage!=pPV->GetObjList();
1752 4758 : if (bExtraPassForWholePage) nPgAnz++; // First search in AktObjList, then on the entire page
1753 4758 : sal_uInt16 nPgNum=bBack ? 0 : nPgAnz;
1754 15374 : while (pHitObj==NULL && (bBack ? nPgNum<nPgAnz : nPgNum>0)) {
1755 5858 : sal_uIntPtr nTmpOptions=nOptions;
1756 5858 : if (!bBack) nPgNum--;
1757 5858 : const SetOfByte* pMVisLay=NULL;
1758 5858 : SdrObjList* pObjList=NULL;
1759 5858 : if (pnPassNum!=NULL) *pnPassNum&=~(SDRSEARCHPASS_MASTERPAGE|SDRSEARCHPASS_INACTIVELIST);
1760 5858 : if (nPgNum>=nPgAnz-1 || (bExtraPassForWholePage && nPgNum>=nPgAnz-2))
1761 : {
1762 4758 : pObjList=pPV->GetObjList();
1763 9516 : if (bExtraPassForWholePage && nPgNum==nPgAnz-2) {
1764 0 : pObjList=pPage;
1765 0 : if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_INACTIVELIST;
1766 : }
1767 : }
1768 : else
1769 : {
1770 : // otherwise MasterPage
1771 1100 : SdrPage& rMasterPage = pPage->TRG_GetMasterPage();
1772 1100 : pMVisLay = &pPage->TRG_GetMasterPageVisibleLayers();
1773 1100 : pObjList = &rMasterPage;
1774 :
1775 1100 : if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_MASTERPAGE;
1776 1100 : nTmpOptions=nTmpOptions | SDRSEARCH_IMPISMASTER;
1777 : }
1778 5858 : pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObjList,pPV,nTmpOptions,pMVisLay,pObj,&(GetMarkedObjectList()));
1779 5858 : if (bBack) nPgNum++;
1780 : }
1781 : }
1782 : }
1783 5308 : if (pHitObj!=NULL) {
1784 10 : if (ppRootObj!=NULL) *ppRootObj=pObj;
1785 10 : if ((nOptions & SDRSEARCH_DEEP) !=0) pObj=pHitObj;
1786 10 : if ((nOptions & SDRSEARCH_TESTTEXTEDIT) !=0) {
1787 0 : if (!pObj->HasTextEdit() || pPV->GetLockedLayers().IsSet(pObj->GetLayer())) {
1788 0 : pObj=NULL;
1789 : }
1790 : }
1791 10 : if (pObj!=NULL && (nOptions & SDRSEARCH_TESTMACRO) !=0) {
1792 0 : SdrObjMacroHitRec aHitRec;
1793 0 : aHitRec.aPos=aPt;
1794 0 : aHitRec.aDownPos=aPt;
1795 0 : aHitRec.nTol=nTol;
1796 0 : aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
1797 0 : aHitRec.pPageView=pPV;
1798 0 : if (!pObj->HasMacro() || !pObj->IsMacroHit(aHitRec)) pObj=NULL;
1799 : }
1800 10 : if (pObj!=NULL && (nOptions & SDRSEARCH_WITHTEXT) !=0 && pObj->GetOutlinerParaObject()==NULL) pObj=NULL;
1801 10 : if (pObj!=NULL && (nOptions & SDRSEARCH_TESTTEXTAREA) !=0 && pPV)
1802 : {
1803 0 : if(!SdrObjectPrimitiveHit(*pObj, aPt, 0, *pPV, 0, true))
1804 : {
1805 0 : pObj = 0;
1806 : }
1807 : }
1808 10 : if (pObj!=NULL) {
1809 10 : rpObj=pObj;
1810 10 : rpPV=pPV;
1811 10 : if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_DIRECT;
1812 : }
1813 : }
1814 5308 : return rpObj!=NULL;
1815 : }
1816 :
1817 0 : bool SdrMarkView::PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions) const
1818 : {
1819 0 : SortMarkedObjects();
1820 0 : bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0;
1821 0 : bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0;
1822 0 : rpObj=NULL;
1823 0 : rpPV=NULL;
1824 0 : Point aPt(rPnt);
1825 0 : sal_uInt16 nTol=(sal_uInt16)nHitTolLog;
1826 0 : bool bFnd=false;
1827 0 : const size_t nMarkAnz=GetMarkedObjectCount();
1828 0 : for (size_t nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1829 0 : --nMarkNum;
1830 0 : SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1831 0 : SdrPageView* pPV=pM->GetPageView();
1832 0 : SdrObject* pObj=pM->GetMarkedSdrObj();
1833 0 : bFnd = 0 != CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,SDRSEARCH_TESTMARKABLE,0);
1834 0 : if (bFnd) {
1835 0 : rpObj=pObj;
1836 0 : rpPV=pPV;
1837 : }
1838 : }
1839 0 : if ((bBoundCheckOn2ndPass || bCheckNearestOn3rdPass) && !bFnd) {
1840 0 : SdrObject* pBestObj=NULL;
1841 0 : SdrPageView* pBestPV=NULL;
1842 0 : sal_uIntPtr nBestDist=ULONG_MAX;
1843 0 : for (size_t nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
1844 0 : --nMarkNum;
1845 0 : SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
1846 0 : SdrPageView* pPV=pM->GetPageView();
1847 0 : SdrObject* pObj=pM->GetMarkedSdrObj();
1848 0 : Rectangle aRect(pObj->GetCurrentBoundRect());
1849 0 : aRect.Left ()-=nTol;
1850 0 : aRect.Top ()-=nTol;
1851 0 : aRect.Right ()+=nTol;
1852 0 : aRect.Bottom()+=nTol;
1853 0 : if (aRect.IsInside(aPt)) {
1854 0 : bFnd=true;
1855 0 : rpObj=pObj;
1856 0 : rpPV=pPV;
1857 0 : } else if (bCheckNearestOn3rdPass) {
1858 0 : sal_uIntPtr nDist=0;
1859 0 : if (aPt.X()<aRect.Left()) nDist+=aRect.Left()-aPt.X();
1860 0 : if (aPt.X()>aRect.Right()) nDist+=aPt.X()-aRect.Right();
1861 0 : if (aPt.Y()<aRect.Top()) nDist+=aRect.Top()-aPt.Y();
1862 0 : if (aPt.Y()>aRect.Bottom()) nDist+=aPt.Y()-aRect.Bottom();
1863 0 : if (nDist<nBestDist) {
1864 0 : pBestObj=pObj;
1865 0 : pBestPV=pPV;
1866 : }
1867 : }
1868 : }
1869 0 : if (bCheckNearestOn3rdPass && !bFnd) {
1870 0 : rpObj=pBestObj;
1871 0 : rpPV=pBestPV;
1872 0 : bFnd=pBestObj!=NULL;
1873 : }
1874 : }
1875 0 : return bFnd;
1876 : }
1877 :
1878 :
1879 3138 : void SdrMarkView::UnmarkAllObj(SdrPageView* pPV)
1880 : {
1881 3138 : if (GetMarkedObjectCount()!=0) {
1882 536 : BrkAction();
1883 536 : if (pPV!=NULL)
1884 : {
1885 12 : GetMarkedObjectListWriteAccess().DeletePageView(*pPV);
1886 : }
1887 : else
1888 : {
1889 524 : GetMarkedObjectListWriteAccess().Clear();
1890 : }
1891 536 : pMarkedObj=NULL;
1892 536 : pMarkedPV=NULL;
1893 536 : MarkListHasChanged();
1894 536 : AdjustMarkHdl();
1895 : }
1896 3138 : }
1897 :
1898 0 : void SdrMarkView::MarkAllObj(SdrPageView* _pPV)
1899 : {
1900 0 : BrkAction();
1901 :
1902 0 : if(!_pPV)
1903 : {
1904 0 : _pPV = GetSdrPageView();
1905 : }
1906 :
1907 : // #i69171# _pPV may still be NULL if there is no SDrPageView (!), e.g. when inserting
1908 : // other files
1909 0 : if(_pPV)
1910 : {
1911 0 : const bool bMarkChg(GetMarkedObjectListWriteAccess().InsertPageView(*_pPV));
1912 :
1913 0 : if(bMarkChg)
1914 : {
1915 0 : MarkListHasChanged();
1916 : }
1917 : }
1918 :
1919 0 : if(GetMarkedObjectCount())
1920 : {
1921 0 : AdjustMarkHdl();
1922 : }
1923 0 : }
1924 :
1925 86459 : void SdrMarkView::AdjustMarkHdl()
1926 : {
1927 86459 : CheckMarked();
1928 86459 : SetMarkRects();
1929 86459 : SetMarkHandles();
1930 86459 : }
1931 :
1932 516 : Rectangle SdrMarkView::GetMarkedObjBoundRect() const
1933 : {
1934 516 : Rectangle aRect;
1935 1032 : for (size_t nm=0; nm<GetMarkedObjectCount(); ++nm) {
1936 516 : SdrMark* pM=GetSdrMarkByIndex(nm);
1937 516 : SdrObject* pO=pM->GetMarkedSdrObj();
1938 516 : Rectangle aR1(pO->GetCurrentBoundRect());
1939 : // Ensure marked area includes the calc offset
1940 : // ( if applicable ) to sync to grid
1941 516 : aR1 += pO->GetGridOffset();
1942 516 : if (aRect.IsEmpty()) aRect=aR1;
1943 0 : else aRect.Union(aR1);
1944 : }
1945 516 : return aRect;
1946 : }
1947 :
1948 60219 : Point SdrMarkView::GetGridOffset() const
1949 : {
1950 60219 : Point aOffset;
1951 : // calculate the area occupied by the union of each marked object
1952 : // ( synced to grid ) and compare to the same unsynced area to calculate
1953 : // the offset. Hopefully that's the sensible thing to do
1954 60219 : const Rectangle& aGroupSyncedRect = GetMarkedObjRect();
1955 60219 : aOffset = aGroupSyncedRect.TopLeft() - aMarkedObjRectNoOffset.TopLeft();
1956 60219 : return aOffset;
1957 : }
1958 :
1959 114898 : const Rectangle& SdrMarkView::GetMarkedObjRect() const
1960 : {
1961 114898 : if (bMarkedObjRectDirty) {
1962 60227 : ((SdrMarkView*)this)->bMarkedObjRectDirty=false;
1963 60227 : Rectangle aRect;
1964 60227 : Rectangle aRect2;
1965 61292 : for (size_t nm=0; nm<GetMarkedObjectCount(); ++nm) {
1966 1065 : SdrMark* pM=GetSdrMarkByIndex(nm);
1967 1065 : SdrObject* pO=pM->GetMarkedSdrObj();
1968 1065 : Rectangle aR1(pO->GetSnapRect());
1969 : // apply calc offset to marked object rect
1970 : // ( necessary for handles to be displayed in
1971 : // correct position )
1972 1065 : if (aRect2.IsEmpty()) aRect2=aR1;
1973 583 : else aRect2.Union( aR1 );
1974 1065 : aR1 += pO->GetGridOffset();
1975 1065 : if (aRect.IsEmpty()) aRect=aR1;
1976 583 : else aRect.Union(aR1);
1977 : }
1978 60227 : ((SdrMarkView*)this)->aMarkedObjRect=aRect;
1979 60227 : ((SdrMarkView*)this)->aMarkedObjRectNoOffset=aRect2;
1980 : }
1981 114898 : return aMarkedObjRect;
1982 : }
1983 :
1984 :
1985 :
1986 0 : void SdrMarkView::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, OUString& rStr, sal_uInt16 nVal, sal_uInt16 nOpt) const
1987 : {
1988 0 : rStr = ImpGetResStr(nStrCacheID);
1989 0 : sal_Int32 nPos = rStr.indexOf("%1");
1990 :
1991 0 : if(nPos != -1)
1992 : {
1993 0 : if(nOpt == IMPSDR_POINTSDESCRIPTION)
1994 : {
1995 0 : rStr = rStr.replaceAt(nPos, 2, GetDescriptionOfMarkedPoints());
1996 : }
1997 0 : else if(nOpt == IMPSDR_GLUEPOINTSDESCRIPTION)
1998 : {
1999 0 : rStr = rStr.replaceAt(nPos, 2, GetDescriptionOfMarkedGluePoints());
2000 : }
2001 : else
2002 : {
2003 0 : rStr = rStr.replaceAt(nPos, 2, GetDescriptionOfMarkedObjects());
2004 : }
2005 : }
2006 :
2007 0 : rStr = rStr.replaceFirst("%2", OUString::number( nVal ));
2008 0 : }
2009 :
2010 :
2011 :
2012 0 : bool SdrMarkView::EnterMarkedGroup()
2013 : {
2014 0 : bool bRet=false;
2015 : // We enter only the first group found (in only one PageView), because
2016 : // PageView::EnterGroup calls an AdjustMarkHdl.
2017 : // TODO: I'll have to prevent that via a flag.
2018 0 : SdrPageView* pPV = GetSdrPageView();
2019 :
2020 0 : if(pPV)
2021 : {
2022 0 : bool bEnter=false;
2023 0 : for (size_t nm = GetMarkedObjectCount(); nm > 0 && !bEnter;)
2024 : {
2025 0 : --nm;
2026 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
2027 0 : if (pM->GetPageView()==pPV) {
2028 0 : SdrObject* pObj=pM->GetMarkedSdrObj();
2029 0 : if (pObj->IsGroupObject()) {
2030 0 : if (pPV->EnterGroup(pObj)) {
2031 0 : bRet=true;
2032 0 : bEnter=true;
2033 : }
2034 : }
2035 : }
2036 : }
2037 : }
2038 0 : return bRet;
2039 : }
2040 :
2041 :
2042 :
2043 8078 : void SdrMarkView::MarkListHasChanged()
2044 : {
2045 8078 : GetMarkedObjectListWriteAccess().SetNameDirty();
2046 8078 : SetEdgesOfMarkedNodesDirty();
2047 :
2048 8078 : bMarkedObjRectDirty=true;
2049 8078 : bMarkedPointsRectsDirty=true;
2050 : #ifdef DBG_UTIL
2051 : if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
2052 : #endif
2053 8078 : bool bOneEdgeMarked=false;
2054 8078 : if (GetMarkedObjectCount()==1) {
2055 700 : const SdrObject* pObj=GetMarkedObjectByIndex(0);
2056 700 : if (pObj->GetObjInventor()==SdrInventor) {
2057 698 : sal_uInt16 nIdent=pObj->GetObjIdentifier();
2058 698 : bOneEdgeMarked=nIdent==OBJ_EDGE;
2059 : }
2060 : }
2061 8078 : ImpSetGlueVisible4(bOneEdgeMarked);
2062 8078 : }
2063 :
2064 :
2065 :
2066 0 : void SdrMarkView::SetMoveOutside(bool bOn)
2067 : {
2068 0 : aHdl.SetMoveOutside(bOn);
2069 0 : }
2070 :
2071 16823 : void SdrMarkView::SetDesignMode( bool _bOn )
2072 : {
2073 16823 : if ( bDesignMode != _bOn )
2074 : {
2075 15203 : bDesignMode = _bOn;
2076 15203 : SdrPageView* pPageView = GetSdrPageView();
2077 15203 : if ( pPageView )
2078 46 : pPageView->SetDesignMode( _bOn );
2079 : }
2080 17474 : }
2081 :
2082 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|