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