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 <svx/svdedtv.hxx> 32 #include <math.h> 33 34 #ifndef _MATH_H 35 #define _MATH_H 36 #endif 37 #include <tools/bigint.hxx> 38 #include <svl/itemiter.hxx> 39 #include <vcl/msgbox.hxx> 40 #include <svx/rectenum.hxx> 41 #include <svx/svxids.hrc> // fuer SID_ATTR_TRANSFORM_... 42 #include <svx/svdattr.hxx> // fuer Get/SetGeoAttr 43 #include "svx/svditext.hxx" 44 #include "svx/svditer.hxx" 45 #include <svx/svdtrans.hxx> 46 #include <svx/svdundo.hxx> 47 #include <svx/svdpage.hxx> 48 #include <svx/svdpagv.hxx> 49 #include <svx/svdlayer.hxx> // fuer MergeNotPersistAttr 50 #include <svx/svdattrx.hxx> // fuer MergeNotPersistAttr 51 #include <svx/svdetc.hxx> // fuer SearchOutlinerItems 52 #include <svx/svdopath.hxx> // fuer Crook 53 #include "svx/svdstr.hrc" // Namen aus der Resource 54 #include "svx/svdglob.hxx" // StringCache 55 #include <editeng/eeitem.hxx> 56 #include <svl/aeitem.hxx> 57 #include <svl/whiter.hxx> 58 #include <svx/sdr/contact/objectcontact.hxx> 59 #include <svx/sdr/contact/viewcontact.hxx> 60 #include <svx/e3dsceneupdater.hxx> 61 #include <svx/obj3d.hxx> 62 63 //////////////////////////////////////////////////////////////////////////////////////////////////// 64 //////////////////////////////////////////////////////////////////////////////////////////////////// 65 //////////////////////////////////////////////////////////////////////////////////////////////////// 66 //////////////////////////////////////////////////////////////////////////////////////////////////// 67 // 68 // @@@@@ @@@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@ 69 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ 70 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@ 71 // @@@@ @@ @@ @@ @@ @@@@@ @@ @@@@ @@@@@@@ 72 // @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@ 73 // @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@ 74 // @@@@@ @@@@@ @@ @@ @ @@ @@@@@ @@ @@ 75 // 76 //////////////////////////////////////////////////////////////////////////////////////////////////// 77 //////////////////////////////////////////////////////////////////////////////////////////////////// 78 79 void SdrEditView::SetMarkedObjRect(const Rectangle& rRect, sal_Bool bCopy) 80 { 81 DBG_ASSERT(!rRect.IsEmpty(),"SetMarkedObjRect() mit leerem Rect mach keinen Sinn"); 82 if (rRect.IsEmpty()) return; 83 sal_uIntPtr nAnz=GetMarkedObjectCount(); 84 if (nAnz==0) return; 85 Rectangle aR0(GetMarkedObjRect()); 86 DBG_ASSERT(!aR0.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() ist leer"); 87 if (aR0.IsEmpty()) return; 88 long x0=aR0.Left(); 89 long y0=aR0.Top(); 90 long w0=aR0.Right()-x0; 91 long h0=aR0.Bottom()-y0; 92 long x1=rRect.Left(); 93 long y1=rRect.Top(); 94 long w1=rRect.Right()-x1; 95 long h1=rRect.Bottom()-y1; 96 XubString aStr; 97 ImpTakeDescriptionStr(STR_EditPosSize,aStr); 98 if (bCopy) 99 aStr+=ImpGetResStr(STR_EditWithCopy); 100 101 const bool bUndo = IsUndoEnabled(); 102 if( bUndo ) 103 BegUndo(aStr); 104 105 if (bCopy) 106 CopyMarkedObj(); 107 108 for (sal_uIntPtr nm=0; nm<nAnz; nm++) 109 { 110 SdrMark* pM=GetSdrMarkByIndex(nm); 111 SdrObject* pO=pM->GetMarkedSdrObj(); 112 if( bUndo ) 113 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); 114 115 Rectangle aR1(pO->GetSnapRect()); 116 if (!aR1.IsEmpty()) 117 { 118 if (aR1==aR0) 119 { 120 aR1=rRect; 121 } 122 else 123 { // aR1 von aR0 nach rRect transformieren 124 aR1.Move(-x0,-y0); 125 BigInt l(aR1.Left()); 126 BigInt r(aR1.Right()); 127 BigInt t(aR1.Top()); 128 BigInt b(aR1.Bottom()); 129 if (w0!=0) { 130 l*=w1; l/=w0; 131 r*=w1; r/=w0; 132 } else { 133 l=0; r=w1; 134 } 135 if (h0!=0) { 136 t*=h1; t/=h0; 137 b*=h1; b/=h0; 138 } else { 139 t=0; b=h1; 140 } 141 aR1.Left ()=long(l); 142 aR1.Right ()=long(r); 143 aR1.Top ()=long(t); 144 aR1.Bottom()=long(b); 145 aR1.Move(x1,y1); 146 } 147 pO->SetSnapRect(aR1); 148 } else { 149 DBG_ERROR("SetMarkedObjRect(): pObj->GetSnapRect() liefert leeres Rect"); 150 } 151 } 152 if( bUndo ) 153 EndUndo(); 154 } 155 156 std::vector< SdrUndoAction* > SdrEditView::CreateConnectorUndo( SdrObject& rO ) 157 { 158 std::vector< SdrUndoAction* > vUndoActions; 159 160 if ( rO.GetBroadcaster() ) 161 { 162 const SdrPage* pPage = rO.GetPage(); 163 if ( pPage ) 164 { 165 SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS ); 166 while( aIter.IsMore() ) 167 { 168 SdrObject* pPartObj = aIter.Next(); 169 if ( pPartObj->ISA( SdrEdgeObj ) ) 170 { 171 if ( ( pPartObj->GetConnectedNode( sal_False ) == &rO ) || 172 ( pPartObj->GetConnectedNode( sal_True ) == &rO ) ) 173 { 174 vUndoActions.push_back( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pPartObj ) ); 175 } 176 } 177 } 178 } 179 } 180 return vUndoActions; 181 } 182 183 void SdrEditView::AddUndoActions( std::vector< SdrUndoAction* >& rUndoActions ) 184 { 185 std::vector< SdrUndoAction* >::iterator aUndoActionIter( rUndoActions.begin() ); 186 while( aUndoActionIter != rUndoActions.end() ) 187 AddUndo( *aUndoActionIter++ ); 188 } 189 190 void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy) 191 { 192 const bool bUndo = IsUndoEnabled(); 193 194 if( bUndo ) 195 { 196 XubString aStr(ImpGetResStr(STR_EditMove)); 197 if (bCopy) 198 aStr+=ImpGetResStr(STR_EditWithCopy); 199 // benoetigt eigene UndoGroup wegen Parameter 200 BegUndo(aStr,GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVE); 201 } 202 203 if (bCopy) 204 CopyMarkedObj(); 205 206 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 207 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 208 { 209 SdrMark* pM=GetSdrMarkByIndex(nm); 210 SdrObject* pO=pM->GetMarkedSdrObj(); 211 if( bUndo ) 212 { 213 std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); 214 AddUndoActions( vConnectorUndoActions ); 215 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,rSiz)); 216 } 217 pO->Move(rSiz); 218 } 219 220 if( bUndo ) 221 EndUndo(); 222 } 223 224 void SdrEditView::ResizeMarkedObj(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy) 225 { 226 const bool bUndo = IsUndoEnabled(); 227 if( bUndo ) 228 { 229 XubString aStr; 230 ImpTakeDescriptionStr(STR_EditResize,aStr); 231 if (bCopy) 232 aStr+=ImpGetResStr(STR_EditWithCopy); 233 BegUndo(aStr); 234 } 235 236 if (bCopy) 237 CopyMarkedObj(); 238 239 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 240 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 241 { 242 SdrMark* pM=GetSdrMarkByIndex(nm); 243 SdrObject* pO=pM->GetMarkedSdrObj(); 244 if( bUndo ) 245 { 246 std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); 247 AddUndoActions( vConnectorUndoActions ); 248 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); 249 } 250 pO->Resize(rRef,xFact,yFact); 251 } 252 253 if( bUndo ) 254 EndUndo(); 255 } 256 257 long SdrEditView::GetMarkedObjRotate() const 258 { 259 sal_Bool b1st=sal_True; 260 sal_Bool bOk=sal_True; 261 long nWink=0; 262 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 263 for (sal_uIntPtr nm=0; nm<nMarkAnz && bOk; nm++) { 264 SdrMark* pM=GetSdrMarkByIndex(nm); 265 SdrObject* pO=pM->GetMarkedSdrObj(); 266 long nWink2=pO->GetRotateAngle(); 267 if (b1st) nWink=nWink2; 268 else if (nWink2!=nWink) bOk=sal_False; 269 b1st=sal_False; 270 } 271 if (!bOk) nWink=0; 272 return nWink; 273 } 274 275 void SdrEditView::RotateMarkedObj(const Point& rRef, long nWink, bool bCopy) 276 { 277 const bool bUndo = IsUndoEnabled(); 278 if( bUndo ) 279 { 280 XubString aStr; 281 ImpTakeDescriptionStr(STR_EditRotate,aStr); 282 if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); 283 BegUndo(aStr); 284 } 285 286 if (bCopy) 287 CopyMarkedObj(); 288 289 double nSin=sin(nWink*nPi180); 290 double nCos=cos(nWink*nPi180); 291 const sal_uInt32 nMarkAnz(GetMarkedObjectCount()); 292 293 if(nMarkAnz) 294 { 295 std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; 296 297 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++) 298 { 299 SdrMark* pM = GetSdrMarkByIndex(nm); 300 SdrObject* pO = pM->GetMarkedSdrObj(); 301 302 if( bUndo ) 303 { 304 // extra undo actions for changed connector which now may hold it's layouted path (SJ) 305 std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); 306 AddUndoActions( vConnectorUndoActions ); 307 308 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); 309 } 310 311 // set up a scene updater if object is a 3d object 312 if(dynamic_cast< E3dObject* >(pO)) 313 { 314 aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO)); 315 } 316 317 pO->Rotate(rRef,nWink,nSin,nCos); 318 } 319 320 // fire scene updaters 321 while(!aUpdaters.empty()) 322 { 323 delete aUpdaters.back(); 324 aUpdaters.pop_back(); 325 } 326 } 327 328 if( bUndo ) 329 EndUndo(); 330 } 331 332 void SdrEditView::MirrorMarkedObj(const Point& rRef1, const Point& rRef2, bool bCopy) 333 { 334 const bool bUndo = IsUndoEnabled(); 335 336 if( bUndo ) 337 { 338 XubString aStr; 339 Point aDif(rRef2-rRef1); 340 if (aDif.X()==0) ImpTakeDescriptionStr(STR_EditMirrorHori,aStr); 341 else if (aDif.Y()==0) ImpTakeDescriptionStr(STR_EditMirrorVert,aStr); 342 else if (Abs(aDif.X())==Abs(aDif.Y())) ImpTakeDescriptionStr(STR_EditMirrorDiag,aStr); 343 else ImpTakeDescriptionStr(STR_EditMirrorFree,aStr); 344 if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); 345 BegUndo(aStr); 346 } 347 348 if (bCopy) 349 CopyMarkedObj(); 350 351 const sal_uInt32 nMarkAnz(GetMarkedObjectCount()); 352 353 if(nMarkAnz) 354 { 355 std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; 356 357 for(sal_uInt32 nm(0); nm < nMarkAnz; nm++) 358 { 359 SdrMark* pM = GetSdrMarkByIndex(nm); 360 SdrObject* pO = pM->GetMarkedSdrObj(); 361 362 if( bUndo ) 363 { 364 // extra undo actions for changed connector which now may hold it's layouted path (SJ) 365 std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); 366 AddUndoActions( vConnectorUndoActions ); 367 368 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); 369 } 370 371 // set up a scene updater if object is a 3d object 372 if(dynamic_cast< E3dObject* >(pO)) 373 { 374 aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO)); 375 } 376 377 pO->Mirror(rRef1,rRef2); 378 } 379 380 // fire scene updaters 381 while(!aUpdaters.empty()) 382 { 383 delete aUpdaters.back(); 384 aUpdaters.pop_back(); 385 } 386 } 387 388 if( bUndo ) 389 EndUndo(); 390 } 391 392 void SdrEditView::MirrorMarkedObjHorizontal(sal_Bool bCopy) 393 { 394 Point aCenter(GetMarkedObjRect().Center()); 395 Point aPt2(aCenter); 396 aPt2.Y()++; 397 MirrorMarkedObj(aCenter,aPt2,bCopy); 398 } 399 400 void SdrEditView::MirrorMarkedObjVertical(sal_Bool bCopy) 401 { 402 Point aCenter(GetMarkedObjRect().Center()); 403 Point aPt2(aCenter); 404 aPt2.X()++; 405 MirrorMarkedObj(aCenter,aPt2,bCopy); 406 } 407 408 long SdrEditView::GetMarkedObjShear() const 409 { 410 sal_Bool b1st=sal_True; 411 sal_Bool bOk=sal_True; 412 long nWink=0; 413 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 414 for (sal_uIntPtr nm=0; nm<nMarkAnz && bOk; nm++) { 415 SdrMark* pM=GetSdrMarkByIndex(nm); 416 SdrObject* pO=pM->GetMarkedSdrObj(); 417 long nWink2=pO->GetShearAngle(); 418 if (b1st) nWink=nWink2; 419 else if (nWink2!=nWink) bOk=sal_False; 420 b1st=sal_False; 421 } 422 if (nWink>SDRMAXSHEAR) nWink=SDRMAXSHEAR; 423 if (nWink<-SDRMAXSHEAR) nWink=-SDRMAXSHEAR; 424 if (!bOk) nWink=0; 425 return nWink; 426 } 427 428 void SdrEditView::ShearMarkedObj(const Point& rRef, long nWink, bool bVShear, bool bCopy) 429 { 430 const bool bUndo = IsUndoEnabled(); 431 432 if( bUndo ) 433 { 434 XubString aStr; 435 ImpTakeDescriptionStr(STR_EditShear,aStr); 436 if (bCopy) 437 aStr+=ImpGetResStr(STR_EditWithCopy); 438 BegUndo(aStr); 439 } 440 441 if (bCopy) 442 CopyMarkedObj(); 443 444 double nTan=tan(nWink*nPi180); 445 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 446 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 447 { 448 SdrMark* pM=GetSdrMarkByIndex(nm); 449 SdrObject* pO=pM->GetMarkedSdrObj(); 450 if( bUndo ) 451 { 452 std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); 453 AddUndoActions( vConnectorUndoActions ); 454 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); 455 } 456 pO->Shear(rRef,nWink,nTan,bVShear); 457 } 458 459 if( bUndo ) 460 EndUndo(); 461 } 462 463 void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& rRef, const Point& rRad, 464 SdrCrookMode eMode, sal_Bool bVertical, sal_Bool bNoContortion, sal_Bool bRotate, const Rectangle& rMarkRect) 465 { 466 SdrPathObj* pPath=PTR_CAST(SdrPathObj,pO); 467 sal_Bool bDone = sal_False; 468 469 if(pPath!=NULL && !bNoContortion) 470 { 471 XPolyPolygon aXPP(pPath->GetPathPoly()); 472 switch (eMode) { 473 case SDRCROOK_ROTATE : CrookRotatePoly (aXPP,rRef,rRad,bVertical); break; 474 case SDRCROOK_SLANT : CrookSlantPoly (aXPP,rRef,rRad,bVertical); break; 475 case SDRCROOK_STRETCH: CrookStretchPoly(aXPP,rRef,rRad,bVertical,rMarkRect); break; 476 } // switch 477 pPath->SetPathPoly(aXPP.getB2DPolyPolygon()); 478 bDone = sal_True; 479 } 480 481 if(!bDone && !pPath && pO->IsPolyObj() && 0L != pO->GetPointCount()) 482 { 483 // FuerPolyObj's, aber NICHT fuer SdrPathObj's, z.B. fuer's Bemassungsobjekt 484 sal_uInt32 nPtAnz(pO->GetPointCount()); 485 XPolygon aXP((sal_uInt16)nPtAnz); 486 sal_uInt32 nPtNum; 487 488 for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) 489 { 490 Point aPt(pO->GetPoint(nPtNum)); 491 aXP[(sal_uInt16)nPtNum]=aPt; 492 } 493 494 switch (eMode) 495 { 496 case SDRCROOK_ROTATE : CrookRotatePoly (aXP,rRef,rRad,bVertical); break; 497 case SDRCROOK_SLANT : CrookSlantPoly (aXP,rRef,rRad,bVertical); break; 498 case SDRCROOK_STRETCH: CrookStretchPoly(aXP,rRef,rRad,bVertical,rMarkRect); break; 499 } 500 501 for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) 502 { 503 // hier koennte man vieleicht auch mal das Broadcasting optimieren 504 // ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch 505 pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum); 506 } 507 508 bDone = sal_True; 509 } 510 511 if(!bDone) 512 { 513 // Fuer alle anderen oder wenn bNoContortion 514 Point aCtr0(pO->GetSnapRect().Center()); 515 Point aCtr1(aCtr0); 516 sal_Bool bRotOk(sal_False); 517 double nSin(0.0), nCos(1.0); 518 double nWink(0.0); 519 520 if(0 != rRad.X() && 0 != rRad.Y()) 521 { 522 bRotOk = bRotate; 523 524 switch (eMode) 525 { 526 case SDRCROOK_ROTATE : nWink=CrookRotateXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); bRotOk=bRotate; break; 527 case SDRCROOK_SLANT : nWink=CrookSlantXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); break; 528 case SDRCROOK_STRETCH: nWink=CrookStretchXPoint(aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical,rMarkRect); break; 529 } 530 } 531 532 aCtr1 -= aCtr0; 533 534 if(bRotOk) 535 pO->Rotate(aCtr0, Round(nWink/nPi180), nSin, nCos); 536 537 pO->Move(Size(aCtr1.X(),aCtr1.Y())); 538 } 539 } 540 541 void SdrEditView::CrookMarkedObj(const Point& rRef, const Point& rRad, SdrCrookMode eMode, 542 bool bVertical, bool bNoContortion, bool bCopy) 543 { 544 Rectangle aMarkRect(GetMarkedObjRect()); 545 const bool bUndo = IsUndoEnabled(); 546 547 bool bRotate=bNoContortion && eMode==SDRCROOK_ROTATE && IsRotateAllowed(sal_False); 548 549 if( bUndo ) 550 { 551 XubString aStr; 552 ImpTakeDescriptionStr(bNoContortion?STR_EditCrook:STR_EditCrookContortion,aStr); 553 if (bCopy) 554 aStr+=ImpGetResStr(STR_EditWithCopy); 555 BegUndo(aStr); 556 } 557 558 if (bCopy) 559 CopyMarkedObj(); 560 561 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 562 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 563 { 564 SdrMark* pM=GetSdrMarkByIndex(nm); 565 SdrObject* pO=pM->GetMarkedSdrObj(); 566 if( bUndo ) 567 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); 568 569 const SdrObjList* pOL=pO->GetSubList(); 570 if (bNoContortion || pOL==NULL) { 571 ImpCrookObj(pO,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect); 572 } else { 573 SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS); 574 while (aIter.IsMore()) { 575 SdrObject* pO1=aIter.Next(); 576 ImpCrookObj(pO1,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect); 577 } 578 } 579 } 580 581 if( bUndo ) 582 EndUndo(); 583 } 584 585 void SdrEditView::ImpDistortObj(SdrObject* pO, const Rectangle& rRef, const XPolygon& rDistortedRect, sal_Bool bNoContortion) 586 { 587 SdrPathObj* pPath = PTR_CAST(SdrPathObj, pO); 588 589 if(!bNoContortion && pPath) 590 { 591 XPolyPolygon aXPP(pPath->GetPathPoly()); 592 aXPP.Distort(rRef, rDistortedRect); 593 pPath->SetPathPoly(aXPP.getB2DPolyPolygon()); 594 } 595 else if(pO->IsPolyObj()) 596 { 597 // z.B. fuer's Bemassungsobjekt 598 sal_uInt32 nPtAnz(pO->GetPointCount()); 599 XPolygon aXP((sal_uInt16)nPtAnz); 600 sal_uInt32 nPtNum; 601 602 for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) 603 { 604 Point aPt(pO->GetPoint(nPtNum)); 605 aXP[(sal_uInt16)nPtNum]=aPt; 606 } 607 608 aXP.Distort(rRef, rDistortedRect); 609 610 for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) 611 { 612 // hier koennte man vieleicht auch mal das Broadcasting optimieren 613 // ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch 614 pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum); 615 } 616 } 617 } 618 619 void SdrEditView::DistortMarkedObj(const Rectangle& rRef, const XPolygon& rDistortedRect, bool bNoContortion, bool bCopy) 620 { 621 const bool bUndo = IsUndoEnabled(); 622 623 if( bUndo ) 624 { 625 XubString aStr; 626 ImpTakeDescriptionStr(STR_EditDistort,aStr); 627 if (bCopy) 628 aStr+=ImpGetResStr(STR_EditWithCopy); 629 BegUndo(aStr); 630 } 631 632 if (bCopy) 633 CopyMarkedObj(); 634 635 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 636 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 637 { 638 SdrMark* pM=GetSdrMarkByIndex(nm); 639 SdrObject* pO=pM->GetMarkedSdrObj(); 640 if( bUndo ) 641 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); 642 643 Rectangle aRefRect(rRef); 644 XPolygon aRefPoly(rDistortedRect); 645 const SdrObjList* pOL=pO->GetSubList(); 646 if (bNoContortion || pOL==NULL) { 647 ImpDistortObj(pO,aRefRect,aRefPoly,bNoContortion); 648 } else { 649 SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS); 650 while (aIter.IsMore()) { 651 SdrObject* pO1=aIter.Next(); 652 ImpDistortObj(pO1,aRefRect,aRefPoly,bNoContortion); 653 } 654 } 655 } 656 if( bUndo ) 657 EndUndo(); 658 } 659 660 //////////////////////////////////////////////////////////////////////////////////////////////////// 661 662 void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, sal_Bool /*bReplaceAll*/) 663 { 664 // bReplaceAll hat hier keinerlei Wirkung 665 Rectangle aAllSnapRect(GetMarkedObjRect()); 666 const SfxPoolItem *pPoolItem=NULL; 667 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,sal_True,&pPoolItem)==SFX_ITEM_SET) { 668 long n=((const SdrTransformRef1XItem*)pPoolItem)->GetValue(); 669 SetRef1(Point(n,GetRef1().Y())); 670 } 671 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,sal_True,&pPoolItem)==SFX_ITEM_SET) { 672 long n=((const SdrTransformRef1YItem*)pPoolItem)->GetValue(); 673 SetRef1(Point(GetRef1().X(),n)); 674 } 675 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,sal_True,&pPoolItem)==SFX_ITEM_SET) { 676 long n=((const SdrTransformRef2XItem*)pPoolItem)->GetValue(); 677 SetRef2(Point(n,GetRef2().Y())); 678 } 679 if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,sal_True,&pPoolItem)==SFX_ITEM_SET) { 680 long n=((const SdrTransformRef2YItem*)pPoolItem)->GetValue(); 681 SetRef2(Point(GetRef2().X(),n)); 682 } 683 long nAllPosX=0; sal_Bool bAllPosX=sal_False; 684 long nAllPosY=0; sal_Bool bAllPosY=sal_False; 685 long nAllWdt=0; sal_Bool bAllWdt=sal_False; 686 long nAllHgt=0; sal_Bool bAllHgt=sal_False; 687 sal_Bool bDoIt=sal_False; 688 if (rAttr.GetItemState(SDRATTR_ALLPOSITIONX,sal_True,&pPoolItem)==SFX_ITEM_SET) { 689 nAllPosX=((const SdrAllPositionXItem*)pPoolItem)->GetValue(); 690 bAllPosX=sal_True; bDoIt=sal_True; 691 } 692 if (rAttr.GetItemState(SDRATTR_ALLPOSITIONY,sal_True,&pPoolItem)==SFX_ITEM_SET) { 693 nAllPosY=((const SdrAllPositionYItem*)pPoolItem)->GetValue(); 694 bAllPosY=sal_True; bDoIt=sal_True; 695 } 696 if (rAttr.GetItemState(SDRATTR_ALLSIZEWIDTH,sal_True,&pPoolItem)==SFX_ITEM_SET) { 697 nAllWdt=((const SdrAllSizeWidthItem*)pPoolItem)->GetValue(); 698 bAllWdt=sal_True; bDoIt=sal_True; 699 } 700 if (rAttr.GetItemState(SDRATTR_ALLSIZEHEIGHT,sal_True,&pPoolItem)==SFX_ITEM_SET) { 701 nAllHgt=((const SdrAllSizeHeightItem*)pPoolItem)->GetValue(); 702 bAllHgt=sal_True; bDoIt=sal_True; 703 } 704 if (bDoIt) { 705 Rectangle aRect(aAllSnapRect); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!! 706 if (bAllPosX) aRect.Move(nAllPosX-aRect.Left(),0); 707 if (bAllPosY) aRect.Move(0,nAllPosY-aRect.Top()); 708 if (bAllWdt) aRect.Right()=aAllSnapRect.Left()+nAllWdt; 709 if (bAllHgt) aRect.Bottom()=aAllSnapRect.Top()+nAllHgt; 710 SetMarkedObjRect(aRect); 711 } 712 if (rAttr.GetItemState(SDRATTR_RESIZEXALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { 713 Fraction aXFact=((const SdrResizeXAllItem*)pPoolItem)->GetValue(); 714 ResizeMarkedObj(aAllSnapRect.TopLeft(),aXFact,Fraction(1,1)); 715 } 716 if (rAttr.GetItemState(SDRATTR_RESIZEYALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { 717 Fraction aYFact=((const SdrResizeYAllItem*)pPoolItem)->GetValue(); 718 ResizeMarkedObj(aAllSnapRect.TopLeft(),Fraction(1,1),aYFact); 719 } 720 if (rAttr.GetItemState(SDRATTR_ROTATEALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { 721 long nAngle=((const SdrRotateAllItem*)pPoolItem)->GetValue(); 722 RotateMarkedObj(aAllSnapRect.Center(),nAngle); 723 } 724 if (rAttr.GetItemState(SDRATTR_HORZSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { 725 long nAngle=((const SdrHorzShearAllItem*)pPoolItem)->GetValue(); 726 ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_False); 727 } 728 if (rAttr.GetItemState(SDRATTR_VERTSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { 729 long nAngle=((const SdrVertShearAllItem*)pPoolItem)->GetValue(); 730 ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_True); 731 } 732 733 const bool bUndo = IsUndoEnabled(); 734 735 // Todo: WhichRange nach Notwendigkeit ueberpruefen. 736 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 737 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 738 { 739 const SdrMark* pM=GetSdrMarkByIndex(nm); 740 SdrObject* pObj=pM->GetMarkedSdrObj(); 741 //const SdrPageView* pPV=pM->GetPageView(); 742 if( bUndo ) 743 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); 744 745 pObj->ApplyNotPersistAttr(rAttr); 746 } 747 } 748 749 void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet& rAttr, sal_Bool /*bOnlyHardAttr*/) const 750 { 751 // bOnlyHardAttr hat hier keinerlei Wirkung 752 // Hier muss ausserdem noch der Nullpunkt und 753 // die PvPos berueksichtigt werden. 754 Rectangle aAllSnapRect(GetMarkedObjRect()); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!! 755 long nAllSnapPosX=aAllSnapRect.Left(); 756 long nAllSnapPosY=aAllSnapRect.Top(); 757 long nAllSnapWdt=aAllSnapRect.GetWidth()-1; 758 long nAllSnapHgt=aAllSnapRect.GetHeight()-1; 759 // koennte mal zu CheckPossibilities mit rein 760 sal_Bool bMovProtect=sal_False,bMovProtectDC=sal_False; 761 sal_Bool bSizProtect=sal_False,bSizProtectDC=sal_False; 762 sal_Bool bPrintable =sal_True ,bPrintableDC=sal_False; 763 sal_Bool bVisible = sal_True, bVisibleDC=sal_False; 764 SdrLayerID nLayerId=0; sal_Bool bLayerDC=sal_False; 765 XubString aObjName; sal_Bool bObjNameDC=sal_False,bObjNameSet=sal_False; 766 long nSnapPosX=0; sal_Bool bSnapPosXDC=sal_False; 767 long nSnapPosY=0; sal_Bool bSnapPosYDC=sal_False; 768 long nSnapWdt=0; sal_Bool bSnapWdtDC=sal_False; 769 long nSnapHgt=0; sal_Bool bSnapHgtDC=sal_False; 770 long nLogicWdt=0; sal_Bool bLogicWdtDC=sal_False,bLogicWdtDiff=sal_False; 771 long nLogicHgt=0; sal_Bool bLogicHgtDC=sal_False,bLogicHgtDiff=sal_False; 772 long nRotAngle=0; sal_Bool bRotAngleDC=sal_False; 773 long nShrAngle=0; sal_Bool bShrAngleDC=sal_False; 774 Rectangle aSnapRect; 775 Rectangle aLogicRect; 776 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 777 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) { 778 const SdrMark* pM=GetSdrMarkByIndex(nm); 779 const SdrObject* pObj=pM->GetMarkedSdrObj(); 780 if (nm==0) { 781 nLayerId=pObj->GetLayer(); 782 bMovProtect=pObj->IsMoveProtect(); 783 bSizProtect=pObj->IsResizeProtect(); 784 bPrintable =pObj->IsPrintable(); 785 bVisible = pObj->IsVisible(); 786 Rectangle aSnapRect2(pObj->GetSnapRect()); 787 Rectangle aLogicRect2(pObj->GetLogicRect()); 788 nSnapPosX=aSnapRect2.Left(); 789 nSnapPosY=aSnapRect2.Top(); 790 nSnapWdt=aSnapRect2.GetWidth()-1; 791 nSnapHgt=aSnapRect2.GetHeight()-1; 792 nLogicWdt=aLogicRect2.GetWidth()-1; 793 nLogicHgt=aLogicRect2.GetHeight()-1; 794 bLogicWdtDiff=nLogicWdt!=nSnapWdt; 795 bLogicHgtDiff=nLogicHgt!=nSnapHgt; 796 nRotAngle=pObj->GetRotateAngle(); 797 nShrAngle=pObj->GetShearAngle(); 798 } else { 799 if (!bLayerDC && nLayerId !=pObj->GetLayer()) bLayerDC=sal_True; 800 if (!bMovProtectDC && bMovProtect!=pObj->IsMoveProtect()) bMovProtectDC=sal_True; 801 if (!bSizProtectDC && bSizProtect!=pObj->IsResizeProtect()) bSizProtectDC=sal_True; 802 if (!bPrintableDC && bPrintable !=pObj->IsPrintable()) bPrintableDC=sal_True; 803 if (!bVisibleDC && bVisible !=pObj->IsVisible()) bVisibleDC=sal_True; 804 if (!bRotAngleDC && nRotAngle !=pObj->GetRotateAngle()) bRotAngleDC=sal_True; 805 if (!bShrAngleDC && nShrAngle !=pObj->GetShearAngle()) bShrAngleDC=sal_True; 806 if (!bSnapWdtDC || !bSnapHgtDC || !bSnapPosXDC || !bSnapPosYDC || !bLogicWdtDiff || !bLogicHgtDiff) { 807 aSnapRect=pObj->GetSnapRect(); 808 if (nSnapPosX!=aSnapRect.Left()) bSnapPosXDC=sal_True; 809 if (nSnapPosY!=aSnapRect.Top()) bSnapPosYDC=sal_True; 810 if (nSnapWdt!=aSnapRect.GetWidth()-1) bSnapWdtDC=sal_True; 811 if (nSnapHgt!=aSnapRect.GetHeight()-1) bSnapHgtDC=sal_True; 812 } 813 if (!bLogicWdtDC || !bLogicHgtDC || !bLogicWdtDiff || !bLogicHgtDiff) { 814 aLogicRect=pObj->GetLogicRect(); 815 if (nLogicWdt!=aLogicRect.GetWidth()-1) bLogicWdtDC=sal_True; 816 if (nLogicHgt!=aLogicRect.GetHeight()-1) bLogicHgtDC=sal_True; 817 if (!bLogicWdtDiff && aSnapRect.GetWidth()!=aLogicRect.GetWidth()) bLogicWdtDiff=sal_True; 818 if (!bLogicHgtDiff && aSnapRect.GetHeight()!=aLogicRect.GetHeight()) bLogicHgtDiff=sal_True; 819 } 820 } 821 if (!bObjNameDC ) { 822 if (!bObjNameSet) { 823 aObjName=pObj->GetName(); 824 } else { 825 if (aObjName!=pObj->GetName()) bObjNameDC=sal_True; 826 } 827 } 828 } 829 830 if (bSnapPosXDC || nAllSnapPosX!=nSnapPosX) rAttr.Put(SdrAllPositionXItem(nAllSnapPosX)); 831 if (bSnapPosYDC || nAllSnapPosY!=nSnapPosY) rAttr.Put(SdrAllPositionYItem(nAllSnapPosY)); 832 if (bSnapWdtDC || nAllSnapWdt !=nSnapWdt ) rAttr.Put(SdrAllSizeWidthItem(nAllSnapWdt)); 833 if (bSnapHgtDC || nAllSnapHgt !=nSnapHgt ) rAttr.Put(SdrAllSizeHeightItem(nAllSnapHgt)); 834 835 // Items fuer reine Transformationen 836 rAttr.Put(SdrMoveXItem()); 837 rAttr.Put(SdrMoveYItem()); 838 rAttr.Put(SdrResizeXOneItem()); 839 rAttr.Put(SdrResizeYOneItem()); 840 rAttr.Put(SdrRotateOneItem()); 841 rAttr.Put(SdrHorzShearOneItem()); 842 rAttr.Put(SdrVertShearOneItem()); 843 844 if (nMarkAnz>1) { 845 rAttr.Put(SdrResizeXAllItem()); 846 rAttr.Put(SdrResizeYAllItem()); 847 rAttr.Put(SdrRotateAllItem()); 848 rAttr.Put(SdrHorzShearAllItem()); 849 rAttr.Put(SdrVertShearAllItem()); 850 } 851 852 if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR) 853 { 854 rAttr.Put(SdrTransformRef1XItem(GetRef1().X())); 855 rAttr.Put(SdrTransformRef1YItem(GetRef1().Y())); 856 } 857 858 if(eDragMode == SDRDRAG_MIRROR) 859 { 860 rAttr.Put(SdrTransformRef2XItem(GetRef2().X())); 861 rAttr.Put(SdrTransformRef2YItem(GetRef2().Y())); 862 } 863 } 864 865 SfxItemSet SdrEditView::GetAttrFromMarked(sal_Bool bOnlyHardAttr) const 866 { 867 SfxItemSet aSet(pMod->GetItemPool()); 868 MergeAttrFromMarked(aSet,bOnlyHardAttr); 869 //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there) 870 //so we do not set them here 871 // #i32448# 872 // Do not disable, but clear the items. 873 aSet.ClearItem(EE_FEATURE_TAB); 874 aSet.ClearItem(EE_FEATURE_LINEBR); 875 aSet.ClearItem(EE_FEATURE_NOTCONV); 876 aSet.ClearItem(EE_FEATURE_FIELD); 877 return aSet; 878 } 879 880 void SdrEditView::MergeAttrFromMarked(SfxItemSet& rAttr, sal_Bool bOnlyHardAttr) const 881 { 882 sal_uInt32 nMarkAnz(GetMarkedObjectCount()); 883 884 for(sal_uInt32 a(0); a < nMarkAnz; a++) 885 { 886 // #80277# merging was done wrong in the prev version 887 //const SfxItemSet& rSet = GetMarkedObjectByIndex()->GetItemSet(); 888 const SfxItemSet& rSet = GetMarkedObjectByIndex(a)->GetMergedItemSet(); 889 SfxWhichIter aIter(rSet); 890 sal_uInt16 nWhich(aIter.FirstWhich()); 891 892 while(nWhich) 893 { 894 if(!bOnlyHardAttr) 895 { 896 if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False)) 897 rAttr.InvalidateItem(nWhich); 898 else 899 rAttr.MergeValue(rSet.Get(nWhich), sal_True); 900 } 901 else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False)) 902 { 903 const SfxPoolItem& rItem = rSet.Get(nWhich); 904 rAttr.MergeValue(rItem, sal_True); 905 } 906 907 nWhich = aIter.NextWhich(); 908 } 909 } 910 } 911 912 void SdrEditView::SetAttrToMarked(const SfxItemSet& rAttr, sal_Bool bReplaceAll) 913 { 914 if (AreObjectsMarked()) 915 { 916 #ifdef DBG_UTIL 917 { 918 sal_Bool bHasEEFeatureItems=sal_False; 919 SfxItemIter aIter(rAttr); 920 const SfxPoolItem* pItem=aIter.FirstItem(); 921 while (!bHasEEFeatureItems && pItem!=NULL) { 922 if (!IsInvalidItem(pItem)) { 923 sal_uInt16 nW=pItem->Which(); 924 if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=sal_True; 925 } 926 pItem=aIter.NextItem(); 927 } 928 if(bHasEEFeatureItems) 929 { 930 String aMessage; 931 aMessage.AppendAscii("SdrEditView::SetAttrToMarked(): Das setzen von EE_FEATURE-Items an der SdrView macht keinen Sinn! Es fuehrt nur zu Overhead und nicht mehr lesbaren Dokumenten."); 932 InfoBox(NULL, aMessage).Execute(); 933 } 934 } 935 #endif 936 937 // #103836# if the user thets character attributes to the complete shape, 938 // we want to remove all hard set character attributes with same 939 // which ids from the text. We do that later but here we remember 940 // all character attribute which id's that are set. 941 std::vector<sal_uInt16> aCharWhichIds; 942 { 943 SfxItemIter aIter(rAttr); 944 const SfxPoolItem* pItem=aIter.FirstItem(); 945 while( pItem!=NULL ) 946 { 947 if (!IsInvalidItem(pItem)) 948 { 949 sal_uInt16 nWhich = pItem->Which(); 950 if (nWhich>=EE_CHAR_START && nWhich<=EE_CHAR_END) 951 aCharWhichIds.push_back( nWhich ); 952 } 953 pItem=aIter.NextItem(); 954 } 955 } 956 957 // Joe, 2.7.98: Damit Undo nach Format.Standard auch die Textattribute korrekt restauriert 958 sal_Bool bHasEEItems=SearchOutlinerItems(rAttr,bReplaceAll); 959 960 // AW 030100: save additional geom info when para or char attributes 961 // are changed and the geom form of the text object might be changed 962 sal_Bool bPossibleGeomChange(sal_False); 963 SfxWhichIter aIter(rAttr); 964 sal_uInt16 nWhich = aIter.FirstWhich(); 965 while(!bPossibleGeomChange && nWhich) 966 { 967 SfxItemState eState = rAttr.GetItemState(nWhich); 968 if(eState == SFX_ITEM_SET) 969 { 970 if((nWhich >= SDRATTR_TEXT_MINFRAMEHEIGHT && nWhich <= SDRATTR_TEXT_CONTOURFRAME) 971 || nWhich == SDRATTR_3DOBJ_PERCENT_DIAGONAL 972 || nWhich == SDRATTR_3DOBJ_BACKSCALE 973 || nWhich == SDRATTR_3DOBJ_DEPTH 974 || nWhich == SDRATTR_3DOBJ_END_ANGLE 975 || nWhich == SDRATTR_3DSCENE_DISTANCE) 976 { 977 bPossibleGeomChange = sal_True; 978 } 979 } 980 nWhich = aIter.NextWhich(); 981 } 982 983 const bool bUndo = IsUndoEnabled(); 984 if( bUndo ) 985 { 986 XubString aStr; 987 ImpTakeDescriptionStr(STR_EditSetAttributes,aStr); 988 BegUndo(aStr); 989 } 990 991 const sal_uInt32 nMarkAnz(GetMarkedObjectCount()); 992 std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; 993 994 // create ItemSet without SFX_ITEM_DONTCARE. Put() 995 // uses it's second parameter (bInvalidAsDefault) to 996 // remove all such items to set them to default. 997 SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges()); 998 aAttr.Put(rAttr, sal_True); 999 1000 // #i38135# 1001 bool bResetAnimationTimer(false); 1002 1003 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 1004 { 1005 SdrMark* pM=GetSdrMarkByIndex(nm); 1006 SdrObject* pObj = pM->GetMarkedSdrObj(); 1007 1008 if( bUndo ) 1009 { 1010 std::vector< SdrUndoAction* > vConnectorUndoActions; 1011 SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >( pObj ); 1012 if ( pEdgeObj ) 1013 bPossibleGeomChange = sal_True; 1014 else if( bUndo ) 1015 vConnectorUndoActions = CreateConnectorUndo( *pObj ); 1016 1017 AddUndoActions( vConnectorUndoActions ); 1018 } 1019 1020 // new geometry undo 1021 if(bPossibleGeomChange && bUndo) 1022 { 1023 // save position and size of obect, too 1024 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); 1025 } 1026 1027 if( bUndo ) 1028 { 1029 // #i8508# 1030 // If this is a text object also rescue the OutlinerParaObject since 1031 // applying attributes to the object may change text layout when 1032 // multiple portions exist with multiple formats. If a OutlinerParaObject 1033 // really exists and needs to be rescued is evaluated in the undo 1034 // implementation itself. 1035 const bool bRescueText = dynamic_cast< SdrTextObj* >(pObj) != 0; 1036 1037 // add attribute undo 1038 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj,sal_False,bHasEEItems || bPossibleGeomChange || bRescueText)); 1039 } 1040 1041 // set up a scxene updater if object is a 3d object 1042 if(dynamic_cast< E3dObject* >(pObj)) 1043 { 1044 aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj)); 1045 } 1046 1047 // set attributes at object 1048 pObj->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll); 1049 1050 if(pObj->ISA(SdrTextObj)) 1051 { 1052 SdrTextObj* pTextObj = ((SdrTextObj*)pObj); 1053 1054 if(!aCharWhichIds.empty()) 1055 { 1056 Rectangle aOldBoundRect = pTextObj->GetLastBoundRect(); 1057 1058 // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect()); 1059 pTextObj->RemoveOutlinerCharacterAttribs( aCharWhichIds ); 1060 1061 // object has changed, should be called form 1062 // RemoveOutlinerCharacterAttribs. This will change when the text 1063 // object implementation changes. 1064 pTextObj->SetChanged(); 1065 1066 pTextObj->BroadcastObjectChange(); 1067 pTextObj->SendUserCall(SDRUSERCALL_CHGATTR, aOldBoundRect); 1068 } 1069 } 1070 1071 // #i38495# 1072 if(!bResetAnimationTimer) 1073 { 1074 if(pObj->GetViewContact().isAnimatedInAnyViewObjectContact()) 1075 { 1076 bResetAnimationTimer = true; 1077 } 1078 } 1079 } 1080 1081 // fire scene updaters 1082 while(!aUpdaters.empty()) 1083 { 1084 delete aUpdaters.back(); 1085 aUpdaters.pop_back(); 1086 } 1087 1088 // #i38135# 1089 if(bResetAnimationTimer) 1090 { 1091 SetAnimationTimer(0L); 1092 } 1093 1094 // besser vorher checken, was gemacht werden soll: 1095 // pObj->SetAttr() oder SetNotPersistAttr() 1096 // !!! fehlende Implementation !!! 1097 SetNotPersistAttrToMarked(rAttr,bReplaceAll); 1098 1099 if( bUndo ) 1100 EndUndo(); 1101 } 1102 } 1103 1104 SfxStyleSheet* SdrEditView::GetStyleSheetFromMarked() const 1105 { 1106 SfxStyleSheet* pRet=NULL; 1107 sal_Bool b1st=sal_True; 1108 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 1109 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) { 1110 SdrMark* pM=GetSdrMarkByIndex(nm); 1111 SfxStyleSheet* pSS=pM->GetMarkedSdrObj()->GetStyleSheet(); 1112 if (b1st) pRet=pSS; 1113 else if (pRet!=pSS) return NULL; // verschiedene StyleSheets 1114 b1st=sal_False; 1115 } 1116 return pRet; 1117 } 1118 1119 void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr) 1120 { 1121 if (AreObjectsMarked()) 1122 { 1123 const bool bUndo = IsUndoEnabled(); 1124 1125 if( bUndo ) 1126 { 1127 XubString aStr; 1128 if (pStyleSheet!=NULL) 1129 ImpTakeDescriptionStr(STR_EditSetStylesheet,aStr); 1130 else 1131 ImpTakeDescriptionStr(STR_EditDelStylesheet,aStr); 1132 BegUndo(aStr); 1133 } 1134 1135 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 1136 for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) 1137 { 1138 SdrMark* pM=GetSdrMarkByIndex(nm); 1139 if( bUndo ) 1140 { 1141 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pM->GetMarkedSdrObj())); 1142 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM->GetMarkedSdrObj(),true,true)); 1143 } 1144 pM->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); 1145 } 1146 1147 if( bUndo ) 1148 EndUndo(); 1149 } 1150 } 1151 1152 //////////////////////////////////////////////////////////////////////////////////////////////////// 1153 1154 /* new interface src537 */ 1155 sal_Bool SdrEditView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const 1156 { 1157 if(GetMarkedObjectCount()) 1158 { 1159 rTargetSet.Put(GetAttrFromMarked(bOnlyHardAttr), sal_False); 1160 return sal_True; 1161 } 1162 else 1163 { 1164 return SdrMarkView::GetAttributes(rTargetSet, bOnlyHardAttr); 1165 } 1166 } 1167 1168 sal_Bool SdrEditView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll) 1169 { 1170 if (GetMarkedObjectCount()!=0) { 1171 SetAttrToMarked(rSet,bReplaceAll); 1172 return sal_True; 1173 } else { 1174 return SdrMarkView::SetAttributes(rSet,bReplaceAll); 1175 } 1176 } 1177 1178 SfxStyleSheet* SdrEditView::GetStyleSheet() const // SfxStyleSheet* SdrEditView::GetStyleSheet(sal_Bool& rOk) const 1179 { 1180 if (GetMarkedObjectCount()!=0) { 1181 //rOk=sal_True; 1182 return GetStyleSheetFromMarked(); 1183 } else { 1184 return SdrMarkView::GetStyleSheet(); // SdrMarkView::GetStyleSheet(rOk); 1185 } 1186 } 1187 1188 sal_Bool SdrEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr) 1189 { 1190 if (GetMarkedObjectCount()!=0) { 1191 SetStyleSheetToMarked(pStyleSheet,bDontRemoveHardAttr); 1192 return sal_True; 1193 } else { 1194 return SdrMarkView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); 1195 } 1196 } 1197 1198 //////////////////////////////////////////////////////////////////////////////////////////////////// 1199 1200 SfxItemSet SdrEditView::GetGeoAttrFromMarked() const 1201 { 1202 SfxItemSet aRetSet(pMod->GetItemPool(), // SID_ATTR_TRANSFORM_... aus s:svxids.hrc 1203 SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE, 1204 SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT, 1205 SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS, 1206 0); 1207 if (AreObjectsMarked()) { 1208 SfxItemSet aMarkAttr(GetAttrFromMarked(sal_False)); // wg. AutoGrowHeight und Eckenradius 1209 Rectangle aRect(GetMarkedObjRect()); 1210 1211 if(GetSdrPageView()) 1212 { 1213 GetSdrPageView()->LogicToPagePos(aRect); 1214 } 1215 1216 // Position 1217 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X,aRect.Left())); 1218 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y,aRect.Top())); 1219 1220 // Groesse 1221 long nResizeRefX=aRect.Left(); 1222 long nResizeRefY=aRect.Top(); 1223 if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Resize 1224 nResizeRefX=aRef1.X(); 1225 nResizeRefY=aRef1.Y(); 1226 } 1227 aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH,aRect.Right()-aRect.Left())); 1228 aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT,aRect.Bottom()-aRect.Top())); 1229 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X,nResizeRefX)); 1230 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y,nResizeRefY)); 1231 1232 Point aRotateAxe(aRef1); 1233 1234 if(GetSdrPageView()) 1235 { 1236 GetSdrPageView()->LogicToPagePos(aRotateAxe); 1237 } 1238 1239 // Drehung 1240 long nRotateRefX=aRect.Center().X(); 1241 long nRotateRefY=aRect.Center().Y(); 1242 if (eDragMode==SDRDRAG_ROTATE) { 1243 nRotateRefX=aRotateAxe.X(); 1244 nRotateRefY=aRotateAxe.Y(); 1245 } 1246 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE,GetMarkedObjRotate())); 1247 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X,nRotateRefX)); 1248 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y,nRotateRefY)); 1249 1250 // Shear 1251 long nShearRefX=aRect.Left(); 1252 long nShearRefY=aRect.Bottom(); 1253 if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Shear 1254 nShearRefX=aRotateAxe.X(); 1255 nShearRefY=aRotateAxe.Y(); 1256 } 1257 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR,GetMarkedObjShear())); 1258 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X,nShearRefX)); 1259 aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y,nShearRefY)); 1260 1261 // Pruefen der einzelnen Objekte, ob Objekte geschuetzt sind 1262 const SdrMarkList& rMarkList=GetMarkedObjectList(); 1263 sal_uIntPtr nMarkCount=rMarkList.GetMarkCount(); 1264 SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj(); 1265 sal_Bool bPosProt=pObj->IsMoveProtect(); 1266 sal_Bool bSizProt=pObj->IsResizeProtect(); 1267 sal_Bool bPosProtDontCare=sal_False; 1268 sal_Bool bSizProtDontCare=sal_False; 1269 for (sal_uIntPtr i=1; i<nMarkCount && (!bPosProtDontCare || !bSizProtDontCare); i++) { 1270 pObj=rMarkList.GetMark(i)->GetMarkedSdrObj(); 1271 if (bPosProt!=pObj->IsMoveProtect()) bPosProtDontCare=sal_True; 1272 if (bSizProt!=pObj->IsResizeProtect()) bSizProtDontCare=sal_True; 1273 } 1274 1275 // InvalidateItem setzt das Item auf DONT_CARE 1276 if (bPosProtDontCare) { 1277 aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS); 1278 } else { 1279 aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS,bPosProt)); 1280 } 1281 if (bSizProtDontCare) { 1282 aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE); 1283 } else { 1284 aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE,bSizProt)); 1285 } 1286 1287 SfxItemState eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH); 1288 sal_Bool bAutoGrow=((SdrTextAutoGrowWidthItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue(); 1289 if (eState==SFX_ITEM_DONTCARE) { 1290 aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH); 1291 } else if (eState==SFX_ITEM_SET) { 1292 aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH,bAutoGrow)); 1293 } 1294 1295 eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT); 1296 bAutoGrow=((SdrTextAutoGrowHeightItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue(); 1297 if (eState==SFX_ITEM_DONTCARE) { 1298 aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT); 1299 } else if (eState==SFX_ITEM_SET) { 1300 aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT,bAutoGrow)); 1301 } 1302 1303 eState=aMarkAttr.GetItemState(SDRATTR_ECKENRADIUS); 1304 long nRadius=((SdrEckenradiusItem&)(aMarkAttr.Get(SDRATTR_ECKENRADIUS))).GetValue(); 1305 if (eState==SFX_ITEM_DONTCARE) { 1306 aRetSet.InvalidateItem(SDRATTR_ECKENRADIUS); 1307 } else if (eState==SFX_ITEM_SET) { 1308 aRetSet.Put(SdrEckenradiusItem(nRadius)); 1309 } 1310 1311 } 1312 return aRetSet; 1313 } 1314 1315 Point ImpGetPoint(Rectangle aRect, RECT_POINT eRP) 1316 { 1317 switch(eRP) { 1318 case RP_LT: return aRect.TopLeft(); 1319 case RP_MT: return aRect.TopCenter(); 1320 case RP_RT: return aRect.TopRight(); 1321 case RP_LM: return aRect.LeftCenter(); 1322 case RP_MM: return aRect.Center(); 1323 case RP_RM: return aRect.RightCenter(); 1324 case RP_LB: return aRect.BottomLeft(); 1325 case RP_MB: return aRect.BottomCenter(); 1326 case RP_RB: return aRect.BottomRight(); 1327 } 1328 return Point(); // Sollte nicht vorkommen ! 1329 } 1330 1331 void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr) 1332 { 1333 Rectangle aRect(GetMarkedObjRect()); 1334 1335 if(GetSdrPageView()) 1336 { 1337 GetSdrPageView()->LogicToPagePos(aRect); 1338 } 1339 1340 long nOldRotateAngle=GetMarkedObjRotate(); 1341 long nOldShearAngle=GetMarkedObjShear(); 1342 const SdrMarkList& rMarkList=GetMarkedObjectList(); 1343 sal_uIntPtr nMarkCount=rMarkList.GetMarkCount(); 1344 SdrObject* pObj=NULL; 1345 1346 RECT_POINT eSizePoint=RP_MM; 1347 long nPosDX=0; 1348 long nPosDY=0; 1349 long nSizX=0; 1350 long nSizY=0; 1351 long nRotateAngle=0; 1352 1353 // #86909# 1354 sal_Bool bModeIsRotate(eDragMode == SDRDRAG_ROTATE); 1355 long nRotateX(0); 1356 long nRotateY(0); 1357 long nOldRotateX(0); 1358 long nOldRotateY(0); 1359 if(bModeIsRotate) 1360 { 1361 Point aRotateAxe(aRef1); 1362 1363 if(GetSdrPageView()) 1364 { 1365 GetSdrPageView()->LogicToPagePos(aRotateAxe); 1366 } 1367 1368 nRotateX = nOldRotateX = aRotateAxe.X(); 1369 nRotateY = nOldRotateY = aRotateAxe.Y(); 1370 } 1371 1372 long nNewShearAngle=0; 1373 long nShearAngle=0; 1374 long nShearX=0; 1375 long nShearY=0; 1376 sal_Bool bShearVert=sal_False; 1377 1378 sal_Bool bChgPos=sal_False; 1379 sal_Bool bChgSiz=sal_False; 1380 sal_Bool bChgHgt=sal_False; 1381 sal_Bool bRotate=sal_False; 1382 sal_Bool bShear =sal_False; 1383 1384 sal_Bool bSetAttr=sal_False; 1385 SfxItemSet aSetAttr(pMod->GetItemPool()); 1386 1387 const SfxPoolItem* pPoolItem=NULL; 1388 1389 // Position 1390 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_X,sal_True,&pPoolItem)) { 1391 nPosDX=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Left(); 1392 bChgPos=sal_True; 1393 } 1394 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_Y,sal_True,&pPoolItem)){ 1395 nPosDY=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Top(); 1396 bChgPos=sal_True; 1397 } 1398 // Groesse 1399 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_WIDTH,sal_True,&pPoolItem)) { 1400 nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue(); 1401 bChgSiz=sal_True; 1402 } 1403 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,sal_True,&pPoolItem)) { 1404 nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue(); 1405 bChgSiz=sal_True; 1406 bChgHgt=sal_True; 1407 } 1408 if (bChgSiz) { 1409 eSizePoint=(RECT_POINT)((const SfxAllEnumItem&)rAttr.Get(SID_ATTR_TRANSFORM_SIZE_POINT)).GetValue(); 1410 } 1411 1412 // Rotation 1413 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE,sal_True,&pPoolItem)) { 1414 nRotateAngle=((const SfxInt32Item*)pPoolItem)->GetValue()-nOldRotateAngle; 1415 bRotate = (nRotateAngle != 0); 1416 } 1417 1418 // #86909# pos rot point x 1419 if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_X, sal_True ,&pPoolItem)) 1420 nRotateX = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_X)).GetValue(); 1421 1422 // #86909# pos rot point y 1423 if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_Y, sal_True ,&pPoolItem)) 1424 nRotateY = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_Y)).GetValue(); 1425 1426 // Shear 1427 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR,sal_True,&pPoolItem)) { 1428 nNewShearAngle=((const SfxInt32Item*)pPoolItem)->GetValue(); 1429 if (nNewShearAngle>SDRMAXSHEAR) nNewShearAngle=SDRMAXSHEAR; 1430 if (nNewShearAngle<-SDRMAXSHEAR) nNewShearAngle=-SDRMAXSHEAR; 1431 if (nNewShearAngle!=nOldShearAngle) { 1432 bShearVert=((const SfxBoolItem&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL)).GetValue(); 1433 if (bShearVert) { 1434 nShearAngle=nNewShearAngle; 1435 } else { 1436 if (nNewShearAngle!=0 && nOldShearAngle!=0) { 1437 // Bugfix #25714#. 1438 double nOld=tan((double)nOldShearAngle*nPi180); 1439 double nNew=tan((double)nNewShearAngle*nPi180); 1440 nNew-=nOld; 1441 nNew=atan(nNew)/nPi180; 1442 nShearAngle=Round(nNew); 1443 } else { 1444 nShearAngle=nNewShearAngle-nOldShearAngle; 1445 } 1446 } 1447 bShear=nShearAngle!=0; 1448 if (bShear) { 1449 nShearX=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_X)).GetValue(); 1450 nShearY=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_Y)).GetValue(); 1451 } 1452 } 1453 } 1454 1455 // AutoGrow 1456 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOWIDTH,sal_True,&pPoolItem)) { 1457 sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue(); 1458 aSetAttr.Put(SdrTextAutoGrowWidthItem(bAutoGrow)); 1459 bSetAttr=sal_True; 1460 } 1461 1462 if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOHEIGHT,sal_True,&pPoolItem)) { 1463 sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue(); 1464 aSetAttr.Put(SdrTextAutoGrowHeightItem(bAutoGrow)); 1465 bSetAttr=sal_True; 1466 } 1467 1468 // Eckenradius 1469 if (bEdgeRadiusAllowed && SFX_ITEM_SET==rAttr.GetItemState(SDRATTR_ECKENRADIUS,sal_True,&pPoolItem)) { 1470 long nRadius=((SdrEckenradiusItem*)pPoolItem)->GetValue(); 1471 aSetAttr.Put(SdrEckenradiusItem(nRadius)); 1472 bSetAttr=sal_True; 1473 } 1474 1475 ForcePossibilities(); 1476 1477 BegUndo(ImpGetResStr(STR_EditTransform),GetDescriptionOfMarkedObjects()); 1478 1479 if (bSetAttr) { 1480 SetAttrToMarked(aSetAttr,sal_False); 1481 } 1482 1483 // Groesse und Hoehe aendern 1484 if (bChgSiz && (bResizeFreeAllowed || bResizePropAllowed)) { 1485 Fraction aWdt(nSizX,aRect.Right()-aRect.Left()); 1486 Fraction aHgt(nSizY,aRect.Bottom()-aRect.Top()); 1487 Point aRef(ImpGetPoint(aRect,eSizePoint)); 1488 1489 if(GetSdrPageView()) 1490 { 1491 GetSdrPageView()->PagePosToLogic(aRef); 1492 } 1493 1494 ResizeMarkedObj(aRef,aWdt,aHgt); 1495 } 1496 1497 // Rotieren 1498 if (bRotate && (bRotateFreeAllowed || bRotate90Allowed)) { 1499 Point aRef(nRotateX,nRotateY); 1500 1501 if(GetSdrPageView()) 1502 { 1503 GetSdrPageView()->PagePosToLogic(aRef); 1504 } 1505 1506 RotateMarkedObj(aRef,nRotateAngle); 1507 } 1508 1509 // #86909# set rotation point position 1510 if(bModeIsRotate && (nRotateX != nOldRotateX || nRotateY != nOldRotateY)) 1511 { 1512 Point aNewRef1(nRotateX, nRotateY); 1513 1514 if(GetSdrPageView()) 1515 { 1516 GetSdrPageView()->PagePosToLogic(aNewRef1); 1517 } 1518 1519 SetRef1(aNewRef1); 1520 } 1521 1522 // Shear 1523 if (bShear && bShearAllowed) { 1524 Point aRef(nShearX,nShearY); 1525 1526 if(GetSdrPageView()) 1527 { 1528 GetSdrPageView()->PagePosToLogic(aRef); 1529 } 1530 1531 ShearMarkedObj(aRef,nShearAngle,bShearVert); 1532 1533 // #i74358# 1534 // ShearMarkedObj creates a linear combination of the existing transformation and 1535 // the new shear to apply. If the object is already transformed (e.g. rotated) the 1536 // linear combination will not decompose to the same start values again, but to a 1537 // new combination. Thus it makes no sense to check if the wanted shear is reached 1538 // or not. Taking out. 1539 #if 0 1540 long nTempAngle=GetMarkedObjShear(); 1541 if (nTempAngle!=0 && nTempAngle!=nNewShearAngle && !bShearVert) { 1542 // noch eine 2. Iteration zur Kompensation der Rundungsfehler 1543 double nOld=tan((double)nTempAngle*nPi180); 1544 double nNew=tan((double)nNewShearAngle*nPi180); 1545 nNew-=nOld; 1546 nNew=atan(nNew)/nPi180; 1547 nTempAngle=Round(nNew); 1548 if (nTempAngle!=0) { 1549 ShearMarkedObj(aRef,nTempAngle,bShearVert); 1550 } 1551 } 1552 #endif 1553 } 1554 1555 // Position aendern 1556 if (bChgPos && bMoveAllowed) { 1557 MoveMarkedObj(Size(nPosDX,nPosDY)); 1558 } 1559 1560 // protect position 1561 if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POS, sal_True, &pPoolItem)) 1562 { 1563 const sal_Bool bProtPos(((const SfxBoolItem*)pPoolItem)->GetValue()); 1564 bool bChanged(false); 1565 1566 for(sal_uInt32 i(0); i < nMarkCount; i++) 1567 { 1568 pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); 1569 1570 if(pObj->IsMoveProtect() != bProtPos) 1571 { 1572 bChanged = true; 1573 pObj->SetMoveProtect(bProtPos); 1574 1575 if(bProtPos) 1576 { 1577 pObj->SetResizeProtect(true); 1578 } 1579 } 1580 } 1581 1582 if(bChanged) 1583 { 1584 bMoveProtect = bProtPos; 1585 1586 if(bProtPos) 1587 { 1588 bResizeProtect = true; 1589 } 1590 1591 // #i77187# there is no simple method to get the toolbars updated 1592 // in the application. The App is listening to selection change and i 1593 // will use it here (even if not true). It's acceptable since changing 1594 // this model data is pretty rare and only possible using the F4 dialog 1595 MarkListHasChanged(); 1596 } 1597 } 1598 1599 if(!bMoveProtect) 1600 { 1601 // protect size 1602 if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_SIZE, sal_True, &pPoolItem)) 1603 { 1604 const sal_Bool bProtSize(((const SfxBoolItem*)pPoolItem)->GetValue()); 1605 bool bChanged(false); 1606 1607 for(sal_uInt32 i(0); i < nMarkCount; i++) 1608 { 1609 pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); 1610 1611 if(pObj->IsResizeProtect() != bProtSize) 1612 { 1613 bChanged = true; 1614 pObj->SetResizeProtect(bProtSize); 1615 } 1616 } 1617 1618 if(bChanged) 1619 { 1620 bResizeProtect = bProtSize; 1621 1622 // #i77187# see above 1623 MarkListHasChanged(); 1624 } 1625 } 1626 } 1627 1628 EndUndo(); 1629 } 1630 1631 //////////////////////////////////////////////////////////////////////////////////////////////////// 1632 1633 sal_Bool SdrEditView::IsAlignPossible() const 1634 { // Mindestens 2 markierte Objekte, davon mind. 1 beweglich 1635 ForcePossibilities(); 1636 sal_uIntPtr nAnz=GetMarkedObjectCount(); 1637 if (nAnz==0) return sal_False; // Nix markiert! 1638 if (nAnz==1) return bMoveAllowed; // einzelnes Obj an der Seite ausrichten 1639 return bOneOrMoreMovable; // ansonsten ist MarkCount>=2 1640 } 1641 1642 void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor, SdrVertAlign eVert, sal_Bool bBoundRects) 1643 { 1644 if (eHor==SDRHALIGN_NONE && eVert==SDRVALIGN_NONE) 1645 return; 1646 1647 SortMarkedObjects(); 1648 if (GetMarkedObjectCount()<1) 1649 return; 1650 1651 const bool bUndo = IsUndoEnabled(); 1652 if( bUndo ) 1653 { 1654 XubString aStr(GetDescriptionOfMarkedObjects()); 1655 if (eHor==SDRHALIGN_NONE) 1656 { 1657 switch (eVert) 1658 { 1659 case SDRVALIGN_TOP : ImpTakeDescriptionStr(STR_EditAlignVTop ,aStr); break; 1660 case SDRVALIGN_BOTTOM: ImpTakeDescriptionStr(STR_EditAlignVBottom,aStr); break; 1661 case SDRVALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignVCenter,aStr); break; 1662 default: break; 1663 } 1664 } 1665 else if (eVert==SDRVALIGN_NONE) 1666 { 1667 switch (eHor) 1668 { 1669 case SDRHALIGN_LEFT : ImpTakeDescriptionStr(STR_EditAlignHLeft ,aStr); break; 1670 case SDRHALIGN_RIGHT : ImpTakeDescriptionStr(STR_EditAlignHRight ,aStr); break; 1671 case SDRHALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignHCenter,aStr); break; 1672 default: break; 1673 } 1674 } 1675 else if (eHor==SDRHALIGN_CENTER && eVert==SDRVALIGN_CENTER) 1676 { 1677 ImpTakeDescriptionStr(STR_EditAlignCenter,aStr); 1678 } 1679 else 1680 { 1681 ImpTakeDescriptionStr(STR_EditAlign,aStr); 1682 } 1683 BegUndo(aStr); 1684 } 1685 1686 Rectangle aBound; 1687 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 1688 sal_uIntPtr nm; 1689 sal_Bool bHasFixed=sal_False; 1690 for (nm=0; nm<nMarkAnz; nm++) 1691 { 1692 SdrMark* pM=GetSdrMarkByIndex(nm); 1693 SdrObject* pObj=pM->GetMarkedSdrObj(); 1694 SdrObjTransformInfoRec aInfo; 1695 pObj->TakeObjInfo(aInfo); 1696 if (!aInfo.bMoveAllowed || pObj->IsMoveProtect()) 1697 { 1698 Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect()); 1699 aBound.Union(aObjRect); 1700 bHasFixed=sal_True; 1701 } 1702 } 1703 if (!bHasFixed) 1704 { 1705 if (nMarkAnz==1) 1706 { // einzelnes Obj an der Seite ausrichten 1707 const SdrObject* pObj=GetMarkedObjectByIndex(0L); 1708 const SdrPage* pPage=pObj->GetPage(); 1709 const SdrPageGridFrameList* pGFL=pPage->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj->GetSnapRect())); 1710 const SdrPageGridFrame* pFrame=NULL; 1711 if (pGFL!=NULL && pGFL->GetCount()!=0) 1712 { // Writer 1713 pFrame=&((*pGFL)[0]); 1714 } 1715 1716 if (pFrame!=NULL) 1717 { // Writer 1718 aBound=pFrame->GetUserArea(); 1719 } 1720 else 1721 { 1722 aBound=Rectangle(pPage->GetLftBorder(),pPage->GetUppBorder(), 1723 pPage->GetWdt()-pPage->GetRgtBorder(), 1724 pPage->GetHgt()-pPage->GetLwrBorder()); 1725 } 1726 } 1727 else 1728 { 1729 if (bBoundRects) 1730 aBound=GetMarkedObjBoundRect(); 1731 else 1732 aBound=GetMarkedObjRect(); 1733 } 1734 } 1735 Point aCenter(aBound.Center()); 1736 for (nm=0; nm<nMarkAnz; nm++) 1737 { 1738 SdrMark* pM=GetSdrMarkByIndex(nm); 1739 SdrObject* pObj=pM->GetMarkedSdrObj(); 1740 SdrObjTransformInfoRec aInfo; 1741 pObj->TakeObjInfo(aInfo); 1742 if (aInfo.bMoveAllowed && !pObj->IsMoveProtect()) 1743 { 1744 // SdrPageView* pPV=pM->GetPageView(); 1745 long nXMov=0; 1746 long nYMov=0; 1747 Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect()); 1748 switch (eVert) 1749 { 1750 case SDRVALIGN_TOP : nYMov=aBound.Top() -aObjRect.Top() ; break; 1751 case SDRVALIGN_BOTTOM: nYMov=aBound.Bottom()-aObjRect.Bottom() ; break; 1752 case SDRVALIGN_CENTER: nYMov=aCenter.Y() -aObjRect.Center().Y(); break; 1753 default: break; 1754 } 1755 switch (eHor) 1756 { 1757 case SDRHALIGN_LEFT : nXMov=aBound.Left() -aObjRect.Left() ; break; 1758 case SDRHALIGN_RIGHT : nXMov=aBound.Right() -aObjRect.Right() ; break; 1759 case SDRHALIGN_CENTER: nXMov=aCenter.X() -aObjRect.Center().X(); break; 1760 default: break; 1761 } 1762 if (nXMov!=0 || nYMov!=0) 1763 { 1764 // #104104# SdrEdgeObj needs an extra SdrUndoGeoObj since the 1765 // connections may need to be saved 1766 if( bUndo ) 1767 { 1768 if( dynamic_cast<SdrEdgeObj*>(pObj) ) 1769 { 1770 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); 1771 } 1772 1773 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,Size(nXMov,nYMov))); 1774 } 1775 1776 pObj->Move(Size(nXMov,nYMov)); 1777 } 1778 } 1779 } 1780 1781 if( bUndo ) 1782 EndUndo(); 1783 } 1784 1785