Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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>
38 :
39 : using namespace com::sun::star;
40 :
41 11826 : void SdrEditView::ImpResetPossibilityFlags()
42 : {
43 11826 : bReadOnly =false;
44 :
45 11826 : bGroupPossible =false;
46 11826 : bUnGroupPossible =false;
47 11826 : bGrpEnterPossible =false;
48 11826 : bDeletePossible =false;
49 11826 : bToTopPossible =false;
50 11826 : bToBtmPossible =false;
51 11826 : bReverseOrderPossible =false;
52 :
53 11826 : bImportMtfPossible =false;
54 11826 : bCombinePossible =false;
55 11826 : bDismantlePossible =false;
56 11826 : bCombineNoPolyPolyPossible =false;
57 11826 : bDismantleMakeLinesPossible=false;
58 11826 : bOrthoDesiredOnMarked =false;
59 :
60 11826 : bMoreThanOneNotMovable =false;
61 11826 : bOneOrMoreMovable =false;
62 11826 : bMoreThanOneNoMovRot =false;
63 11826 : bContortionPossible =false;
64 11826 : bAllPolys =false;
65 11826 : bOneOrMorePolys =false;
66 11826 : bMoveAllowed =false;
67 11826 : bResizeFreeAllowed =false;
68 11826 : bResizePropAllowed =false;
69 11826 : bRotateFreeAllowed =false;
70 11826 : bRotate90Allowed =false;
71 11826 : bMirrorFreeAllowed =false;
72 11826 : bMirror45Allowed =false;
73 11826 : bMirror90Allowed =false;
74 11826 : bTransparenceAllowed =false;
75 11826 : bCropAllowed =false;
76 11826 : bGradientAllowed =false;
77 11826 : bShearAllowed =false;
78 11826 : bEdgeRadiusAllowed =false;
79 11826 : bCanConvToPath =false;
80 11826 : bCanConvToPoly =false;
81 11826 : bCanConvToContour =false;
82 11826 : bCanConvToPathLineToArea=false;
83 11826 : bCanConvToPolyLineToArea=false;
84 11826 : bMoveProtect =false;
85 11826 : bResizeProtect =false;
86 11826 : }
87 :
88 9504 : void SdrEditView::ImpClearVars()
89 : {
90 9504 : ImpResetPossibilityFlags();
91 9504 : bPossibilitiesDirty=true; // << Purify didn't like this
92 9504 : bBundleVirtObj=false;
93 9504 : }
94 :
95 9504 : SdrEditView::SdrEditView(SdrModel* pModel1, OutputDevice* pOut):
96 9504 : SdrMarkView(pModel1,pOut)
97 : {
98 9504 : ImpClearVars();
99 9504 : }
100 :
101 9438 : SdrEditView::~SdrEditView()
102 : {
103 9438 : }
104 :
105 :
106 :
107 0 : SdrLayer* SdrEditView::InsertNewLayer(const OUString& rName, sal_uInt16 nPos)
108 : {
109 0 : SdrLayerAdmin& rLA=pMod->GetLayerAdmin();
110 0 : sal_uInt16 nMax=rLA.GetLayerCount();
111 0 : if (nPos>nMax) nPos=nMax;
112 0 : SdrLayer* pNewLayer=rLA.NewLayer(rName,nPos);
113 :
114 0 : if( GetModel()->IsUndoEnabled() )
115 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewLayer(nPos,rLA,*pMod));
116 :
117 0 : pMod->SetChanged();
118 0 : return pNewLayer;
119 : }
120 :
121 : #include <svx/svdogrp.hxx>
122 : #include <svx/scene3d.hxx>
123 :
124 0 : bool SdrEditView::ImpDelLayerCheck(SdrObjList* pOL, SdrLayerID nDelID) const
125 : {
126 0 : bool bDelAll(true);
127 :
128 0 : for(size_t nObjNum = pOL->GetObjCount(); nObjNum > 0 && bDelAll;)
129 : {
130 0 : nObjNum--;
131 0 : SdrObject* pObj = pOL->GetObj(nObjNum);
132 0 : SdrObjList* pSubOL = pObj->GetSubList();
133 :
134 : // explicitly test for group objects and 3d scenes
135 0 : if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
136 : {
137 0 : if(!ImpDelLayerCheck(pSubOL, nDelID))
138 : {
139 0 : bDelAll = false;
140 : }
141 : }
142 : else
143 : {
144 0 : if(pObj->GetLayer() != nDelID)
145 : {
146 0 : bDelAll = false;
147 : }
148 : }
149 : }
150 :
151 0 : return bDelAll;
152 : }
153 :
154 0 : void SdrEditView::ImpDelLayerDelObjs(SdrObjList* pOL, SdrLayerID nDelID)
155 : {
156 0 : const size_t nObjCount(pOL->GetObjCount());
157 : // make sure OrdNums are correct
158 0 : pOL->GetObj(0)->GetOrdNum();
159 :
160 0 : const bool bUndo = GetModel()->IsUndoEnabled();
161 :
162 0 : for(size_t nObjNum = nObjCount; nObjNum > 0;)
163 : {
164 0 : nObjNum--;
165 0 : SdrObject* pObj = pOL->GetObj(nObjNum);
166 0 : SdrObjList* pSubOL = pObj->GetSubList();
167 :
168 :
169 : // explicitly test for group objects and 3d scenes
170 0 : if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
171 : {
172 0 : if(ImpDelLayerCheck(pSubOL, nDelID))
173 : {
174 0 : if( bUndo )
175 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
176 0 : pOL->RemoveObject(nObjNum);
177 :
178 0 : if( !bUndo )
179 0 : SdrObject::Free( pObj );
180 : }
181 : else
182 : {
183 0 : ImpDelLayerDelObjs(pSubOL, nDelID);
184 : }
185 : }
186 : else
187 : {
188 0 : if(pObj->GetLayer() == nDelID)
189 : {
190 0 : if( bUndo )
191 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
192 0 : pOL->RemoveObject(nObjNum);
193 0 : if( !bUndo )
194 0 : SdrObject::Free( pObj );
195 : }
196 : }
197 : }
198 0 : }
199 :
200 1 : void SdrEditView::DeleteLayer(const OUString& rName)
201 : {
202 1 : SdrLayerAdmin& rLA = pMod->GetLayerAdmin();
203 1 : SdrLayer* pLayer = rLA.GetLayer(rName, true);
204 1 : sal_uInt16 nLayerNum(rLA.GetLayerPos(pLayer));
205 :
206 1 : if(SDRLAYER_NOTFOUND != nLayerNum)
207 : {
208 :
209 1 : SdrLayerID nDelID = pLayer->GetID();
210 :
211 1 : const bool bUndo = IsUndoEnabled();
212 1 : if( bUndo )
213 1 : BegUndo(ImpGetResStr(STR_UndoDelLayer));
214 :
215 1 : bool bMaPg(true);
216 :
217 3 : for(sal_uInt16 nPageKind(0); nPageKind < 2; nPageKind++)
218 : {
219 : // MasterPages and DrawPages
220 2 : sal_uInt16 nPgAnz(bMaPg ? pMod->GetMasterPageCount() : pMod->GetPageCount());
221 :
222 8 : for(sal_uInt16 nPgNum(0); nPgNum < nPgAnz; nPgNum++)
223 : {
224 : // over all pages
225 6 : SdrPage* pPage = (bMaPg) ? pMod->GetMasterPage(nPgNum) : pMod->GetPage(nPgNum);
226 6 : const size_t nObjCount(pPage->GetObjCount());
227 :
228 : // make sure OrdNums are correct
229 6 : if(nObjCount)
230 2 : pPage->GetObj(0)->GetOrdNum();
231 :
232 15 : for(size_t nObjNum(nObjCount); nObjNum > 0;)
233 : {
234 3 : nObjNum--;
235 3 : SdrObject* pObj = pPage->GetObj(nObjNum);
236 3 : SdrObjList* pSubOL = pObj->GetSubList();
237 :
238 : // explicitly test for group objects and 3d scenes
239 3 : if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
240 : {
241 0 : if(ImpDelLayerCheck(pSubOL, nDelID))
242 : {
243 0 : if( bUndo )
244 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
245 0 : pPage->RemoveObject(nObjNum);
246 0 : if( !bUndo )
247 0 : SdrObject::Free(pObj);
248 : }
249 : else
250 : {
251 0 : ImpDelLayerDelObjs(pSubOL, nDelID);
252 : }
253 : }
254 : else
255 : {
256 3 : if(pObj->GetLayer() == nDelID)
257 : {
258 1 : if( bUndo )
259 1 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
260 1 : pPage->RemoveObject(nObjNum);
261 1 : if( !bUndo )
262 0 : SdrObject::Free(pObj);
263 : }
264 : }
265 : }
266 : }
267 2 : bMaPg = false;
268 : }
269 :
270 1 : if( bUndo )
271 : {
272 1 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteLayer(nLayerNum, rLA, *pMod));
273 1 : rLA.RemoveLayer(nLayerNum);
274 1 : EndUndo();
275 : }
276 : else
277 : {
278 0 : delete rLA.RemoveLayer(nLayerNum);
279 : }
280 :
281 1 : pMod->SetChanged();
282 : }
283 1 : }
284 :
285 :
286 :
287 78 : void SdrEditView::EndUndo()
288 : {
289 : // #i13033#
290 : // Comparison changed to 1L since EndUndo() is called later now
291 : // and EndUndo WILL change count to count-1
292 78 : if(1L == pMod->GetUndoBracketLevel())
293 : {
294 65 : ImpBroadcastEdgesOfMarkedNodes();
295 : }
296 :
297 : // #i13033#
298 : // moved to bottom to still have access to UNDOs inside of
299 : // ImpBroadcastEdgesOfMarkedNodes()
300 78 : pMod->EndUndo();
301 78 : }
302 :
303 65 : void SdrEditView::ImpBroadcastEdgesOfMarkedNodes()
304 : {
305 65 : std::vector<SdrObject*>::const_iterator iterPos;
306 65 : const std::vector<SdrObject*>& rAllMarkedObjects = GetTransitiveHullOfMarkedObjects();
307 :
308 : // #i13033#
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 362 : for(size_t a(0); a < rAllMarkedObjects.size(); a++)
313 : {
314 297 : SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, rAllMarkedObjects[a]);
315 :
316 297 : if(pEdge)
317 : {
318 0 : SdrObject* pObj1 = pEdge->GetConnectedNode(false);
319 0 : SdrObject* pObj2 = pEdge->GetConnectedNode(true);
320 :
321 0 : if(pObj1 && !pEdge->CheckNodeConnection(false))
322 : {
323 0 : iterPos = std::find(rAllMarkedObjects.begin(),rAllMarkedObjects.end(),pObj1);
324 :
325 0 : if (iterPos == rAllMarkedObjects.end())
326 : {
327 0 : if( IsUndoEnabled() )
328 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge));
329 0 : pEdge->DisconnectFromNode(false);
330 : }
331 : }
332 :
333 0 : if(pObj2 && !pEdge->CheckNodeConnection(true))
334 : {
335 0 : iterPos = std::find(rAllMarkedObjects.begin(),rAllMarkedObjects.end(),pObj2);
336 :
337 0 : if (iterPos == rAllMarkedObjects.end())
338 : {
339 0 : if( IsUndoEnabled() )
340 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge));
341 0 : pEdge->DisconnectFromNode(true);
342 : }
343 : }
344 : }
345 : }
346 :
347 65 : const size_t nMarkedEdgeAnz = GetMarkedEdgesOfMarkedNodes().GetMarkCount();
348 :
349 65 : for (size_t i=0; i<nMarkedEdgeAnz; ++i) {
350 0 : SdrMark* pEM = GetMarkedEdgesOfMarkedNodes().GetMark(i);
351 0 : SdrObject* pEdgeTmp=pEM->GetMarkedSdrObj();
352 0 : SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pEdgeTmp);
353 0 : if (pEdge!=NULL) {
354 0 : pEdge->SetEdgeTrackDirty();
355 : }
356 : }
357 65 : }
358 :
359 :
360 : // Possibilities
361 :
362 :
363 4661 : void SdrEditView::MarkListHasChanged()
364 : {
365 4661 : SdrMarkView::MarkListHasChanged();
366 4661 : bPossibilitiesDirty=true;
367 4661 : }
368 :
369 3699 : void SdrEditView::ModelHasChanged()
370 : {
371 3699 : SdrMarkView::ModelHasChanged();
372 3699 : bPossibilitiesDirty=true;
373 3699 : }
374 :
375 4 : bool SdrEditView::IsResizeAllowed(bool bProp) const
376 : {
377 4 : ForcePossibilities();
378 4 : if (bResizeProtect) return false;
379 4 : if (bProp) return bResizePropAllowed;
380 0 : return bResizeFreeAllowed;
381 : }
382 :
383 0 : bool SdrEditView::IsRotateAllowed(bool b90Deg) const
384 : {
385 0 : ForcePossibilities();
386 0 : if (bMoveProtect) return false;
387 0 : if (b90Deg) return bRotate90Allowed;
388 0 : return bRotateFreeAllowed;
389 : }
390 :
391 8350 : bool SdrEditView::IsMirrorAllowed(bool b45Deg, bool b90Deg) const
392 : {
393 8350 : ForcePossibilities();
394 8350 : if (bMoveProtect) return false;
395 8350 : if (b90Deg) return bMirror90Allowed;
396 4175 : if (b45Deg) return bMirror45Allowed;
397 4175 : return bMirrorFreeAllowed && !bMoveProtect;
398 : }
399 :
400 4175 : bool SdrEditView::IsTransparenceAllowed() const
401 : {
402 4175 : ForcePossibilities();
403 4175 : return bTransparenceAllowed;
404 : }
405 :
406 0 : bool SdrEditView::IsCropAllowed() const
407 : {
408 0 : ForcePossibilities();
409 0 : return bCropAllowed;
410 : }
411 :
412 4175 : bool SdrEditView::IsGradientAllowed() const
413 : {
414 4175 : ForcePossibilities();
415 4175 : return bGradientAllowed;
416 : }
417 :
418 0 : bool SdrEditView::IsShearAllowed() const
419 : {
420 0 : ForcePossibilities();
421 0 : if (bResizeProtect) return false;
422 0 : return bShearAllowed;
423 : }
424 :
425 0 : bool SdrEditView::IsEdgeRadiusAllowed() const
426 : {
427 0 : ForcePossibilities();
428 0 : return bEdgeRadiusAllowed;
429 : }
430 :
431 4167 : bool SdrEditView::IsCrookAllowed(bool bNoContortion) const
432 : {
433 : // CrookMode missing here (no rotations allowed when shearing ...)
434 4167 : ForcePossibilities();
435 4167 : if (bNoContortion) {
436 0 : if (!bRotateFreeAllowed) return false;
437 0 : return !bMoveProtect && bMoveAllowed;
438 : } else {
439 4167 : return !bResizeProtect && bContortionPossible;
440 : }
441 : }
442 :
443 0 : bool SdrEditView::IsDistortAllowed(bool bNoContortion) const
444 : {
445 0 : ForcePossibilities();
446 0 : if (bNoContortion) {
447 0 : return false;
448 : } else {
449 0 : return !bResizeProtect && bContortionPossible;
450 : }
451 : }
452 :
453 0 : bool SdrEditView::IsCombinePossible(bool bNoPolyPoly) const
454 : {
455 0 : ForcePossibilities();
456 0 : if (bNoPolyPoly) return bCombineNoPolyPolyPossible;
457 0 : else return bCombinePossible;
458 : }
459 :
460 0 : bool SdrEditView::IsDismantlePossible(bool bMakeLines) const
461 : {
462 0 : ForcePossibilities();
463 0 : if (bMakeLines) return bDismantleMakeLinesPossible;
464 0 : else return bDismantlePossible;
465 : }
466 :
467 2322 : void SdrEditView::CheckPossibilities()
468 : {
469 2322 : if (bSomeObjChgdFlag) bPossibilitiesDirty=true;
470 :
471 2322 : if(bSomeObjChgdFlag)
472 : {
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.
476 2145 : CheckMarked();
477 : }
478 :
479 2322 : if (bPossibilitiesDirty) {
480 2322 : ImpResetPossibilityFlags();
481 2322 : SortMarkedObjects();
482 2322 : const size_t nMarkCount=GetMarkedObjectCount();
483 2322 : if (nMarkCount!=0) {
484 6 : bReverseOrderPossible=nMarkCount>=2;
485 :
486 6 : size_t nMovableCount=0;
487 6 : bGroupPossible=nMarkCount>=2;
488 6 : bCombinePossible=nMarkCount>=2;
489 6 : if (nMarkCount==1) {
490 : // check bCombinePossible more thoroughly
491 : // still missing ...
492 6 : const SdrObject* pObj=GetMarkedObjectByIndex(0);
493 : //const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
494 6 : bool bGroup=pObj->GetSubList()!=NULL;
495 6 : bool bHasText=pObj->GetOutlinerParaObject()!=NULL;
496 6 : if (bGroup || bHasText) {
497 2 : bCombinePossible=true;
498 : }
499 : }
500 6 : bCombineNoPolyPolyPossible=bCombinePossible;
501 6 : bDeletePossible=true;
502 : // accept transformations for now
503 6 : bMoveAllowed =true;
504 6 : bResizeFreeAllowed=true;
505 6 : bResizePropAllowed=true;
506 6 : bRotateFreeAllowed=true;
507 6 : bRotate90Allowed =true;
508 6 : bMirrorFreeAllowed=true;
509 6 : bMirror45Allowed =true;
510 6 : bMirror90Allowed =true;
511 6 : bShearAllowed =true;
512 6 : bEdgeRadiusAllowed=false;
513 6 : bContortionPossible=true;
514 6 : bCanConvToContour = true;
515 :
516 : // these ones are only allowed when single object is selected
517 6 : bTransparenceAllowed = (nMarkCount == 1);
518 6 : bGradientAllowed = (nMarkCount == 1);
519 6 : bCropAllowed = (nMarkCount == 1);
520 6 : if(bGradientAllowed)
521 : {
522 : // gradient depends on fill style
523 6 : const SdrMark* pM = GetSdrMarkByIndex(0);
524 6 : const SdrObject* pObj = pM->GetMarkedSdrObj();
525 :
526 : // may be group object, so get merged ItemSet
527 6 : const SfxItemSet& rSet = pObj->GetMergedItemSet();
528 6 : SfxItemState eState = rSet.GetItemState(XATTR_FILLSTYLE, false);
529 :
530 6 : if(SfxItemState::DONTCARE != eState)
531 : {
532 : // If state is not DONTCARE, test the item
533 6 : drawing::FillStyle eFillStyle = static_cast<const XFillStyleItem&>(rSet.Get(XATTR_FILLSTYLE)).GetValue();
534 :
535 6 : if(eFillStyle != drawing::FillStyle_GRADIENT)
536 : {
537 6 : bGradientAllowed = false;
538 : }
539 : }
540 : }
541 :
542 6 : bool bNoMovRotFound=false;
543 6 : const SdrPageView* pPV0=NULL;
544 :
545 12 : for (size_t nm=0; nm<nMarkCount; ++nm) {
546 6 : const SdrMark* pM=GetSdrMarkByIndex(nm);
547 6 : const SdrObject* pObj=pM->GetMarkedSdrObj();
548 6 : const SdrPageView* pPV=pM->GetPageView();
549 6 : if (pPV!=pPV0) {
550 6 : if (pPV->IsReadOnly()) bReadOnly=true;
551 6 : pPV0=pPV;
552 : }
553 :
554 6 : SdrObjTransformInfoRec aInfo;
555 6 : pObj->TakeObjInfo(aInfo);
556 6 : bool bMovPrt=pObj->IsMoveProtect();
557 6 : bool bSizPrt=pObj->IsResizeProtect();
558 6 : if (!bMovPrt && aInfo.bMoveAllowed) nMovableCount++; // count MovableObjs
559 6 : if (bMovPrt) bMoveProtect=true;
560 6 : if (bSizPrt) bResizeProtect=true;
561 :
562 : // not allowed when not allowed at one object
563 6 : if(!aInfo.bTransparenceAllowed)
564 3 : bTransparenceAllowed = false;
565 :
566 : // If one of these can't do something, none can
567 6 : if (!aInfo.bMoveAllowed ) bMoveAllowed =false;
568 6 : if (!aInfo.bResizeFreeAllowed) bResizeFreeAllowed=false;
569 6 : if (!aInfo.bResizePropAllowed) bResizePropAllowed=false;
570 6 : if (!aInfo.bRotateFreeAllowed) bRotateFreeAllowed=false;
571 6 : if (!aInfo.bRotate90Allowed ) bRotate90Allowed =false;
572 6 : if (!aInfo.bMirrorFreeAllowed) bMirrorFreeAllowed=false;
573 6 : if (!aInfo.bMirror45Allowed ) bMirror45Allowed =false;
574 6 : if (!aInfo.bMirror90Allowed ) bMirror90Allowed =false;
575 6 : if (!aInfo.bShearAllowed ) bShearAllowed =false;
576 6 : if (aInfo.bEdgeRadiusAllowed) bEdgeRadiusAllowed=true;
577 6 : 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 6 : if (!bMoreThanOneNoMovRot) {
581 6 : if (!aInfo.bMoveAllowed || !aInfo.bResizeFreeAllowed) {
582 0 : bMoreThanOneNoMovRot=bNoMovRotFound;
583 0 : bNoMovRotFound=true;
584 : }
585 : }
586 :
587 : // Must be resizeable to allow cropping
588 6 : if (!aInfo.bResizeFreeAllowed && !aInfo.bResizePropAllowed)
589 0 : bCropAllowed = false;
590 :
591 : // if one member cannot be converted, no conversion is possible
592 6 : if(!aInfo.bCanConvToContour)
593 2 : bCanConvToContour = false;
594 :
595 : // Ungroup
596 6 : if (!bUnGroupPossible) bUnGroupPossible=pObj->GetSubList()!=NULL;
597 : // ConvertToCurve: If at least one can be converted, that is fine.
598 6 : if (aInfo.bCanConvToPath ) bCanConvToPath =true;
599 6 : if (aInfo.bCanConvToPoly ) bCanConvToPoly =true;
600 6 : if (aInfo.bCanConvToPathLineToArea) bCanConvToPathLineToArea=true;
601 6 : if (aInfo.bCanConvToPolyLineToArea) bCanConvToPolyLineToArea=true;
602 :
603 : // Combine/Dismantle
604 6 : if(bCombinePossible)
605 : {
606 2 : bCombinePossible = ImpCanConvertForCombine(pObj);
607 2 : bCombineNoPolyPolyPossible = bCombinePossible;
608 : }
609 :
610 6 : if (!bDismantlePossible) bDismantlePossible = ImpCanDismantle(pObj, false);
611 6 : if (!bDismantleMakeLinesPossible) bDismantleMakeLinesPossible = ImpCanDismantle(pObj, true);
612 : // check OrthoDesiredOnMarked
613 6 : if (!bOrthoDesiredOnMarked && !aInfo.bNoOrthoDesired) bOrthoDesiredOnMarked=true;
614 : // check ImportMtf
615 :
616 6 : if (!bImportMtfPossible)
617 : {
618 6 : const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
619 6 : const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
620 :
621 6 : if(pSdrGrafObj && ((pSdrGrafObj->HasGDIMetaFile() && !pSdrGrafObj->IsEPS()) || pSdrGrafObj->isEmbeddedSvg()))
622 : {
623 0 : bImportMtfPossible = true;
624 : }
625 :
626 6 : if(pSdrOle2Obj)
627 : {
628 0 : bImportMtfPossible = pSdrOle2Obj->GetObjRef().is();
629 : }
630 : }
631 : }
632 :
633 6 : bMoreThanOneNotMovable=nMovableCount<nMarkCount-1;
634 6 : bOneOrMoreMovable=nMovableCount!=0;
635 6 : bGrpEnterPossible=bUnGroupPossible;
636 : }
637 2322 : ImpCheckToTopBtmPossible();
638 2322 : static_cast<SdrPolyEditView*>(this)->ImpCheckPolyPossibilities();
639 2322 : bPossibilitiesDirty=false;
640 :
641 2322 : if (bReadOnly) {
642 0 : bool bMerker1=bGrpEnterPossible;
643 0 : ImpResetPossibilityFlags();
644 0 : bReadOnly=true;
645 0 : bGrpEnterPossible=bMerker1;
646 : }
647 2322 : if (bMoveAllowed) {
648 : // Don't allow moving glued connectors.
649 : // Currently only implemented for single selection.
650 6 : if (nMarkCount==1) {
651 6 : SdrObject* pObj=GetMarkedObjectByIndex(0);
652 6 : SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
653 6 : if (pEdge!=NULL) {
654 0 : SdrObject* pNode1=pEdge->GetConnectedNode(true);
655 0 : SdrObject* pNode2=pEdge->GetConnectedNode(false);
656 0 : if (pNode1!=NULL || pNode2!=NULL) bMoveAllowed=false;
657 : }
658 : }
659 : }
660 : }
661 2322 : }
662 :
663 :
664 :
665 1 : void SdrEditView::ForceMarkedObjToAnotherPage()
666 : {
667 1 : bool bFlg=false;
668 2 : for (size_t nm=0; nm<GetMarkedObjectCount(); ++nm) {
669 1 : SdrMark* pM=GetSdrMarkByIndex(nm);
670 1 : SdrObject* pObj=pM->GetMarkedSdrObj();
671 1 : Rectangle aObjRect(pObj->GetCurrentBoundRect());
672 1 : Rectangle aPgRect(pM->GetPageView()->GetPageRect());
673 1 : if (!aObjRect.IsOver(aPgRect)) {
674 0 : bool bFnd=false;
675 0 : SdrPageView* pPV = GetSdrPageView();
676 :
677 0 : if(pPV)
678 : {
679 0 : bFnd = aObjRect.IsOver(pPV->GetPageRect());
680 : }
681 :
682 0 : if(bFnd)
683 : {
684 0 : pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum());
685 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
686 0 : pPV->GetObjList()->InsertObject(pObj, SAL_MAX_SIZE, &aReason);
687 0 : pM->SetPageView(pPV);
688 0 : InvalidateAllWin(aObjRect);
689 0 : bFlg=true;
690 : }
691 : }
692 : }
693 1 : if (bFlg) {
694 0 : MarkListHasChanged();
695 : }
696 1 : }
697 :
698 7 : void SdrEditView::DeleteMarkedList(const SdrMarkList& rMark)
699 : {
700 7 : if (rMark.GetMarkCount()!=0)
701 : {
702 7 : rMark.ForceSort();
703 :
704 7 : const bool bUndo = IsUndoEnabled();
705 7 : if( bUndo )
706 7 : BegUndo();
707 7 : const size_t nMarkCount(rMark.GetMarkCount());
708 :
709 7 : if(nMarkCount)
710 : {
711 7 : std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
712 :
713 7 : if( bUndo )
714 : {
715 35 : for(size_t nm = nMarkCount; nm > 0;)
716 : {
717 21 : --nm;
718 21 : SdrMark* pM = rMark.GetMark(nm);
719 21 : SdrObject* pObj = pM->GetMarkedSdrObj();
720 :
721 : // extra undo actions for changed connector which now may hold its laid out path (SJ)
722 21 : std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pObj ) );
723 21 : AddUndoActions( vConnectorUndoActions );
724 :
725 21 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
726 21 : }
727 : }
728 :
729 : // make sure, OrderNums are correct:
730 7 : rMark.GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
731 :
732 14 : std::vector< SdrObject* > aRemoved3DObjects;
733 :
734 35 : for(size_t nm = nMarkCount; nm > 0;)
735 : {
736 21 : --nm;
737 21 : SdrMark* pM = rMark.GetMark(nm);
738 21 : SdrObject* pObj = pM->GetMarkedSdrObj();
739 21 : SdrObjList* pOL = pObj->GetObjList();
740 21 : const size_t nOrdNum(pObj->GetOrdNumDirect());
741 :
742 21 : bool bIs3D = dynamic_cast< E3dObject* >(pObj);
743 : // set up a scene updater if object is a 3d object
744 21 : if(bIs3D)
745 : {
746 0 : aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj));
747 : }
748 :
749 21 : pOL->RemoveObject(nOrdNum);
750 :
751 21 : if( !bUndo )
752 : {
753 0 : if( bIs3D )
754 0 : aRemoved3DObjects.push_back( pObj ); // may be needed later
755 : else
756 0 : SdrObject::Free(pObj);
757 : }
758 : }
759 :
760 : // fire scene updaters
761 14 : while(!aUpdaters.empty())
762 : {
763 0 : delete aUpdaters.back();
764 0 : aUpdaters.pop_back();
765 : }
766 :
767 7 : if( !bUndo )
768 : {
769 : // now delete removed scene objects
770 0 : while(!aRemoved3DObjects.empty())
771 : {
772 0 : SdrObject::Free( aRemoved3DObjects.back() );
773 0 : aRemoved3DObjects.pop_back();
774 : }
775 7 : }
776 : }
777 :
778 7 : if( bUndo )
779 7 : EndUndo();
780 : }
781 7 : }
782 :
783 1 : void SdrEditView::DeleteMarkedObj()
784 : {
785 : // #i110981# return when nothing is to be done at all
786 1 : if(!GetMarkedObjectCount())
787 : {
788 1 : return;
789 : }
790 :
791 : // moved breaking action and undo start outside loop
792 1 : BrkAction();
793 1 : BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_DELETE);
794 :
795 : // remove as long as something is selected. This allows to schedule objects for
796 : // removal for a next run as needed
797 3 : while(GetMarkedObjectCount())
798 : {
799 : // vector to remember the parents which may be empty after object removal
800 1 : std::vector< SdrObject* > aParents;
801 :
802 : {
803 1 : const SdrMarkList& rMarkList = GetMarkedObjectList();
804 1 : const size_t nCount(rMarkList.GetMarkCount());
805 :
806 2 : for(size_t a = 0; a < nCount; ++a)
807 : {
808 : // in the first run, add all found parents, but only once
809 1 : SdrMark* pMark = rMarkList.GetMark(a);
810 1 : SdrObject* pObject = pMark->GetMarkedSdrObj();
811 1 : SdrObject* pParent = pObject->GetObjList()->GetOwnerObj();
812 :
813 1 : if(pParent)
814 : {
815 0 : if(!aParents.empty())
816 : {
817 : std::vector< SdrObject* >::iterator aFindResult =
818 0 : std::find(aParents.begin(), aParents.end(), pParent);
819 :
820 0 : if(aFindResult == aParents.end())
821 : {
822 0 : aParents.push_back(pParent);
823 : }
824 : }
825 : else
826 : {
827 0 : aParents.push_back(pParent);
828 : }
829 : }
830 : }
831 :
832 1 : if(!aParents.empty())
833 : {
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 0 : for(size_t a = 0; a < nCount; ++a)
838 : {
839 0 : SdrMark* pMark = rMarkList.GetMark(a);
840 0 : SdrObject* pObject = pMark->GetMarkedSdrObj();
841 :
842 : std::vector< SdrObject* >::iterator aFindResult =
843 0 : std::find(aParents.begin(), aParents.end(), pObject);
844 :
845 0 : if(aFindResult != aParents.end())
846 : {
847 0 : aParents.erase(aFindResult);
848 : }
849 : }
850 : }
851 : }
852 :
853 : // original stuff: remove selected objects. Handle clear will
854 : // do something only once
855 1 : DeleteMarkedList(GetMarkedObjectList());
856 1 : GetMarkedObjectListWriteAccess().Clear();
857 1 : maHdlList.Clear();
858 :
859 2 : while(aParents.size() && !GetMarkedObjectCount())
860 : {
861 : // iterate over remembered parents
862 0 : SdrObject* pParent = aParents.back();
863 0 : aParents.pop_back();
864 :
865 0 : if(pParent->GetSubList() && 0 == pParent->GetSubList()->GetObjCount())
866 : {
867 : // we detected an empty parent, a candidate to leave group/3DScene
868 : // if entered
869 0 : if(GetSdrPageView()->GetAktGroup()
870 0 : && GetSdrPageView()->GetAktGroup() == pParent)
871 : {
872 0 : GetSdrPageView()->LeaveOneGroup();
873 : }
874 :
875 : // schedule empty parent for removal
876 0 : GetMarkedObjectListWriteAccess().InsertEntry(
877 0 : SdrMark(pParent, GetSdrPageView()));
878 : }
879 : }
880 1 : }
881 :
882 : // end undo and change messaging moved at the end
883 1 : EndUndo();
884 1 : MarkListHasChanged();
885 : }
886 :
887 0 : void SdrEditView::CopyMarkedObj()
888 : {
889 0 : SortMarkedObjects();
890 :
891 0 : SdrMarkList aSourceObjectsForCopy(GetMarkedObjectList());
892 : // The following loop is used instead of MarkList::Merge(), to be
893 : // able to flag the MarkEntries.
894 0 : const size_t nEdgeAnz = GetEdgesOfMarkedNodes().GetMarkCount();
895 0 : for (size_t nEdgeNum=0; nEdgeNum<nEdgeAnz; ++nEdgeNum) {
896 0 : SdrMark aM(*GetEdgesOfMarkedNodes().GetMark(nEdgeNum));
897 0 : aM.SetUser(1);
898 0 : aSourceObjectsForCopy.InsertEntry(aM);
899 0 : }
900 0 : aSourceObjectsForCopy.ForceSort();
901 :
902 : // #i13033#
903 : // New mechanism to re-create the connections of cloned connectors
904 0 : CloneList aCloneList;
905 :
906 0 : const bool bUndo = IsUndoEnabled();
907 :
908 0 : GetMarkedObjectListWriteAccess().Clear();
909 0 : size_t nCloneErrCnt=0;
910 0 : const size_t nMarkCount=aSourceObjectsForCopy.GetMarkCount();
911 0 : for (size_t nm=0; nm<nMarkCount; ++nm) {
912 0 : SdrMark* pM=aSourceObjectsForCopy.GetMark(nm);
913 0 : SdrObject* pO=pM->GetMarkedSdrObj()->Clone();
914 0 : if (pO!=NULL) {
915 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
916 0 : pM->GetPageView()->GetObjList()->InsertObject(pO, SAL_MAX_SIZE, &aReason);
917 :
918 0 : if( bUndo )
919 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoCopyObject(*pO));
920 :
921 0 : SdrMark aME(*pM);
922 0 : aME.SetMarkedSdrObj(pO);
923 0 : aCloneList.AddPair(pM->GetMarkedSdrObj(), pO);
924 :
925 0 : if (pM->GetUser()==0)
926 : {
927 : // otherwise it is only an Edge we have to copy as well
928 0 : GetMarkedObjectListWriteAccess().InsertEntry(aME);
929 0 : }
930 : } else {
931 0 : nCloneErrCnt++;
932 : }
933 : }
934 :
935 : // #i13033#
936 : // New mechanism to re-create the connections of cloned connectors
937 0 : aCloneList.CopyConnections();
938 :
939 : if(nCloneErrCnt)
940 : {
941 : #ifdef DBG_UTIL
942 : OStringBuffer aStr("SdrEditView::CopyMarkedObj(): Error when cloning ");
943 :
944 : if(nCloneErrCnt == 1)
945 : {
946 : aStr.append("a drawing object.");
947 : }
948 : else
949 : {
950 : aStr.append(static_cast<sal_Int32>(nCloneErrCnt));
951 : aStr.append(" drawing objects.");
952 : }
953 :
954 : aStr.append(" This object's/These objects's connections will not be copied.");
955 : OSL_FAIL(aStr.getStr());
956 : #endif
957 : }
958 0 : MarkListHasChanged();
959 0 : }
960 :
961 :
962 :
963 0 : bool SdrEditView::InsertObjectAtView(SdrObject* pObj, SdrPageView& rPV, SdrInsertFlags nOptions)
964 : {
965 0 : if (nOptions & SdrInsertFlags::SETDEFLAYER) {
966 0 : SdrLayerID nLayer=rPV.GetPage()->GetLayerAdmin().GetLayerID(aAktLayer,true);
967 0 : if (nLayer==SDRLAYER_NOTFOUND) nLayer=0;
968 0 : if (rPV.GetLockedLayers().IsSet(nLayer) || !rPV.GetVisibleLayers().IsSet(nLayer)) {
969 0 : SdrObject::Free( pObj ); // Layer locked or invisible
970 0 : return false;
971 : }
972 0 : pObj->NbcSetLayer(nLayer);
973 : }
974 0 : if (nOptions & SdrInsertFlags::SETDEFATTR) {
975 0 : if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, false);
976 0 : pObj->SetMergedItemSet(aDefaultAttr);
977 : }
978 0 : if (!pObj->IsInserted()) {
979 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL);
980 0 : if (nOptions & SdrInsertFlags::NOBROADCAST) {
981 0 : rPV.GetObjList()->NbcInsertObject(pObj, SAL_MAX_SIZE, &aReason);
982 : } else {
983 0 : rPV.GetObjList()->InsertObject(pObj, SAL_MAX_SIZE, &aReason);
984 : }
985 : }
986 0 : if( IsUndoEnabled() )
987 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
988 :
989 0 : if (!(nOptions & SdrInsertFlags::DONTMARK)) {
990 0 : if (!(nOptions & SdrInsertFlags::ADDMARK)) UnmarkAllObj();
991 0 : MarkObj(pObj,&rPV);
992 : }
993 0 : return true;
994 : }
995 :
996 0 : void SdrEditView::ReplaceObjectAtView(SdrObject* pOldObj, SdrPageView& rPV, SdrObject* pNewObj, bool bMark)
997 : {
998 0 : if(IsTextEdit())
999 : {
1000 : #ifdef DBG_UTIL
1001 : if(dynamic_cast< SdrTextObj* >(pOldObj) && static_cast< SdrTextObj* >(pOldObj)->IsTextEditActive())
1002 : {
1003 : OSL_ENSURE(false, "OldObject is in TextEdit mode, this has to be ended before replacing it usnig SdrEndTextEdit (!)");
1004 : }
1005 :
1006 : if(dynamic_cast< SdrTextObj* >(pNewObj) && static_cast< SdrTextObj* >(pNewObj)->IsTextEditActive())
1007 : {
1008 : OSL_ENSURE(false, "NewObject is in TextEdit mode, this has to be ended before replacing it usnig SdrEndTextEdit (!)");
1009 : }
1010 : #endif
1011 :
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 0 : SdrView *pSdrView = dynamic_cast<SdrView*>(this);
1016 0 : if (pSdrView)
1017 0 : pSdrView->SdrEndTextEdit();
1018 : }
1019 :
1020 0 : SdrObjList* pOL=pOldObj->GetObjList();
1021 0 : const bool bUndo = IsUndoEnabled();
1022 0 : if( bUndo )
1023 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pOldObj,*pNewObj));
1024 :
1025 0 : if( IsObjMarked( pOldObj ) )
1026 0 : MarkObj( pOldObj, &rPV, true /*unmark!*/ );
1027 :
1028 0 : pOL->ReplaceObject(pNewObj,pOldObj->GetOrdNum());
1029 :
1030 0 : if( !bUndo )
1031 0 : SdrObject::Free( pOldObj );
1032 :
1033 0 : if (bMark) MarkObj(pNewObj,&rPV);
1034 0 : }
1035 :
1036 :
1037 :
1038 2350 : bool SdrEditView::IsUndoEnabled() const
1039 : {
1040 2350 : return pMod->IsUndoEnabled();
1041 435 : }
1042 :
1043 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|