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 using namespace com::sun::star
;
41 void SdrEditView::ImpResetPossibilityFlags()
45 bGroupPossible
=false;
46 bUnGroupPossible
=false;
47 bGrpEnterPossible
=false;
48 bDeletePossible
=false;
49 bToTopPossible
=false;
50 bToBtmPossible
=false;
51 bReverseOrderPossible
=false;
53 bImportMtfPossible
=false;
54 bCombinePossible
=false;
55 bDismantlePossible
=false;
56 bCombineNoPolyPolyPossible
=false;
57 bDismantleMakeLinesPossible
=false;
58 bOrthoDesiredOnMarked
=false;
60 bMoreThanOneNotMovable
=false;
61 bOneOrMoreMovable
=false;
62 bMoreThanOneNoMovRot
=false;
63 bContortionPossible
=false;
65 bOneOrMorePolys
=false;
67 bResizeFreeAllowed
=false;
68 bResizePropAllowed
=false;
69 bRotateFreeAllowed
=false;
70 bRotate90Allowed
=false;
71 bMirrorFreeAllowed
=false;
72 bMirror45Allowed
=false;
73 bMirror90Allowed
=false;
74 bTransparenceAllowed
=false;
76 bGradientAllowed
=false;
78 bEdgeRadiusAllowed
=false;
79 bCanConvToPath
=false;
80 bCanConvToPoly
=false;
81 bCanConvToContour
=false;
82 bCanConvToPathLineToArea
=false;
83 bCanConvToPolyLineToArea
=false;
85 bResizeProtect
=false;
88 void SdrEditView::ImpClearVars()
90 ImpResetPossibilityFlags();
91 bPossibilitiesDirty
=true; // << Purify didn't like this
95 SdrEditView::SdrEditView(SdrModel
* pModel1
, OutputDevice
* pOut
):
96 SdrMarkView(pModel1
,pOut
)
101 SdrEditView::~SdrEditView()
107 SdrLayer
* SdrEditView::InsertNewLayer(const OUString
& rName
, sal_uInt16 nPos
)
109 SdrLayerAdmin
& rLA
=pMod
->GetLayerAdmin();
110 sal_uInt16 nMax
=rLA
.GetLayerCount();
111 if (nPos
>nMax
) nPos
=nMax
;
112 SdrLayer
* pNewLayer
=rLA
.NewLayer(rName
,nPos
);
114 if( GetModel()->IsUndoEnabled() )
115 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewLayer(nPos
,rLA
,*pMod
));
121 #include <svx/svdogrp.hxx>
122 #include <svx/scene3d.hxx>
124 bool SdrEditView::ImpDelLayerCheck(SdrObjList
* pOL
, SdrLayerID nDelID
) const
128 for(size_t nObjNum
= pOL
->GetObjCount(); nObjNum
> 0 && bDelAll
;)
131 SdrObject
* pObj
= pOL
->GetObj(nObjNum
);
132 SdrObjList
* pSubOL
= pObj
->GetSubList();
134 // explicitly test for group objects and 3d scenes
135 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
137 if(!ImpDelLayerCheck(pSubOL
, nDelID
))
144 if(pObj
->GetLayer() != nDelID
)
154 void SdrEditView::ImpDelLayerDelObjs(SdrObjList
* pOL
, SdrLayerID nDelID
)
156 const size_t nObjAnz(pOL
->GetObjCount());
157 // make sure OrdNums are correct
158 pOL
->GetObj(0)->GetOrdNum();
160 const bool bUndo
= GetModel()->IsUndoEnabled();
162 for(size_t nObjNum
= nObjAnz
; nObjNum
> 0;)
165 SdrObject
* pObj
= pOL
->GetObj(nObjNum
);
166 SdrObjList
* pSubOL
= pObj
->GetSubList();
169 // explicitly test for group objects and 3d scenes
170 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
172 if(ImpDelLayerCheck(pSubOL
, nDelID
))
175 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
176 pOL
->RemoveObject(nObjNum
);
179 SdrObject::Free( pObj
);
183 ImpDelLayerDelObjs(pSubOL
, nDelID
);
188 if(pObj
->GetLayer() == nDelID
)
191 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
192 pOL
->RemoveObject(nObjNum
);
194 SdrObject::Free( pObj
);
200 void SdrEditView::DeleteLayer(const OUString
& rName
)
202 SdrLayerAdmin
& rLA
= pMod
->GetLayerAdmin();
203 SdrLayer
* pLayer
= rLA
.GetLayer(rName
, true);
204 sal_uInt16
nLayerNum(rLA
.GetLayerPos(pLayer
));
206 if(SDRLAYER_NOTFOUND
!= nLayerNum
)
209 SdrLayerID nDelID
= pLayer
->GetID();
211 const bool bUndo
= IsUndoEnabled();
213 BegUndo(ImpGetResStr(STR_UndoDelLayer
));
217 for(sal_uInt16
nPageKind(0); nPageKind
< 2; nPageKind
++)
219 // MasterPages and DrawPages
220 sal_uInt16
nPgAnz(bMaPg
? pMod
->GetMasterPageCount() : pMod
->GetPageCount());
222 for(sal_uInt16
nPgNum(0); nPgNum
< nPgAnz
; nPgNum
++)
225 SdrPage
* pPage
= (bMaPg
) ? pMod
->GetMasterPage(nPgNum
) : pMod
->GetPage(nPgNum
);
226 const size_t nObjAnz(pPage
->GetObjCount());
228 // make sure OrdNums are correct
230 pPage
->GetObj(0)->GetOrdNum();
232 for(size_t nObjNum(nObjAnz
); nObjNum
> 0;)
235 SdrObject
* pObj
= pPage
->GetObj(nObjNum
);
236 SdrObjList
* pSubOL
= pObj
->GetSubList();
238 // explicitly test for group objects and 3d scenes
239 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
241 if(ImpDelLayerCheck(pSubOL
, nDelID
))
244 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
245 pPage
->RemoveObject(nObjNum
);
247 SdrObject::Free(pObj
);
251 ImpDelLayerDelObjs(pSubOL
, nDelID
);
256 if(pObj
->GetLayer() == nDelID
)
259 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
260 pPage
->RemoveObject(nObjNum
);
262 SdrObject::Free(pObj
);
272 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteLayer(nLayerNum
, rLA
, *pMod
));
273 rLA
.RemoveLayer(nLayerNum
);
278 delete rLA
.RemoveLayer(nLayerNum
);
287 void SdrEditView::EndUndo()
290 // Comparison changed to 1L since EndUndo() is called later now
291 // and EndUndo WILL change count to count-1
292 if(1L == pMod
->GetUndoBracketLevel())
294 ImpBroadcastEdgesOfMarkedNodes();
298 // moved to bottom to still have access to UNDOs inside of
299 // ImpBroadcastEdgesOfMarkedNodes()
303 void SdrEditView::ImpBroadcastEdgesOfMarkedNodes()
305 std::vector
<SdrObject
*>::const_iterator iterPos
;
306 const std::vector
<SdrObject
*>& rAllMarkedObjects
= GetTransitiveHullOfMarkedObjects();
309 // New mechanism to search for necessary disconnections for
310 // changed connectors inside the transitive hull of all at
311 // the beginning of UNDO selected objects
312 for(sal_uInt32
a(0L); a
< rAllMarkedObjects
.size(); a
++)
314 SdrEdgeObj
* pEdge
= PTR_CAST(SdrEdgeObj
, rAllMarkedObjects
[a
]);
318 SdrObject
* pObj1
= pEdge
->GetConnectedNode(false);
319 SdrObject
* pObj2
= pEdge
->GetConnectedNode(true);
321 if(pObj1
&& !pEdge
->CheckNodeConnection(false))
323 iterPos
= std::find(rAllMarkedObjects
.begin(),rAllMarkedObjects
.end(),pObj1
);
325 if (iterPos
== rAllMarkedObjects
.end())
327 if( IsUndoEnabled() )
328 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge
));
329 pEdge
->DisconnectFromNode(false);
333 if(pObj2
&& !pEdge
->CheckNodeConnection(true))
335 iterPos
= std::find(rAllMarkedObjects
.begin(),rAllMarkedObjects
.end(),pObj2
);
337 if (iterPos
== rAllMarkedObjects
.end())
339 if( IsUndoEnabled() )
340 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge
));
341 pEdge
->DisconnectFromNode(true);
347 const size_t nMarkedEdgeAnz
= GetMarkedEdgesOfMarkedNodes().GetMarkCount();
349 for (size_t i
=0; i
<nMarkedEdgeAnz
; ++i
) {
350 SdrMark
* pEM
= GetMarkedEdgesOfMarkedNodes().GetMark(i
);
351 SdrObject
* pEdgeTmp
=pEM
->GetMarkedSdrObj();
352 SdrEdgeObj
* pEdge
=PTR_CAST(SdrEdgeObj
,pEdgeTmp
);
354 pEdge
->SetEdgeTrackDirty();
363 void SdrEditView::MarkListHasChanged()
365 SdrMarkView::MarkListHasChanged();
366 bPossibilitiesDirty
=true;
369 void SdrEditView::ModelHasChanged()
371 SdrMarkView::ModelHasChanged();
372 bPossibilitiesDirty
=true;
375 bool SdrEditView::IsResizeAllowed(bool bProp
) const
377 ForcePossibilities();
378 if (bResizeProtect
) return false;
379 if (bProp
) return bResizePropAllowed
;
380 return bResizeFreeAllowed
;
383 bool SdrEditView::IsRotateAllowed(bool b90Deg
) const
385 ForcePossibilities();
386 if (bMoveProtect
) return false;
387 if (b90Deg
) return bRotate90Allowed
;
388 return bRotateFreeAllowed
;
391 bool SdrEditView::IsMirrorAllowed(bool b45Deg
, bool b90Deg
) const
393 ForcePossibilities();
394 if (bMoveProtect
) return false;
395 if (b90Deg
) return bMirror90Allowed
;
396 if (b45Deg
) return bMirror45Allowed
;
397 return bMirrorFreeAllowed
&& !bMoveProtect
;
400 bool SdrEditView::IsTransparenceAllowed() const
402 ForcePossibilities();
403 return bTransparenceAllowed
;
406 bool SdrEditView::IsCropAllowed() const
408 ForcePossibilities();
412 bool SdrEditView::IsGradientAllowed() const
414 ForcePossibilities();
415 return bGradientAllowed
;
418 bool SdrEditView::IsShearAllowed() const
420 ForcePossibilities();
421 if (bResizeProtect
) return false;
422 return bShearAllowed
;
425 bool SdrEditView::IsEdgeRadiusAllowed() const
427 ForcePossibilities();
428 return bEdgeRadiusAllowed
;
431 bool SdrEditView::IsCrookAllowed(bool bNoContortion
) const
433 // CrookMode missing here (no rotations allowed when shearing ...)
434 ForcePossibilities();
436 if (!bRotateFreeAllowed
) return false;
437 return !bMoveProtect
&& bMoveAllowed
;
439 return !bResizeProtect
&& bContortionPossible
;
443 bool SdrEditView::IsDistortAllowed(bool bNoContortion
) const
445 ForcePossibilities();
449 return !bResizeProtect
&& bContortionPossible
;
453 bool SdrEditView::IsCombinePossible(bool bNoPolyPoly
) const
455 ForcePossibilities();
456 if (bNoPolyPoly
) return bCombineNoPolyPolyPossible
;
457 else return bCombinePossible
;
460 bool SdrEditView::IsDismantlePossible(bool bMakeLines
) const
462 ForcePossibilities();
463 if (bMakeLines
) return bDismantleMakeLinesPossible
;
464 else return bDismantlePossible
;
467 void SdrEditView::CheckPossibilities()
469 if (bSomeObjChgdFlag
) bPossibilitiesDirty
=true;
473 // This call IS necessary to correct the MarkList, in which
474 // no longer to the model belonging objects still can reside.
475 // These ones need to be removed.
479 if (bPossibilitiesDirty
) {
480 ImpResetPossibilityFlags();
482 const size_t nMarkCount
=GetMarkedObjectCount();
484 bReverseOrderPossible
=nMarkCount
>=2;
486 size_t nMovableCount
=0;
487 bGroupPossible
=nMarkCount
>=2;
488 bCombinePossible
=nMarkCount
>=2;
490 // check bCombinePossible more thoroughly
492 const SdrObject
* pObj
=GetMarkedObjectByIndex(0);
493 //const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
494 bool bGroup
=pObj
->GetSubList()!=NULL
;
495 bool bHasText
=pObj
->GetOutlinerParaObject()!=NULL
;
496 if (bGroup
|| bHasText
) {
497 bCombinePossible
=true;
500 bCombineNoPolyPolyPossible
=bCombinePossible
;
501 bDeletePossible
=true;
502 // accept transformations for now
504 bResizeFreeAllowed
=true;
505 bResizePropAllowed
=true;
506 bRotateFreeAllowed
=true;
507 bRotate90Allowed
=true;
508 bMirrorFreeAllowed
=true;
509 bMirror45Allowed
=true;
510 bMirror90Allowed
=true;
512 bEdgeRadiusAllowed
=false;
513 bContortionPossible
=true;
514 bCanConvToContour
= true;
516 // these ones are only allowed when single object is selected
517 bTransparenceAllowed
= (nMarkCount
== 1);
518 bGradientAllowed
= (nMarkCount
== 1);
519 bCropAllowed
= (nMarkCount
== 1);
522 // gradient depends on fill style
523 const SdrMark
* pM
= GetSdrMarkByIndex(0);
524 const SdrObject
* pObj
= pM
->GetMarkedSdrObj();
526 // may be group object, so get merged ItemSet
527 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
528 SfxItemState eState
= rSet
.GetItemState(XATTR_FILLSTYLE
, false);
530 if(SfxItemState::DONTCARE
!= eState
)
532 // If state is not DONTCARE, test the item
533 drawing::FillStyle eFillStyle
= static_cast<const XFillStyleItem
&>(rSet
.Get(XATTR_FILLSTYLE
)).GetValue();
535 if(eFillStyle
!= drawing::FillStyle_GRADIENT
)
537 bGradientAllowed
= false;
542 bool bNoMovRotFound
=false;
543 const SdrPageView
* pPV0
=NULL
;
545 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
546 const SdrMark
* pM
=GetSdrMarkByIndex(nm
);
547 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
548 const SdrPageView
* pPV
=pM
->GetPageView();
550 if (pPV
->IsReadOnly()) bReadOnly
=true;
554 SdrObjTransformInfoRec aInfo
;
555 pObj
->TakeObjInfo(aInfo
);
556 bool bMovPrt
=pObj
->IsMoveProtect();
557 bool bSizPrt
=pObj
->IsResizeProtect();
558 if (!bMovPrt
&& aInfo
.bMoveAllowed
) nMovableCount
++; // count MovableObjs
559 if (bMovPrt
) bMoveProtect
=true;
560 if (bSizPrt
) bResizeProtect
=true;
562 // not allowed when not allowed at one object
563 if(!aInfo
.bTransparenceAllowed
)
564 bTransparenceAllowed
= false;
566 // If one of these can't do something, none can
567 if (!aInfo
.bMoveAllowed
) bMoveAllowed
=false;
568 if (!aInfo
.bResizeFreeAllowed
) bResizeFreeAllowed
=false;
569 if (!aInfo
.bResizePropAllowed
) bResizePropAllowed
=false;
570 if (!aInfo
.bRotateFreeAllowed
) bRotateFreeAllowed
=false;
571 if (!aInfo
.bRotate90Allowed
) bRotate90Allowed
=false;
572 if (!aInfo
.bMirrorFreeAllowed
) bMirrorFreeAllowed
=false;
573 if (!aInfo
.bMirror45Allowed
) bMirror45Allowed
=false;
574 if (!aInfo
.bMirror90Allowed
) bMirror90Allowed
=false;
575 if (!aInfo
.bShearAllowed
) bShearAllowed
=false;
576 if (aInfo
.bEdgeRadiusAllowed
) bEdgeRadiusAllowed
=true;
577 if (aInfo
.bNoContortion
) bContortionPossible
=false;
578 // For Crook with Contortion: all objects have to be
579 // Movable and Rotatable, except for a maximum of 1 of them
580 if (!bMoreThanOneNoMovRot
) {
581 if (!aInfo
.bMoveAllowed
|| !aInfo
.bResizeFreeAllowed
) {
582 bMoreThanOneNoMovRot
=bNoMovRotFound
;
587 // Must be resizeable to allow cropping
588 if (!aInfo
.bResizeFreeAllowed
&& !aInfo
.bResizePropAllowed
)
589 bCropAllowed
= false;
591 // if one member cannot be converted, no conversion is possible
592 if(!aInfo
.bCanConvToContour
)
593 bCanConvToContour
= false;
596 if (!bUnGroupPossible
) bUnGroupPossible
=pObj
->GetSubList()!=NULL
;
597 // ConvertToCurve: If at least one can be converted, that is fine.
598 if (aInfo
.bCanConvToPath
) bCanConvToPath
=true;
599 if (aInfo
.bCanConvToPoly
) bCanConvToPoly
=true;
600 if (aInfo
.bCanConvToPathLineToArea
) bCanConvToPathLineToArea
=true;
601 if (aInfo
.bCanConvToPolyLineToArea
) bCanConvToPolyLineToArea
=true;
606 bCombinePossible
= ImpCanConvertForCombine(pObj
);
607 bCombineNoPolyPolyPossible
= bCombinePossible
;
610 if (!bDismantlePossible
) bDismantlePossible
= ImpCanDismantle(pObj
, false);
611 if (!bDismantleMakeLinesPossible
) bDismantleMakeLinesPossible
= ImpCanDismantle(pObj
, true);
612 // check OrthoDesiredOnMarked
613 if (!bOrthoDesiredOnMarked
&& !aInfo
.bNoOrthoDesired
) bOrthoDesiredOnMarked
=true;
616 if (!bImportMtfPossible
)
618 const SdrGrafObj
* pSdrGrafObj
= dynamic_cast< const SdrGrafObj
* >(pObj
);
619 const SdrOle2Obj
* pSdrOle2Obj
= dynamic_cast< const SdrOle2Obj
* >(pObj
);
621 if(pSdrGrafObj
&& ((pSdrGrafObj
->HasGDIMetaFile() && !pSdrGrafObj
->IsEPS()) || pSdrGrafObj
->isEmbeddedSvg()))
623 bImportMtfPossible
= true;
628 bImportMtfPossible
= pSdrOle2Obj
->GetObjRef().is();
633 bMoreThanOneNotMovable
=nMovableCount
<nMarkCount
-1;
634 bOneOrMoreMovable
=nMovableCount
!=0;
635 bGrpEnterPossible
=bUnGroupPossible
;
637 ImpCheckToTopBtmPossible();
638 static_cast<SdrPolyEditView
*>(this)->ImpCheckPolyPossibilities();
639 bPossibilitiesDirty
=false;
642 bool bMerker1
=bGrpEnterPossible
;
643 ImpResetPossibilityFlags();
645 bGrpEnterPossible
=bMerker1
;
648 // Don't allow moving glued connectors.
649 // Currently only implemented for single selection.
651 SdrObject
* pObj
=GetMarkedObjectByIndex(0);
652 SdrEdgeObj
* pEdge
=PTR_CAST(SdrEdgeObj
,pObj
);
654 SdrObject
* pNode1
=pEdge
->GetConnectedNode(true);
655 SdrObject
* pNode2
=pEdge
->GetConnectedNode(false);
656 if (pNode1
!=NULL
|| pNode2
!=NULL
) bMoveAllowed
=false;
665 void SdrEditView::ForceMarkedObjToAnotherPage()
668 for (size_t nm
=0; nm
<GetMarkedObjectCount(); ++nm
) {
669 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
670 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
671 Rectangle
aObjRect(pObj
->GetCurrentBoundRect());
672 Rectangle
aPgRect(pM
->GetPageView()->GetPageRect());
673 if (!aObjRect
.IsOver(aPgRect
)) {
675 SdrPageView
* pPV
= GetSdrPageView();
679 bFnd
= aObjRect
.IsOver(pPV
->GetPageRect());
684 pM
->GetPageView()->GetObjList()->RemoveObject(pObj
->GetOrdNum());
685 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
686 pPV
->GetObjList()->InsertObject(pObj
, SAL_MAX_SIZE
, &aReason
);
687 pM
->SetPageView(pPV
);
688 InvalidateAllWin(aObjRect
);
694 MarkListHasChanged();
698 void SdrEditView::DeleteMarkedList(const SdrMarkList
& rMark
)
700 if (rMark
.GetMarkCount()!=0)
704 const bool bUndo
= IsUndoEnabled();
707 const size_t nMarkCount(rMark
.GetMarkCount());
711 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
715 for(size_t nm
= nMarkCount
; nm
> 0;)
718 SdrMark
* pM
= rMark
.GetMark(nm
);
719 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
721 // extra undo actions for changed connector which now may hold its laid out path (SJ)
722 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pObj
) );
723 AddUndoActions( vConnectorUndoActions
);
725 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
));
729 // make sure, OrderNums are correct:
730 rMark
.GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
732 std::vector
< SdrObject
* > aRemoved3DObjects
;
734 for(size_t nm
= nMarkCount
; nm
> 0;)
737 SdrMark
* pM
= rMark
.GetMark(nm
);
738 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
739 SdrObjList
* pOL
= pObj
->GetObjList();
740 const size_t nOrdNum(pObj
->GetOrdNumDirect());
742 bool bIs3D
= dynamic_cast< E3dObject
* >(pObj
);
743 // set up a scene updater if object is a 3d object
746 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pObj
));
749 pOL
->RemoveObject(nOrdNum
);
754 aRemoved3DObjects
.push_back( pObj
); // may be needed later
756 SdrObject::Free(pObj
);
760 // fire scene updaters
761 while(!aUpdaters
.empty())
763 delete aUpdaters
.back();
764 aUpdaters
.pop_back();
769 // now delete removed scene objects
770 while(!aRemoved3DObjects
.empty())
772 SdrObject::Free( aRemoved3DObjects
.back() );
773 aRemoved3DObjects
.pop_back();
783 void SdrEditView::DeleteMarkedObj()
785 // #i110981# return when nothing is to be done at all
786 if(!GetMarkedObjectCount())
791 // moved breaking action and undo start outside loop
793 BegUndo(ImpGetResStr(STR_EditDelete
),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_DELETE
);
795 // remove as long as something is selected. This allows to schedule objects for
796 // removal for a next run as needed
797 while(GetMarkedObjectCount())
799 // vector to remember the parents which may be empty after object removal
800 std::vector
< SdrObject
* > aParents
;
803 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
804 const size_t nCount(rMarkList
.GetMarkCount());
806 for(size_t a
= 0; a
< nCount
; ++a
)
808 // in the first run, add all found parents, but only once
809 SdrMark
* pMark
= rMarkList
.GetMark(a
);
810 SdrObject
* pObject
= pMark
->GetMarkedSdrObj();
811 SdrObject
* pParent
= pObject
->GetObjList()->GetOwnerObj();
815 if(!aParents
.empty())
817 std::vector
< SdrObject
* >::iterator aFindResult
=
818 std::find(aParents
.begin(), aParents
.end(), pParent
);
820 if(aFindResult
== aParents
.end())
822 aParents
.push_back(pParent
);
827 aParents
.push_back(pParent
);
832 if(!aParents
.empty())
834 // in a 2nd run, remove all objects which may already be scheduled for
835 // removal. I am not sure if this can happen, but theoretically
836 // a to-be-removed object may already be the group/3DScene itself
837 for(size_t a
= 0; a
< nCount
; ++a
)
839 SdrMark
* pMark
= rMarkList
.GetMark(a
);
840 SdrObject
* pObject
= pMark
->GetMarkedSdrObj();
842 std::vector
< SdrObject
* >::iterator aFindResult
=
843 std::find(aParents
.begin(), aParents
.end(), pObject
);
845 if(aFindResult
!= aParents
.end())
847 aParents
.erase(aFindResult
);
853 // original stuff: remove selected objects. Handle clear will
854 // do something only once
855 DeleteMarkedList(GetMarkedObjectList());
856 GetMarkedObjectListWriteAccess().Clear();
859 while(aParents
.size() && !GetMarkedObjectCount())
861 // iterate over remembered parents
862 SdrObject
* pParent
= aParents
.back();
865 if(pParent
->GetSubList() && 0 == pParent
->GetSubList()->GetObjCount())
867 // we detected an empty parent, a candidate to leave group/3DScene
869 if(GetSdrPageView()->GetAktGroup()
870 && GetSdrPageView()->GetAktGroup() == pParent
)
872 GetSdrPageView()->LeaveOneGroup();
875 // schedule empty parent for removal
876 GetMarkedObjectListWriteAccess().InsertEntry(
877 SdrMark(pParent
, GetSdrPageView()));
882 // end undo and change messaging moved at the end
884 MarkListHasChanged();
887 void SdrEditView::CopyMarkedObj()
891 SdrMarkList
aSourceObjectsForCopy(GetMarkedObjectList());
892 // The following loop is used instead of MarkList::Merge(), to be
893 // able to flag the MarkEntries.
894 const size_t nEdgeAnz
= GetEdgesOfMarkedNodes().GetMarkCount();
895 for (size_t nEdgeNum
=0; nEdgeNum
<nEdgeAnz
; ++nEdgeNum
) {
896 SdrMark
aM(*GetEdgesOfMarkedNodes().GetMark(nEdgeNum
));
898 aSourceObjectsForCopy
.InsertEntry(aM
);
900 aSourceObjectsForCopy
.ForceSort();
903 // New mechanism to re-create the connections of cloned connectors
904 CloneList aCloneList
;
906 const bool bUndo
= IsUndoEnabled();
908 GetMarkedObjectListWriteAccess().Clear();
909 size_t nCloneErrCnt
=0;
910 const size_t nMarkCount
=aSourceObjectsForCopy
.GetMarkCount();
911 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
912 SdrMark
* pM
=aSourceObjectsForCopy
.GetMark(nm
);
913 SdrObject
* pO
=pM
->GetMarkedSdrObj()->Clone();
915 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
916 pM
->GetPageView()->GetObjList()->InsertObject(pO
, SAL_MAX_SIZE
, &aReason
);
919 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoCopyObject(*pO
));
922 aME
.SetMarkedSdrObj(pO
);
923 aCloneList
.AddPair(pM
->GetMarkedSdrObj(), pO
);
925 if (pM
->GetUser()==0)
927 // otherwise it is only an Edge we have to copy as well
928 GetMarkedObjectListWriteAccess().InsertEntry(aME
);
936 // New mechanism to re-create the connections of cloned connectors
937 aCloneList
.CopyConnections();
942 OStringBuffer
aStr("SdrEditView::CopyMarkedObj(): Error when cloning ");
944 if(nCloneErrCnt
== 1)
946 aStr
.append("a drawing object.");
950 aStr
.append(static_cast<sal_Int32
>(nCloneErrCnt
));
951 aStr
.append(" drawing objects.");
954 aStr
.append(" This object's/These objects's connections will not be copied.");
955 OSL_FAIL(aStr
.getStr());
958 MarkListHasChanged();
963 bool SdrEditView::InsertObjectAtView(SdrObject
* pObj
, SdrPageView
& rPV
, SdrInsertFlags nOptions
)
965 if (nOptions
& SdrInsertFlags::SETDEFLAYER
) {
966 SdrLayerID nLayer
=rPV
.GetPage()->GetLayerAdmin().GetLayerID(aAktLayer
,true);
967 if (nLayer
==SDRLAYER_NOTFOUND
) nLayer
=0;
968 if (rPV
.GetLockedLayers().IsSet(nLayer
) || !rPV
.GetVisibleLayers().IsSet(nLayer
)) {
969 SdrObject::Free( pObj
); // Layer locked or invisible
972 pObj
->NbcSetLayer(nLayer
);
974 if (nOptions
& SdrInsertFlags::SETDEFATTR
) {
975 if (pDefaultStyleSheet
!=NULL
) pObj
->NbcSetStyleSheet(pDefaultStyleSheet
, false);
976 pObj
->SetMergedItemSet(aDefaultAttr
);
978 if (!pObj
->IsInserted()) {
979 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
980 if (nOptions
& SdrInsertFlags::NOBROADCAST
) {
981 rPV
.GetObjList()->NbcInsertObject(pObj
, SAL_MAX_SIZE
, &aReason
);
983 rPV
.GetObjList()->InsertObject(pObj
, SAL_MAX_SIZE
, &aReason
);
986 if( IsUndoEnabled() )
987 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj
));
989 if (!(nOptions
& SdrInsertFlags::DONTMARK
)) {
990 if (!(nOptions
& SdrInsertFlags::ADDMARK
)) UnmarkAllObj();
996 void SdrEditView::ReplaceObjectAtView(SdrObject
* pOldObj
, SdrPageView
& rPV
, SdrObject
* pNewObj
, bool bMark
)
1001 if(dynamic_cast< SdrTextObj
* >(pOldObj
) && static_cast< SdrTextObj
* >(pOldObj
)->IsTextEditActive())
1003 OSL_ENSURE(false, "OldObject is in TextEdit mode, this has to be ended before replacing it usnig SdrEndTextEdit (!)");
1006 if(dynamic_cast< SdrTextObj
* >(pNewObj
) && static_cast< SdrTextObj
* >(pNewObj
)->IsTextEditActive())
1008 OSL_ENSURE(false, "NewObject is in TextEdit mode, this has to be ended before replacing it usnig SdrEndTextEdit (!)");
1012 // #i123468# emergency repair situation, needs to cast up to a class derived from
1013 // this one; (aw080 has a mechanism for that and the view hierarchy is secured to
1014 // always be a SdrView)
1015 SdrView
*pSdrView
= dynamic_cast<SdrView
*>(this);
1017 pSdrView
->SdrEndTextEdit();
1020 SdrObjList
* pOL
=pOldObj
->GetObjList();
1021 const bool bUndo
= IsUndoEnabled();
1023 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pOldObj
,*pNewObj
));
1025 if( IsObjMarked( pOldObj
) )
1026 MarkObj( pOldObj
, &rPV
, true /*unmark!*/ );
1028 pOL
->ReplaceObject(pNewObj
,pOldObj
->GetOrdNum());
1031 SdrObject::Free( pOldObj
);
1033 if (bMark
) MarkObj(pNewObj
,&rPV
);
1038 bool SdrEditView::IsUndoEnabled() const
1040 return pMod
->IsUndoEnabled();
1043 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */