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