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 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 107 void SdrEditView::ImpClearVars() 108 { 109 ImpResetPossibilityFlags(); 110 bPossibilitiesDirty=sal_True; // << war von Purify angemeckert 111 bBundleVirtObj=sal_False; 112 } 113 114 SdrEditView::SdrEditView(SdrModel* pModel1, OutputDevice* pOut): 115 SdrMarkView(pModel1,pOut) 116 { 117 ImpClearVars(); 118 } 119 120 SdrEditView::~SdrEditView() 121 { 122 } 123 124 //////////////////////////////////////////////////////////////////////////////////////////////////// 125 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 143 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 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 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 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 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 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 398 void SdrEditView::MarkListHasChanged() 399 { 400 SdrMarkView::MarkListHasChanged(); 401 bPossibilitiesDirty=sal_True; 402 } 403 404 void SdrEditView::ModelHasChanged() 405 { 406 SdrMarkView::ModelHasChanged(); 407 bPossibilitiesDirty=sal_True; 408 } 409 410 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 418 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 426 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 435 sal_Bool SdrEditView::IsTransparenceAllowed() const 436 { 437 ForcePossibilities(); 438 return bTransparenceAllowed; 439 } 440 441 sal_Bool SdrEditView::IsGradientAllowed() const 442 { 443 ForcePossibilities(); 444 return bGradientAllowed; 445 } 446 447 sal_Bool SdrEditView::IsShearAllowed() const 448 { 449 ForcePossibilities(); 450 if (bResizeProtect) return sal_False; 451 return bShearAllowed; 452 } 453 454 sal_Bool SdrEditView::IsEdgeRadiusAllowed() const 455 { 456 ForcePossibilities(); 457 return bEdgeRadiusAllowed; 458 } 459 460 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 472 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 482 sal_Bool SdrEditView::IsCombinePossible(sal_Bool bNoPolyPoly) const 483 { 484 ForcePossibilities(); 485 if (bNoPolyPoly) return bCombineNoPolyPolyPossible; 486 else return bCombinePossible; 487 } 488 489 sal_Bool SdrEditView::IsDismantlePossible(sal_Bool bMakeLines) const 490 { 491 ForcePossibilities(); 492 if (bMakeLines) return bDismantleMakeLinesPossible; 493 else return bDismantlePossible; 494 } 495 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 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 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 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 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 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 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 1064 bool SdrEditView::IsUndoEnabled() const 1065 { 1066 return pMod->IsUndoEnabled(); 1067 } 1068