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