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