1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/metaact.hxx>
21 #include <svx/svdedtv.hxx>
22 #include <svx/svdundo.hxx>
23 #include <svx/svdograf.hxx>
24 #include <svx/svdopath.hxx>
25 #include <svx/svdoole2.hxx>
26 #include <svx/svdopage.hxx>
27 #include <svx/svdoedge.hxx>
28 #include <svx/svdlayer.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <svx/svdpage.hxx>
31 #include <svx/svdpoev.hxx>
32 #include "svx/svdstr.hrc"
33 #include "svdglob.hxx"
34 #include <svx/e3dsceneupdater.hxx>
35 #include <rtl/strbuf.hxx>
36 #include <svx/svdview.hxx>
37 #include <clonelist.hxx>
39 void SdrEditView::ImpResetPossibilityFlags()
43 bGroupPossible
=false;
44 bUnGroupPossible
=false;
45 bGrpEnterPossible
=false;
46 bDeletePossible
=false;
47 bToTopPossible
=false;
48 bToBtmPossible
=false;
49 bReverseOrderPossible
=false;
51 bImportMtfPossible
=false;
52 bCombinePossible
=false;
53 bDismantlePossible
=false;
54 bCombineNoPolyPolyPossible
=false;
55 bDismantleMakeLinesPossible
=false;
56 bOrthoDesiredOnMarked
=false;
58 bMoreThanOneNotMovable
=false;
59 bOneOrMoreMovable
=false;
60 bMoreThanOneNoMovRot
=false;
61 bContortionPossible
=false;
63 bOneOrMorePolys
=false;
65 bResizeFreeAllowed
=false;
66 bResizePropAllowed
=false;
67 bRotateFreeAllowed
=false;
68 bRotate90Allowed
=false;
69 bMirrorFreeAllowed
=false;
70 bMirror45Allowed
=false;
71 bMirror90Allowed
=false;
72 bTransparenceAllowed
=false;
73 bGradientAllowed
=false;
75 bEdgeRadiusAllowed
=false;
76 bCanConvToPath
=false;
77 bCanConvToPoly
=false;
78 bCanConvToContour
=false;
79 bCanConvToPathLineToArea
=false;
80 bCanConvToPolyLineToArea
=false;
82 bResizeProtect
=false;
85 void SdrEditView::ImpClearVars()
87 ImpResetPossibilityFlags();
88 bPossibilitiesDirty
=true; // << Purify didn't like this
92 SdrEditView::SdrEditView(SdrModel
* pModel1
, OutputDevice
* pOut
):
93 SdrMarkView(pModel1
,pOut
)
98 SdrEditView::~SdrEditView()
104 SdrLayer
* SdrEditView::InsertNewLayer(const OUString
& rName
, sal_uInt16 nPos
)
106 SdrLayerAdmin
& rLA
=pMod
->GetLayerAdmin();
107 sal_uInt16 nMax
=rLA
.GetLayerCount();
108 if (nPos
>nMax
) nPos
=nMax
;
109 SdrLayer
* pNewLayer
=rLA
.NewLayer(rName
,nPos
);
111 if( GetModel()->IsUndoEnabled() )
112 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewLayer(nPos
,rLA
,*pMod
));
118 #include <svx/svdogrp.hxx>
119 #include <svx/scene3d.hxx>
121 bool SdrEditView::ImpDelLayerCheck(SdrObjList
* pOL
, SdrLayerID nDelID
) const
124 sal_uInt32
nObjAnz(pOL
->GetObjCount());
126 for(sal_uInt32
nObjNum(nObjAnz
); nObjNum
> 0 && bDelAll
;)
129 SdrObject
* pObj
= pOL
->GetObj(nObjNum
);
130 SdrObjList
* pSubOL
= pObj
->GetSubList();
132 // explicitly test for group objects and 3d scenes
133 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
135 if(!ImpDelLayerCheck(pSubOL
, nDelID
))
142 if(pObj
->GetLayer() != nDelID
)
152 void SdrEditView::ImpDelLayerDelObjs(SdrObjList
* pOL
, SdrLayerID nDelID
)
154 sal_uInt32
nObjAnz(pOL
->GetObjCount());
155 // make sure OrdNums are correct
156 pOL
->GetObj(0)->GetOrdNum();
158 const bool bUndo
= GetModel()->IsUndoEnabled();
160 for(sal_uInt32
nObjNum(nObjAnz
); nObjNum
> 0;)
163 SdrObject
* pObj
= pOL
->GetObj(nObjNum
);
164 SdrObjList
* pSubOL
= pObj
->GetSubList();
167 // explicitly test for group objects and 3d scenes
168 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
170 if(ImpDelLayerCheck(pSubOL
, nDelID
))
173 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
174 pOL
->RemoveObject(nObjNum
);
177 SdrObject::Free( pObj
);
181 ImpDelLayerDelObjs(pSubOL
, nDelID
);
186 if(pObj
->GetLayer() == nDelID
)
189 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
190 pOL
->RemoveObject(nObjNum
);
192 SdrObject::Free( pObj
);
198 void SdrEditView::DeleteLayer(const OUString
& rName
)
200 SdrLayerAdmin
& rLA
= pMod
->GetLayerAdmin();
201 SdrLayer
* pLayer
= rLA
.GetLayer(rName
, true);
202 sal_uInt16
nLayerNum(rLA
.GetLayerPos(pLayer
));
204 if(SDRLAYER_NOTFOUND
!= nLayerNum
)
207 SdrLayerID nDelID
= pLayer
->GetID();
209 const bool bUndo
= IsUndoEnabled();
211 BegUndo(ImpGetResStr(STR_UndoDelLayer
));
215 for(sal_uInt16
nPageKind(0); nPageKind
< 2; nPageKind
++)
217 // MasterPages and DrawPages
218 sal_uInt16
nPgAnz(bMaPg
? pMod
->GetMasterPageCount() : pMod
->GetPageCount());
220 for(sal_uInt16
nPgNum(0); nPgNum
< nPgAnz
; nPgNum
++)
223 SdrPage
* pPage
= (bMaPg
) ? pMod
->GetMasterPage(nPgNum
) : pMod
->GetPage(nPgNum
);
224 sal_uInt32
nObjAnz(pPage
->GetObjCount());
226 // make sure OrdNums are correct
228 pPage
->GetObj(0)->GetOrdNum();
230 for(sal_uInt32
nObjNum(nObjAnz
); nObjNum
> 0;)
233 SdrObject
* pObj
= pPage
->GetObj(nObjNum
);
234 SdrObjList
* pSubOL
= pObj
->GetSubList();
236 // explicitly test for group objects and 3d scenes
237 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
239 if(ImpDelLayerCheck(pSubOL
, nDelID
))
242 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
243 pPage
->RemoveObject(nObjNum
);
245 SdrObject::Free(pObj
);
249 ImpDelLayerDelObjs(pSubOL
, nDelID
);
254 if(pObj
->GetLayer() == nDelID
)
257 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
258 pPage
->RemoveObject(nObjNum
);
260 SdrObject::Free(pObj
);
270 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteLayer(nLayerNum
, rLA
, *pMod
));
271 rLA
.RemoveLayer(nLayerNum
);
276 delete rLA
.RemoveLayer(nLayerNum
);
285 void SdrEditView::EndUndo()
288 // Comparison changed to 1L since EndUndo() is called later now
289 // and EndUndo WILL change count to count-1
290 if(1L == pMod
->GetUndoBracketLevel())
292 ImpBroadcastEdgesOfMarkedNodes();
296 // moved to bottom to still have access to UNDOs inside of
297 // ImpBroadcastEdgesOfMarkedNodes()
301 void SdrEditView::ImpBroadcastEdgesOfMarkedNodes()
303 std::vector
<SdrObject
*>::const_iterator iterPos
;
304 const std::vector
<SdrObject
*>& rAllMarkedObjects
= GetTransitiveHullOfMarkedObjects();
307 // New mechanism to search for necessary disconnections for
308 // changed connectors inside the transitive hull of all at
309 // the beginning of UNDO selected objects
310 for(sal_uInt32
a(0L); a
< rAllMarkedObjects
.size(); a
++)
312 SdrEdgeObj
* pEdge
= PTR_CAST(SdrEdgeObj
, rAllMarkedObjects
[a
]);
316 SdrObject
* pObj1
= pEdge
->GetConnectedNode(false);
317 SdrObject
* pObj2
= pEdge
->GetConnectedNode(true);
319 if(pObj1
&& !pEdge
->CheckNodeConnection(false))
321 iterPos
= std::find(rAllMarkedObjects
.begin(),rAllMarkedObjects
.end(),pObj1
);
323 if (iterPos
== rAllMarkedObjects
.end())
325 if( IsUndoEnabled() )
326 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge
));
327 pEdge
->DisconnectFromNode(false);
331 if(pObj2
&& !pEdge
->CheckNodeConnection(true))
333 iterPos
= std::find(rAllMarkedObjects
.begin(),rAllMarkedObjects
.end(),pObj2
);
335 if (iterPos
== rAllMarkedObjects
.end())
337 if( IsUndoEnabled() )
338 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge
));
339 pEdge
->DisconnectFromNode(true);
345 sal_uIntPtr nMarkedEdgeAnz
= GetMarkedEdgesOfMarkedNodes().GetMarkCount();
348 for (i
=0; i
<nMarkedEdgeAnz
; i
++) {
349 SdrMark
* pEM
= GetMarkedEdgesOfMarkedNodes().GetMark(i
);
350 SdrObject
* pEdgeTmp
=pEM
->GetMarkedSdrObj();
351 SdrEdgeObj
* pEdge
=PTR_CAST(SdrEdgeObj
,pEdgeTmp
);
353 pEdge
->SetEdgeTrackDirty();
362 void SdrEditView::MarkListHasChanged()
364 SdrMarkView::MarkListHasChanged();
365 bPossibilitiesDirty
=true;
368 void SdrEditView::ModelHasChanged()
370 SdrMarkView::ModelHasChanged();
371 bPossibilitiesDirty
=true;
374 bool SdrEditView::IsResizeAllowed(bool bProp
) const
376 ForcePossibilities();
377 if (bResizeProtect
) return false;
378 if (bProp
) return bResizePropAllowed
;
379 return bResizeFreeAllowed
;
382 bool SdrEditView::IsRotateAllowed(bool b90Deg
) const
384 ForcePossibilities();
385 if (bMoveProtect
) return false;
386 if (b90Deg
) return bRotate90Allowed
;
387 return bRotateFreeAllowed
;
390 bool SdrEditView::IsMirrorAllowed(bool b45Deg
, bool b90Deg
) const
392 ForcePossibilities();
393 if (bMoveProtect
) return false;
394 if (b90Deg
) return bMirror90Allowed
;
395 if (b45Deg
) return bMirror45Allowed
;
396 return bMirrorFreeAllowed
&& !bMoveProtect
;
399 bool SdrEditView::IsTransparenceAllowed() const
401 ForcePossibilities();
402 return bTransparenceAllowed
;
405 bool SdrEditView::IsGradientAllowed() const
407 ForcePossibilities();
408 return bGradientAllowed
;
411 bool SdrEditView::IsShearAllowed() const
413 ForcePossibilities();
414 if (bResizeProtect
) return false;
415 return bShearAllowed
;
418 bool SdrEditView::IsEdgeRadiusAllowed() const
420 ForcePossibilities();
421 return bEdgeRadiusAllowed
;
424 bool SdrEditView::IsCrookAllowed(bool bNoContortion
) const
426 // CrookMode missing here (no rotations allowed when shearing ...)
427 ForcePossibilities();
429 if (!bRotateFreeAllowed
) return false;
430 return !bMoveProtect
&& bMoveAllowed
;
432 return !bResizeProtect
&& bContortionPossible
;
436 bool SdrEditView::IsDistortAllowed(bool bNoContortion
) const
438 ForcePossibilities();
442 return !bResizeProtect
&& bContortionPossible
;
446 bool SdrEditView::IsCombinePossible(bool bNoPolyPoly
) const
448 ForcePossibilities();
449 if (bNoPolyPoly
) return bCombineNoPolyPolyPossible
;
450 else return bCombinePossible
;
453 bool SdrEditView::IsDismantlePossible(bool bMakeLines
) const
455 ForcePossibilities();
456 if (bMakeLines
) return bDismantleMakeLinesPossible
;
457 else return bDismantlePossible
;
460 void SdrEditView::CheckPossibilities()
462 if (bSomeObjChgdFlag
) bPossibilitiesDirty
=true;
466 // This call IS necessary to correct the MarkList, in which
467 // no longer to the model belonging objects still can reside.
468 // These ones need to be removed.
472 if (bPossibilitiesDirty
) {
473 ImpResetPossibilityFlags();
475 sal_uIntPtr nMarkAnz
=GetMarkedObjectCount();
477 bReverseOrderPossible
=nMarkAnz
>=2;
479 sal_uIntPtr nMovableCount
=0;
480 bGroupPossible
=nMarkAnz
>=2;
481 bCombinePossible
=nMarkAnz
>=2;
483 // check bCombinePossible more thoroughly
485 const SdrObject
* pObj
=GetMarkedObjectByIndex(0);
486 //const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
487 bool bGroup
=pObj
->GetSubList()!=NULL
;
488 bool bHasText
=pObj
->GetOutlinerParaObject()!=NULL
;
489 if (bGroup
|| bHasText
) {
490 bCombinePossible
=true;
493 bCombineNoPolyPolyPossible
=bCombinePossible
;
494 bDeletePossible
=true;
495 // accept transformations for now
497 bResizeFreeAllowed
=true;
498 bResizePropAllowed
=true;
499 bRotateFreeAllowed
=true;
500 bRotate90Allowed
=true;
501 bMirrorFreeAllowed
=true;
502 bMirror45Allowed
=true;
503 bMirror90Allowed
=true;
505 bEdgeRadiusAllowed
=false;
506 bContortionPossible
=true;
507 bCanConvToContour
= true;
509 // these ones are only allowed when single object is selected
510 bTransparenceAllowed
= (nMarkAnz
== 1);
511 bGradientAllowed
= (nMarkAnz
== 1);
514 // gradient depends on fill style
515 const SdrMark
* pM
= GetSdrMarkByIndex(0);
516 const SdrObject
* pObj
= pM
->GetMarkedSdrObj();
518 // may be group object, so get merged ItemSet
519 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
520 SfxItemState eState
= rSet
.GetItemState(XATTR_FILLSTYLE
, false);
522 if(SFX_ITEM_DONTCARE
!= eState
)
524 // If state is not DONTCARE, test the item
525 XFillStyle eFillStyle
= ((XFillStyleItem
&)(rSet
.Get(XATTR_FILLSTYLE
))).GetValue();
527 if(eFillStyle
!= XFILL_GRADIENT
)
529 bGradientAllowed
= false;
534 bool bNoMovRotFound
=false;
535 const SdrPageView
* pPV0
=NULL
;
537 for (sal_uIntPtr nm
=0; nm
<nMarkAnz
; nm
++) {
538 const SdrMark
* pM
=GetSdrMarkByIndex(nm
);
539 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
540 const SdrPageView
* pPV
=pM
->GetPageView();
542 if (pPV
->IsReadOnly()) bReadOnly
=true;
546 SdrObjTransformInfoRec aInfo
;
547 pObj
->TakeObjInfo(aInfo
);
548 bool bMovPrt
=pObj
->IsMoveProtect();
549 bool bSizPrt
=pObj
->IsResizeProtect();
550 if (!bMovPrt
&& aInfo
.bMoveAllowed
) nMovableCount
++; // count MovableObjs
551 if (bMovPrt
) bMoveProtect
=true;
552 if (bSizPrt
) bResizeProtect
=true;
554 // not allowed when not allowed at one object
555 if(!aInfo
.bTransparenceAllowed
)
556 bTransparenceAllowed
= false;
558 // If one of these can't do something, none can
559 if (!aInfo
.bMoveAllowed
) bMoveAllowed
=false;
560 if (!aInfo
.bResizeFreeAllowed
) bResizeFreeAllowed
=false;
561 if (!aInfo
.bResizePropAllowed
) bResizePropAllowed
=false;
562 if (!aInfo
.bRotateFreeAllowed
) bRotateFreeAllowed
=false;
563 if (!aInfo
.bRotate90Allowed
) bRotate90Allowed
=false;
564 if (!aInfo
.bMirrorFreeAllowed
) bMirrorFreeAllowed
=false;
565 if (!aInfo
.bMirror45Allowed
) bMirror45Allowed
=false;
566 if (!aInfo
.bMirror90Allowed
) bMirror90Allowed
=false;
567 if (!aInfo
.bShearAllowed
) bShearAllowed
=false;
568 if (aInfo
.bEdgeRadiusAllowed
) bEdgeRadiusAllowed
=true;
569 if (aInfo
.bNoContortion
) bContortionPossible
=false;
570 // For Crook with Contortion: all objects have to be
571 // Movable and Rotatable, except for a maximum of 1 of them
572 if (!bMoreThanOneNoMovRot
) {
573 if (!aInfo
.bMoveAllowed
|| !aInfo
.bResizeFreeAllowed
) {
574 bMoreThanOneNoMovRot
=bNoMovRotFound
;
579 // if one member cannot be converted, no conversion is possible
580 if(!aInfo
.bCanConvToContour
)
581 bCanConvToContour
= false;
584 if (!bUnGroupPossible
) bUnGroupPossible
=pObj
->GetSubList()!=NULL
;
585 // ConvertToCurve: If at least one can be converted, that is fine.
586 if (aInfo
.bCanConvToPath
) bCanConvToPath
=true;
587 if (aInfo
.bCanConvToPoly
) bCanConvToPoly
=true;
588 if (aInfo
.bCanConvToPathLineToArea
) bCanConvToPathLineToArea
=true;
589 if (aInfo
.bCanConvToPolyLineToArea
) bCanConvToPolyLineToArea
=true;
594 bCombinePossible
= ImpCanConvertForCombine(pObj
);
595 bCombineNoPolyPolyPossible
= bCombinePossible
;
598 if (!bDismantlePossible
) bDismantlePossible
= ImpCanDismantle(pObj
, false);
599 if (!bDismantleMakeLinesPossible
) bDismantleMakeLinesPossible
= ImpCanDismantle(pObj
, true);
600 // check OrthoDesiredOnMarked
601 if (!bOrthoDesiredOnMarked
&& !aInfo
.bNoOrthoDesired
) bOrthoDesiredOnMarked
=true;
604 if (!bImportMtfPossible
)
606 const SdrGrafObj
* pSdrGrafObj
= dynamic_cast< const SdrGrafObj
* >(pObj
);
607 const SdrOle2Obj
* pSdrOle2Obj
= dynamic_cast< const SdrOle2Obj
* >(pObj
);
609 if(pSdrGrafObj
&& ((pSdrGrafObj
->HasGDIMetaFile() && !pSdrGrafObj
->IsEPS()) || pSdrGrafObj
->isEmbeddedSvg()))
611 bImportMtfPossible
= true;
616 bImportMtfPossible
= pSdrOle2Obj
->GetObjRef().is();
621 bMoreThanOneNotMovable
=nMovableCount
<nMarkAnz
-1;
622 bOneOrMoreMovable
=nMovableCount
!=0;
623 bGrpEnterPossible
=bUnGroupPossible
;
625 ImpCheckToTopBtmPossible();
626 ((SdrPolyEditView
*)this)->ImpCheckPolyPossibilities();
627 bPossibilitiesDirty
=false;
630 bool bMerker1
=bGrpEnterPossible
;
631 ImpResetPossibilityFlags();
633 bGrpEnterPossible
=bMerker1
;
636 // Don't allow moving glued connectors.
637 // Currently only implemented for single selection.
639 SdrObject
* pObj
=GetMarkedObjectByIndex(0);
640 SdrEdgeObj
* pEdge
=PTR_CAST(SdrEdgeObj
,pObj
);
642 SdrObject
* pNode1
=pEdge
->GetConnectedNode(true);
643 SdrObject
* pNode2
=pEdge
->GetConnectedNode(false);
644 if (pNode1
!=NULL
|| pNode2
!=NULL
) bMoveAllowed
=false;
653 void SdrEditView::ForceMarkedObjToAnotherPage()
656 for (sal_uIntPtr nm
=0; nm
<GetMarkedObjectCount(); nm
++) {
657 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
658 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
659 Rectangle
aObjRect(pObj
->GetCurrentBoundRect());
660 Rectangle
aPgRect(pM
->GetPageView()->GetPageRect());
661 if (!aObjRect
.IsOver(aPgRect
)) {
663 SdrPageView
* pPV
= GetSdrPageView();
667 bFnd
= aObjRect
.IsOver(pPV
->GetPageRect());
672 pM
->GetPageView()->GetObjList()->RemoveObject(pObj
->GetOrdNum());
673 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
674 pPV
->GetObjList()->InsertObject(pObj
,CONTAINER_APPEND
,&aReason
);
675 pM
->SetPageView(pPV
);
676 InvalidateAllWin(aObjRect
);
682 MarkListHasChanged();
686 void SdrEditView::DeleteMarkedList(const SdrMarkList
& rMark
)
688 if (rMark
.GetMarkCount()!=0)
692 const bool bUndo
= IsUndoEnabled();
695 const sal_uInt32
nMarkAnz(rMark
.GetMarkCount());
700 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
704 for(nm
= nMarkAnz
; nm
> 0;)
707 SdrMark
* pM
= rMark
.GetMark(nm
);
708 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
710 // extra undo actions for changed connector which now may hold its layed out path (SJ)
711 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pObj
) );
712 AddUndoActions( vConnectorUndoActions
);
714 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
));
718 // make sure, OrderNums are correct:
719 rMark
.GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
721 std::vector
< SdrObject
* > aRemoved3DObjects
;
723 for(nm
= nMarkAnz
; nm
> 0;)
726 SdrMark
* pM
= rMark
.GetMark(nm
);
727 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
728 SdrObjList
* pOL
= pObj
->GetObjList();
729 const sal_uInt32
nOrdNum(pObj
->GetOrdNumDirect());
731 bool bIs3D
= dynamic_cast< E3dObject
* >(pObj
);
732 // set up a scene updater if object is a 3d object
735 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pObj
));
738 pOL
->RemoveObject(nOrdNum
);
743 aRemoved3DObjects
.push_back( pObj
); // may be needed later
745 SdrObject::Free(pObj
);
749 // fire scene updaters
750 while(!aUpdaters
.empty())
752 delete aUpdaters
.back();
753 aUpdaters
.pop_back();
758 // now delete removed scene objects
759 while(!aRemoved3DObjects
.empty())
761 SdrObject::Free( aRemoved3DObjects
.back() );
762 aRemoved3DObjects
.pop_back();
772 void SdrEditView::DeleteMarkedObj()
774 // #i110981# return when nothing is to be done at all
775 if(!GetMarkedObjectCount())
780 // moved breaking action and undo start outside loop
782 BegUndo(ImpGetResStr(STR_EditDelete
),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_DELETE
);
784 // remove as long as something is selected. This allows to schedule objects for
785 // removal for a next run as needed
786 while(GetMarkedObjectCount())
788 // vector to remember the parents which may be empty after object removal
789 std::vector
< SdrObject
* > aParents
;
792 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
793 const sal_uInt32
nCount(rMarkList
.GetMarkCount());
796 for(a
= 0; a
< nCount
; a
++)
798 // in the first run, add all found parents, but only once
799 SdrMark
* pMark
= rMarkList
.GetMark(a
);
800 SdrObject
* pObject
= pMark
->GetMarkedSdrObj();
801 SdrObject
* pParent
= pObject
->GetObjList()->GetOwnerObj();
805 if(!aParents
.empty())
807 std::vector
< SdrObject
* >::iterator aFindResult
=
808 std::find(aParents
.begin(), aParents
.end(), pParent
);
810 if(aFindResult
== aParents
.end())
812 aParents
.push_back(pParent
);
817 aParents
.push_back(pParent
);
822 if(!aParents
.empty())
824 // in a 2nd run, remove all objects which may already be scheduled for
825 // removal. I am not sure if this can happen, but theoretically
826 // a to-be-removed object may already be the group/3DScene itself
827 for(a
= 0; a
< nCount
; a
++)
829 SdrMark
* pMark
= rMarkList
.GetMark(a
);
830 SdrObject
* pObject
= pMark
->GetMarkedSdrObj();
832 std::vector
< SdrObject
* >::iterator aFindResult
=
833 std::find(aParents
.begin(), aParents
.end(), pObject
);
835 if(aFindResult
!= aParents
.end())
837 aParents
.erase(aFindResult
);
843 // original stuff: remove selected objects. Handle clear will
844 // do something only once
845 DeleteMarkedList(GetMarkedObjectList());
846 GetMarkedObjectListWriteAccess().Clear();
849 while(aParents
.size() && !GetMarkedObjectCount())
851 // iterate over remembered parents
852 SdrObject
* pParent
= aParents
.back();
855 if(pParent
->GetSubList() && 0 == pParent
->GetSubList()->GetObjCount())
857 // we detected an empty parent, a candidate to leave group/3DScene
859 if(GetSdrPageView()->GetAktGroup()
860 && GetSdrPageView()->GetAktGroup() == pParent
)
862 GetSdrPageView()->LeaveOneGroup();
865 // schedule empty parent for removal
866 GetMarkedObjectListWriteAccess().InsertEntry(
867 SdrMark(pParent
, GetSdrPageView()));
872 // end undo and change messaging moved at the end
874 MarkListHasChanged();
877 void SdrEditView::CopyMarkedObj()
881 SdrMarkList
aSourceObjectsForCopy(GetMarkedObjectList());
882 // The following loop is used instead of MarkList::Merge(), to be
883 // able to flag the MarkEntries.
884 sal_uIntPtr nEdgeAnz
= GetEdgesOfMarkedNodes().GetMarkCount();
885 for (sal_uIntPtr nEdgeNum
=0; nEdgeNum
<nEdgeAnz
; nEdgeNum
++) {
886 SdrMark
aM(*GetEdgesOfMarkedNodes().GetMark(nEdgeNum
));
888 aSourceObjectsForCopy
.InsertEntry(aM
);
890 aSourceObjectsForCopy
.ForceSort();
893 // New mechanism to re-create the connections of cloned connectors
894 CloneList aCloneList
;
896 const bool bUndo
= IsUndoEnabled();
898 GetMarkedObjectListWriteAccess().Clear();
899 sal_uIntPtr nCloneErrCnt
=0;
900 sal_uIntPtr nMarkAnz
=aSourceObjectsForCopy
.GetMarkCount();
902 for (nm
=0; nm
<nMarkAnz
; nm
++) {
903 SdrMark
* pM
=aSourceObjectsForCopy
.GetMark(nm
);
904 SdrObject
* pO
=pM
->GetMarkedSdrObj()->Clone();
906 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
907 pM
->GetPageView()->GetObjList()->InsertObject(pO
,CONTAINER_APPEND
,&aReason
);
910 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoCopyObject(*pO
));
913 aME
.SetMarkedSdrObj(pO
);
914 aCloneList
.AddPair(pM
->GetMarkedSdrObj(), pO
);
916 if (pM
->GetUser()==0)
918 // otherwise it is only an Edge we have to copy as well
919 GetMarkedObjectListWriteAccess().InsertEntry(aME
);
927 // New mechanism to re-create the connections of cloned connectors
928 aCloneList
.CopyConnections();
930 if(0L != nCloneErrCnt
)
933 OStringBuffer
aStr("SdrEditView::CopyMarkedObj(): Error when cloning ");
935 if(nCloneErrCnt
== 1)
937 aStr
.append("a drawing object.");
941 aStr
.append(static_cast<sal_Int32
>(nCloneErrCnt
));
942 aStr
.append(" drawing objects.");
945 aStr
.append(" This object's/These objects's connections will not be copied.");
946 OSL_FAIL(aStr
.getStr());
949 MarkListHasChanged();
954 bool SdrEditView::InsertObjectAtView(SdrObject
* pObj
, SdrPageView
& rPV
, sal_uIntPtr nOptions
)
956 if ((nOptions
& SDRINSERT_SETDEFLAYER
)!=0) {
957 SdrLayerID nLayer
=rPV
.GetPage()->GetLayerAdmin().GetLayerID(aAktLayer
,true);
958 if (nLayer
==SDRLAYER_NOTFOUND
) nLayer
=0;
959 if (rPV
.GetLockedLayers().IsSet(nLayer
) || !rPV
.GetVisibleLayers().IsSet(nLayer
)) {
960 SdrObject::Free( pObj
); // Layer locked or invisible
963 pObj
->NbcSetLayer(nLayer
);
965 if ((nOptions
& SDRINSERT_SETDEFATTR
)!=0) {
966 if (pDefaultStyleSheet
!=NULL
) pObj
->NbcSetStyleSheet(pDefaultStyleSheet
, false);
967 pObj
->SetMergedItemSet(aDefaultAttr
);
969 if (!pObj
->IsInserted()) {
970 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
971 if ((nOptions
& SDRINSERT_NOBROADCAST
)!=0) {
972 rPV
.GetObjList()->NbcInsertObject(pObj
,CONTAINER_APPEND
,&aReason
);
974 rPV
.GetObjList()->InsertObject(pObj
,CONTAINER_APPEND
,&aReason
);
977 if( IsUndoEnabled() )
978 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj
));
980 if ((nOptions
& SDRINSERT_DONTMARK
)==0) {
981 if ((nOptions
& SDRINSERT_ADDMARK
)==0) UnmarkAllObj();
987 void SdrEditView::ReplaceObjectAtView(SdrObject
* pOldObj
, SdrPageView
& rPV
, SdrObject
* pNewObj
, bool bMark
)
992 if(pOldObj
&& dynamic_cast< SdrTextObj
* >(pOldObj
) && static_cast< SdrTextObj
* >(pOldObj
)->IsTextEditActive())
994 OSL_ENSURE(false, "OldObject is in TextEdit mode, this has to be ended before replacing it usnig SdrEndTextEdit (!)");
997 if(pNewObj
&& dynamic_cast< SdrTextObj
* >(pNewObj
) && static_cast< SdrTextObj
* >(pNewObj
)->IsTextEditActive())
999 OSL_ENSURE(false, "NewObject is in TextEdit mode, this has to be ended before replacing it usnig SdrEndTextEdit (!)");
1003 // #i123468# emergency repair situation, needs to cast up to a class derived from
1004 // this one; (aw080 has a mechanism for that and the view hierarchy is secured to
1005 // always be a SdrView)
1006 SdrView
*pSdrView
= dynamic_cast<SdrView
*>(this);
1008 pSdrView
->SdrEndTextEdit();
1011 SdrObjList
* pOL
=pOldObj
->GetObjList();
1012 const bool bUndo
= IsUndoEnabled();
1014 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pOldObj
,*pNewObj
));
1016 if( IsObjMarked( pOldObj
) )
1017 MarkObj( pOldObj
, &rPV
, true /*unmark!*/ );
1019 pOL
->ReplaceObject(pNewObj
,pOldObj
->GetOrdNum());
1022 SdrObject::Free( pOldObj
);
1024 if (bMark
) MarkObj(pNewObj
,&rPV
);
1029 bool SdrEditView::IsUndoEnabled() const
1031 return pMod
->IsUndoEnabled();
1034 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */