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