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/svdmrkv.hxx> 28 #include <svx/svdetc.hxx> 29 #include <svx/svdoedge.hxx> 30 #include "svx/svdglob.hxx" 31 #include "svx/svditext.hxx" 32 #include <svx/svdview.hxx> 33 #include <svx/svdpagv.hxx> 34 #include <svx/svdpage.hxx> 35 #include "svddrgm1.hxx" 36 37 #ifdef DBG_UTIL 38 #include <svdibrow.hxx> 39 #endif 40 41 #include <svx/svdoole2.hxx> 42 #include <svx/xgrad.hxx> 43 #include <svx/xflgrit.hxx> 44 #include "gradtrns.hxx" 45 #include <svx/xflftrit.hxx> 46 #include <svx/dialmgr.hxx> 47 #include "svx/svdstr.hrc" 48 #include <svx/svdundo.hxx> 49 #include <svx/svdopath.hxx> 50 #include <svx/scene3d.hxx> 51 #include <svx/svdovirt.hxx> 52 #include <svx/sdr/overlay/overlayrollingrectangle.hxx> 53 #include <svx/sdr/overlay/overlaymanager.hxx> 54 #include <svx/sdrpaintwindow.hxx> 55 #include <svx/sdrpagewindow.hxx> 56 #include <svx/sdrhittesthelper.hxx> 57 #include <svx/svdocapt.hxx> 58 #include <svx/svdograf.hxx> 59 60 //////////////////////////////////////////////////////////////////////////////////////////////////// 61 // predefines 62 63 class SdrUnoControlList; 64 65 //////////////////////////////////////////////////////////////////////////////////////////////////// 66 // #114409#-3 Migrate Marking of Objects, Points and GluePoints 67 68 class ImplMarkingOverlay 69 { 70 // The OverlayObjects 71 ::sdr::overlay::OverlayObjectList maObjects; 72 73 // The remembered second position in logical coodinates 74 basegfx::B2DPoint maSecondPosition; 75 76 // bitfield 77 // A flag to remember if the action is for unmarking. 78 unsigned mbUnmarking : 1; 79 80 public: 81 ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking = sal_False); 82 ~ImplMarkingOverlay(); 83 84 void SetSecondPosition(const basegfx::B2DPoint& rNewPosition); 85 sal_Bool IsUnmarking() const { return mbUnmarking; } 86 }; 87 88 ImplMarkingOverlay::ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking) 89 : maSecondPosition(rStartPos), 90 mbUnmarking(bUnmarking) 91 { 92 for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++) 93 { 94 SdrPaintWindow* pCandidate = rView.GetPaintWindow(a); 95 ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager(); 96 97 if(pTargetOverlay) 98 { 99 ::sdr::overlay::OverlayRollingRectangleStriped* pNew = new ::sdr::overlay::OverlayRollingRectangleStriped( 100 rStartPos, rStartPos, false); 101 pTargetOverlay->add(*pNew); 102 maObjects.append(*pNew); 103 } 104 } 105 } 106 107 ImplMarkingOverlay::~ImplMarkingOverlay() 108 { 109 // The OverlayObjects are cleared using the destructor of OverlayObjectList. 110 // That destructor calls clear() at the list which removes all objects from the 111 // OverlayManager and deletes them. 112 } 113 114 void ImplMarkingOverlay::SetSecondPosition(const basegfx::B2DPoint& rNewPosition) 115 { 116 if(rNewPosition != maSecondPosition) 117 { 118 // apply to OverlayObjects 119 for(sal_uInt32 a(0L); a < maObjects.count(); a++) 120 { 121 ::sdr::overlay::OverlayRollingRectangleStriped& rCandidate = (::sdr::overlay::OverlayRollingRectangleStriped&)maObjects.getOverlayObject(a); 122 rCandidate.setSecondPosition(rNewPosition); 123 } 124 125 // remember new position 126 maSecondPosition = rNewPosition; 127 } 128 } 129 130 //////////////////////////////////////////////////////////////////////////////////////////////////// 131 //////////////////////////////////////////////////////////////////////////////////////////////////// 132 // 133 // @@ @@ @@@@ @@@@@ @@ @@ @@ @@ @@ @@@@@ @@ @@ 134 // @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ 135 // @@@@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@ 136 // @@@@@@@ @@@@@@ @@@@@ @@@@ @@@@@ @@ @@@@ @@@@@@@ 137 // @@ @ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@ 138 // @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@ 139 // @@ @@ @@ @@ @@ @@ @@ @@ @ @@ @@@@@ @@ @@ 140 // 141 //////////////////////////////////////////////////////////////////////////////////////////////////// 142 //////////////////////////////////////////////////////////////////////////////////////////////////// 143 144 void SdrMarkView::ImpClearVars() 145 { 146 eDragMode=SDRDRAG_MOVE; 147 //HMHbHdlShown=sal_False; 148 bRefHdlShownOnly=sal_False; 149 eEditMode=SDREDITMODE_EDIT; 150 eEditMode0=SDREDITMODE_EDIT; 151 bDesignMode=sal_False; 152 pMarkedObj=NULL; 153 pMarkedPV=NULL; 154 bForceFrameHandles=sal_False; 155 bPlusHdlAlways=sal_False; 156 nFrameHandlesLimit=50; 157 bInsPolyPoint=sal_False; 158 mnInsPointNum = 0L; 159 bMarkedObjRectDirty=sal_False; 160 bMarkedPointsRectsDirty=sal_False; 161 mbMarkHandlesHidden = false; 162 bMrkPntDirty=sal_False; 163 bMarkHdlWhenTextEdit=sal_False; 164 bMarkableObjCountDirty=sal_False; // noch nicht implementiert 165 nMarkableObjCount=0; // noch nicht implementiert 166 167 // #114409#-3 Migrate selections 168 BrkMarkObj(); 169 BrkMarkPoints(); 170 BrkMarkGluePoints(); 171 } 172 173 SdrMarkView::SdrMarkView(SdrModel* pModel1, OutputDevice* pOut) 174 : SdrSnapView(pModel1,pOut), 175 mpMarkObjOverlay(0L), 176 mpMarkPointsOverlay(0L), 177 mpMarkGluePointsOverlay(0L), 178 aHdl(this), 179 mpSdrViewSelection(new sdr::ViewSelection()) 180 { 181 ImpClearVars(); 182 StartListening(*pModel1); 183 } 184 185 SdrMarkView::~SdrMarkView() 186 { 187 // #114409#-3 Migrate selections 188 BrkMarkObj(); 189 BrkMarkPoints(); 190 BrkMarkGluePoints(); 191 delete mpSdrViewSelection; 192 } 193 194 void __EXPORT SdrMarkView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) 195 { 196 SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint); 197 if (pSdrHint!=NULL) 198 { 199 SdrHintKind eKind=pSdrHint->GetKind(); 200 201 if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED) 202 { 203 bMarkedObjRectDirty=sal_True; 204 bMarkedPointsRectsDirty=sal_True; 205 } 206 /* removed for now since this breaks existing code who iterates over the mark list and sequentially replaces objects 207 if( eKind==HINT_OBJREMOVED && IsObjMarked( const_cast<SdrObject*>(pSdrHint->GetObject()) ) ) 208 { 209 MarkObj( const_cast<SdrObject*>(pSdrHint->GetObject()), GetSdrPageView(), sal_True ); 210 } 211 */ 212 } 213 SdrSnapView::Notify(rBC,rHint); 214 } 215 216 void SdrMarkView::ModelHasChanged() 217 { 218 SdrPaintView::ModelHasChanged(); 219 GetMarkedObjectListWriteAccess().SetNameDirty(); 220 bMarkedObjRectDirty=sal_True; 221 bMarkedPointsRectsDirty=sal_True; 222 // Es sind beispielsweise Obj markiert und maMarkedObjectListist Sorted. 223 // In einer anderen View 2 wird die ObjOrder veraendert 224 // (z.B. MovToTop()). Dann ist Neusortieren der MarkList erforderlich. 225 GetMarkedObjectListWriteAccess().SetUnsorted(); 226 SortMarkedObjects(); 227 bMrkPntDirty=sal_True; 228 UndirtyMrkPnt(); 229 SdrView* pV=(SdrView*)this; 230 if (pV!=NULL && !pV->IsDragObj() && !pV->IsInsObjPoint()) { // an dieser Stelle habe ich ein ziemliches Problem !!! 231 AdjustMarkHdl(); 232 } 233 } 234 235 //////////////////////////////////////////////////////////////////////////////////////////////////// 236 237 sal_Bool SdrMarkView::IsAction() const 238 { 239 return SdrSnapView::IsAction() || IsMarkObj() || IsMarkPoints() || IsMarkGluePoints(); 240 } 241 242 void SdrMarkView::MovAction(const Point& rPnt) 243 { 244 SdrSnapView::MovAction(rPnt); 245 246 if(IsMarkObj()) 247 { 248 MovMarkObj(rPnt); 249 } 250 else if(IsMarkPoints()) 251 { 252 MovMarkPoints(rPnt); 253 } 254 else if(IsMarkGluePoints()) 255 { 256 MovMarkGluePoints(rPnt); 257 } 258 } 259 260 void SdrMarkView::EndAction() 261 { 262 if(IsMarkObj()) 263 { 264 EndMarkObj(); 265 } 266 else if(IsMarkPoints()) 267 { 268 EndMarkPoints(); 269 } 270 else if(IsMarkGluePoints()) 271 { 272 EndMarkGluePoints(); 273 } 274 275 SdrSnapView::EndAction(); 276 } 277 278 void SdrMarkView::BckAction() 279 { 280 SdrSnapView::BckAction(); 281 BrkMarkObj(); 282 BrkMarkPoints(); 283 BrkMarkGluePoints(); 284 } 285 286 void SdrMarkView::BrkAction() 287 { 288 SdrSnapView::BrkAction(); 289 BrkMarkObj(); 290 BrkMarkPoints(); 291 BrkMarkGluePoints(); 292 } 293 294 void SdrMarkView::TakeActionRect(Rectangle& rRect) const 295 { 296 if(IsMarkObj() || IsMarkPoints() || IsMarkGluePoints()) 297 { 298 rRect = Rectangle(aDragStat.GetStart(), aDragStat.GetNow()); 299 } 300 else 301 { 302 SdrSnapView::TakeActionRect(rRect); 303 } 304 } 305 306 //////////////////////////////////////////////////////////////////////////////////////////////////// 307 308 void SdrMarkView::ClearPageView() 309 { 310 UnmarkAllObj(); 311 SdrSnapView::ClearPageView(); 312 } 313 314 void SdrMarkView::HideSdrPage() 315 { 316 bool bMrkChg(false); 317 //HMHbool bVis(false); 318 319 if(mpPageView) 320 { 321 // break all creation actions when hiding page (#75081#) 322 BrkAction(); 323 //HMHbVis = IsMarkHdlShown(); 324 325 //HMHif(bVis) 326 //HMH{ 327 //HMH HideMarkHdl(); 328 //HMH} 329 330 // Alle Markierungen dieser Seite verwerfen 331 bMrkChg = GetMarkedObjectListWriteAccess().DeletePageView(*mpPageView); 332 } 333 334 SdrSnapView::HideSdrPage(); 335 336 if(bMrkChg) 337 { 338 MarkListHasChanged(); 339 AdjustMarkHdl(); 340 } 341 342 //HMHif(bVis) 343 //HMH{ 344 //HMH ShowMarkHdl(); 345 //HMH} 346 } 347 348 //////////////////////////////////////////////////////////////////////////////////////////////////// 349 350 sal_Bool SdrMarkView::BegMarkObj(const Point& rPnt, sal_Bool bUnmark) 351 { 352 BrkAction(); 353 354 DBG_ASSERT(0L == mpMarkObjOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkObjOverlay (!)"); 355 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y()); 356 mpMarkObjOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark); 357 358 aDragStat.Reset(rPnt); 359 aDragStat.NextPoint(); 360 aDragStat.SetMinMove(nMinMovLog); 361 362 return sal_True; 363 } 364 365 void SdrMarkView::MovMarkObj(const Point& rPnt) 366 { 367 if(IsMarkObj() && aDragStat.CheckMinMoved(rPnt)) 368 { 369 aDragStat.NextMove(rPnt); 370 DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)"); 371 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y()); 372 mpMarkObjOverlay->SetSecondPosition(aNewPos); 373 } 374 } 375 376 sal_Bool SdrMarkView::EndMarkObj() 377 { 378 sal_Bool bRetval(sal_False); 379 380 if(IsMarkObj()) 381 { 382 if(aDragStat.IsMinMoved()) 383 { 384 Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow()); 385 aRect.Justify(); 386 MarkObj(aRect, mpMarkObjOverlay->IsUnmarking()); 387 bRetval = sal_True; 388 } 389 390 // cleanup 391 BrkMarkObj(); 392 } 393 394 return bRetval; 395 } 396 397 void SdrMarkView::BrkMarkObj() 398 { 399 if(IsMarkObj()) 400 { 401 DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)"); 402 delete mpMarkObjOverlay; 403 mpMarkObjOverlay = 0L; 404 } 405 } 406 407 //////////////////////////////////////////////////////////////////////////////////////////////////// 408 409 sal_Bool SdrMarkView::BegMarkPoints(const Point& rPnt, sal_Bool bUnmark) 410 { 411 if(HasMarkablePoints()) 412 { 413 BrkAction(); 414 415 DBG_ASSERT(0L == mpMarkPointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkPointsOverlay (!)"); 416 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y()); 417 mpMarkPointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark); 418 419 aDragStat.Reset(rPnt); 420 aDragStat.NextPoint(); 421 aDragStat.SetMinMove(nMinMovLog); 422 423 return sal_True; 424 } 425 426 return sal_False; 427 } 428 429 void SdrMarkView::MovMarkPoints(const Point& rPnt) 430 { 431 if(IsMarkPoints() && aDragStat.CheckMinMoved(rPnt)) 432 { 433 aDragStat.NextMove(rPnt); 434 435 DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)"); 436 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y()); 437 mpMarkPointsOverlay->SetSecondPosition(aNewPos); 438 } 439 } 440 441 sal_Bool SdrMarkView::EndMarkPoints() 442 { 443 sal_Bool bRetval(sal_False); 444 445 if(IsMarkPoints()) 446 { 447 if(aDragStat.IsMinMoved()) 448 { 449 Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow()); 450 aRect.Justify(); 451 MarkPoints(aRect, mpMarkPointsOverlay->IsUnmarking()); 452 453 bRetval = sal_True; 454 } 455 456 // cleanup 457 BrkMarkPoints(); 458 } 459 460 return bRetval; 461 } 462 463 void SdrMarkView::BrkMarkPoints() 464 { 465 if(IsMarkPoints()) 466 { 467 DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)"); 468 delete mpMarkPointsOverlay; 469 mpMarkPointsOverlay = 0L; 470 } 471 } 472 473 //////////////////////////////////////////////////////////////////////////////////////////////////// 474 475 sal_Bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, sal_Bool bUnmark) 476 { 477 if(HasMarkableGluePoints()) 478 { 479 BrkAction(); 480 481 DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)"); 482 basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y()); 483 mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark); 484 485 aDragStat.Reset(rPnt); 486 aDragStat.NextPoint(); 487 aDragStat.SetMinMove(nMinMovLog); 488 489 return sal_True; 490 } 491 492 return sal_False; 493 } 494 495 void SdrMarkView::MovMarkGluePoints(const Point& rPnt) 496 { 497 if(IsMarkGluePoints() && aDragStat.CheckMinMoved(rPnt)) 498 { 499 aDragStat.NextMove(rPnt); 500 501 DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)"); 502 basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y()); 503 mpMarkGluePointsOverlay->SetSecondPosition(aNewPos); 504 } 505 } 506 507 sal_Bool SdrMarkView::EndMarkGluePoints() 508 { 509 sal_Bool bRetval(sal_False); 510 511 if(IsMarkGluePoints()) 512 { 513 if(aDragStat.IsMinMoved()) 514 { 515 Rectangle aRect(aDragStat.GetStart(),aDragStat.GetNow()); 516 aRect.Justify(); 517 MarkGluePoints(&aRect, mpMarkGluePointsOverlay->IsUnmarking()); 518 519 bRetval = sal_True; 520 } 521 522 // cleanup 523 BrkMarkGluePoints(); 524 } 525 526 return bRetval; 527 } 528 529 void SdrMarkView::BrkMarkGluePoints() 530 { 531 if(IsMarkGluePoints()) 532 { 533 DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)"); 534 delete mpMarkGluePointsOverlay; 535 mpMarkGluePointsOverlay = 0L; 536 } 537 } 538 539 sal_Bool SdrMarkView::HasMarkableObj() const 540 { 541 sal_uIntPtr nCount=0; 542 543 SdrPageView* pPV = GetSdrPageView(); 544 if(pPV) 545 { 546 SdrObjList* pOL=pPV->GetObjList(); 547 sal_uIntPtr nObjAnz=pOL->GetObjCount(); 548 for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz && nCount==0; nObjNum++) { 549 SdrObject* pObj=pOL->GetObj(nObjNum); 550 if (IsObjMarkable(pObj,pPV)) { 551 nCount++; 552 } 553 } 554 } 555 return nCount!=0; 556 } 557 558 sal_uIntPtr SdrMarkView::GetMarkableObjCount() const 559 { 560 sal_uIntPtr nCount=0; 561 SdrPageView* pPV = GetSdrPageView(); 562 563 if(pPV) 564 { 565 SdrObjList* pOL=pPV->GetObjList(); 566 sal_uIntPtr nObjAnz=pOL->GetObjCount(); 567 for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz; nObjNum++) { 568 SdrObject* pObj=pOL->GetObj(nObjNum); 569 if (IsObjMarkable(pObj,pPV)) { 570 nCount++; 571 } 572 } 573 } 574 return nCount; 575 } 576 577 //HMHvoid SdrMarkView::ImpShowMarkHdl(bool /*bNoRefHdl*/) 578 //HMH{ 579 //HMH bNoRefHdl=sal_False; // geht leider erstmal nicht anders 580 //HMH if (!bHdlShown) { 581 //HMH bRefHdlShownOnly=sal_False; 582 //HMH bHdlShown=sal_True; 583 //HMH } 584 //HMH} 585 586 //HMHvoid SdrMarkView::ShowMarkHdl(bool /*bNoRefHdl*/) 587 //HMH{ 588 //HMH bNoRefHdl=sal_False; // geht leider erstmal nicht anders 589 //HMH ImpShowMarkHdl(bNoRefHdl); 590 //HMH} 591 592 593 //HMHvoid SdrMarkView::HideMarkHdl(bool /*bNoRefHdl*/) 594 //HMH{ 595 //HMH bNoRefHdl=sal_False; // geht leider erstmal nicht anders 596 //HMH if (bHdlShown) { 597 //HMH bRefHdlShownOnly=bNoRefHdl; 598 //HMH bHdlShown=sal_False; 599 //HMH } 600 //HMH} 601 602 void SdrMarkView::hideMarkHandles() 603 { 604 if(!mbMarkHandlesHidden) 605 { 606 mbMarkHandlesHidden = true; 607 AdjustMarkHdl(); 608 } 609 } 610 611 void SdrMarkView::showMarkHandles() 612 { 613 if(mbMarkHandlesHidden) 614 { 615 mbMarkHandlesHidden = false; 616 AdjustMarkHdl(); 617 } 618 } 619 620 sal_Bool SdrMarkView::ImpIsFrameHandles() const 621 { 622 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 623 sal_Bool bFrmHdl=nMarkAnz>nFrameHandlesLimit || bForceFrameHandles; 624 sal_Bool bStdDrag=eDragMode==SDRDRAG_MOVE; 625 if (nMarkAnz==1 && bStdDrag && bFrmHdl) 626 { 627 const SdrObject* pObj=GetMarkedObjectByIndex(0); 628 if (pObj->GetObjInventor()==SdrInventor) 629 { 630 sal_uInt16 nIdent=pObj->GetObjIdentifier(); 631 if (nIdent==OBJ_LINE || nIdent==OBJ_EDGE || nIdent==OBJ_CAPTION || nIdent==OBJ_MEASURE || nIdent==OBJ_CUSTOMSHAPE || nIdent==OBJ_TABLE ) 632 { 633 bFrmHdl=sal_False; 634 } 635 } 636 } 637 if (!bStdDrag && !bFrmHdl) { 638 // Grundsaetzlich erstmal alle anderen Dragmodi nur mit FrameHandles 639 bFrmHdl=sal_True; 640 if (eDragMode==SDRDRAG_ROTATE) { 641 // bei Rotate ObjOwn-Drag, wenn mind. 1 PolyObj 642 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && bFrmHdl; nMarkNum++) { 643 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum); 644 const SdrObject* pObj=pM->GetMarkedSdrObj(); 645 bFrmHdl=!pObj->IsPolyObj(); 646 } 647 } 648 } 649 if (!bFrmHdl) { 650 // FrameHandles, wenn wenigstens 1 Obj kein SpecialDrag kann 651 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && !bFrmHdl; nMarkNum++) { 652 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum); 653 const SdrObject* pObj=pM->GetMarkedSdrObj(); 654 bFrmHdl=!pObj->hasSpecialDrag(); 655 } 656 } 657 658 // no FrameHdl for crop 659 if(bFrmHdl && SDRDRAG_CROP == eDragMode) 660 { 661 bFrmHdl = sal_False; 662 } 663 664 return bFrmHdl; 665 } 666 667 void SdrMarkView::SetMarkHandles() 668 { 669 // #105722# remember old focus handle values to search for it again 670 const SdrHdl* pSaveOldFocusHdl = aHdl.GetFocusHdl(); 671 sal_Bool bSaveOldFocus(sal_False); 672 sal_uInt32 nSavePolyNum(0L), nSavePointNum(0L); 673 SdrHdlKind eSaveKind(HDL_MOVE); 674 SdrObject* pSaveObj = NULL; 675 676 if(pSaveOldFocusHdl 677 && pSaveOldFocusHdl->GetObj() 678 && pSaveOldFocusHdl->GetObj()->ISA(SdrPathObj) 679 && (pSaveOldFocusHdl->GetKind() == HDL_POLY || pSaveOldFocusHdl->GetKind() == HDL_BWGT)) 680 { 681 bSaveOldFocus = sal_True; 682 nSavePolyNum = pSaveOldFocusHdl->GetPolyNum(); 683 nSavePointNum = pSaveOldFocusHdl->GetPointNum(); 684 pSaveObj = pSaveOldFocusHdl->GetObj(); 685 eSaveKind = pSaveOldFocusHdl->GetKind(); 686 } 687 688 // delete/clear all handles. This will always be done, even with areMarkHandlesHidden() 689 aHdl.Clear(); 690 aHdl.SetRotateShear(eDragMode==SDRDRAG_ROTATE); 691 aHdl.SetDistortShear(eDragMode==SDRDRAG_SHEAR); 692 pMarkedObj=NULL; 693 pMarkedPV=NULL; 694 695 // are handles enabled at all? Create only then 696 if(!areMarkHandlesHidden()) 697 { 698 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 699 sal_Bool bStdDrag=eDragMode==SDRDRAG_MOVE; 700 sal_Bool bSingleTextObjMark=sal_False; 701 702 if (nMarkAnz==1) 703 { 704 pMarkedObj=GetMarkedObjectByIndex(0); 705 bSingleTextObjMark = 706 pMarkedObj && 707 pMarkedObj->ISA(SdrTextObj) && 708 static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame(); 709 } 710 711 sal_Bool bFrmHdl=ImpIsFrameHandles(); 712 713 if (nMarkAnz>0) 714 { 715 pMarkedPV=GetSdrPageViewOfMarkedByIndex(0); 716 717 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz && (pMarkedPV!=NULL || !bFrmHdl); nMarkNum++) 718 { 719 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum); 720 721 if (pMarkedPV!=pM->GetPageView()) 722 { 723 pMarkedPV=NULL; 724 } 725 } 726 } 727 728 // check if text edit or ole is active and handles need to be suppressed. This may be the case 729 // when a single object is selected 730 // Using a strict return statement is okay here; no handles means *no* handles. 731 if(pMarkedObj) 732 { 733 // formally #i33755#: If TextEdit is active the EditEngine will directly paint 734 // to the window, so suppress Overlay and handles completely; a text frame for 735 // the active text edit will be painted by the repaitnt mechanism in 736 // SdrObjEditView::ImpPaintOutlinerView in this case. This needs to be reworked 737 // in the future 738 // Also formally #122142#: Pretty much the same for SdrCaptionObj's in calc. 739 if(((SdrView*)this)->IsTextEdit()) 740 { 741 const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pMarkedObj); 742 743 if(pSdrTextObj && pSdrTextObj->IsInEditMode()) 744 { 745 return; 746 } 747 } 748 749 // formally #i118524#: if inplace activated OLE is selected, suppress handles 750 const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pMarkedObj); 751 752 if(pSdrOle2Obj && (pSdrOle2Obj->isInplaceActive() || pSdrOle2Obj->isUiActive())) 753 { 754 return; 755 } 756 } 757 758 if (bFrmHdl) 759 { 760 Rectangle aRect(GetMarkedObjRect()); 761 762 if(!aRect.IsEmpty()) 763 { // sonst nix gefunden 764 if( bSingleTextObjMark ) 765 { 766 const sal_uIntPtr nSiz0=aHdl.GetHdlCount(); 767 pMarkedObj->AddToHdlList(aHdl); 768 const sal_uIntPtr nSiz1=aHdl.GetHdlCount(); 769 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++) 770 { 771 SdrHdl* pHdl=aHdl.GetHdl(i); 772 pHdl->SetObj(pMarkedObj); 773 pHdl->SetPageView(pMarkedPV); 774 pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); 775 } 776 } 777 else 778 { 779 sal_Bool bWdt0=aRect.Left()==aRect.Right(); 780 sal_Bool bHgt0=aRect.Top()==aRect.Bottom(); 781 if (bWdt0 && bHgt0) 782 { 783 aHdl.AddHdl(new SdrHdl(aRect.TopLeft(),HDL_UPLFT)); 784 } 785 else if (!bStdDrag && (bWdt0 || bHgt0)) 786 { 787 aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT)); 788 aHdl.AddHdl(new SdrHdl(aRect.BottomRight(),HDL_LWRGT)); 789 } 790 else 791 { 792 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT)); 793 if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopCenter() ,HDL_UPPER)); 794 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopRight() ,HDL_UPRGT)); 795 if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.LeftCenter() ,HDL_LEFT )); 796 if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.RightCenter() ,HDL_RIGHT)); 797 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomLeft() ,HDL_LWLFT)); 798 if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomCenter(),HDL_LOWER)); 799 if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomRight() ,HDL_LWRGT)); 800 } 801 } 802 } 803 } 804 else 805 { 806 bool bDone(false); 807 808 // moved crop handling to non-frame part and the handle creation to SdrGrafObj 809 if(1 == nMarkAnz && pMarkedObj && SDRDRAG_CROP == eDragMode) 810 { 811 const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pMarkedObj); 812 813 if(pSdrGrafObj) 814 { 815 pSdrGrafObj->addCropHandles(aHdl); 816 bDone = true; 817 } 818 } 819 820 if(!bDone) 821 { 822 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) 823 { 824 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum); 825 SdrObject* pObj=pM->GetMarkedSdrObj(); 826 SdrPageView* pPV=pM->GetPageView(); 827 const sal_uIntPtr nSiz0=aHdl.GetHdlCount(); 828 pObj->AddToHdlList(aHdl); 829 const sal_uIntPtr nSiz1=aHdl.GetHdlCount(); 830 bool bPoly=pObj->IsPolyObj(); 831 const SdrUShortCont* pMrkPnts=pM->GetMarkedPoints(); 832 for (sal_uIntPtr i=nSiz0; i<nSiz1; i++) 833 { 834 SdrHdl* pHdl=aHdl.GetHdl(i); 835 pHdl->SetObj(pObj); 836 pHdl->SetPageView(pPV); 837 pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); 838 if (bPoly) 839 { 840 sal_Bool bSelected=pMrkPnts!=NULL && pMrkPnts->Exist(sal_uInt16(i-nSiz0)); 841 pHdl->SetSelected(bSelected); 842 //sal_Bool bPlus=bPlusHdlAlways; 843 if (bPlusHdlAlways || bSelected) 844 { 845 sal_uInt32 nPlusAnz=pObj->GetPlusHdlCount(*pHdl); 846 for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++) 847 { 848 SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,nPlusNum); 849 if (pPlusHdl!=NULL) 850 { 851 pPlusHdl->SetObj(pObj); 852 pPlusHdl->SetPageView(pPV); 853 pPlusHdl->SetPlusHdl(sal_True); 854 aHdl.AddHdl(pPlusHdl); 855 } 856 } 857 } 858 } 859 } 860 } 861 } 862 } 863 864 // GluePoint-Handles 865 for (sal_uIntPtr nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) 866 { 867 const SdrMark* pM=GetSdrMarkByIndex(nMarkNum); 868 SdrObject* pObj=pM->GetMarkedSdrObj(); 869 SdrPageView* pPV=pM->GetPageView(); 870 const SdrUShortCont* pMrkGlue=pM->GetMarkedGluePoints(); 871 if (pMrkGlue!=NULL) 872 { 873 const SdrGluePointList* pGPL=pObj->GetGluePointList(); 874 if (pGPL!=NULL) 875 { 876 //sal_uInt16 nGlueAnz=pGPL->GetCount(); 877 sal_uInt16 nAnz=(sal_uInt16)pMrkGlue->GetCount(); 878 for (sal_uInt16 nNum=0; nNum<nAnz; nNum++) 879 { 880 sal_uInt16 nId=pMrkGlue->GetObject(nNum); 881 //nNum changed to nNumGP because already used in for loop 882 sal_uInt16 nNumGP=pGPL->FindGluePoint(nId); 883 if (nNumGP!=SDRGLUEPOINT_NOTFOUND) 884 { 885 const SdrGluePoint& rGP=(*pGPL)[nNumGP]; 886 Point aPos(rGP.GetAbsolutePos(*pObj)); 887 SdrHdl* pGlueHdl=new SdrHdl(aPos,HDL_GLUE); 888 pGlueHdl->SetObj(pObj); 889 pGlueHdl->SetPageView(pPV); 890 pGlueHdl->SetObjHdlNum(nId); 891 aHdl.AddHdl(pGlueHdl); 892 } 893 } 894 } 895 } 896 } 897 898 // Drehpunkt/Spiegelachse 899 AddDragModeHdl(eDragMode); 900 901 // sort handles 902 aHdl.Sort(); 903 904 // add custom handles (used by other apps, e.g. AnchorPos) 905 AddCustomHdl(); 906 907 // #105722# try to restore focus handle index from remembered values 908 if(bSaveOldFocus) 909 { 910 for(sal_uInt32 a(0); a < aHdl.GetHdlCount(); a++) 911 { 912 SdrHdl* pCandidate = aHdl.GetHdl(a); 913 914 if(pCandidate->GetObj() 915 && pCandidate->GetObj() == pSaveObj 916 && pCandidate->GetKind() == eSaveKind 917 && pCandidate->GetPolyNum() == nSavePolyNum 918 && pCandidate->GetPointNum() == nSavePointNum) 919 { 920 aHdl.SetFocusHdl(pCandidate); 921 break; 922 } 923 } 924 } 925 } 926 } 927 928 void SdrMarkView::AddCustomHdl() 929 { 930 // add custom handles (used by other apps, e.g. AnchorPos) 931 } 932 933 void SdrMarkView::SetDragMode(SdrDragMode eMode) 934 { 935 SdrDragMode eMode0=eDragMode; 936 eDragMode=eMode; 937 if (eDragMode==SDRDRAG_RESIZE) eDragMode=SDRDRAG_MOVE; 938 if (eDragMode!=eMode0) { 939 //HMHBOOL bVis=IsMarkHdlShown(); 940 //HMHif (bVis) HideMarkHdl(); 941 ForceRefToMarked(); 942 SetMarkHandles(); 943 //HMHif (bVis) ShowMarkHdl(); 944 { 945 if (AreObjectsMarked()) MarkListHasChanged(); 946 } 947 } 948 } 949 950 void SdrMarkView::AddDragModeHdl(SdrDragMode eMode) 951 { 952 switch(eMode) 953 { 954 case SDRDRAG_ROTATE: 955 { 956 // add rotation center 957 SdrHdl* pHdl = new SdrHdl(aRef1, HDL_REF1); 958 959 aHdl.AddHdl(pHdl); 960 961 break; 962 } 963 case SDRDRAG_MIRROR: 964 { 965 // add mirror axis 966 SdrHdl* pHdl3 = new SdrHdl(aRef2, HDL_REF2); 967 SdrHdl* pHdl2 = new SdrHdl(aRef1, HDL_REF1); 968 SdrHdl* pHdl1 = new SdrHdlLine(*pHdl2, *pHdl3, HDL_MIRX); 969 970 pHdl1->SetObjHdlNum(1); // fuer Sortierung 971 pHdl2->SetObjHdlNum(2); // fuer Sortierung 972 pHdl3->SetObjHdlNum(3); // fuer Sortierung 973 974 aHdl.AddHdl(pHdl1); // Linie als erstes, damit als letztes im HitTest 975 aHdl.AddHdl(pHdl2); 976 aHdl.AddHdl(pHdl3); 977 978 break; 979 } 980 case SDRDRAG_TRANSPARENCE: 981 { 982 // add interactive transparence handle 983 sal_uIntPtr nMarkAnz = GetMarkedObjectCount(); 984 if(nMarkAnz == 1) 985 { 986 SdrObject* pObj = GetMarkedObjectByIndex(0); 987 SdrModel* pModel = GetModel(); 988 const SfxItemSet& rSet = pObj->GetMergedItemSet(); 989 990 if(SFX_ITEM_SET != rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, sal_False)) 991 { 992 // add this item, it's not yet there 993 XFillFloatTransparenceItem aNewItem( 994 (const XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)); 995 XGradient aGrad = aNewItem.GetGradientValue(); 996 997 aNewItem.SetEnabled(sal_True); 998 aGrad.SetStartIntens(100); 999 aGrad.SetEndIntens(100); 1000 aNewItem.SetGradientValue(aGrad); 1001 1002 // add undo to allow user to take back this step 1003 if( pModel->IsUndoEnabled() ) 1004 { 1005 pModel->BegUndo(SVX_RESSTR(SIP_XA_FILLTRANSPARENCE)); 1006 pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj)); 1007 pModel->EndUndo(); 1008 } 1009 1010 //pObj->SetItemAndBroadcast(aNewItem); 1011 SfxItemSet aNewSet(pModel->GetItemPool()); 1012 aNewSet.Put(aNewItem); 1013 pObj->SetMergedItemSetAndBroadcast(aNewSet); 1014 } 1015 1016 // set values and transform to vector set 1017 GradTransformer aGradTransformer; 1018 GradTransVector aGradTransVector; 1019 GradTransGradient aGradTransGradient; 1020 1021 aGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue(); 1022 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj); 1023 1024 // build handles 1025 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY())); 1026 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY())); 1027 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True); 1028 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, sal_True); 1029 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_False); 1030 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!"); 1031 1032 // link them 1033 pGradHdl->SetColorHandles(pColHdl1, pColHdl2); 1034 pGradHdl->SetObj(pObj); 1035 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl)); 1036 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl)); 1037 1038 // insert them 1039 aHdl.AddHdl(pColHdl1); 1040 aHdl.AddHdl(pColHdl2); 1041 aHdl.AddHdl(pGradHdl); 1042 } 1043 break; 1044 } 1045 case SDRDRAG_GRADIENT: 1046 { 1047 // add interactive gradient handle 1048 sal_uIntPtr nMarkAnz = GetMarkedObjectCount(); 1049 if(nMarkAnz == 1) 1050 { 1051 SdrObject* pObj = GetMarkedObjectByIndex(0); 1052 const SfxItemSet& rSet = pObj->GetMergedItemSet(); 1053 XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue(); 1054 1055 if(eFillStyle == XFILL_GRADIENT) 1056 { 1057 // set values and transform to vector set 1058 GradTransformer aGradTransformer; 1059 GradTransVector aGradTransVector; 1060 GradTransGradient aGradTransGradient; 1061 Size aHdlSize(15, 15); 1062 1063 aGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue(); 1064 aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj); 1065 1066 // build handles 1067 const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY())); 1068 const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY())); 1069 SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, sal_False); 1070 SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, sal_False); 1071 SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, sal_True); 1072 DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!"); 1073 1074 // link them 1075 pGradHdl->SetColorHandles(pColHdl1, pColHdl2); 1076 pGradHdl->SetObj(pObj); 1077 pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl)); 1078 pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl)); 1079 1080 // insert them 1081 aHdl.AddHdl(pColHdl1); 1082 aHdl.AddHdl(pColHdl2); 1083 aHdl.AddHdl(pGradHdl); 1084 } 1085 } 1086 break; 1087 } 1088 case SDRDRAG_CROP: 1089 { 1090 // todo 1091 break; 1092 } 1093 default: break; 1094 } 1095 } 1096 1097 /** handle mouse over effects for handles */ 1098 sal_Bool SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin) 1099 { 1100 if(aHdl.GetHdlCount()) 1101 { 1102 SdrHdl* pMouseOverHdl = 0; 1103 if( !rMEvt.IsLeaveWindow() && pWin ) 1104 { 1105 Point aMDPos( pWin->PixelToLogic( rMEvt.GetPosPixel() ) ); 1106 pMouseOverHdl = PickHandle(aMDPos); 1107 } 1108 1109 // notify last mouse over handle that he lost the mouse 1110 const sal_uIntPtr nHdlCount = aHdl.GetHdlCount(); 1111 1112 for(sal_uIntPtr nHdl = 0; nHdl < nHdlCount; nHdl++ ) 1113 { 1114 SdrHdl* pCurrentHdl = GetHdl(nHdl); 1115 if( pCurrentHdl->mbMouseOver ) 1116 { 1117 if( pCurrentHdl != pMouseOverHdl ) 1118 { 1119 pCurrentHdl->mbMouseOver = false; 1120 pCurrentHdl->onMouseLeave(); 1121 } 1122 break; 1123 } 1124 } 1125 1126 // notify current mouse over handle 1127 if( pMouseOverHdl /* && !pMouseOverHdl->mbMouseOver */ ) 1128 { 1129 pMouseOverHdl->mbMouseOver = true; 1130 pMouseOverHdl->onMouseEnter(rMEvt); 1131 } 1132 } 1133 return SdrSnapView::MouseMove(rMEvt, pWin); 1134 } 1135 1136 void SdrMarkView::ForceRefToMarked() 1137 { 1138 switch(eDragMode) 1139 { 1140 case SDRDRAG_ROTATE: 1141 { 1142 Rectangle aR(GetMarkedObjRect()); 1143 aRef1 = aR.Center(); 1144 1145 break; 1146 } 1147 1148 case SDRDRAG_MIRROR: 1149 { 1150 // Erstmal die laenge der Spiegelachsenlinie berechnen 1151 long nOutMin=0; 1152 long nOutMax=0; 1153 long nMinLen=0; 1154 long nObjDst=0; 1155 long nOutHgt=0; 1156 OutputDevice* pOut=GetFirstOutputDevice(); 1157 //OutputDevice* pOut=GetWin(0); 1158 if (pOut!=NULL) { 1159 // Mindestlaenge 50 Pixel 1160 nMinLen=pOut->PixelToLogic(Size(0,50)).Height(); 1161 // 20 Pixel fuer RefPt-Abstand vom Obj 1162 nObjDst=pOut->PixelToLogic(Size(0,20)).Height(); 1163 // MinY/MaxY 1164 // Abstand zum Rand = Mindestlaenge = 10 Pixel 1165 long nDst=pOut->PixelToLogic(Size(0,10)).Height(); 1166 nOutMin=-pOut->GetMapMode().GetOrigin().Y(); 1167 nOutMax=pOut->GetOutputSize().Height()-1+nOutMin; 1168 nOutMin+=nDst; 1169 nOutMax-=nDst; 1170 // Absolute Mindestlaenge jedoch 10 Pixel 1171 if (nOutMax-nOutMin<nDst) { 1172 nOutMin+=nOutMax+1; 1173 nOutMin/=2; 1174 nOutMin-=(nDst+1)/2; 1175 nOutMax=nOutMin+nDst; 1176 } 1177 nOutHgt=nOutMax-nOutMin; 1178 // Sonst Mindestlaenge = 1/4 OutHgt 1179 long nTemp=nOutHgt/4; 1180 if (nTemp>nMinLen) nMinLen=nTemp; 1181 } 1182 1183 Rectangle aR(GetMarkedObjBoundRect()); 1184 Point aCenter(aR.Center()); 1185 long nMarkHgt=aR.GetHeight()-1; 1186 long nHgt=nMarkHgt+nObjDst*2; // 20 Pixel obej und unten ueberstehend 1187 if (nHgt<nMinLen) nHgt=nMinLen; // Mindestlaenge 50 Pixel bzw. 1/4 OutHgt 1188 1189 long nY1=aCenter.Y()-(nHgt+1)/2; 1190 long nY2=nY1+nHgt; 1191 1192 if (pOut!=NULL && nMinLen>nOutHgt) nMinLen=nOutHgt; // evtl. noch etwas verkuerzen 1193 1194 if (pOut!=NULL) { // nun vollstaendig in den sichtbaren Bereich schieben 1195 if (nY1<nOutMin) { 1196 nY1=nOutMin; 1197 if (nY2<nY1+nMinLen) nY2=nY1+nMinLen; 1198 } 1199 if (nY2>nOutMax) { 1200 nY2=nOutMax; 1201 if (nY1>nY2-nMinLen) nY1=nY2-nMinLen; 1202 } 1203 } 1204 1205 aRef1.X()=aCenter.X(); 1206 aRef1.Y()=nY1; 1207 aRef2.X()=aCenter.X(); 1208 aRef2.Y()=nY2; 1209 1210 break; 1211 } 1212 1213 case SDRDRAG_TRANSPARENCE: 1214 case SDRDRAG_GRADIENT: 1215 case SDRDRAG_CROP: 1216 { 1217 Rectangle aRect(GetMarkedObjBoundRect()); 1218 aRef1 = aRect.TopLeft(); 1219 aRef2 = aRect.BottomRight(); 1220 break; 1221 } 1222 default: break; 1223 } 1224 } 1225 1226 void SdrMarkView::SetRef1(const Point& rPt) 1227 { 1228 if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR) 1229 { 1230 aRef1 = rPt; 1231 SdrHdl* pH = aHdl.GetHdl(HDL_REF1); 1232 if(pH) 1233 pH->SetPos(rPt); 1234 //HMHShowMarkHdl(); 1235 } 1236 } 1237 1238 void SdrMarkView::SetRef2(const Point& rPt) 1239 { 1240 if(eDragMode == SDRDRAG_MIRROR) 1241 { 1242 aRef2 = rPt; 1243 SdrHdl* pH = aHdl.GetHdl(HDL_REF2); 1244 if(pH) 1245 pH->SetPos(rPt); 1246 //HMHShowMarkHdl(); 1247 } 1248 } 1249 1250 void SdrMarkView::CheckMarked() 1251 { 1252 for (sal_uIntPtr nm=GetMarkedObjectCount(); nm>0;) { 1253 nm--; 1254 SdrMark* pM=GetSdrMarkByIndex(nm); 1255 SdrObject* pObj=pM->GetMarkedSdrObj(); 1256 SdrPageView* pPV=pM->GetPageView(); 1257 SdrLayerID nLay=pObj->GetLayer(); 1258 sal_Bool bRaus=!pObj->IsInserted(); // Obj geloescht? 1259 if (!pObj->Is3DObj()) { 1260 bRaus=bRaus || pObj->GetPage()!=pPV->GetPage(); // Obj ploetzlich in anderer Page oder Group 1261 } 1262 bRaus=bRaus || pPV->GetLockedLayers().IsSet(nLay) || // Layer gesperrt? 1263 !pPV->GetVisibleLayers().IsSet(nLay); // Layer nicht sichtbar? 1264 1265 if( !bRaus ) 1266 bRaus = !pObj->IsVisible(); // not visible objects can not be marked 1267 1268 if (!bRaus) { 1269 // Joe am 9.3.1997: Gruppierte Objekten koennen nun auch 1270 // markiert werden. Nach EnterGroup muessen aber die Objekte 1271 // der hoeheren Ebene deselektiert werden. 1272 const SdrObjList* pOOL=pObj->GetObjList(); 1273 const SdrObjList* pVOL=pPV->GetObjList(); 1274 while (pOOL!=NULL && pOOL!=pVOL) { 1275 pOOL=pOOL->GetUpList(); 1276 } 1277 bRaus=pOOL!=pVOL; 1278 } 1279 1280 if (bRaus) 1281 { 1282 GetMarkedObjectListWriteAccess().DeleteMark(nm); 1283 } 1284 else 1285 { 1286 if (!IsGluePointEditMode()) { // Markierte GluePoints nur im GlueEditMode 1287 SdrUShortCont* pPts=pM->GetMarkedGluePoints(); 1288 if (pPts!=NULL && pPts->GetCount()!=0) { 1289 pPts->Clear(); 1290 } 1291 } 1292 } 1293 } 1294 1295 // #97995# at least reset the remembered BoundRect to prevent handle 1296 // generation if bForceFrameHandles is TRUE. 1297 bMarkedObjRectDirty = sal_True; 1298 } 1299 1300 void SdrMarkView::SetMarkRects() 1301 { 1302 SdrPageView* pPV = GetSdrPageView(); 1303 1304 if(pPV) 1305 { 1306 pPV->SetHasMarkedObj(GetSnapRectFromMarkedObjects(pPV, pPV->MarkSnap())); 1307 GetBoundRectFromMarkedObjects(pPV, pPV->MarkBound()); 1308 } 1309 } 1310 1311 void SdrMarkView::SetFrameHandles(sal_Bool bOn) 1312 { 1313 if (bOn!=bForceFrameHandles) { 1314 sal_Bool bOld=ImpIsFrameHandles(); 1315 bForceFrameHandles=bOn; 1316 sal_Bool bNew=ImpIsFrameHandles(); 1317 if (bNew!=bOld) { 1318 AdjustMarkHdl(); //HMHTRUE); 1319 MarkListHasChanged(); 1320 } 1321 } 1322 } 1323 1324 void SdrMarkView::SetEditMode(SdrViewEditMode eMode) 1325 { 1326 if (eMode!=eEditMode) { 1327 sal_Bool bGlue0=eEditMode==SDREDITMODE_GLUEPOINTEDIT; 1328 sal_Bool bEdge0=((SdrCreateView*)this)->IsEdgeTool(); 1329 eEditMode0=eEditMode; 1330 eEditMode=eMode; 1331 sal_Bool bGlue1=eEditMode==SDREDITMODE_GLUEPOINTEDIT; 1332 sal_Bool bEdge1=((SdrCreateView*)this)->IsEdgeTool(); 1333 // etwas Aufwand um Flackern zu verhindern beim Umschalten 1334 // zwischen GlueEdit und EdgeTool 1335 if (bGlue1 && !bGlue0) ImpSetGlueVisible2(bGlue1); 1336 if (bEdge1!=bEdge0) ImpSetGlueVisible3(bEdge1); 1337 if (!bGlue1 && bGlue0) ImpSetGlueVisible2(bGlue1); 1338 if (bGlue0 && !bGlue1) UnmarkAllGluePoints(); 1339 } 1340 } 1341 1342 //////////////////////////////////////////////////////////////////////////////////////////////////// 1343 1344 sal_Bool SdrMarkView::IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const 1345 { 1346 if (pObj) 1347 { 1348 if (pObj->IsMarkProtect() || 1349 (!bDesignMode && pObj->IsUnoObj())) 1350 { 1351 // Objekt nicht selektierbar oder 1352 // SdrUnoObj nicht im DesignMode 1353 return sal_False; 1354 } 1355 } 1356 return pPV!=NULL ? pPV->IsObjMarkable(pObj) : sal_True; 1357 } 1358 1359 sal_Bool SdrMarkView::IsMarkedObjHit(const Point& rPnt, short nTol) const 1360 { 1361 sal_Bool bRet=sal_False; 1362 nTol=ImpGetHitTolLogic(nTol,NULL); 1363 Point aPt(rPnt); 1364 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount() && !bRet; nm++) { 1365 SdrMark* pM=GetSdrMarkByIndex(nm); 1366 bRet = 0 != CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0); 1367 } 1368 return bRet; 1369 } 1370 1371 SdrHdl* SdrMarkView::PickHandle(const Point& rPnt, sal_uIntPtr nOptions, SdrHdl* pHdl0) const 1372 { 1373 if (bSomeObjChgdFlag) { // ggf. Handles neu berechnen lassen! 1374 FlushComeBackTimer(); 1375 } 1376 sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0; 1377 sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0; 1378 Point aPt(rPnt); 1379 return aHdl.IsHdlListHit(aPt,bBack,bNext,pHdl0); 1380 } 1381 1382 sal_Bool SdrMarkView::MarkObj(const Point& rPnt, short nTol, sal_Bool bToggle, sal_Bool bDeep) 1383 { 1384 SdrObject* pObj; 1385 SdrPageView* pPV; 1386 nTol=ImpGetHitTolLogic(nTol,NULL); 1387 sal_uIntPtr nOptions=SDRSEARCH_PICKMARKABLE; 1388 if (bDeep) nOptions=nOptions|SDRSEARCH_DEEP; 1389 sal_Bool bRet=PickObj(rPnt,(sal_uInt16)nTol,pObj,pPV,nOptions); 1390 if (bRet) { 1391 sal_Bool bUnmark=bToggle && IsObjMarked(pObj); 1392 MarkObj(pObj,pPV,bUnmark); 1393 } 1394 return bRet; 1395 } 1396 1397 sal_Bool SdrMarkView::MarkNextObj(sal_Bool bPrev) 1398 { 1399 SdrPageView* pPageView = GetSdrPageView(); 1400 1401 if(!pPageView) 1402 { 1403 return sal_False; 1404 } 1405 1406 SortMarkedObjects(); 1407 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 1408 sal_uIntPtr nChgMarkNum = ULONG_MAX; // Nummer des zu ersetzenden MarkEntries 1409 sal_uIntPtr nSearchObjNum = bPrev ? 0 : ULONG_MAX; 1410 if (nMarkAnz!=0) { 1411 nChgMarkNum=bPrev ? 0 : sal_uIntPtr(nMarkAnz-1); 1412 SdrMark* pM=GetSdrMarkByIndex(nChgMarkNum); 1413 OSL_ASSERT(pM!=NULL); 1414 if (pM->GetMarkedSdrObj() != NULL) 1415 nSearchObjNum = pM->GetMarkedSdrObj()->GetNavigationPosition(); 1416 } 1417 1418 SdrObject* pMarkObj=NULL; 1419 SdrObjList* pSearchObjList=pPageView->GetObjList(); 1420 sal_uIntPtr nObjAnz=pSearchObjList->GetObjCount(); 1421 if (nObjAnz!=0) { 1422 if (nSearchObjNum>nObjAnz) nSearchObjNum=nObjAnz; 1423 while (pMarkObj==NULL && ((!bPrev && nSearchObjNum>0) || (bPrev && nSearchObjNum<nObjAnz))) 1424 { 1425 if (!bPrev) 1426 nSearchObjNum--; 1427 SdrObject* pSearchObj = pSearchObjList->GetObjectForNavigationPosition(nSearchObjNum); 1428 if (IsObjMarkable(pSearchObj,pPageView)) 1429 { 1430 if (TryToFindMarkedObject(pSearchObj)==CONTAINER_ENTRY_NOTFOUND) 1431 { 1432 pMarkObj=pSearchObj; 1433 } 1434 } 1435 if (bPrev) nSearchObjNum++; 1436 } 1437 } 1438 1439 if(!pMarkObj) 1440 { 1441 return sal_False; 1442 } 1443 1444 if (nChgMarkNum!=ULONG_MAX) 1445 { 1446 GetMarkedObjectListWriteAccess().DeleteMark(nChgMarkNum); 1447 } 1448 MarkObj(pMarkObj,pPageView); // ruft auch MarkListHasChanged(), AdjustMarkHdl() 1449 return sal_True; 1450 } 1451 1452 sal_Bool SdrMarkView::MarkNextObj(const Point& rPnt, short nTol, sal_Bool bPrev) 1453 { 1454 SortMarkedObjects(); 1455 nTol=ImpGetHitTolLogic(nTol,NULL); 1456 Point aPt(rPnt); 1457 SdrMark* pTopMarkHit=NULL; 1458 SdrMark* pBtmMarkHit=NULL; 1459 sal_uIntPtr nTopMarkHit=0; 1460 sal_uIntPtr nBtmMarkHit=0; 1461 // oberstes der markierten Objekte suchen, das von rPnt getroffen wird 1462 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 1463 sal_uIntPtr nm=0; 1464 for (nm=nMarkAnz; nm>0 && pTopMarkHit==NULL;) { 1465 nm--; 1466 SdrMark* pM=GetSdrMarkByIndex(nm); 1467 if(CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0)) 1468 { 1469 pTopMarkHit=pM; 1470 nTopMarkHit=nm; 1471 } 1472 } 1473 // Nichts gefunden, dann ganz normal ein Obj markieren. 1474 if (pTopMarkHit==NULL) return MarkObj(rPnt,sal_uInt16(nTol),sal_False); 1475 1476 SdrObject* pTopObjHit=pTopMarkHit->GetMarkedSdrObj(); 1477 SdrObjList* pObjList=pTopObjHit->GetObjList(); 1478 SdrPageView* pPV=pTopMarkHit->GetPageView(); 1479 // unterstes der markierten Objekte suchen, das von rPnt getroffen wird 1480 // und auf der gleichen PageView liegt wie pTopMarkHit 1481 for (nm=0; nm<nMarkAnz && pBtmMarkHit==NULL; nm++) { 1482 SdrMark* pM=GetSdrMarkByIndex(nm); 1483 SdrPageView* pPV2=pM->GetPageView(); 1484 if (pPV2==pPV && CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pM->GetMarkedSdrObj(),pPV2,0,0)) 1485 { 1486 pBtmMarkHit=pM; 1487 nBtmMarkHit=nm; 1488 } 1489 } 1490 if (pBtmMarkHit==NULL) { pBtmMarkHit=pTopMarkHit; nBtmMarkHit=nTopMarkHit; } 1491 SdrObject* pBtmObjHit=pBtmMarkHit->GetMarkedSdrObj(); 1492 sal_uIntPtr nObjAnz=pObjList->GetObjCount(); 1493 1494 // #110988# 1495 //sal_uIntPtr nSearchBeg=bPrev ? pBtmObjHit->GetOrdNum()+1 : pTopObjHit->GetOrdNum(); 1496 sal_uInt32 nSearchBeg; 1497 E3dScene* pScene = NULL; 1498 SdrObject* pObjHit = (bPrev) ? pBtmObjHit : pTopObjHit; 1499 sal_Bool bRemap = pObjHit->ISA(E3dCompoundObject) 1500 ? ((E3dCompoundObject*)pObjHit)->IsAOrdNumRemapCandidate(pScene) 1501 : sal_False; 1502 1503 if(bPrev) 1504 { 1505 sal_uInt32 nOrdNumBtm(pBtmObjHit->GetOrdNum()); 1506 1507 if(bRemap) 1508 { 1509 nOrdNumBtm = pScene->RemapOrdNum(nOrdNumBtm); 1510 } 1511 1512 nSearchBeg = nOrdNumBtm + 1; 1513 } 1514 else 1515 { 1516 sal_uInt32 nOrdNumTop(pTopObjHit->GetOrdNum()); 1517 1518 if(bRemap) 1519 { 1520 nOrdNumTop = pScene->RemapOrdNum(nOrdNumTop); 1521 } 1522 1523 nSearchBeg = nOrdNumTop; 1524 } 1525 1526 sal_uIntPtr no=nSearchBeg; 1527 SdrObject* pFndObj=NULL; 1528 //SdrObject* pAktObj=NULL; 1529 while (pFndObj==NULL && ((!bPrev && no>0) || (bPrev && no<nObjAnz))) { 1530 if (!bPrev) no--; 1531 SdrObject* pObj; 1532 1533 if(bRemap) 1534 { 1535 pObj = pObjList->GetObj(pScene->RemapOrdNum(no)); 1536 } 1537 else 1538 { 1539 pObj = pObjList->GetObj(no); 1540 } 1541 1542 if (CheckSingleSdrObjectHit(aPt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_TESTMARKABLE,0)) 1543 { 1544 if (TryToFindMarkedObject(pObj)==CONTAINER_ENTRY_NOTFOUND) { 1545 pFndObj=pObj; 1546 } else { 1547 // hier wg. Performance ggf. noch no auf Top bzw. auf Btm stellen 1548 } 1549 } 1550 if (bPrev) no++; 1551 } 1552 if (pFndObj!=NULL) 1553 { 1554 GetMarkedObjectListWriteAccess().DeleteMark(bPrev?nBtmMarkHit:nTopMarkHit); 1555 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pFndObj,pPV)); 1556 MarkListHasChanged(); 1557 AdjustMarkHdl(); //HMHTRUE); 1558 } 1559 return pFndObj!=NULL; 1560 } 1561 1562 sal_Bool SdrMarkView::MarkObj(const Rectangle& rRect, sal_Bool bUnmark) 1563 { 1564 sal_Bool bFnd=sal_False; 1565 Rectangle aR(rRect); 1566 SdrObject* pObj; 1567 SdrObjList* pObjList; 1568 BrkAction(); 1569 SdrPageView* pPV = GetSdrPageView(); 1570 1571 if(pPV) 1572 { 1573 pObjList=pPV->GetObjList(); 1574 Rectangle aFrm1(aR); 1575 sal_uIntPtr nObjAnz=pObjList->GetObjCount(); 1576 for (sal_uIntPtr nO=0; nO<nObjAnz; nO++) { 1577 pObj=pObjList->GetObj(nO); 1578 Rectangle aRect(pObj->GetCurrentBoundRect()); 1579 if (aFrm1.IsInside(aRect)) { 1580 if (!bUnmark) { 1581 if (IsObjMarkable(pObj,pPV)) 1582 { 1583 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV)); 1584 bFnd=sal_True; 1585 } 1586 } else { 1587 sal_uIntPtr nPos=TryToFindMarkedObject(pObj); 1588 if (nPos!=CONTAINER_ENTRY_NOTFOUND) 1589 { 1590 GetMarkedObjectListWriteAccess().DeleteMark(nPos); 1591 bFnd=sal_True; 1592 } 1593 } 1594 } 1595 } 1596 } 1597 if (bFnd) { 1598 SortMarkedObjects(); 1599 MarkListHasChanged(); 1600 AdjustMarkHdl(); //HMHTRUE); 1601 //HMHShowMarkHdl(); 1602 } 1603 return bFnd; 1604 } 1605 1606 void SdrMarkView::MarkObj(SdrObject* pObj, SdrPageView* pPV, sal_Bool bUnmark, sal_Bool bImpNoSetMarkHdl) 1607 { 1608 if (pObj!=NULL && pPV!=NULL && IsObjMarkable(pObj, pPV)) { 1609 BrkAction(); 1610 if (!bUnmark) 1611 { 1612 GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV)); 1613 } 1614 else 1615 { 1616 sal_uIntPtr nPos=TryToFindMarkedObject(pObj); 1617 if (nPos!=CONTAINER_ENTRY_NOTFOUND) 1618 { 1619 GetMarkedObjectListWriteAccess().DeleteMark(nPos); 1620 } 1621 } 1622 if (!bImpNoSetMarkHdl) { 1623 MarkListHasChanged(); 1624 AdjustMarkHdl(); //HMHTRUE); 1625 //HMHif (!bSomeObjChgdFlag) { 1626 // ShowMarkHdl kommt sonst mit dem AfterPaintTimer 1627 //HMHShowMarkHdl(); 1628 //HMH} 1629 } 1630 } 1631 } 1632 1633 sal_Bool SdrMarkView::IsObjMarked(SdrObject* pObj) const 1634 { 1635 // nicht so ganz die feine Art: Da FindObject() nicht const ist 1636 // muss ich mich hier auf non-const casten. 1637 sal_uIntPtr nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj); 1638 return nPos!=CONTAINER_ENTRY_NOTFOUND; 1639 } 1640 1641 sal_uInt16 SdrMarkView::GetMarkHdlSizePixel() const 1642 { 1643 return aHdl.GetHdlSize()*2+1; 1644 } 1645 1646 void SdrMarkView::SetSolidMarkHdl(sal_Bool bOn) 1647 { 1648 if (bOn!=aHdl.IsFineHdl()) { 1649 //HMHBOOL bMerk=IsMarkHdlShown(); 1650 //HMHif (bMerk) HideMarkHdl(); 1651 aHdl.SetFineHdl(bOn); 1652 //HMHif (bMerk) ShowMarkHdl(); 1653 } 1654 } 1655 1656 void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz) 1657 { 1658 if (nSiz<3) nSiz=3; 1659 nSiz/=2; 1660 if (nSiz!=aHdl.GetHdlSize()) { 1661 //HMHBOOL bMerk=IsMarkHdlShown(); 1662 //HMHif (bMerk) HideMarkHdl(); 1663 aHdl.SetHdlSize(nSiz); 1664 //HMHif (bMerk) ShowMarkHdl(); 1665 } 1666 } 1667 1668 #define SDRSEARCH_IMPISMASTER 0x80000000 /* MasterPage wird gerade durchsucht */ 1669 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay) const 1670 { 1671 if(((nOptions & SDRSEARCH_IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible())) 1672 { 1673 return NULL; 1674 } 1675 1676 const bool bCheckIfMarkable(nOptions & SDRSEARCH_TESTMARKABLE); 1677 const bool bDeep(nOptions & SDRSEARCH_DEEP); 1678 const bool bOLE(pObj->ISA(SdrOle2Obj)); 1679 const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame()); 1680 SdrObject* pRet=NULL; 1681 Rectangle aRect(pObj->GetCurrentBoundRect()); 1682 sal_uInt16 nTol2(nTol); 1683 1684 // double tolerance for OLE, text frames and objects in 1685 // active text edit 1686 if(bOLE || bTXT || pObj==((SdrObjEditView*)this)->GetTextEditObject()) 1687 { 1688 nTol2*=2; 1689 } 1690 1691 aRect.Left ()-=nTol2; // Einmal Toleranz drauf fuer alle Objekte 1692 aRect.Top ()-=nTol2; 1693 aRect.Right ()+=nTol2; 1694 aRect.Bottom()+=nTol2; 1695 1696 if (aRect.IsInside(rPnt)) 1697 { 1698 if ((!bCheckIfMarkable || IsObjMarkable(pObj,pPV))) 1699 { 1700 SdrObjList* pOL=pObj->GetSubList(); 1701 1702 if (pOL!=NULL && pOL->GetObjCount()!=0) 1703 { 1704 SdrObject* pTmpObj; 1705 // OD 30.06.2003 #108784# - adjustment hit point for virtual 1706 // objects. 1707 Point aPnt( rPnt ); 1708 1709 if ( pObj->ISA(SdrVirtObj) ) 1710 { 1711 Point aOffset = static_cast<SdrVirtObj*>(pObj)->GetOffset(); 1712 aPnt.Move( -aOffset.X(), -aOffset.Y() ); 1713 } 1714 1715 pRet=CheckSingleSdrObjectHit(aPnt,nTol,pOL,pPV,nOptions,pMVisLay,pTmpObj); 1716 } 1717 else 1718 { 1719 if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer())) 1720 { 1721 pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false); 1722 } 1723 } 1724 } 1725 } 1726 1727 if (!bDeep && pRet!=NULL) 1728 { 1729 pRet=pObj; 1730 } 1731 1732 return pRet; 1733 } 1734 1735 SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList* pOL, SdrPageView* pPV, sal_uIntPtr nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj) const 1736 { 1737 sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD)!=0; 1738 SdrObject* pRet=NULL; 1739 rpRootObj=NULL; 1740 if (pOL!=NULL) 1741 { 1742 // #110988# 1743 sal_Bool bRemap(pOL->GetOwnerObj() && pOL->GetOwnerObj()->ISA(E3dScene)); 1744 E3dScene* pRemapScene = (bRemap ? (E3dScene*)pOL->GetOwnerObj() : 0L); 1745 1746 sal_uIntPtr nObjAnz=pOL->GetObjCount(); 1747 sal_uIntPtr nObjNum=bBack ? 0 : nObjAnz; 1748 while (pRet==NULL && (bBack ? nObjNum<nObjAnz : nObjNum>0)) { 1749 if (!bBack) nObjNum--; 1750 SdrObject* pObj; 1751 1752 // #110988# 1753 if(bRemap) 1754 { 1755 pObj = pOL->GetObj(pRemapScene->RemapOrdNum(nObjNum)); 1756 } 1757 else 1758 { 1759 pObj = pOL->GetObj(nObjNum); 1760 } 1761 1762 pRet=CheckSingleSdrObjectHit(rPnt,nTol,pObj,pPV,nOptions,pMVisLay); 1763 if (pRet!=NULL) rpRootObj=pObj; 1764 if (bBack) nObjNum++; 1765 } 1766 } 1767 return pRet; 1768 } 1769 1770 sal_Bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions) const 1771 { 1772 return PickObj(rPnt,nTol,rpObj,rpPV,nOptions,NULL,NULL,NULL); 1773 } 1774 1775 sal_Bool SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr nOptions, SdrObject** ppRootObj, sal_uIntPtr* pnMarkNum, sal_uInt16* pnPassNum) const 1776 { // Fehlt noch Pass2,Pass3 1777 SortMarkedObjects(); 1778 if (ppRootObj!=NULL) *ppRootObj=NULL; 1779 if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND; 1780 if (pnPassNum!=NULL) *pnPassNum=0; 1781 rpObj=NULL; 1782 rpPV=NULL; 1783 sal_Bool bWholePage=(nOptions & SDRSEARCH_WHOLEPAGE) !=0; 1784 sal_Bool bMarked=(nOptions & SDRSEARCH_MARKED) !=0; 1785 sal_Bool bMasters=!bMarked && (nOptions & SDRSEARCH_ALSOONMASTER) !=0; 1786 sal_Bool bBack=(nOptions & SDRSEARCH_BACKWARD) !=0; 1787 #if OSL_DEBUG_LEVEL > 0 1788 sal_Bool bNext=(nOptions & SDRSEARCH_NEXT) !=0; (void)bNext; // n.i. 1789 sal_Bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; (void)bBoundCheckOn2ndPass;// n.i. 1790 sal_Bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; (void)bCheckNearestOn3rdPass;// n.i. 1791 #endif 1792 if (nTol<0) nTol=ImpGetHitTolLogic(nTol,NULL); 1793 Point aPt(rPnt); 1794 SdrObject* pObj=NULL; 1795 SdrObject* pHitObj=NULL; 1796 SdrPageView* pPV=NULL; 1797 if (!bBack && ((SdrObjEditView*)this)->IsTextEditFrameHit(rPnt)) { 1798 pObj=((SdrObjEditView*)this)->GetTextEditObject(); 1799 pHitObj=pObj; 1800 pPV=((SdrObjEditView*)this)->GetTextEditPageView(); 1801 } 1802 if (bMarked) { 1803 sal_uIntPtr nMrkAnz=GetMarkedObjectCount(); 1804 sal_uIntPtr nMrkNum=bBack ? 0 : nMrkAnz; 1805 while (pHitObj==NULL && (bBack ? nMrkNum<nMrkAnz : nMrkNum>0)) { 1806 if (!bBack) nMrkNum--; 1807 SdrMark* pM=GetSdrMarkByIndex(nMrkNum); 1808 pObj=pM->GetMarkedSdrObj(); 1809 pPV=pM->GetPageView(); 1810 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,nOptions,NULL); 1811 if (bBack) nMrkNum++; 1812 } 1813 } 1814 else 1815 { 1816 pPV = GetSdrPageView(); 1817 1818 if(pPV) 1819 { 1820 SdrPage* pPage=pPV->GetPage(); 1821 sal_uInt16 nPgAnz=1; 1822 1823 if(bMasters && pPage->TRG_HasMasterPage()) 1824 { 1825 nPgAnz++; 1826 } 1827 1828 sal_Bool bExtraPassForWholePage=bWholePage && pPage!=pPV->GetObjList(); 1829 if (bExtraPassForWholePage) nPgAnz++; // Suche erst in AktObjList, dann auf der gesamten Page 1830 sal_uInt16 nPgNum=bBack ? 0 : nPgAnz; 1831 while (pHitObj==NULL && (bBack ? nPgNum<nPgAnz : nPgNum>0)) { 1832 sal_uIntPtr nTmpOptions=nOptions; 1833 if (!bBack) nPgNum--; 1834 const SetOfByte* pMVisLay=NULL; 1835 SdrObjList* pObjList=NULL; 1836 if (pnPassNum!=NULL) *pnPassNum&=~(SDRSEARCHPASS_MASTERPAGE|SDRSEARCHPASS_INACTIVELIST); 1837 if (nPgNum>=nPgAnz-1 || (bExtraPassForWholePage && nPgNum>=nPgAnz-2)) 1838 { 1839 pObjList=pPV->GetObjList(); 1840 if (bExtraPassForWholePage && nPgNum==nPgAnz-2) { 1841 pObjList=pPage; 1842 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_INACTIVELIST; 1843 } 1844 } 1845 else 1846 { 1847 // sonst MasterPage 1848 SdrPage& rMasterPage = pPage->TRG_GetMasterPage(); 1849 pMVisLay = &pPage->TRG_GetMasterPageVisibleLayers(); 1850 pObjList = &rMasterPage; 1851 1852 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_MASTERPAGE; 1853 nTmpOptions=nTmpOptions | SDRSEARCH_IMPISMASTER; 1854 } 1855 pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObjList,pPV,nTmpOptions,pMVisLay,pObj); 1856 if (bBack) nPgNum++; 1857 } 1858 } 1859 } 1860 if (pHitObj!=NULL) { 1861 if (ppRootObj!=NULL) *ppRootObj=pObj; 1862 if ((nOptions & SDRSEARCH_DEEP) !=0) pObj=pHitObj; 1863 if ((nOptions & SDRSEARCH_TESTTEXTEDIT) !=0) { 1864 if (!pObj->HasTextEdit() || pPV->GetLockedLayers().IsSet(pObj->GetLayer())) { 1865 pObj=NULL; 1866 } 1867 } 1868 if (pObj!=NULL && (nOptions & SDRSEARCH_TESTMACRO) !=0) { 1869 SdrObjMacroHitRec aHitRec; 1870 aHitRec.aPos=aPt; 1871 aHitRec.aDownPos=aPt; 1872 aHitRec.nTol=nTol; 1873 aHitRec.pVisiLayer=&pPV->GetVisibleLayers(); 1874 aHitRec.pPageView=pPV; 1875 if (!pObj->HasMacro() || !pObj->IsMacroHit(aHitRec)) pObj=NULL; 1876 } 1877 if (pObj!=NULL && (nOptions & SDRSEARCH_WITHTEXT) !=0 && pObj->GetOutlinerParaObject()==NULL) pObj=NULL; 1878 if (pObj!=NULL && (nOptions & SDRSEARCH_TESTTEXTAREA) !=0) 1879 { 1880 if(!SdrObjectPrimitiveHit(*pObj, aPt, 0, *pPV, 0, true)) 1881 { 1882 pObj = 0; 1883 } 1884 } 1885 if (pObj!=NULL) { 1886 rpObj=pObj; 1887 rpPV=pPV; 1888 if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_DIRECT; 1889 } 1890 } 1891 return rpObj!=NULL; 1892 } 1893 1894 sal_Bool SdrMarkView::PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, sal_uIntPtr* pnMarkNum, sal_uIntPtr nOptions) const 1895 { 1896 SortMarkedObjects(); 1897 sal_Bool bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; 1898 sal_Bool bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; 1899 rpObj=NULL; 1900 rpPV=NULL; 1901 if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND; 1902 Point aPt(rPnt); 1903 sal_uInt16 nTol=(sal_uInt16)nHitTolLog; 1904 sal_Bool bFnd=sal_False; 1905 sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); 1906 sal_uIntPtr nMarkNum; 1907 for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) { 1908 nMarkNum--; 1909 SdrMark* pM=GetSdrMarkByIndex(nMarkNum); 1910 SdrPageView* pPV=pM->GetPageView(); 1911 SdrObject* pObj=pM->GetMarkedSdrObj(); 1912 bFnd = 0 != CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,SDRSEARCH_TESTMARKABLE,0); 1913 if (bFnd) { 1914 rpObj=pObj; 1915 rpPV=pPV; 1916 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum; 1917 } 1918 } 1919 if ((bBoundCheckOn2ndPass || bCheckNearestOn3rdPass) && !bFnd) { 1920 SdrObject* pBestObj=NULL; 1921 SdrPageView* pBestPV=NULL; 1922 sal_uIntPtr nBestMarkNum=0; 1923 sal_uIntPtr nBestDist=ULONG_MAX; 1924 for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) { 1925 nMarkNum--; 1926 SdrMark* pM=GetSdrMarkByIndex(nMarkNum); 1927 SdrPageView* pPV=pM->GetPageView(); 1928 SdrObject* pObj=pM->GetMarkedSdrObj(); 1929 Rectangle aRect(pObj->GetCurrentBoundRect()); 1930 aRect.Left ()-=nTol; 1931 aRect.Top ()-=nTol; 1932 aRect.Right ()+=nTol; 1933 aRect.Bottom()+=nTol; 1934 if (aRect.IsInside(aPt)) { 1935 bFnd=sal_True; 1936 rpObj=pObj; 1937 rpPV=pPV; 1938 if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum; 1939 } else if (bCheckNearestOn3rdPass) { 1940 sal_uIntPtr nDist=0; 1941 if (aPt.X()<aRect.Left()) nDist+=aRect.Left()-aPt.X(); 1942 if (aPt.X()>aRect.Right()) nDist+=aPt.X()-aRect.Right(); 1943 if (aPt.Y()<aRect.Top()) nDist+=aRect.Top()-aPt.Y(); 1944 if (aPt.Y()>aRect.Bottom()) nDist+=aPt.Y()-aRect.Bottom(); 1945 if (nDist<nBestDist) { 1946 pBestObj=pObj; 1947 pBestPV=pPV; 1948 nBestMarkNum=nMarkNum; 1949 } 1950 } 1951 } 1952 if (bCheckNearestOn3rdPass && !bFnd) { 1953 rpObj=pBestObj; 1954 rpPV=pBestPV; 1955 if (pnMarkNum!=NULL) *pnMarkNum=nBestMarkNum; 1956 bFnd=pBestObj!=NULL; 1957 } 1958 } 1959 return bFnd; 1960 } 1961 1962 SdrHitKind SdrMarkView::PickSomething(const Point& rPnt, short nTol) const 1963 { 1964 nTol=ImpGetHitTolLogic(nTol,NULL); 1965 SdrHitKind eRet=SDRHIT_NONE; 1966 Point aPt(rPnt); 1967 SdrObject* pObj=NULL; 1968 SdrPageView* pPV=NULL; 1969 if (eRet==SDRHIT_NONE && PickObj(rPnt,sal_uInt16(nTol),pObj,pPV,SDRSEARCH_PICKMARKABLE)) { 1970 Rectangle aRct1(aPt-Point(nTol,nTol),aPt+Point(nTol,nTol)); // HitRect fuer Toleranz 1971 Rectangle aBR(pObj->GetCurrentBoundRect()); 1972 if (aRct1.IsInside(aBR.TopLeft())) eRet=SDRHIT_BOUNDTL; 1973 else if (aRct1.IsInside(aBR.TopCenter())) eRet=SDRHIT_BOUNDTC; 1974 else if (aRct1.IsInside(aBR.TopRight())) eRet=SDRHIT_BOUNDTR; 1975 else if (aRct1.IsInside(aBR.LeftCenter())) eRet=SDRHIT_BOUNDCL; 1976 else if (aRct1.IsInside(aBR.RightCenter())) eRet=SDRHIT_BOUNDCR; 1977 else if (aRct1.IsInside(aBR.BottomLeft())) eRet=SDRHIT_BOUNDBL; 1978 else if (aRct1.IsInside(aBR.BottomCenter())) eRet=SDRHIT_BOUNDBC; 1979 else if (aRct1.IsInside(aBR.BottomRight())) eRet=SDRHIT_BOUNDBR; 1980 else eRet=SDRHIT_OBJECT; 1981 } 1982 return eRet; 1983 } 1984 1985 void SdrMarkView::UnmarkAllObj(SdrPageView* pPV) 1986 { 1987 if (GetMarkedObjectCount()!=0) { 1988 BrkAction(); 1989 //HMHBOOL bVis=bHdlShown; 1990 //HMHif (bVis) HideMarkHdl(); 1991 if (pPV!=NULL) 1992 { 1993 GetMarkedObjectListWriteAccess().DeletePageView(*pPV); 1994 } 1995 else 1996 { 1997 GetMarkedObjectListWriteAccess().Clear(); 1998 } 1999 pMarkedObj=NULL; 2000 pMarkedPV=NULL; 2001 MarkListHasChanged(); 2002 AdjustMarkHdl(); //HMHTRUE); 2003 //HMHif (bVis) ShowMarkHdl(); // ggf. fuer die RefPoints 2004 } 2005 } 2006 2007 void SdrMarkView::MarkAllObj(SdrPageView* _pPV) 2008 { 2009 BrkAction(); 2010 //HMHHideMarkHdl(); 2011 2012 if(!_pPV) 2013 { 2014 _pPV = GetSdrPageView(); 2015 } 2016 2017 // #i69171# _pPV may still be NULL if there is no SDrPageView (!), e.g. when inserting 2018 // other files 2019 if(_pPV) 2020 { 2021 const bool bMarkChg(GetMarkedObjectListWriteAccess().InsertPageView(*_pPV)); 2022 2023 if(bMarkChg) 2024 { 2025 MarkListHasChanged(); 2026 } 2027 } 2028 2029 if(GetMarkedObjectCount()) 2030 { 2031 AdjustMarkHdl(); //HMHTRUE); 2032 //HMHShowMarkHdl(); 2033 } 2034 } 2035 2036 void SdrMarkView::AdjustMarkHdl() //HMHBOOL bRestraintPaint) 2037 { 2038 //HMHBOOL bVis=bHdlShown; 2039 //HMHif (bVis) HideMarkHdl(); 2040 CheckMarked(); 2041 SetMarkRects(); 2042 SetMarkHandles(); 2043 //HMHif(bRestraintPaint && bVis) 2044 //HMH{ 2045 //HMH ShowMarkHdl(); 2046 //HMH} 2047 } 2048 2049 Rectangle SdrMarkView::GetMarkedObjBoundRect() const 2050 { 2051 Rectangle aRect; 2052 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) { 2053 SdrMark* pM=GetSdrMarkByIndex(nm); 2054 SdrObject* pO=pM->GetMarkedSdrObj(); 2055 Rectangle aR1(pO->GetCurrentBoundRect()); 2056 if (aRect.IsEmpty()) aRect=aR1; 2057 else aRect.Union(aR1); 2058 } 2059 return aRect; 2060 } 2061 2062 const Rectangle& SdrMarkView::GetMarkedObjRect() const 2063 { 2064 if (bMarkedObjRectDirty) { 2065 ((SdrMarkView*)this)->bMarkedObjRectDirty=sal_False; 2066 Rectangle aRect; 2067 for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) { 2068 SdrMark* pM=GetSdrMarkByIndex(nm); 2069 SdrObject* pO=pM->GetMarkedSdrObj(); 2070 Rectangle aR1(pO->GetSnapRect()); 2071 if (aRect.IsEmpty()) aRect=aR1; 2072 else aRect.Union(aR1); 2073 } 2074 ((SdrMarkView*)this)->aMarkedObjRect=aRect; 2075 } 2076 return aMarkedObjRect; 2077 } 2078 2079 //////////////////////////////////////////////////////////////////////////////////////////////////// 2080 2081 void SdrMarkView::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal, sal_uInt16 nOpt) const 2082 { 2083 rStr = ImpGetResStr(nStrCacheID); 2084 xub_StrLen nPos = rStr.SearchAscii("%1"); 2085 2086 if(nPos != STRING_NOTFOUND) 2087 { 2088 rStr.Erase(nPos, 2); 2089 2090 if(nOpt == IMPSDR_POINTSDESCRIPTION) 2091 { 2092 rStr.Insert(GetDescriptionOfMarkedPoints(), nPos); 2093 } 2094 else if(nOpt == IMPSDR_GLUEPOINTSDESCRIPTION) 2095 { 2096 rStr.Insert(GetDescriptionOfMarkedGluePoints(), nPos); 2097 } 2098 else 2099 { 2100 rStr.Insert(GetDescriptionOfMarkedObjects(), nPos); 2101 } 2102 } 2103 2104 nPos = rStr.SearchAscii("%2"); 2105 2106 if(nPos != STRING_NOTFOUND) 2107 { 2108 rStr.Erase(nPos, 2); 2109 rStr.Insert(UniString::CreateFromInt32(nVal), nPos); 2110 } 2111 } 2112 2113 //////////////////////////////////////////////////////////////////////////////////////////////////// 2114 2115 sal_Bool SdrMarkView::EnterMarkedGroup() 2116 { 2117 sal_Bool bRet=sal_False; 2118 // Es wird nur die erste gefundene Gruppe (also nur in einer PageView) geentert 2119 // Weil PageView::EnterGroup ein AdjustMarkHdl ruft. 2120 // Das muss ich per Flag mal unterbinden vvvvvvvv 2121 SdrPageView* pPV = GetSdrPageView(); 2122 2123 if(pPV) 2124 { 2125 sal_Bool bEnter=sal_False; 2126 for (sal_uInt32 nm(GetMarkedObjectCount()); nm > 0 && !bEnter;) 2127 { 2128 nm--; 2129 SdrMark* pM=GetSdrMarkByIndex(nm); 2130 if (pM->GetPageView()==pPV) { 2131 SdrObject* pObj=pM->GetMarkedSdrObj(); 2132 if (pObj->IsGroupObject()) { 2133 if (pPV->EnterGroup(pObj)) { 2134 bRet=sal_True; 2135 bEnter=sal_True; 2136 } 2137 } 2138 } 2139 } 2140 } 2141 return bRet; 2142 } 2143 2144 //////////////////////////////////////////////////////////////////////////////////////////////////// 2145 2146 void SdrMarkView::MarkListHasChanged() 2147 { 2148 GetMarkedObjectListWriteAccess().SetNameDirty(); 2149 SetEdgesOfMarkedNodesDirty(); // bEdgesOfMarkedNodesDirty=sal_True; 2150 2151 bMarkedObjRectDirty=sal_True; 2152 bMarkedPointsRectsDirty=sal_True; 2153 #ifdef DBG_UTIL 2154 if (pItemBrowser!=NULL) pItemBrowser->SetDirty(); 2155 #endif 2156 sal_Bool bOneEdgeMarked=sal_False; 2157 if (GetMarkedObjectCount()==1) { 2158 const SdrObject* pObj=GetMarkedObjectByIndex(0); 2159 if (pObj->GetObjInventor()==SdrInventor) { 2160 sal_uInt16 nIdent=pObj->GetObjIdentifier(); 2161 bOneEdgeMarked=nIdent==OBJ_EDGE; 2162 } 2163 } 2164 ImpSetGlueVisible4(bOneEdgeMarked); 2165 } 2166 2167 //////////////////////////////////////////////////////////////////////////////////////////////////// 2168 2169 void SdrMarkView::SetMoveOutside(sal_Bool bOn) 2170 { 2171 aHdl.SetMoveOutside(bOn); 2172 } 2173 2174 sal_Bool SdrMarkView::IsMoveOutside() const 2175 { 2176 return aHdl.IsMoveOutside(); 2177 } 2178 2179 void SdrMarkView::SetDesignMode( sal_Bool _bOn ) 2180 { 2181 if ( bDesignMode != _bOn ) 2182 { 2183 bDesignMode = _bOn; 2184 SdrPageView* pPageView = GetSdrPageView(); 2185 if ( pPageView ) 2186 pPageView->SetDesignMode( _bOn ); 2187 } 2188 } 2189 2190 // MarkHandles Objektaenderung: 2191 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2192 // - Bei Notify mit HINT_OBJCHG (oder so) werden die Handles erstmal versteckt 2193 // (wenn nicht schon wegen Dragging versteckt). 2194 // - XorHdl: Bei ModelHasChanged() werden sie dann wieder angezeigt. 2195 // - PaintEvents kommen nun durch. 2196 // - Die XorHandles werden z.T. wieder uebermalt. 2197 // - Xor: Nach dem Painten werden die Handles im (vom PaintHandler gerufenen) 2198 // CompleteRedraw per ToggleShownXor bei gesetzter ClipRegion nochmal gemalt 2199 // und damit ist alles in Butter. 2200 // - ToggleShownXor macht bei SolidHdl nix weil bHdlShown=FALSE 2201 // - Der AfterPaintTimer wird gestartet. 2202 // - SolidHdl: Im AfterPaintHandler wird ShowMarkHdl gerufen. 2203 // Da die Handles zu diesem Zeitpunkt nicht angezeigt sind wird: 2204 // - SaveBackground durchgefuehrt. 2205 // - DrawMarkHdl gerufen und bHdlShown gesetzt. 2206 // 2207 // MarkHandles bei sonstigem Invalidate: 2208 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2209 // In diesem Fall bekomme ich kein Notify und beim Aufruf des 2210 // PaintHandlers->CompleteRedraw() sind auch die SolidHandles sichtbar. 2211 2212