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