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