xref: /aoo42x/main/svx/source/svdraw/svdedtv.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <vcl/metaact.hxx>
32 #include <svx/svdedtv.hxx>
33 #include <svx/svdundo.hxx>
34 #include <svx/svdograf.hxx>  // fuer Possibilities
35 #include <svx/svdopath.hxx>
36 #include <svx/svdoole2.hxx>
37 #include <svx/svdopage.hxx>
38 #include <svx/svdoedge.hxx>
39 #include <svx/svdlayer.hxx>
40 #include <svx/svdpagv.hxx>
41 #include <svx/svdpage.hxx>
42 #include <svx/svdpoev.hxx>  // fuer die PolyPossiblities
43 #include "svx/svdstr.hrc"   // Namen aus der Resource
44 #include "svx/svdglob.hxx"  // StringCache
45 #include <svx/e3dsceneupdater.hxx>
46 
47 // #i13033#
48 #include <clonelist.hxx>
49 
50 ////////////////////////////////////////////////////////////////////////////////////////////////////
51 ////////////////////////////////////////////////////////////////////////////////////////////////////
52 //
53 //  @@@@@ @@@@@  @@ @@@@@@  @@ @@ @@ @@@@@ @@   @@
54 //  @@    @@  @@ @@   @@    @@ @@ @@ @@    @@   @@
55 //  @@    @@  @@ @@   @@    @@ @@ @@ @@    @@ @ @@
56 //  @@@@  @@  @@ @@   @@    @@@@@ @@ @@@@  @@@@@@@
57 //  @@    @@  @@ @@   @@     @@@  @@ @@    @@@@@@@
58 //  @@    @@  @@ @@   @@     @@@  @@ @@    @@@ @@@
59 //  @@@@@ @@@@@  @@   @@      @   @@ @@@@@ @@   @@
60 //
61 ////////////////////////////////////////////////////////////////////////////////////////////////////
62 ////////////////////////////////////////////////////////////////////////////////////////////////////
63 
64 void SdrEditView::ImpResetPossibilityFlags()
65 {
66 	bReadOnly               =sal_False;
67 
68 	bGroupPossible          =sal_False;
69 	bUnGroupPossible        =sal_False;
70 	bGrpEnterPossible       =sal_False;
71 	bDeletePossible         =sal_False;
72 	bToTopPossible          =sal_False;
73 	bToBtmPossible          =sal_False;
74 	bReverseOrderPossible   =sal_False;
75 
76 	bImportMtfPossible      =sal_False;
77 	bCombinePossible        =sal_False;
78 	bDismantlePossible      =sal_False;
79 	bCombineNoPolyPolyPossible =sal_False;
80 	bDismantleMakeLinesPossible=sal_False;
81 	bOrthoDesiredOnMarked   =sal_False;
82 
83 	bMoreThanOneNotMovable  =sal_False;
84 	bOneOrMoreMovable       =sal_False;
85 	bMoreThanOneNoMovRot    =sal_False;
86 	bContortionPossible     =sal_False;
87 	bAllPolys               =sal_False;
88 	bOneOrMorePolys         =sal_False;
89 	bMoveAllowed            =sal_False;
90 	bResizeFreeAllowed      =sal_False;
91 	bResizePropAllowed      =sal_False;
92 	bRotateFreeAllowed      =sal_False;
93 	bRotate90Allowed        =sal_False;
94 	bMirrorFreeAllowed      =sal_False;
95 	bMirror45Allowed        =sal_False;
96 	bMirror90Allowed        =sal_False;
97 	bTransparenceAllowed	=sal_False;
98 	bGradientAllowed		=sal_False;
99 	bShearAllowed           =sal_False;
100 	bEdgeRadiusAllowed		=sal_False;
101 	bCanConvToPath          =sal_False;
102 	bCanConvToPoly          =sal_False;
103 	bCanConvToContour		=sal_False;
104 	bCanConvToPathLineToArea=sal_False;
105 	bCanConvToPolyLineToArea=sal_False;
106 	bMoveProtect            =sal_False;
107 	bResizeProtect          =sal_False;
108 }
109 
110 void SdrEditView::ImpClearVars()
111 {
112 	ImpResetPossibilityFlags();
113 	bPossibilitiesDirty=sal_True;   // << war von Purify angemeckert
114 	bBundleVirtObj=sal_False;
115 }
116 
117 SdrEditView::SdrEditView(SdrModel* pModel1, OutputDevice* pOut):
118 	SdrMarkView(pModel1,pOut)
119 {
120 	ImpClearVars();
121 }
122 
123 SdrEditView::~SdrEditView()
124 {
125 }
126 
127 ////////////////////////////////////////////////////////////////////////////////////////////////////
128 
129 SdrLayer* SdrEditView::InsertNewLayer(const XubString& rName, sal_uInt16 nPos)
130 {
131 	SdrLayerAdmin& rLA=pMod->GetLayerAdmin();
132 	sal_uInt16 nMax=rLA.GetLayerCount();
133 	if (nPos>nMax) nPos=nMax;
134 	SdrLayer* pNewLayer=rLA.NewLayer(rName,nPos);
135 
136 	if( GetModel()->IsUndoEnabled() )
137 		AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewLayer(nPos,rLA,*pMod));
138 
139 	pMod->SetChanged();
140 	return pNewLayer;
141 }
142 
143 #include <svx/svdogrp.hxx>
144 #include <svx/scene3d.hxx>
145 
146 sal_Bool SdrEditView::ImpDelLayerCheck(SdrObjList* pOL, SdrLayerID nDelID) const
147 {
148 	sal_Bool bDelAll(sal_True);
149 	sal_uInt32 nObjAnz(pOL->GetObjCount());
150 
151 	for(sal_uInt32 nObjNum(nObjAnz); nObjNum > 0 && bDelAll;)
152 	{
153 		nObjNum--;
154 		SdrObject* pObj = pOL->GetObj(nObjNum);
155 		SdrObjList* pSubOL = pObj->GetSubList();
156 
157 		// #104809# Test explicitely for group objects and 3d scenes
158 		if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
159 		{
160 			if(!ImpDelLayerCheck(pSubOL, nDelID))
161 			{
162 				// Rekursion
163 				bDelAll = sal_False;
164 			}
165 		}
166 		else
167 		{
168 			if(pObj->GetLayer() != nDelID)
169 			{
170 				bDelAll = sal_False;
171 			}
172 		}
173 	}
174 
175 	return bDelAll;
176 }
177 
178 void SdrEditView::ImpDelLayerDelObjs(SdrObjList* pOL, SdrLayerID nDelID)
179 {
180 	sal_uInt32 nObjAnz(pOL->GetObjCount());
181 	// make sure OrdNums are correct
182 	pOL->GetObj(0)->GetOrdNum();
183 
184 	const bool bUndo = GetModel()->IsUndoEnabled();
185 
186 	for(sal_uInt32 nObjNum(nObjAnz); nObjNum > 0;)
187 	{
188 		nObjNum--;
189 		SdrObject* pObj = pOL->GetObj(nObjNum);
190 		SdrObjList* pSubOL = pObj->GetSubList();
191 
192 
193 		// #104809# Test explicitely for group objects and 3d scenes
194 		if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
195 		{
196 			if(ImpDelLayerCheck(pSubOL, nDelID))
197 			{
198 				if( bUndo )
199 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
200 				pOL->RemoveObject(nObjNum);
201 
202 				if( !bUndo )
203 					SdrObject::Free( pObj );
204 			}
205 			else
206 			{
207 				ImpDelLayerDelObjs(pSubOL, nDelID);
208 			}
209 		}
210 		else
211 		{
212 			if(pObj->GetLayer() == nDelID)
213 			{
214 				if( bUndo )
215 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
216 				pOL->RemoveObject(nObjNum);
217 				if( !bUndo )
218 					SdrObject::Free( pObj );
219 			}
220 		}
221 	}
222 }
223 
224 void SdrEditView::DeleteLayer(const XubString& rName)
225 {
226 	SdrLayerAdmin& rLA = pMod->GetLayerAdmin();
227 	SdrLayer* pLayer = rLA.GetLayer(rName, sal_True);
228 	sal_uInt16 nLayerNum(rLA.GetLayerPos(pLayer));
229 
230 	if(SDRLAYER_NOTFOUND != nLayerNum)
231 	{
232 
233 		SdrLayerID nDelID = pLayer->GetID();
234 
235 		const bool bUndo = IsUndoEnabled();
236 		if( bUndo )
237 			BegUndo(ImpGetResStr(STR_UndoDelLayer));
238 
239 		sal_Bool bMaPg(sal_True);
240 
241 		for(sal_uInt16 nPageKind(0); nPageKind < 2; nPageKind++)
242 		{
243 			// MasterPages and DrawPages
244 			sal_uInt16 nPgAnz(bMaPg ? pMod->GetMasterPageCount() : pMod->GetPageCount());
245 
246 			for(sal_uInt16 nPgNum(0); nPgNum < nPgAnz; nPgNum++)
247 			{
248 				// over all pages
249 				SdrPage* pPage = (bMaPg) ? pMod->GetMasterPage(nPgNum) : pMod->GetPage(nPgNum);
250 				sal_uInt32 nObjAnz(pPage->GetObjCount());
251 
252 				// make sure OrdNums are correct
253 				if(nObjAnz)
254 					pPage->GetObj(0)->GetOrdNum();
255 
256 				for(sal_uInt32 nObjNum(nObjAnz); nObjNum > 0;)
257 				{
258 					nObjNum--;
259 					SdrObject* pObj = pPage->GetObj(nObjNum);
260 					SdrObjList* pSubOL = pObj->GetSubList();
261 
262 					// #104809# Test explicitely for group objects and 3d scenes
263 					if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
264 					{
265 						if(ImpDelLayerCheck(pSubOL, nDelID))
266 						{
267 							if( bUndo )
268 								AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
269 							pPage->RemoveObject(nObjNum);
270 							if( !bUndo )
271 								SdrObject::Free(pObj);
272 						}
273 						else
274 						{
275 							ImpDelLayerDelObjs(pSubOL, nDelID);
276 						}
277 					}
278 					else
279 					{
280 						if(pObj->GetLayer() == nDelID)
281 						{
282 							if( bUndo )
283 								AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
284 							pPage->RemoveObject(nObjNum);
285 							if( !bUndo )
286 								SdrObject::Free(pObj);
287 						}
288 					}
289 				}
290 			}
291 			bMaPg = sal_False;
292 		}
293 
294 		if( bUndo )
295 		{
296 			AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteLayer(nLayerNum, rLA, *pMod));
297 			rLA.RemoveLayer(nLayerNum);
298 			EndUndo();
299 		}
300 		else
301 		{
302 			delete rLA.RemoveLayer(nLayerNum);
303 		}
304 
305 		pMod->SetChanged();
306 	}
307 }
308 
309 void SdrEditView::MoveLayer(const XubString& rName, sal_uInt16 nNewPos)
310 {
311 	SdrLayerAdmin& rLA=pMod->GetLayerAdmin();
312 	SdrLayer* pLayer=rLA.GetLayer(rName,sal_True);
313 	sal_uInt16 nLayerNum=rLA.GetLayerPos(pLayer);
314 	if (nLayerNum!=SDRLAYER_NOTFOUND)
315 	{
316 		if( IsUndoEnabled() )
317 			AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveLayer(nLayerNum,rLA,*pMod,nNewPos));
318 		rLA.MoveLayer(nLayerNum,nNewPos);
319 		pMod->SetChanged();
320 	}
321 }
322 
323 ////////////////////////////////////////////////////////////////////////////////////////////////////
324 
325 void SdrEditView::EndUndo()
326 {
327 	// #i13033#
328 	// Comparison changed to 1L since EndUndo() is called later now
329 	// and EndUndo WILL change count to count-1
330 	if(1L == pMod->GetUndoBracketLevel())
331 	{
332 		ImpBroadcastEdgesOfMarkedNodes();
333 	}
334 
335 	// #i13033#
336 	// moved to bottom to still have access to UNDOs inside of
337 	// ImpBroadcastEdgesOfMarkedNodes()
338 	pMod->EndUndo();
339 }
340 
341 void SdrEditView::ImpBroadcastEdgesOfMarkedNodes()
342 {
343 	const List& rAllMarkedObjects = GetTransitiveHullOfMarkedObjects();
344 
345 	// #i13033#
346 	// New mechanism to search for necessary disconnections for
347 	// changed connectors inside the transitive hull of all at
348 	// the beginning of UNDO selected objects
349 	for(sal_uInt32 a(0L); a < rAllMarkedObjects.Count(); a++)
350 	{
351 		SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, (SdrObject*)rAllMarkedObjects.GetObject(a));
352 
353 		if(pEdge)
354 		{
355 			SdrObject* pObj1 = pEdge->GetConnectedNode(sal_False);
356 			SdrObject* pObj2 = pEdge->GetConnectedNode(sal_True);
357 
358 			if(pObj1
359 				&& LIST_ENTRY_NOTFOUND == rAllMarkedObjects.GetPos(pObj1)
360 				&& !pEdge->CheckNodeConnection(sal_False))
361 			{
362 				if( IsUndoEnabled() )
363 					AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge));
364 				pEdge->DisconnectFromNode(sal_False);
365 			}
366 
367 			if(pObj2
368 				&& LIST_ENTRY_NOTFOUND == rAllMarkedObjects.GetPos(pObj2)
369 				&& !pEdge->CheckNodeConnection(sal_True))
370 			{
371 				if( IsUndoEnabled() )
372 					AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge));
373 				pEdge->DisconnectFromNode(sal_True);
374 			}
375 		}
376 	}
377 
378 	sal_uIntPtr nMarkedEdgeAnz = GetMarkedEdgesOfMarkedNodes().GetMarkCount();
379 	sal_uInt16 i;
380 
381 	for (i=0; i<nMarkedEdgeAnz; i++) {
382 		SdrMark* pEM = GetMarkedEdgesOfMarkedNodes().GetMark(i);
383 		SdrObject* pEdgeTmp=pEM->GetMarkedSdrObj();
384 		SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pEdgeTmp);
385 		if (pEdge!=NULL) {
386 			pEdge->SetEdgeTrackDirty();
387 		}
388 	}
389 }
390 
391 ////////////////////////////////////////////////////////////////////////////////////////////////////
392 //
393 //  ####   ###   ####  #### # ####  # #    # ##### # #####  ####
394 //  #   # #   # #     #     # #   # # #    #   #   # #     #
395 //  ####  #   #  ###   ###  # ####  # #    #   #   # ####   ###
396 //  #     #   #     #     # # #   # # #    #   #   # #         #
397 //  #      ###  ####  ####  # ####  # #### #   #   # ##### ####
398 //
399 ////////////////////////////////////////////////////////////////////////////////////////////////////
400 
401 void SdrEditView::MarkListHasChanged()
402 {
403 	SdrMarkView::MarkListHasChanged();
404 	bPossibilitiesDirty=sal_True;
405 }
406 
407 void SdrEditView::ModelHasChanged()
408 {
409 	SdrMarkView::ModelHasChanged();
410 	bPossibilitiesDirty=sal_True;
411 }
412 
413 sal_Bool SdrEditView::IsResizeAllowed(sal_Bool bProp) const
414 {
415 	ForcePossibilities();
416 	if (bResizeProtect) return sal_False;
417 	if (bProp) return bResizePropAllowed;
418 	return bResizeFreeAllowed;
419 }
420 
421 sal_Bool SdrEditView::IsRotateAllowed(sal_Bool b90Deg) const
422 {
423 	ForcePossibilities();
424 	if (bMoveProtect) return sal_False;
425 	if (b90Deg) return bRotate90Allowed;
426 	return bRotateFreeAllowed;
427 }
428 
429 sal_Bool SdrEditView::IsMirrorAllowed(sal_Bool b45Deg, sal_Bool b90Deg) const
430 {
431 	ForcePossibilities();
432 	if (bMoveProtect) return sal_False;
433 	if (b90Deg) return bMirror90Allowed;
434 	if (b45Deg) return bMirror45Allowed;
435 	return bMirrorFreeAllowed && !bMoveProtect;
436 }
437 
438 sal_Bool SdrEditView::IsTransparenceAllowed() const
439 {
440 	ForcePossibilities();
441 	return bTransparenceAllowed;
442 }
443 
444 sal_Bool SdrEditView::IsGradientAllowed() const
445 {
446 	ForcePossibilities();
447 	return bGradientAllowed;
448 }
449 
450 sal_Bool SdrEditView::IsShearAllowed() const
451 {
452 	ForcePossibilities();
453 	if (bResizeProtect) return sal_False;
454 	return bShearAllowed;
455 }
456 
457 sal_Bool SdrEditView::IsEdgeRadiusAllowed() const
458 {
459 	ForcePossibilities();
460 	return bEdgeRadiusAllowed;
461 }
462 
463 sal_Bool SdrEditView::IsCrookAllowed(sal_Bool bNoContortion) const
464 {
465 	// CrookMode fehlt hier (weil kein Rotate bei Shear ...)
466 	ForcePossibilities();
467 	if (bNoContortion) {
468 		if (!bRotateFreeAllowed) return sal_False; // Crook is nich
469 		return !bMoveProtect && bMoveAllowed;
470 	} else {
471 		return !bResizeProtect && bContortionPossible;
472 	}
473 }
474 
475 sal_Bool SdrEditView::IsDistortAllowed(sal_Bool bNoContortion) const
476 {
477 	ForcePossibilities();
478 	if (bNoContortion) {
479 		return sal_False;
480 	} else {
481 		return !bResizeProtect && bContortionPossible;
482 	}
483 }
484 
485 sal_Bool SdrEditView::IsCombinePossible(sal_Bool bNoPolyPoly) const
486 {
487 	ForcePossibilities();
488 	if (bNoPolyPoly) return bCombineNoPolyPolyPossible;
489 	else return bCombinePossible;
490 }
491 
492 sal_Bool SdrEditView::IsDismantlePossible(sal_Bool bMakeLines) const
493 {
494 	ForcePossibilities();
495 	if (bMakeLines) return bDismantleMakeLinesPossible;
496 	else return bDismantlePossible;
497 }
498 
499 void SdrEditView::CheckPossibilities()
500 {
501 	if (bSomeObjChgdFlag) bPossibilitiesDirty=sal_True;
502 
503 	if(bSomeObjChgdFlag)
504 	{
505 		// This call IS necessary to correct the MarkList, in which
506 		// no longer to the model belonging objects still can reside.
507 		// These ones nned to be removed.
508 		CheckMarked();
509 	}
510 
511 	if (bPossibilitiesDirty) {
512 		ImpResetPossibilityFlags();
513 		SortMarkedObjects();
514 		sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
515 		if (nMarkAnz!=0) {
516 			bReverseOrderPossible=nMarkAnz>=2;
517 
518 			sal_uIntPtr nMovableCount=0;
519 			bGroupPossible=nMarkAnz>=2;
520 			bCombinePossible=nMarkAnz>=2;
521 			if (nMarkAnz==1) {
522 				// bCombinePossible gruendlicher checken
523 				// fehlt noch ...
524 				const SdrObject* pObj=GetMarkedObjectByIndex(0);
525 				//const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
526 				sal_Bool bGroup=pObj->GetSubList()!=NULL;
527 				sal_Bool bHasText=pObj->GetOutlinerParaObject()!=NULL;
528 				if (bGroup || bHasText) {
529 					bCombinePossible=sal_True;
530 				}
531 			}
532 			bCombineNoPolyPolyPossible=bCombinePossible;
533 			bDeletePossible=sal_True;
534 			// Zu den Transformationen erstmal ja sagen
535 			bMoveAllowed      =sal_True;
536 			bResizeFreeAllowed=sal_True;
537 			bResizePropAllowed=sal_True;
538 			bRotateFreeAllowed=sal_True;
539 			bRotate90Allowed  =sal_True;
540 			bMirrorFreeAllowed=sal_True;
541 			bMirror45Allowed  =sal_True;
542 			bMirror90Allowed  =sal_True;
543 			bShearAllowed     =sal_True;
544 			bEdgeRadiusAllowed=sal_False;
545 			bContortionPossible=sal_True;
546 			bCanConvToContour = sal_True;
547 
548 			// these ones are only allowed when single object is selected
549 			bTransparenceAllowed = (nMarkAnz == 1);
550 			bGradientAllowed = (nMarkAnz == 1);
551 			if(bGradientAllowed)
552 			{
553 				// gradient depends on fillstyle
554 				const SdrMark* pM = GetSdrMarkByIndex(0);
555 				const SdrObject* pObj = pM->GetMarkedSdrObj();
556 
557 				// maybe group object, so get merged ItemSet
558 				const SfxItemSet& rSet = pObj->GetMergedItemSet();
559 				SfxItemState eState = rSet.GetItemState(XATTR_FILLSTYLE, sal_False);
560 
561 				if(SFX_ITEM_DONTCARE != eState)
562 				{
563 					// If state is not DONTCARE, test the item
564 					XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
565 
566 					if(eFillStyle != XFILL_GRADIENT)
567 					{
568 						bGradientAllowed = sal_False;
569 					}
570 				}
571 			}
572 
573 			sal_Bool bNoMovRotFound=sal_False;
574 			const SdrPageView* pPV0=NULL;
575 
576 			for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
577 				const SdrMark* pM=GetSdrMarkByIndex(nm);
578 				const SdrObject* pObj=pM->GetMarkedSdrObj();
579 				const SdrPageView* pPV=pM->GetPageView();
580 				if (pPV!=pPV0) {
581 					if (pPV->IsReadOnly()) bReadOnly=sal_True;
582 					pPV0=pPV;
583 				}
584 
585 				SdrObjTransformInfoRec aInfo;
586 				pObj->TakeObjInfo(aInfo);
587 				sal_Bool bMovPrt=pObj->IsMoveProtect();
588 				sal_Bool bSizPrt=pObj->IsResizeProtect();
589 				if (!bMovPrt && aInfo.bMoveAllowed) nMovableCount++; // Menge der MovableObjs zaehlen
590 				if (bMovPrt) bMoveProtect=sal_True;
591 				if (bSizPrt) bResizeProtect=sal_True;
592 
593 				// not allowed when not allowed at one object
594 				if(!aInfo.bTransparenceAllowed)
595 					bTransparenceAllowed = sal_False;
596 
597 				// Wenn einer was nicht kann, duerfen's alle nicht
598 				if (!aInfo.bMoveAllowed      ) bMoveAllowed      =sal_False;
599 				if (!aInfo.bResizeFreeAllowed) bResizeFreeAllowed=sal_False;
600 				if (!aInfo.bResizePropAllowed) bResizePropAllowed=sal_False;
601 				if (!aInfo.bRotateFreeAllowed) bRotateFreeAllowed=sal_False;
602 				if (!aInfo.bRotate90Allowed  ) bRotate90Allowed  =sal_False;
603 				if (!aInfo.bMirrorFreeAllowed) bMirrorFreeAllowed=sal_False;
604 				if (!aInfo.bMirror45Allowed  ) bMirror45Allowed  =sal_False;
605 				if (!aInfo.bMirror90Allowed  ) bMirror90Allowed  =sal_False;
606 				if (!aInfo.bShearAllowed     ) bShearAllowed     =sal_False;
607 				if (aInfo.bEdgeRadiusAllowed) bEdgeRadiusAllowed=sal_True;
608 				if (aInfo.bNoContortion      ) bContortionPossible=sal_False;
609 				// Fuer Crook mit Contortion: Alle Objekte muessen
610 				// Movable und Rotatable sein, ausser maximal 1
611 				if (!bMoreThanOneNoMovRot) {
612 					if (!aInfo.bMoveAllowed || !aInfo.bResizeFreeAllowed) {
613 						bMoreThanOneNoMovRot=bNoMovRotFound;
614 						bNoMovRotFound=sal_True;
615 					}
616 				}
617 
618 				// when one member cannot be converted, no conversion is possible
619 				if(!aInfo.bCanConvToContour)
620 					bCanConvToContour = sal_False;
621 
622 				// Ungroup
623 				if (!bUnGroupPossible) bUnGroupPossible=pObj->GetSubList()!=NULL;
624 				// ConvertToCurve: Wenn mind. einer konvertiert werden kann ist das ok.
625 				if (aInfo.bCanConvToPath          ) bCanConvToPath          =sal_True;
626 				if (aInfo.bCanConvToPoly          ) bCanConvToPoly          =sal_True;
627 				if (aInfo.bCanConvToPathLineToArea) bCanConvToPathLineToArea=sal_True;
628 				if (aInfo.bCanConvToPolyLineToArea) bCanConvToPolyLineToArea=sal_True;
629 
630 				// Combine/Dismantle
631 				if(bCombinePossible)
632 				{
633 					bCombinePossible = ImpCanConvertForCombine(pObj);
634 					bCombineNoPolyPolyPossible = bCombinePossible;
635 				}
636 
637 				if (!bDismantlePossible) bDismantlePossible = ImpCanDismantle(pObj, sal_False);
638 				if (!bDismantleMakeLinesPossible) bDismantleMakeLinesPossible = ImpCanDismantle(pObj, sal_True);
639 				// OrthoDesiredOnMarked checken
640 				if (!bOrthoDesiredOnMarked && !aInfo.bNoOrthoDesired) bOrthoDesiredOnMarked=sal_True;
641 				// ImportMtf checken
642 
643                 if (!bImportMtfPossible) {
644                     sal_Bool bGraf=HAS_BASE(SdrGrafObj,pObj);
645                     sal_Bool bOle2=HAS_BASE(SdrOle2Obj,pObj);
646 
647 					if( bGraf &&
648                         ((SdrGrafObj*)pObj)->HasGDIMetaFile() &&
649                         !( ((SdrGrafObj*)pObj)->IsEPS() || ((SdrGrafObj*)pObj)->IsRenderGraphic() ) )
650                     {
651 						bImportMtfPossible = sal_True;
652                     }
653 
654 					if (bOle2)
655                         bImportMtfPossible=((SdrOle2Obj*)pObj)->GetObjRef().is();
656                 }
657 			}
658 
659 			bMoreThanOneNotMovable=nMovableCount<nMarkAnz-1;
660 			bOneOrMoreMovable=nMovableCount!=0;
661 			bGrpEnterPossible=bUnGroupPossible;
662 		}
663 		ImpCheckToTopBtmPossible();
664 		((SdrPolyEditView*)this)->ImpCheckPolyPossibilities();
665 		bPossibilitiesDirty=sal_False;
666 
667 		if (bReadOnly) {
668 			sal_Bool bMerker1=bGrpEnterPossible;
669 			ImpResetPossibilityFlags();
670 			bReadOnly=sal_True;
671 			bGrpEnterPossible=bMerker1;
672 		}
673 		if (bMoveAllowed) {
674 			// Verschieben von angeklebten Verbindern unterbinden
675 			// Derzeit nur fuer Einfachselektion implementiert.
676 			if (nMarkAnz==1) {
677 				SdrObject* pObj=GetMarkedObjectByIndex(0);
678 				SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
679 				if (pEdge!=NULL) {
680 					SdrObject* pNode1=pEdge->GetConnectedNode(sal_True);
681 					SdrObject* pNode2=pEdge->GetConnectedNode(sal_False);
682 					if (pNode1!=NULL || pNode2!=NULL) bMoveAllowed=sal_False;
683 				}
684 			}
685 		}
686 	}
687 }
688 
689 ////////////////////////////////////////////////////////////////////////////////////////////////////
690 
691 void SdrEditView::ForceMarkedObjToAnotherPage()
692 {
693 	sal_Bool bFlg=sal_False;
694 	for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) {
695 		SdrMark* pM=GetSdrMarkByIndex(nm);
696 		SdrObject* pObj=pM->GetMarkedSdrObj();
697 		Rectangle aObjRect(pObj->GetCurrentBoundRect());
698 		Rectangle aPgRect(pM->GetPageView()->GetPageRect());
699 		if (!aObjRect.IsOver(aPgRect)) {
700 			sal_Bool bFnd=sal_False;
701 			SdrPageView* pPV = GetSdrPageView();
702 
703 			if(pPV)
704 			{
705 				bFnd = aObjRect.IsOver(pPV->GetPageRect());
706 			}
707 
708 			if(bFnd)
709 			{
710 				pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum());
711 				SdrInsertReason aReason(SDRREASON_VIEWCALL);
712 				pPV->GetObjList()->InsertObject(pObj,CONTAINER_APPEND,&aReason);
713 				pM->SetPageView(pPV);
714 				InvalidateAllWin(aObjRect);
715 				bFlg=sal_True;
716 			}
717 		}
718 	}
719 	if (bFlg) {
720 		MarkListHasChanged();
721 	}
722 }
723 
724 void SdrEditView::DeleteMarkedList(const SdrMarkList& rMark)
725 {
726 	if (rMark.GetMarkCount()!=0)
727 	{
728 		rMark.ForceSort();
729 
730 		const bool bUndo = IsUndoEnabled();
731 		if( bUndo )
732 			BegUndo();
733 		const sal_uInt32 nMarkAnz(rMark.GetMarkCount());
734 
735         if(nMarkAnz)
736         {
737 		    sal_uInt32 nm(0);
738             std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
739 
740 			if( bUndo )
741 			{
742 				for(nm = nMarkAnz; nm > 0;)
743 				{
744 					nm--;
745 					SdrMark* pM = rMark.GetMark(nm);
746     				SdrObject* pObj = pM->GetMarkedSdrObj();
747 
748 					// extra undo actions for changed connector which now may hold it's layouted path (SJ)
749 					std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pObj ) );
750 					AddUndoActions( vConnectorUndoActions );
751 
752 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
753 				}
754 			}
755 
756             // Sicherstellen, dass die OrderNums stimmen:
757 		    rMark.GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
758 
759 			std::vector< SdrObject* > aRemoved3DObjects;
760 
761             for(nm = nMarkAnz; nm > 0;)
762             {
763 			    nm--;
764 			    SdrMark* pM = rMark.GetMark(nm);
765 			    SdrObject* pObj = pM->GetMarkedSdrObj();
766 			    SdrObjList*  pOL = pObj->GetObjList(); //#52680#
767 			    const sal_uInt32 nOrdNum(pObj->GetOrdNumDirect());
768 
769 				bool bIs3D = dynamic_cast< E3dObject* >(pObj);
770                 // set up a scene updater if object is a 3d object
771                 if(bIs3D)
772                 {
773                     aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj));
774                 }
775 
776                 pOL->RemoveObject(nOrdNum);
777 
778 				if( !bUndo )
779 				{
780 					if( bIs3D )
781 						aRemoved3DObjects.push_back( pObj ); // may be needed later
782 					else
783 						SdrObject::Free(pObj);
784 				}
785 		    }
786 
787             // fire scene updaters
788             while(!aUpdaters.empty())
789             {
790                 delete aUpdaters.back();
791                 aUpdaters.pop_back();
792             }
793 
794 			if( !bUndo )
795 			{
796 				// now delete removed scene objects
797 				while(!aRemoved3DObjects.empty())
798 				{
799 					SdrObject::Free( aRemoved3DObjects.back() );
800 					aRemoved3DObjects.pop_back();
801 				}
802 			}
803 		}
804 
805 		if( bUndo )
806 			EndUndo();
807 	}
808 }
809 
810 void SdrEditView::DeleteMarkedObj()
811 {
812     // #i110981# return when nothing is to be done at all
813     if(!GetMarkedObjectCount())
814     {
815         return;
816     }
817 
818 	// moved breaking action and undo start outside loop
819 	BrkAction();
820 	BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_DELETE);
821 
822 	// remove as long as something is selected. This allows to schedule objects for
823 	// removal for a next run as needed
824 	while(GetMarkedObjectCount())
825 	{
826 		// vector to remember the parents which may be empty after object removal
827 		std::vector< SdrObject* > aParents;
828 
829 		{
830 			const SdrMarkList& rMarkList = GetMarkedObjectList();
831 			const sal_uInt32 nCount(rMarkList.GetMarkCount());
832 			sal_uInt32 a(0);
833 
834 			for(a = 0; a < nCount; a++)
835 			{
836 				// in the first run, add all found parents, but only once
837 			    SdrMark* pMark = rMarkList.GetMark(a);
838 				SdrObject* pObject = pMark->GetMarkedSdrObj();
839 				SdrObject* pParent = pObject->GetObjList()->GetOwnerObj();
840 
841 				if(pParent)
842 				{
843 					if(!aParents.empty())
844 					{
845 						std::vector< SdrObject* >::iterator aFindResult =
846 							std::find(aParents.begin(), aParents.end(), pParent);
847 
848 						if(aFindResult == aParents.end())
849 						{
850 							aParents.push_back(pParent);
851 						}
852 					}
853 					else
854 					{
855 						aParents.push_back(pParent);
856 					}
857 				}
858 			}
859 
860 			if(!aParents.empty())
861 			{
862 				// in a 2nd run, remove all objects which may already be scheduled for
863 				// removal. I am not sure if this can happen, but theoretically
864 				// a to-be-removed object may already be the group/3DScene itself
865 				for(a = 0; a < nCount; a++)
866 				{
867 					SdrMark* pMark = rMarkList.GetMark(a);
868 					SdrObject* pObject = pMark->GetMarkedSdrObj();
869 
870 					std::vector< SdrObject* >::iterator aFindResult =
871 						std::find(aParents.begin(), aParents.end(), pObject);
872 
873 					if(aFindResult != aParents.end())
874 					{
875 						aParents.erase(aFindResult);
876 					}
877 				}
878 			}
879 		}
880 
881 		// original stuff: remove selected objects. Handle clear will
882 		// do something only once
883 		DeleteMarkedList(GetMarkedObjectList());
884 		GetMarkedObjectListWriteAccess().Clear();
885 		aHdl.Clear();
886 
887 		while(aParents.size() && !GetMarkedObjectCount())
888 		{
889 			// iterate over remembered parents
890 			SdrObject* pParent = aParents.back();
891 			aParents.pop_back();
892 
893 			if(pParent->GetSubList() && 0 == pParent->GetSubList()->GetObjCount())
894 			{
895 				// we detected an empty parent, a candidate to leave group/3DScene
896 				// if entered
897 				if(GetSdrPageView()->GetAktGroup()
898 					&& GetSdrPageView()->GetAktGroup() == pParent)
899 				{
900 					GetSdrPageView()->LeaveOneGroup();
901 				}
902 
903 				// schedule empty parent for removal
904 				GetMarkedObjectListWriteAccess().InsertEntry(
905 					SdrMark(pParent, GetSdrPageView()));
906 			}
907 		}
908 	}
909 
910 	// end undo and change messaging moved at the end
911 	EndUndo();
912 	MarkListHasChanged();
913 }
914 
915 void SdrEditView::CopyMarkedObj()
916 {
917 	SortMarkedObjects();
918 
919 	SdrMarkList aSourceObjectsForCopy(GetMarkedObjectList());
920 	// Folgende Schleife Anstatt MarkList::Merge(), damit
921 	// ich jeweils mein Flag an die MarkEntries setzen kann.
922 	sal_uIntPtr nEdgeAnz = GetEdgesOfMarkedNodes().GetMarkCount();
923 	for (sal_uIntPtr nEdgeNum=0; nEdgeNum<nEdgeAnz; nEdgeNum++) {
924 		SdrMark aM(*GetEdgesOfMarkedNodes().GetMark(nEdgeNum));
925 		aM.SetUser(1);
926 		aSourceObjectsForCopy.InsertEntry(aM);
927 	}
928 	aSourceObjectsForCopy.ForceSort();
929 
930 	// #i13033#
931 	// New mechanism to re-create the connections of cloned connectors
932 	CloneList aCloneList;
933 
934 	const bool bUndo = IsUndoEnabled();
935 
936 	GetMarkedObjectListWriteAccess().Clear();
937 	sal_uIntPtr nCloneErrCnt=0;
938 	sal_uIntPtr nMarkAnz=aSourceObjectsForCopy.GetMarkCount();
939 	sal_uIntPtr nm;
940 	for (nm=0; nm<nMarkAnz; nm++) {
941 		SdrMark* pM=aSourceObjectsForCopy.GetMark(nm);
942 		SdrObject* pO=pM->GetMarkedSdrObj()->Clone();
943 		if (pO!=NULL) {
944 			SdrInsertReason aReason(SDRREASON_VIEWCALL);
945 			pM->GetPageView()->GetObjList()->InsertObject(pO,CONTAINER_APPEND,&aReason);
946 
947 			if( bUndo )
948 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoCopyObject(*pO));
949 
950 			SdrMark aME(*pM);
951 			aME.SetMarkedSdrObj(pO);
952 			aCloneList.AddPair(pM->GetMarkedSdrObj(), pO);
953 
954 			if (pM->GetUser()==0)
955 			{
956 				// Sonst war's nur eine mitzukierende Edge
957 				GetMarkedObjectListWriteAccess().InsertEntry(aME);
958 			}
959 		} else {
960 			nCloneErrCnt++;
961 		}
962 	}
963 
964 	// #i13033#
965 	// New mechanism to re-create the connections of cloned connectors
966 	aCloneList.CopyConnections();
967 
968 	if(0L != nCloneErrCnt)
969 	{
970 #ifdef DBG_UTIL
971 		ByteString aStr("SdrEditView::CopyMarkedObj(): Fehler beim Clonen ");
972 
973 		if(nCloneErrCnt == 1)
974 		{
975 			aStr += "eines Zeichenobjekts.";
976 		}
977 		else
978 		{
979 			aStr += "von ";
980 			aStr += ByteString::CreateFromInt32( nCloneErrCnt );
981 			aStr += " Zeichenobjekten.";
982 		}
983 
984 		aStr += " Objektverbindungen werden nicht mitkopiert.";
985 		DBG_ERROR(aStr.GetBuffer());
986 #endif
987 	}
988 	MarkListHasChanged();
989 }
990 
991 ////////////////////////////////////////////////////////////////////////////////////////////////////
992 
993 sal_Bool SdrEditView::InsertObjectAtView(SdrObject* pObj, SdrPageView& rPV, sal_uIntPtr nOptions)
994 {
995 	if ((nOptions & SDRINSERT_SETDEFLAYER)!=0) {
996 		SdrLayerID nLayer=rPV.GetPage()->GetLayerAdmin().GetLayerID(aAktLayer,sal_True);
997 		if (nLayer==SDRLAYER_NOTFOUND) nLayer=0;
998 		if (rPV.GetLockedLayers().IsSet(nLayer) || !rPV.GetVisibleLayers().IsSet(nLayer)) {
999 			SdrObject::Free( pObj ); // Layer gesperrt oder nicht sichtbar
1000 			return sal_False;
1001 		}
1002 		pObj->NbcSetLayer(nLayer);
1003 	}
1004 	if ((nOptions & SDRINSERT_SETDEFATTR)!=0) {
1005 		if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
1006 		pObj->SetMergedItemSet(aDefaultAttr);
1007 	}
1008 	if (!pObj->IsInserted()) {
1009 		SdrInsertReason aReason(SDRREASON_VIEWCALL);
1010 		if ((nOptions & SDRINSERT_NOBROADCAST)!=0) {
1011 			rPV.GetObjList()->NbcInsertObject(pObj,CONTAINER_APPEND,&aReason);
1012 		} else {
1013 			rPV.GetObjList()->InsertObject(pObj,CONTAINER_APPEND,&aReason);
1014 		}
1015 	}
1016 	if( IsUndoEnabled() )
1017 		AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
1018 
1019 	if ((nOptions & SDRINSERT_DONTMARK)==0) {
1020 		if ((nOptions & SDRINSERT_ADDMARK)==0) UnmarkAllObj();
1021 		MarkObj(pObj,&rPV);
1022 	}
1023 	return sal_True;
1024 }
1025 
1026 void SdrEditView::ReplaceObjectAtView(SdrObject* pOldObj, SdrPageView& rPV, SdrObject* pNewObj, sal_Bool bMark)
1027 {
1028 	SdrObjList* pOL=pOldObj->GetObjList();
1029 	const bool bUndo = IsUndoEnabled();
1030 	if( bUndo  )
1031 		AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pOldObj,*pNewObj));
1032 
1033 	if( IsObjMarked( pOldObj ) )
1034 	    MarkObj( pOldObj, &rPV, sal_True /*unmark!*/ );
1035 
1036 	pOL->ReplaceObject(pNewObj,pOldObj->GetOrdNum());
1037 
1038 	if( !bUndo )
1039 		SdrObject::Free( pOldObj );
1040 
1041 	if (bMark) MarkObj(pNewObj,&rPV);
1042 }
1043 
1044 ////////////////////////////////////////////////////////////////////////////////////////////////////
1045 
1046 bool SdrEditView::IsUndoEnabled() const
1047 {
1048 	return pMod->IsUndoEnabled();
1049 }
1050