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