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