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> // for Possibilities
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> // for the PolyPossiblities
32 #include "svx/svdstr.hrc" // names taken from the resource
33 #include "svx/svdglob.hxx" // StringCache
34 #include <svx/e3dsceneupdater.hxx>
35 #include <rtl/strbuf.hxx>
38 #include <clonelist.hxx>
40 void SdrEditView::ImpResetPossibilityFlags()
44 bGroupPossible
=sal_False
;
45 bUnGroupPossible
=sal_False
;
46 bGrpEnterPossible
=sal_False
;
47 bDeletePossible
=sal_False
;
48 bToTopPossible
=sal_False
;
49 bToBtmPossible
=sal_False
;
50 bReverseOrderPossible
=sal_False
;
52 bImportMtfPossible
=sal_False
;
53 bCombinePossible
=sal_False
;
54 bDismantlePossible
=sal_False
;
55 bCombineNoPolyPolyPossible
=sal_False
;
56 bDismantleMakeLinesPossible
=sal_False
;
57 bOrthoDesiredOnMarked
=sal_False
;
59 bMoreThanOneNotMovable
=sal_False
;
60 bOneOrMoreMovable
=sal_False
;
61 bMoreThanOneNoMovRot
=sal_False
;
62 bContortionPossible
=sal_False
;
64 bOneOrMorePolys
=sal_False
;
65 bMoveAllowed
=sal_False
;
66 bResizeFreeAllowed
=sal_False
;
67 bResizePropAllowed
=sal_False
;
68 bRotateFreeAllowed
=sal_False
;
69 bRotate90Allowed
=sal_False
;
70 bMirrorFreeAllowed
=sal_False
;
71 bMirror45Allowed
=sal_False
;
72 bMirror90Allowed
=sal_False
;
73 bTransparenceAllowed
=sal_False
;
74 bGradientAllowed
=sal_False
;
75 bShearAllowed
=sal_False
;
76 bEdgeRadiusAllowed
=sal_False
;
77 bCanConvToPath
=sal_False
;
78 bCanConvToPoly
=sal_False
;
79 bCanConvToContour
=sal_False
;
80 bCanConvToPathLineToArea
=sal_False
;
81 bCanConvToPolyLineToArea
=sal_False
;
82 bMoveProtect
=sal_False
;
83 bResizeProtect
=sal_False
;
86 void SdrEditView::ImpClearVars()
88 ImpResetPossibilityFlags();
89 bPossibilitiesDirty
=sal_True
; // << Purify didn't like this
90 bBundleVirtObj
=sal_False
;
93 SdrEditView::SdrEditView(SdrModel
* pModel1
, OutputDevice
* pOut
):
94 SdrMarkView(pModel1
,pOut
)
99 SdrEditView::~SdrEditView()
103 ////////////////////////////////////////////////////////////////////////////////////////////////////
105 SdrLayer
* SdrEditView::InsertNewLayer(const XubString
& rName
, sal_uInt16 nPos
)
107 SdrLayerAdmin
& rLA
=pMod
->GetLayerAdmin();
108 sal_uInt16 nMax
=rLA
.GetLayerCount();
109 if (nPos
>nMax
) nPos
=nMax
;
110 SdrLayer
* pNewLayer
=rLA
.NewLayer(rName
,nPos
);
112 if( GetModel()->IsUndoEnabled() )
113 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewLayer(nPos
,rLA
,*pMod
));
119 #include <svx/svdogrp.hxx>
120 #include <svx/scene3d.hxx>
122 sal_Bool
SdrEditView::ImpDelLayerCheck(SdrObjList
* pOL
, SdrLayerID nDelID
) const
124 sal_Bool
bDelAll(sal_True
);
125 sal_uInt32
nObjAnz(pOL
->GetObjCount());
127 for(sal_uInt32
nObjNum(nObjAnz
); nObjNum
> 0 && bDelAll
;)
130 SdrObject
* pObj
= pOL
->GetObj(nObjNum
);
131 SdrObjList
* pSubOL
= pObj
->GetSubList();
133 // explicitly test for group objects and 3d scenes
134 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
136 if(!ImpDelLayerCheck(pSubOL
, nDelID
))
143 if(pObj
->GetLayer() != nDelID
)
153 void SdrEditView::ImpDelLayerDelObjs(SdrObjList
* pOL
, SdrLayerID nDelID
)
155 sal_uInt32
nObjAnz(pOL
->GetObjCount());
156 // make sure OrdNums are correct
157 pOL
->GetObj(0)->GetOrdNum();
159 const bool bUndo
= GetModel()->IsUndoEnabled();
161 for(sal_uInt32
nObjNum(nObjAnz
); nObjNum
> 0;)
164 SdrObject
* pObj
= pOL
->GetObj(nObjNum
);
165 SdrObjList
* pSubOL
= pObj
->GetSubList();
168 // explicitly test for group objects and 3d scenes
169 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
171 if(ImpDelLayerCheck(pSubOL
, nDelID
))
174 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
175 pOL
->RemoveObject(nObjNum
);
178 SdrObject::Free( pObj
);
182 ImpDelLayerDelObjs(pSubOL
, nDelID
);
187 if(pObj
->GetLayer() == nDelID
)
190 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
191 pOL
->RemoveObject(nObjNum
);
193 SdrObject::Free( pObj
);
199 void SdrEditView::DeleteLayer(const XubString
& rName
)
201 SdrLayerAdmin
& rLA
= pMod
->GetLayerAdmin();
202 SdrLayer
* pLayer
= rLA
.GetLayer(rName
, sal_True
);
203 sal_uInt16
nLayerNum(rLA
.GetLayerPos(pLayer
));
205 if(SDRLAYER_NOTFOUND
!= nLayerNum
)
208 SdrLayerID nDelID
= pLayer
->GetID();
210 const bool bUndo
= IsUndoEnabled();
212 BegUndo(ImpGetResStr(STR_UndoDelLayer
));
216 for(sal_uInt16
nPageKind(0); nPageKind
< 2; nPageKind
++)
218 // MasterPages and DrawPages
219 sal_uInt16
nPgAnz(bMaPg
? pMod
->GetMasterPageCount() : pMod
->GetPageCount());
221 for(sal_uInt16
nPgNum(0); nPgNum
< nPgAnz
; nPgNum
++)
224 SdrPage
* pPage
= (bMaPg
) ? pMod
->GetMasterPage(nPgNum
) : pMod
->GetPage(nPgNum
);
225 sal_uInt32
nObjAnz(pPage
->GetObjCount());
227 // make sure OrdNums are correct
229 pPage
->GetObj(0)->GetOrdNum();
231 for(sal_uInt32
nObjNum(nObjAnz
); nObjNum
> 0;)
234 SdrObject
* pObj
= pPage
->GetObj(nObjNum
);
235 SdrObjList
* pSubOL
= pObj
->GetSubList();
237 // explicitly test for group objects and 3d scenes
238 if(pSubOL
&& (pObj
->ISA(SdrObjGroup
) || pObj
->ISA(E3dScene
)))
240 if(ImpDelLayerCheck(pSubOL
, nDelID
))
243 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
244 pPage
->RemoveObject(nObjNum
);
246 SdrObject::Free(pObj
);
250 ImpDelLayerDelObjs(pSubOL
, nDelID
);
255 if(pObj
->GetLayer() == nDelID
)
258 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
, true));
259 pPage
->RemoveObject(nObjNum
);
261 SdrObject::Free(pObj
);
271 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteLayer(nLayerNum
, rLA
, *pMod
));
272 rLA
.RemoveLayer(nLayerNum
);
277 delete rLA
.RemoveLayer(nLayerNum
);
284 ////////////////////////////////////////////////////////////////////////////////////////////////////
286 void SdrEditView::EndUndo()
289 // Comparison changed to 1L since EndUndo() is called later now
290 // and EndUndo WILL change count to count-1
291 if(1L == pMod
->GetUndoBracketLevel())
293 ImpBroadcastEdgesOfMarkedNodes();
297 // moved to bottom to still have access to UNDOs inside of
298 // ImpBroadcastEdgesOfMarkedNodes()
302 void SdrEditView::ImpBroadcastEdgesOfMarkedNodes()
304 std::vector
<SdrObject
*>::const_iterator iterPos
;
305 const std::vector
<SdrObject
*>& rAllMarkedObjects
= GetTransitiveHullOfMarkedObjects();
308 // New mechanism to search for necessary disconnections for
309 // changed connectors inside the transitive hull of all at
310 // the beginning of UNDO selected objects
311 for(sal_uInt32
a(0L); a
< rAllMarkedObjects
.size(); a
++)
313 SdrEdgeObj
* pEdge
= PTR_CAST(SdrEdgeObj
, rAllMarkedObjects
[a
]);
317 SdrObject
* pObj1
= pEdge
->GetConnectedNode(sal_False
);
318 SdrObject
* pObj2
= pEdge
->GetConnectedNode(sal_True
);
320 if(pObj1
&& !pEdge
->CheckNodeConnection(sal_False
))
322 iterPos
= std::find(rAllMarkedObjects
.begin(),rAllMarkedObjects
.end(),pObj1
);
324 if (iterPos
== rAllMarkedObjects
.end())
326 if( IsUndoEnabled() )
327 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge
));
328 pEdge
->DisconnectFromNode(sal_False
);
332 if(pObj2
&& !pEdge
->CheckNodeConnection(sal_True
))
334 iterPos
= std::find(rAllMarkedObjects
.begin(),rAllMarkedObjects
.end(),pObj2
);
336 if (iterPos
== rAllMarkedObjects
.end())
338 if( IsUndoEnabled() )
339 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge
));
340 pEdge
->DisconnectFromNode(sal_True
);
346 sal_uIntPtr nMarkedEdgeAnz
= GetMarkedEdgesOfMarkedNodes().GetMarkCount();
349 for (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();
359 ////////////////////////////////////////////////////////////////////////////////////////////////////
361 ////////////////////////////////////////////////////////////////////////////////////////////////////
363 void SdrEditView::MarkListHasChanged()
365 SdrMarkView::MarkListHasChanged();
366 bPossibilitiesDirty
=sal_True
;
369 void SdrEditView::ModelHasChanged()
371 SdrMarkView::ModelHasChanged();
372 bPossibilitiesDirty
=sal_True
;
375 sal_Bool
SdrEditView::IsResizeAllowed(sal_Bool bProp
) const
377 ForcePossibilities();
378 if (bResizeProtect
) return sal_False
;
379 if (bProp
) return bResizePropAllowed
;
380 return bResizeFreeAllowed
;
383 sal_Bool
SdrEditView::IsRotateAllowed(sal_Bool b90Deg
) const
385 ForcePossibilities();
386 if (bMoveProtect
) return sal_False
;
387 if (b90Deg
) return bRotate90Allowed
;
388 return bRotateFreeAllowed
;
391 sal_Bool
SdrEditView::IsMirrorAllowed(sal_Bool b45Deg
, sal_Bool b90Deg
) const
393 ForcePossibilities();
394 if (bMoveProtect
) return sal_False
;
395 if (b90Deg
) return bMirror90Allowed
;
396 if (b45Deg
) return bMirror45Allowed
;
397 return bMirrorFreeAllowed
&& !bMoveProtect
;
400 sal_Bool
SdrEditView::IsTransparenceAllowed() const
402 ForcePossibilities();
403 return bTransparenceAllowed
;
406 sal_Bool
SdrEditView::IsGradientAllowed() const
408 ForcePossibilities();
409 return bGradientAllowed
;
412 sal_Bool
SdrEditView::IsShearAllowed() const
414 ForcePossibilities();
415 if (bResizeProtect
) return sal_False
;
416 return bShearAllowed
;
419 sal_Bool
SdrEditView::IsEdgeRadiusAllowed() const
421 ForcePossibilities();
422 return bEdgeRadiusAllowed
;
425 sal_Bool
SdrEditView::IsCrookAllowed(sal_Bool bNoContortion
) const
427 // CrookMode missing here (no rotations allowed when shearing ...)
428 ForcePossibilities();
430 if (!bRotateFreeAllowed
) return sal_False
;
431 return !bMoveProtect
&& bMoveAllowed
;
433 return !bResizeProtect
&& bContortionPossible
;
437 sal_Bool
SdrEditView::IsDistortAllowed(sal_Bool bNoContortion
) const
439 ForcePossibilities();
443 return !bResizeProtect
&& bContortionPossible
;
447 sal_Bool
SdrEditView::IsCombinePossible(sal_Bool bNoPolyPoly
) const
449 ForcePossibilities();
450 if (bNoPolyPoly
) return bCombineNoPolyPolyPossible
;
451 else return bCombinePossible
;
454 sal_Bool
SdrEditView::IsDismantlePossible(sal_Bool bMakeLines
) const
456 ForcePossibilities();
457 if (bMakeLines
) return bDismantleMakeLinesPossible
;
458 else return bDismantlePossible
;
461 void SdrEditView::CheckPossibilities()
463 if (bSomeObjChgdFlag
) bPossibilitiesDirty
=sal_True
;
467 // This call IS necessary to correct the MarkList, in which
468 // no longer to the model belonging objects still can reside.
469 // These ones need to be removed.
473 if (bPossibilitiesDirty
) {
474 ImpResetPossibilityFlags();
476 sal_uIntPtr nMarkAnz
=GetMarkedObjectCount();
478 bReverseOrderPossible
=nMarkAnz
>=2;
480 sal_uIntPtr nMovableCount
=0;
481 bGroupPossible
=nMarkAnz
>=2;
482 bCombinePossible
=nMarkAnz
>=2;
484 // check bCombinePossible more thoroughly
486 const SdrObject
* pObj
=GetMarkedObjectByIndex(0);
487 //const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
488 bool bGroup
=pObj
->GetSubList()!=NULL
;
489 bool bHasText
=pObj
->GetOutlinerParaObject()!=NULL
;
490 if (bGroup
|| bHasText
) {
491 bCombinePossible
=sal_True
;
494 bCombineNoPolyPolyPossible
=bCombinePossible
;
495 bDeletePossible
=sal_True
;
496 // accept transformations for now
497 bMoveAllowed
=sal_True
;
498 bResizeFreeAllowed
=sal_True
;
499 bResizePropAllowed
=sal_True
;
500 bRotateFreeAllowed
=sal_True
;
501 bRotate90Allowed
=sal_True
;
502 bMirrorFreeAllowed
=sal_True
;
503 bMirror45Allowed
=sal_True
;
504 bMirror90Allowed
=sal_True
;
505 bShearAllowed
=sal_True
;
506 bEdgeRadiusAllowed
=sal_False
;
507 bContortionPossible
=sal_True
;
508 bCanConvToContour
= sal_True
;
510 // these ones are only allowed when single object is selected
511 bTransparenceAllowed
= (nMarkAnz
== 1);
512 bGradientAllowed
= (nMarkAnz
== 1);
515 // gradient depends on fill style
516 const SdrMark
* pM
= GetSdrMarkByIndex(0);
517 const SdrObject
* pObj
= pM
->GetMarkedSdrObj();
519 // may be group object, so get merged ItemSet
520 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
521 SfxItemState eState
= rSet
.GetItemState(XATTR_FILLSTYLE
, sal_False
);
523 if(SFX_ITEM_DONTCARE
!= eState
)
525 // If state is not DONTCARE, test the item
526 XFillStyle eFillStyle
= ((XFillStyleItem
&)(rSet
.Get(XATTR_FILLSTYLE
))).GetValue();
528 if(eFillStyle
!= XFILL_GRADIENT
)
530 bGradientAllowed
= sal_False
;
535 sal_Bool bNoMovRotFound
=sal_False
;
536 const SdrPageView
* pPV0
=NULL
;
538 for (sal_uIntPtr nm
=0; nm
<nMarkAnz
; nm
++) {
539 const SdrMark
* pM
=GetSdrMarkByIndex(nm
);
540 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
541 const SdrPageView
* pPV
=pM
->GetPageView();
543 if (pPV
->IsReadOnly()) bReadOnly
=sal_True
;
547 SdrObjTransformInfoRec aInfo
;
548 pObj
->TakeObjInfo(aInfo
);
549 sal_Bool bMovPrt
=pObj
->IsMoveProtect();
550 sal_Bool bSizPrt
=pObj
->IsResizeProtect();
551 if (!bMovPrt
&& aInfo
.bMoveAllowed
) nMovableCount
++; // count MovableObjs
552 if (bMovPrt
) bMoveProtect
=sal_True
;
553 if (bSizPrt
) bResizeProtect
=sal_True
;
555 // not allowed when not allowed at one object
556 if(!aInfo
.bTransparenceAllowed
)
557 bTransparenceAllowed
= sal_False
;
559 // If one of these can't do something, none can
560 if (!aInfo
.bMoveAllowed
) bMoveAllowed
=sal_False
;
561 if (!aInfo
.bResizeFreeAllowed
) bResizeFreeAllowed
=sal_False
;
562 if (!aInfo
.bResizePropAllowed
) bResizePropAllowed
=sal_False
;
563 if (!aInfo
.bRotateFreeAllowed
) bRotateFreeAllowed
=sal_False
;
564 if (!aInfo
.bRotate90Allowed
) bRotate90Allowed
=sal_False
;
565 if (!aInfo
.bMirrorFreeAllowed
) bMirrorFreeAllowed
=sal_False
;
566 if (!aInfo
.bMirror45Allowed
) bMirror45Allowed
=sal_False
;
567 if (!aInfo
.bMirror90Allowed
) bMirror90Allowed
=sal_False
;
568 if (!aInfo
.bShearAllowed
) bShearAllowed
=sal_False
;
569 if (aInfo
.bEdgeRadiusAllowed
) bEdgeRadiusAllowed
=sal_True
;
570 if (aInfo
.bNoContortion
) bContortionPossible
=sal_False
;
571 // For Crook with Contortion: all objects have to be
572 // Movable and Rotatable, except for a maximum of 1 of them
573 if (!bMoreThanOneNoMovRot
) {
574 if (!aInfo
.bMoveAllowed
|| !aInfo
.bResizeFreeAllowed
) {
575 bMoreThanOneNoMovRot
=bNoMovRotFound
;
576 bNoMovRotFound
=sal_True
;
580 // if one member cannot be converted, no conversion is possible
581 if(!aInfo
.bCanConvToContour
)
582 bCanConvToContour
= sal_False
;
585 if (!bUnGroupPossible
) bUnGroupPossible
=pObj
->GetSubList()!=NULL
;
586 // ConvertToCurve: If at least one can be converted, that is fine.
587 if (aInfo
.bCanConvToPath
) bCanConvToPath
=sal_True
;
588 if (aInfo
.bCanConvToPoly
) bCanConvToPoly
=sal_True
;
589 if (aInfo
.bCanConvToPathLineToArea
) bCanConvToPathLineToArea
=sal_True
;
590 if (aInfo
.bCanConvToPolyLineToArea
) bCanConvToPolyLineToArea
=sal_True
;
595 bCombinePossible
= ImpCanConvertForCombine(pObj
);
596 bCombineNoPolyPolyPossible
= bCombinePossible
;
599 if (!bDismantlePossible
) bDismantlePossible
= ImpCanDismantle(pObj
, sal_False
);
600 if (!bDismantleMakeLinesPossible
) bDismantleMakeLinesPossible
= ImpCanDismantle(pObj
, sal_True
);
601 // check OrthoDesiredOnMarked
602 if (!bOrthoDesiredOnMarked
&& !aInfo
.bNoOrthoDesired
) bOrthoDesiredOnMarked
=sal_True
;
605 if (!bImportMtfPossible
)
607 const SdrGrafObj
* pSdrGrafObj
= dynamic_cast< const SdrGrafObj
* >(pObj
);
608 const SdrOle2Obj
* pSdrOle2Obj
= dynamic_cast< const SdrOle2Obj
* >(pObj
);
610 if(pSdrGrafObj
&& ((pSdrGrafObj
->HasGDIMetaFile() && !pSdrGrafObj
->IsEPS()) || pSdrGrafObj
->isEmbeddedSvg()))
612 bImportMtfPossible
= sal_True
;
617 bImportMtfPossible
= pSdrOle2Obj
->GetObjRef().is();
622 bMoreThanOneNotMovable
=nMovableCount
<nMarkAnz
-1;
623 bOneOrMoreMovable
=nMovableCount
!=0;
624 bGrpEnterPossible
=bUnGroupPossible
;
626 ImpCheckToTopBtmPossible();
627 ((SdrPolyEditView
*)this)->ImpCheckPolyPossibilities();
628 bPossibilitiesDirty
=sal_False
;
631 sal_Bool bMerker1
=bGrpEnterPossible
;
632 ImpResetPossibilityFlags();
634 bGrpEnterPossible
=bMerker1
;
637 // Don't allow moving glued connectors.
638 // Currently only implemented for single selection.
640 SdrObject
* pObj
=GetMarkedObjectByIndex(0);
641 SdrEdgeObj
* pEdge
=PTR_CAST(SdrEdgeObj
,pObj
);
643 SdrObject
* pNode1
=pEdge
->GetConnectedNode(sal_True
);
644 SdrObject
* pNode2
=pEdge
->GetConnectedNode(sal_False
);
645 if (pNode1
!=NULL
|| pNode2
!=NULL
) bMoveAllowed
=sal_False
;
652 ////////////////////////////////////////////////////////////////////////////////////////////////////
654 void SdrEditView::ForceMarkedObjToAnotherPage()
657 for (sal_uIntPtr nm
=0; nm
<GetMarkedObjectCount(); nm
++) {
658 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
659 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
660 Rectangle
aObjRect(pObj
->GetCurrentBoundRect());
661 Rectangle
aPgRect(pM
->GetPageView()->GetPageRect());
662 if (!aObjRect
.IsOver(aPgRect
)) {
663 sal_Bool bFnd
=sal_False
;
664 SdrPageView
* pPV
= GetSdrPageView();
668 bFnd
= aObjRect
.IsOver(pPV
->GetPageRect());
673 pM
->GetPageView()->GetObjList()->RemoveObject(pObj
->GetOrdNum());
674 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
675 pPV
->GetObjList()->InsertObject(pObj
,CONTAINER_APPEND
,&aReason
);
676 pM
->SetPageView(pPV
);
677 InvalidateAllWin(aObjRect
);
683 MarkListHasChanged();
687 void SdrEditView::DeleteMarkedList(const SdrMarkList
& rMark
)
689 if (rMark
.GetMarkCount()!=0)
693 const bool bUndo
= IsUndoEnabled();
696 const sal_uInt32
nMarkAnz(rMark
.GetMarkCount());
701 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
705 for(nm
= nMarkAnz
; nm
> 0;)
708 SdrMark
* pM
= rMark
.GetMark(nm
);
709 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
711 // extra undo actions for changed connector which now may hold its layed out path (SJ)
712 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pObj
) );
713 AddUndoActions( vConnectorUndoActions
);
715 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj
));
719 // make sure, OrderNums are correct:
720 rMark
.GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
722 std::vector
< SdrObject
* > aRemoved3DObjects
;
724 for(nm
= nMarkAnz
; nm
> 0;)
727 SdrMark
* pM
= rMark
.GetMark(nm
);
728 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
729 SdrObjList
* pOL
= pObj
->GetObjList();
730 const sal_uInt32
nOrdNum(pObj
->GetOrdNumDirect());
732 bool bIs3D
= dynamic_cast< E3dObject
* >(pObj
);
733 // set up a scene updater if object is a 3d object
736 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pObj
));
739 pOL
->RemoveObject(nOrdNum
);
744 aRemoved3DObjects
.push_back( pObj
); // may be needed later
746 SdrObject::Free(pObj
);
750 // fire scene updaters
751 while(!aUpdaters
.empty())
753 delete aUpdaters
.back();
754 aUpdaters
.pop_back();
759 // now delete removed scene objects
760 while(!aRemoved3DObjects
.empty())
762 SdrObject::Free( aRemoved3DObjects
.back() );
763 aRemoved3DObjects
.pop_back();
773 void SdrEditView::DeleteMarkedObj()
775 // #i110981# return when nothing is to be done at all
776 if(!GetMarkedObjectCount())
781 // moved breaking action and undo start outside loop
783 BegUndo(ImpGetResStr(STR_EditDelete
),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_DELETE
);
785 // remove as long as something is selected. This allows to schedule objects for
786 // removal for a next run as needed
787 while(GetMarkedObjectCount())
789 // vector to remember the parents which may be empty after object removal
790 std::vector
< SdrObject
* > aParents
;
793 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
794 const sal_uInt32
nCount(rMarkList
.GetMarkCount());
797 for(a
= 0; a
< nCount
; a
++)
799 // in the first run, add all found parents, but only once
800 SdrMark
* pMark
= rMarkList
.GetMark(a
);
801 SdrObject
* pObject
= pMark
->GetMarkedSdrObj();
802 SdrObject
* pParent
= pObject
->GetObjList()->GetOwnerObj();
806 if(!aParents
.empty())
808 std::vector
< SdrObject
* >::iterator aFindResult
=
809 std::find(aParents
.begin(), aParents
.end(), pParent
);
811 if(aFindResult
== aParents
.end())
813 aParents
.push_back(pParent
);
818 aParents
.push_back(pParent
);
823 if(!aParents
.empty())
825 // in a 2nd run, remove all objects which may already be scheduled for
826 // removal. I am not sure if this can happen, but theoretically
827 // a to-be-removed object may already be the group/3DScene itself
828 for(a
= 0; a
< nCount
; a
++)
830 SdrMark
* pMark
= rMarkList
.GetMark(a
);
831 SdrObject
* pObject
= pMark
->GetMarkedSdrObj();
833 std::vector
< SdrObject
* >::iterator aFindResult
=
834 std::find(aParents
.begin(), aParents
.end(), pObject
);
836 if(aFindResult
!= aParents
.end())
838 aParents
.erase(aFindResult
);
844 // original stuff: remove selected objects. Handle clear will
845 // do something only once
846 DeleteMarkedList(GetMarkedObjectList());
847 GetMarkedObjectListWriteAccess().Clear();
850 while(aParents
.size() && !GetMarkedObjectCount())
852 // iterate over remembered parents
853 SdrObject
* pParent
= aParents
.back();
856 if(pParent
->GetSubList() && 0 == pParent
->GetSubList()->GetObjCount())
858 // we detected an empty parent, a candidate to leave group/3DScene
860 if(GetSdrPageView()->GetAktGroup()
861 && GetSdrPageView()->GetAktGroup() == pParent
)
863 GetSdrPageView()->LeaveOneGroup();
866 // schedule empty parent for removal
867 GetMarkedObjectListWriteAccess().InsertEntry(
868 SdrMark(pParent
, GetSdrPageView()));
873 // end undo and change messaging moved at the end
875 MarkListHasChanged();
878 void SdrEditView::CopyMarkedObj()
882 SdrMarkList
aSourceObjectsForCopy(GetMarkedObjectList());
883 // The following loop is used instead of MarkList::Merge(), to be
884 // able to flag the MarkEntries.
885 sal_uIntPtr nEdgeAnz
= GetEdgesOfMarkedNodes().GetMarkCount();
886 for (sal_uIntPtr nEdgeNum
=0; nEdgeNum
<nEdgeAnz
; nEdgeNum
++) {
887 SdrMark
aM(*GetEdgesOfMarkedNodes().GetMark(nEdgeNum
));
889 aSourceObjectsForCopy
.InsertEntry(aM
);
891 aSourceObjectsForCopy
.ForceSort();
894 // New mechanism to re-create the connections of cloned connectors
895 CloneList aCloneList
;
897 const bool bUndo
= IsUndoEnabled();
899 GetMarkedObjectListWriteAccess().Clear();
900 sal_uIntPtr nCloneErrCnt
=0;
901 sal_uIntPtr nMarkAnz
=aSourceObjectsForCopy
.GetMarkCount();
903 for (nm
=0; nm
<nMarkAnz
; nm
++) {
904 SdrMark
* pM
=aSourceObjectsForCopy
.GetMark(nm
);
905 SdrObject
* pO
=pM
->GetMarkedSdrObj()->Clone();
907 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
908 pM
->GetPageView()->GetObjList()->InsertObject(pO
,CONTAINER_APPEND
,&aReason
);
911 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoCopyObject(*pO
));
914 aME
.SetMarkedSdrObj(pO
);
915 aCloneList
.AddPair(pM
->GetMarkedSdrObj(), pO
);
917 if (pM
->GetUser()==0)
919 // otherwise it is only an Edge we have to copy as well
920 GetMarkedObjectListWriteAccess().InsertEntry(aME
);
928 // New mechanism to re-create the connections of cloned connectors
929 aCloneList
.CopyConnections();
931 if(0L != nCloneErrCnt
)
934 OStringBuffer
aStr(RTL_CONSTASCII_STRINGPARAM(
935 "SdrEditView::CopyMarkedObj(): Error when cloning "));
937 if(nCloneErrCnt
== 1)
939 aStr
.append(RTL_CONSTASCII_STRINGPARAM("a drawing object."));
943 aStr
.append(static_cast<sal_Int32
>(nCloneErrCnt
));
944 aStr
.append(RTL_CONSTASCII_STRINGPARAM(" drawing objects."));
947 aStr
.append(RTL_CONSTASCII_STRINGPARAM(
948 " This object's/These objects's connections will not be copied."));
949 OSL_FAIL(aStr
.getStr());
952 MarkListHasChanged();
955 ////////////////////////////////////////////////////////////////////////////////////////////////////
957 sal_Bool
SdrEditView::InsertObjectAtView(SdrObject
* pObj
, SdrPageView
& rPV
, sal_uIntPtr nOptions
)
959 if ((nOptions
& SDRINSERT_SETDEFLAYER
)!=0) {
960 SdrLayerID nLayer
=rPV
.GetPage()->GetLayerAdmin().GetLayerID(aAktLayer
,sal_True
);
961 if (nLayer
==SDRLAYER_NOTFOUND
) nLayer
=0;
962 if (rPV
.GetLockedLayers().IsSet(nLayer
) || !rPV
.GetVisibleLayers().IsSet(nLayer
)) {
963 SdrObject::Free( pObj
); // Layer locked or invisible
966 pObj
->NbcSetLayer(nLayer
);
968 if ((nOptions
& SDRINSERT_SETDEFATTR
)!=0) {
969 if (pDefaultStyleSheet
!=NULL
) pObj
->NbcSetStyleSheet(pDefaultStyleSheet
, sal_False
);
970 pObj
->SetMergedItemSet(aDefaultAttr
);
972 if (!pObj
->IsInserted()) {
973 SdrInsertReason
aReason(SDRREASON_VIEWCALL
);
974 if ((nOptions
& SDRINSERT_NOBROADCAST
)!=0) {
975 rPV
.GetObjList()->NbcInsertObject(pObj
,CONTAINER_APPEND
,&aReason
);
977 rPV
.GetObjList()->InsertObject(pObj
,CONTAINER_APPEND
,&aReason
);
980 if( IsUndoEnabled() )
981 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj
));
983 if ((nOptions
& SDRINSERT_DONTMARK
)==0) {
984 if ((nOptions
& SDRINSERT_ADDMARK
)==0) UnmarkAllObj();
990 void SdrEditView::ReplaceObjectAtView(SdrObject
* pOldObj
, SdrPageView
& rPV
, SdrObject
* pNewObj
, sal_Bool bMark
)
992 SdrObjList
* pOL
=pOldObj
->GetObjList();
993 const bool bUndo
= IsUndoEnabled();
995 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pOldObj
,*pNewObj
));
997 if( IsObjMarked( pOldObj
) )
998 MarkObj( pOldObj
, &rPV
, sal_True
/*unmark!*/ );
1000 pOL
->ReplaceObject(pNewObj
,pOldObj
->GetOrdNum());
1003 SdrObject::Free( pOldObj
);
1005 if (bMark
) MarkObj(pNewObj
,&rPV
);
1008 ////////////////////////////////////////////////////////////////////////////////////////////////////
1010 bool SdrEditView::IsUndoEnabled() const
1012 return pMod
->IsUndoEnabled();
1015 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */