1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 32 #ifndef _SVSTDARR_HXX 33 #define _SVSTDARR_USHORTS 34 #include <svl/svstdarr.hxx> 35 #endif 36 37 #include <vcl/dialog.hxx> 38 #include <vcl/msgbox.hxx> 39 #include <vcl/wrkwin.hxx> 40 #include <viewopt.hxx> 41 #include <frmtool.hxx> 42 #include <viscrs.hxx> 43 #include <crsrsh.hxx> 44 #include <doc.hxx> 45 #include <swtable.hxx> 46 #include <viewimp.hxx> 47 #include <dview.hxx> 48 #include <rootfrm.hxx> 49 #include <txtfrm.hxx> // SwTxtFrm 50 #include <docary.hxx> 51 #include <extinput.hxx> 52 #include <ndtxt.hxx> 53 #include <scriptinfo.hxx> 54 #include <mdiexp.hxx> // GetSearchDialog 55 #ifndef _COMCORE_HRC 56 #include <comcore.hrc> // ResId fuer Abfrage wenn zu Search & Replaces 57 #endif 58 59 #include <svx/sdr/overlay/overlaymanager.hxx> 60 #include <svx/sdrpaintwindow.hxx> 61 #include <vcl/svapp.hxx> 62 #include <svx/sdr/overlay/overlayselection.hxx> 63 64 extern void SwCalcPixStatics( OutputDevice *pOut ); 65 66 //Damit beim ShowCrsr nicht immer wieder die gleiche Size teuer ermittelt 67 //werden muss, hier statische Member, die beim Wechsel des MapModes 68 // angepasst werden 69 70 long SwSelPaintRects::nPixPtX = 0; 71 long SwSelPaintRects::nPixPtY = 0; 72 MapMode* SwSelPaintRects::pMapMode = 0; 73 74 75 #ifdef SHOW_BOOKMARKS 76 // #include <IMark.hxx> 77 // 78 // class SwBookmarkRects : public SwSelPaintRects 79 // { 80 // virtual void Paint( const Rectangle& rRect ); 81 // virtual void FillRects(); 82 // 83 // public: 84 // SwBookmarkRects( const SwCrsrShell& rSh ) : SwSelPaintRects( rSh ) {} 85 // }; 86 // 87 // void SwBookmarkRects::Paint( const Rectangle& rRect ) 88 // { 89 // Window* pWin = GetShell()->GetWin(); 90 // 91 // RasterOp eOld( pWin->GetRasterOp() ); 92 // sal_Bool bLCol = pWin->IsLineColor(); 93 // Color aLCol( pWin->GetLineColor() ); 94 // sal_Bool bFCol = pWin->IsFillColor(); 95 // Color aFCol( pWin->GetFillColor() ); 96 // 97 // pWin->SetRasterOp( ROP_XOR ); 98 // Color aCol( RGB_COLORDATA( 0xF0, 0xC8, 0xF0 ) ^ COL_WHITE ); 99 // pWin->SetFillColor( aCol ); 100 // pWin->SetLineColor( aCol ); 101 // 102 // pWin->DrawRect( rRect ); 103 // 104 // if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor(); 105 // if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor(); 106 // pWin->SetRasterOp( eOld ); 107 // } 108 // 109 // void SwBookmarkRects::FillRects() 110 // { 111 // SwRegionRects aReg( GetShell()->VisArea() ); 112 // 113 // const SwBookmarks& rBkmkTbl = GetShell()->getIDocumentMarkAccess()->getBookmarks(); 114 // SwShellCrsr* pCrsr = 0; 115 // for( sal_uInt16 n = 0; n < rBkmkTbl.Count(); ++n ) 116 // { 117 // const SwBookmark& rBkmk = *rBkmkTbl[ n ]; 118 // if( rBkmk.IsBookMark() && rBkmk.GetOtherPos() ) 119 // { 120 // if( !pCrsr ) 121 // { 122 // pCrsr = new SwShellCrsr( *GetShell(), rBkmk.GetPos() ); 123 // pCrsr->SetMark(); 124 // } 125 // else 126 // *pCrsr->GetPoint() = rBkmk.GetPos(); 127 // *pCrsr->GetMark() = *rBkmk.GetOtherPos(); 128 // pCrsr->FillRects(); 129 // for( sal_uInt16 i = 0; i < pCrsr->Count(); ++i ) 130 // aReg -= (*pCrsr)[ i ]; 131 // 132 // pCrsr->Remove( 0, i ); 133 // } 134 // } 135 // if( pCrsr ) delete pCrsr; 136 // 137 // aReg.Invert(); 138 // SwRects::Insert( &aReg, 0 ); 139 // } 140 // 141 // SwBookmarkRects* pBookMarkRects = 0; 142 // 143 // void ShowBookmarks( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 ) 144 // { 145 // if( !pBookMarkRects && pSh->getIDocumentMarkAccess()->getBookmarks().Count() ) 146 // pBookMarkRects = new SwBookmarkRects( *pSh ); 147 // 148 // if( pBookMarkRects ) 149 // { 150 // switch( nAction ) 151 // { 152 // case 1: pBookMarkRects->Show(); break; 153 // case 2: pBookMarkRects->Hide(); break; 154 // case 3: pBookMarkRects->Invalidate( *pRect ); break; 155 // } 156 // 157 // if( !pBookMarkRects->Count() ) 158 // delete pBookMarkRects, pBookMarkRects = 0; 159 // } 160 // } 161 // 162 // #define SHOWBOOKMARKS1( nAct ) ShowBookmarks( GetShell(),nAct ); 163 // #define SHOWBOOKMARKS2( nAct, pRect ) ShowBookmarks( GetShell(),nAct, pRect ); 164 165 #else 166 167 #define SHOWBOOKMARKS1( nAct ) 168 #define SHOWBOOKMARKS2( nAct, pRect ) 169 170 #endif 171 172 #ifdef SHOW_REDLINES 173 #include <redline.hxx> 174 175 class SwRedlineRects : public SwSelPaintRects 176 { 177 sal_uInt16 nMode; 178 sal_uInt16 nNm; 179 180 virtual void Paint( const Rectangle& rRect ); 181 virtual void FillRects(); 182 183 public: 184 SwRedlineRects( const SwCrsrShell& rSh, sal_uInt16 nName, sal_uInt16 n ) 185 : SwSelPaintRects( rSh ), nMode( n ), nNm( nName ) 186 {} 187 }; 188 189 void SwRedlineRects::Paint( const Rectangle& rRect ) 190 { 191 Window* pWin = GetShell()->GetWin(); 192 193 RasterOp eOld( pWin->GetRasterOp() ); 194 sal_Bool bLCol = pWin->IsLineColor(); 195 Color aLCol( pWin->GetLineColor() ); 196 sal_Bool bFCol = pWin->IsFillColor(); 197 Color aFCol( pWin->GetFillColor() ); 198 199 pWin->SetRasterOp( ROP_XOR ); 200 Color aCol; 201 202 sal_uInt8 nVal = 0xc8 - ( (nMode / 4) * 16 ); 203 switch( nMode % 4 ) 204 { 205 case 0: aCol = RGB_COLORDATA( nVal, nVal, 0xFF ); break; 206 case 1: aCol = RGB_COLORDATA( 0xFF, 0xc8, nVal ); break; 207 case 2: aCol = RGB_COLORDATA( nVal, 0xFF, nVal ); break; 208 case 3: aCol = RGB_COLORDATA( 0xFF, nVal, nVal ); break; 209 } 210 aCol = aCol.GetColor() ^ COL_WHITE; 211 212 pWin->SetFillColor( aCol ); 213 pWin->SetLineColor( aCol ); 214 215 pWin->DrawRect( rRect ); 216 217 if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor(); 218 if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor(); 219 pWin->SetRasterOp( eOld ); 220 } 221 222 void SwRedlineRects::FillRects() 223 { 224 SwRegionRects aReg( GetShell()->VisArea() ); 225 226 const SwRedlineTbl& rTbl = GetShell()->GetDoc()->GetRedlineTbl(); 227 SwShellCrsr* pCrsr = 0; 228 for( sal_uInt16 n = 0; n < rTbl.Count(); ++n ) 229 { 230 const SwRedline& rRed = *rTbl[ n ]; 231 if( rRed.HasMark() && (nMode % 4 ) == rRed.GetType() && 232 nNm == rRed.GetAuthor() ) 233 { 234 if( !pCrsr ) 235 { 236 pCrsr = new SwShellCrsr( *GetShell(), *rRed.GetPoint() ); 237 pCrsr->SetMark(); 238 } 239 else 240 *pCrsr->GetPoint() = *rRed.GetPoint(); 241 *pCrsr->GetMark() = *rRed.GetMark(); 242 pCrsr->FillRects(); 243 for( sal_uInt16 i = 0; i < pCrsr->Count(); ++i ) 244 aReg -= (*pCrsr)[ i ]; 245 246 pCrsr->Remove( 0, i ); 247 } 248 } 249 if( pCrsr ) delete pCrsr; 250 251 aReg.Invert(); 252 SwRects::Insert( &aReg, 0 ); 253 } 254 255 SwRedlineRects* aRedlines[ 10 * 4 ]; 256 static int bFirstCall = sal_True; 257 258 void ShowRedlines( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 ) 259 { 260 if( bFirstCall ) 261 { 262 memset( aRedlines, 0, sizeof(aRedlines)); 263 bFirstCall = sal_False; 264 } 265 266 const SwRedlineTbl& rTbl = pSh->GetDoc()->GetRedlineTbl(); 267 const SwRedlineAuthorTbl& rAuthorTbl = pSh->GetDoc()->GetRedlineAuthorTbl(); 268 269 for( sal_uInt16 n = 0; n < rAuthorTbl.Count(); ++n ) 270 { 271 for( int i = 0; i < 4; ++i ) 272 { 273 SwRedlineRects** ppRedRect = &aRedlines[ n * 4 + i ]; 274 if( rTbl.Count() && !*ppRedRect ) 275 *ppRedRect = new SwRedlineRects( *pSh, n, n * 4 + i ); 276 277 if( *ppRedRect ) 278 { 279 switch( nAction ) 280 { 281 case 1: (*ppRedRect)->Show(); break; 282 case 2: (*ppRedRect)->Hide(); break; 283 case 3: (*ppRedRect)->Invalidate( *pRect ); break; 284 } 285 286 if( !(*ppRedRect)->Count() ) 287 delete *ppRedRect, *ppRedRect = 0; 288 } 289 } 290 } 291 } 292 293 #define SHOWREDLINES1( nAct ) ShowRedlines( GetShell(),nAct ); 294 #define SHOWREDLINES2( nAct, pRect ) ShowRedlines( GetShell(),nAct, pRect ); 295 296 #else 297 298 #define SHOWREDLINES1( nAct ) 299 #define SHOWREDLINES2( nAct, pRect ) 300 301 #endif 302 303 #ifdef JP_REDLINE 304 if( GetDoc()->GetRedlineTbl().Count() ) 305 { 306 SwRedlineTbl& rRedlineTbl = (SwRedlineTbl&)GetDoc()->GetRedlineTbl(); 307 for( sal_uInt16 i = 0; i < rRedlineTbl.Count(); ++i ) 308 rRedlineTbl[ i ]->HideRects( *GetShell() ); 309 } 310 #endif 311 312 // -------- Ab hier Klassen / Methoden fuer den nicht Text-Cursor ------ 313 314 SwVisCrsr::SwVisCrsr( const SwCrsrShell * pCShell ) 315 : pCrsrShell( pCShell ) 316 { 317 pCShell->GetWin()->SetCursor( &aTxtCrsr ); 318 bIsVisible = aTxtCrsr.IsVisible(); 319 bIsDragCrsr = sal_False; 320 aTxtCrsr.SetWidth( 0 ); 321 322 #ifdef SW_CRSR_TIMER 323 bTimerOn = sal_True; 324 SetTimeout( 50 ); // 50msec Verzoegerung 325 #endif 326 } 327 328 329 330 SwVisCrsr::~SwVisCrsr() 331 { 332 #ifdef SW_CRSR_TIMER 333 if( bTimerOn ) 334 Stop(); // Timer stoppen 335 #endif 336 337 if( bIsVisible && aTxtCrsr.IsVisible() ) 338 aTxtCrsr.Hide(); 339 340 pCrsrShell->GetWin()->SetCursor( 0 ); 341 } 342 343 344 345 346 void SwVisCrsr::Show() 347 { 348 if( !bIsVisible ) 349 { 350 bIsVisible = sal_True; 351 352 // muss ueberhaupt angezeigt werden ? 353 if( pCrsrShell->VisArea().IsOver( pCrsrShell->aCharRect ) ) 354 #ifdef SW_CRSR_TIMER 355 { 356 if( bTimerOn ) 357 Start(); // Timer aufsetzen 358 else 359 { 360 if( IsActive() ) 361 Stop(); // Timer Stoppen 362 363 _SetPosAndShow(); 364 } 365 } 366 #else 367 _SetPosAndShow(); 368 #endif 369 } 370 } 371 372 373 374 void SwVisCrsr::Hide() 375 { 376 if( bIsVisible ) 377 { 378 bIsVisible = sal_False; 379 380 #ifdef SW_CRSR_TIMER 381 if( IsActive() ) 382 Stop(); // Timer Stoppen 383 #endif 384 385 if( aTxtCrsr.IsVisible() ) // sollten die Flags nicht gueltig sein? 386 aTxtCrsr.Hide(); 387 } 388 } 389 390 #ifdef SW_CRSR_TIMER 391 392 void __EXPORT SwVisCrsr::Timeout() 393 { 394 ASSERT( !bIsDragCrsr, "Timer vorher abschalten" ); 395 if( bIsVisible ) 396 { 397 if ( !pCrsrShell->GetWin() ) //SwFrmFmt::GetGraphic setzt das Win temp aus! 398 Start(); 399 else 400 _SetPosAndShow(); 401 } 402 } 403 404 sal_Bool SwCrsrShell::ChgCrsrTimerFlag( sal_Bool bTimerOn ) 405 { 406 return pVisCrsr->ChgTimerFlag( bTimerOn ); 407 } 408 409 410 sal_Bool SwVisCrsr::ChgTimerFlag( sal_Bool bFlag ) 411 { 412 bOld = bTimerOn; 413 if( !bFlag && bIsVisible && IsActive() ) 414 { 415 Stop(); // Timer Stoppen 416 _SetPosAndShow(); 417 } 418 bTimerOn = bFlag; 419 return bOld; 420 } 421 422 #endif 423 424 425 void SwVisCrsr::_SetPosAndShow() 426 { 427 SwRect aRect; 428 long nTmpY = pCrsrShell->aCrsrHeight.Y(); 429 if( 0 > nTmpY ) 430 { 431 nTmpY = -nTmpY; 432 aTxtCrsr.SetOrientation( 900 ); 433 aRect = SwRect( pCrsrShell->aCharRect.Pos(), 434 Size( pCrsrShell->aCharRect.Height(), nTmpY ) ); 435 aRect.Pos().X() += pCrsrShell->aCrsrHeight.X(); 436 if( pCrsrShell->IsOverwriteCrsr() ) 437 aRect.Pos().Y() += aRect.Width(); 438 } 439 else 440 { 441 aTxtCrsr.SetOrientation( 0 ); 442 aRect = SwRect( pCrsrShell->aCharRect.Pos(), 443 Size( pCrsrShell->aCharRect.Width(), nTmpY ) ); 444 aRect.Pos().Y() += pCrsrShell->aCrsrHeight.X(); 445 } 446 447 // check if cursor should show the current cursor bidi level 448 aTxtCrsr.SetDirection( CURSOR_DIRECTION_NONE ); 449 const SwCursor* pTmpCrsr = pCrsrShell->_GetCrsr(); 450 451 if ( pTmpCrsr && !pCrsrShell->IsOverwriteCrsr() ) 452 { 453 SwNode& rNode = pTmpCrsr->GetPoint()->nNode.GetNode(); 454 if( rNode.IsTxtNode() ) 455 { 456 const SwTxtNode& rTNd = *rNode.GetTxtNode(); 457 const SwFrm* pFrm = rTNd.getLayoutFrm( pCrsrShell->GetLayout(), 0, 0, sal_False ); 458 if ( pFrm ) 459 { 460 const SwScriptInfo* pSI = ((SwTxtFrm*)pFrm)->GetScriptInfo(); 461 // cursor level has to be shown 462 if ( pSI && pSI->CountDirChg() > 1 ) 463 { 464 aTxtCrsr.SetDirection( 465 ( pTmpCrsr->GetCrsrBidiLevel() % 2 ) ? 466 CURSOR_DIRECTION_RTL : 467 CURSOR_DIRECTION_LTR ); 468 } 469 470 if ( pFrm->IsRightToLeft() ) 471 { 472 const OutputDevice *pOut = pCrsrShell->GetOut(); 473 if ( pOut ) 474 { 475 long nSize = pOut->GetSettings().GetStyleSettings().GetCursorSize(); 476 Size aSize( nSize, nSize ); 477 aSize = pOut->PixelToLogic( aSize ); 478 aRect.Left( aRect.Left() - aSize.Width() ); 479 } 480 } 481 } 482 } 483 } 484 485 if( aRect.Height() ) 486 { 487 ::SwCalcPixStatics( pCrsrShell->GetOut() ); 488 ::SwAlignRect( aRect, (ViewShell*)pCrsrShell ); 489 } 490 if( !pCrsrShell->IsOverwriteCrsr() || bIsDragCrsr || 491 pCrsrShell->IsSelection() ) 492 aRect.Width( 0 ); 493 494 aTxtCrsr.SetSize( aRect.SSize() ); 495 496 aTxtCrsr.SetPos( aRect.Pos() ); 497 if ( !pCrsrShell->IsCrsrReadonly() || pCrsrShell->GetViewOptions()->IsSelectionInReadonly() ) 498 { 499 if ( pCrsrShell->GetDrawView() ) 500 ((SwDrawView*)pCrsrShell->GetDrawView())->SetAnimationEnabled( 501 !pCrsrShell->IsSelection() ); 502 503 sal_uInt16 nStyle = bIsDragCrsr ? CURSOR_SHADOW : 0; 504 if( nStyle != aTxtCrsr.GetStyle() ) 505 { 506 aTxtCrsr.SetStyle( nStyle ); 507 aTxtCrsr.SetWindow( bIsDragCrsr ? pCrsrShell->GetWin() : 0 ); 508 } 509 510 aTxtCrsr.Show(); 511 } 512 } 513 514 ////////////////////////////////////////////////////////////////////////////// 515 516 SwSelPaintRects::SwSelPaintRects( const SwCrsrShell& rCSh ) 517 : SwRects( 0 ), 518 pCShell( &rCSh ), 519 mpCursorOverlay(0) 520 { 521 } 522 523 SwSelPaintRects::~SwSelPaintRects() 524 { 525 Hide(); 526 } 527 528 void SwSelPaintRects::swapContent(SwSelPaintRects& rSwap) 529 { 530 SwRects aTempRects; 531 aTempRects.Insert(this, 0); 532 533 Remove(0, Count()); 534 Insert(&rSwap, 0); 535 536 rSwap.Remove(0, rSwap.Count()); 537 rSwap.Insert(&aTempRects, 0); 538 539 // #i75172# also swap mpCursorOverlay 540 sdr::overlay::OverlayObject* pTempOverlay = getCursorOverlay(); 541 setCursorOverlay(rSwap.getCursorOverlay()); 542 rSwap.setCursorOverlay(pTempOverlay); 543 } 544 545 void SwSelPaintRects::Hide() 546 { 547 if(mpCursorOverlay) 548 { 549 delete mpCursorOverlay; 550 mpCursorOverlay = 0; 551 } 552 553 SwRects::Remove( 0, Count() ); 554 } 555 556 void SwSelPaintRects::Show() 557 { 558 SdrView* pView = (SdrView*)pCShell->GetDrawView(); 559 560 if(pView && pView->PaintWindowCount()) 561 { 562 // reset rects 563 SwRects::Remove( 0, SwRects::Count() ); 564 FillRects(); 565 566 // get new rects 567 std::vector< basegfx::B2DRange > aNewRanges; 568 569 for(sal_uInt16 a(0); a < Count(); a++) 570 { 571 const SwRect aNextRect((*this)[a]); 572 const Rectangle aPntRect(aNextRect.SVRect()); 573 574 aNewRanges.push_back(basegfx::B2DRange( 575 aPntRect.Left(), aPntRect.Top(), 576 aPntRect.Right() + 1, aPntRect.Bottom() + 1)); 577 } 578 579 if(mpCursorOverlay) 580 { 581 if(aNewRanges.size()) 582 { 583 static_cast< sdr::overlay::OverlaySelection* >(mpCursorOverlay)->setRanges(aNewRanges); 584 } 585 else 586 { 587 delete mpCursorOverlay; 588 mpCursorOverlay = 0; 589 } 590 } 591 else if(Count()) 592 { 593 SdrPaintWindow* pCandidate = pView->GetPaintWindow(0); 594 sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager(); 595 596 if(pTargetOverlay) 597 { 598 // #i97672# get the system's hilight color and limit it to the maximum 599 // allowed luminance. This is needed to react on too bright hilight colors 600 // which would otherwise vive a bad visualisation 601 const OutputDevice *pOut = Application::GetDefaultDevice(); 602 Color aHighlight(pOut->GetSettings().GetStyleSettings().GetHighlightColor()); 603 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 604 const basegfx::BColor aSelection(aHighlight.getBColor()); 605 const double fLuminance(aSelection.luminance()); 606 const double fMaxLum(aSvtOptionsDrawinglayer.GetSelectionMaximumLuminancePercent() / 100.0); 607 608 if(fLuminance > fMaxLum) 609 { 610 const double fFactor(fMaxLum / fLuminance); 611 const basegfx::BColor aNewSelection( 612 aSelection.getRed() * fFactor, 613 aSelection.getGreen() * fFactor, 614 aSelection.getBlue() * fFactor); 615 616 aHighlight = Color(aNewSelection); 617 } 618 619 // create correct selection 620 mpCursorOverlay = new sdr::overlay::OverlaySelection( 621 sdr::overlay::OVERLAY_TRANSPARENT, 622 aHighlight, 623 aNewRanges, 624 true); 625 626 pTargetOverlay->add(*mpCursorOverlay); 627 } 628 } 629 } 630 } 631 632 void SwSelPaintRects::Invalidate( const SwRect& rRect ) 633 { 634 sal_uInt16 nSz = Count(); 635 if( !nSz ) 636 return; 637 638 SwRegionRects aReg( GetShell()->VisArea() ); 639 aReg.Remove( 0, aReg.Count() ); 640 aReg.Insert( this, 0 ); 641 aReg -= rRect; 642 SwRects::Remove( 0, nSz ); 643 SwRects::Insert( &aReg, 0 ); 644 645 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 646 // Liegt die Selection rechts oder unten ausserhalb des sichtbaren 647 // Bereiches, so ist diese nie auf eine Pixel rechts/unten aligned. 648 // Das muss hier erkannt und ggf. das Rechteckt erweitert werden. 649 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 650 if( GetShell()->bVisPortChgd && 0 != ( nSz = Count()) ) 651 { 652 SwSelPaintRects::Get1PixelInLogic( *GetShell() ); 653 SwRect* pRect = (SwRect*)GetData(); 654 for( ; nSz--; ++pRect ) 655 { 656 if( pRect->Right() == GetShell()->aOldRBPos.X() ) 657 pRect->Right( pRect->Right() + nPixPtX ); 658 if( pRect->Bottom() == GetShell()->aOldRBPos.Y() ) 659 pRect->Bottom( pRect->Bottom() + nPixPtY ); 660 } 661 } 662 } 663 664 void SwSelPaintRects::Paint( const Rectangle& /*rRect*/ ) 665 { 666 // nothing to do with overlays 667 } 668 669 670 // check current MapMode of the shell and set possibly the static members. 671 // Optional set the parameters pX, pY 672 void SwSelPaintRects::Get1PixelInLogic( const ViewShell& rSh, 673 long* pX, long* pY ) 674 { 675 const OutputDevice* pOut = rSh.GetWin(); 676 if ( ! pOut ) 677 pOut = rSh.GetOut(); 678 679 const MapMode& rMM = pOut->GetMapMode(); 680 if( pMapMode->GetMapUnit() != rMM.GetMapUnit() || 681 pMapMode->GetScaleX() != rMM.GetScaleX() || 682 pMapMode->GetScaleY() != rMM.GetScaleY() ) 683 { 684 *pMapMode = rMM; 685 Size aTmp( 1, 1 ); 686 aTmp = pOut->PixelToLogic( aTmp ); 687 nPixPtX = aTmp.Width(); 688 nPixPtY = aTmp.Height(); 689 } 690 if( pX ) 691 *pX = nPixPtX; 692 if( pY ) 693 *pY = nPixPtY; 694 } 695 696 697 /* */ 698 699 SwShellCrsr::SwShellCrsr( const SwCrsrShell& rCShell, const SwPosition &rPos ) 700 : SwCursor(rPos,0,false), SwSelPaintRects(rCShell), pPt(SwPaM::GetPoint()) 701 {} 702 703 704 SwShellCrsr::SwShellCrsr( const SwCrsrShell& rCShell, const SwPosition &rPos, 705 const Point& rPtPos, SwPaM* pRing ) 706 : SwCursor(rPos, pRing, false), SwSelPaintRects(rCShell), aMkPt(rPtPos), 707 aPtPt(rPtPos), pPt(SwPaM::GetPoint()) 708 {} 709 710 711 SwShellCrsr::SwShellCrsr( SwShellCrsr& rICrsr ) 712 : SwCursor(rICrsr), SwSelPaintRects(*rICrsr.GetShell()), 713 aMkPt(rICrsr.GetMkPos()), aPtPt(rICrsr.GetPtPos()), pPt(SwPaM::GetPoint()) 714 {} 715 716 SwShellCrsr::~SwShellCrsr() {} 717 718 719 bool SwShellCrsr::IsReadOnlyAvailable() const 720 { 721 return GetShell()->IsReadOnlyAvailable(); 722 } 723 724 void SwShellCrsr::SetMark() 725 { 726 if( SwPaM::GetPoint() == pPt ) 727 aMkPt = aPtPt; 728 else 729 aPtPt = aMkPt; 730 SwPaM::SetMark(); 731 } 732 733 void SwShellCrsr::FillRects() 734 { 735 // die neuen Rechtecke berechnen 736 if( HasMark() && 737 GetPoint()->nNode.GetNode().IsCntntNode() && 738 GetPoint()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() ) && 739 (GetMark()->nNode == GetPoint()->nNode || 740 (GetMark()->nNode.GetNode().IsCntntNode() && 741 GetMark()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() ) ) )) 742 GetShell()->GetLayout()->CalcFrmRects( *this, GetShell()->IsTableMode() ); //swmod 071107//swmod 071225 743 } 744 745 746 void SwShellCrsr::Show() 747 { 748 SwShellCrsr * pTmp = this; 749 do { 750 pTmp->SwSelPaintRects::Show(); 751 } while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) ); 752 753 SHOWBOOKMARKS1( 1 ) 754 SHOWREDLINES1( 1 ) 755 } 756 757 758 // Dieses Rechteck wird neu gepaintet, also ist die SSelection in 759 // dem Bereich ungueltig 760 void SwShellCrsr::Invalidate( const SwRect& rRect ) 761 { 762 SwShellCrsr * pTmp = this; 763 764 do 765 { 766 pTmp->SwSelPaintRects::Invalidate( rRect ); 767 768 // --> FME 2005-08-18 #125102# 769 // skip any non SwShellCrsr objects in the ring 770 // (see:SwAutoFormat::DeleteSel() 771 // <-- 772 Ring* pTmpRing = pTmp; 773 pTmp = 0; 774 do 775 { 776 pTmpRing = pTmpRing->GetNext(); 777 pTmp = dynamic_cast<SwShellCrsr*>(pTmpRing); 778 } 779 while ( !pTmp ); 780 } 781 while( this != pTmp ); 782 783 SHOWBOOKMARKS2( 3, &rRect ) 784 SHOWREDLINES2( 3, &rRect ) 785 } 786 787 788 void SwShellCrsr::Hide() 789 { 790 SwShellCrsr * pTmp = this; 791 do { 792 pTmp->SwSelPaintRects::Hide(); 793 } while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) ); 794 795 SHOWBOOKMARKS1( 2 ) 796 SHOWREDLINES1( 2 ) 797 } 798 799 SwCursor* SwShellCrsr::Create( SwPaM* pRing ) const 800 { 801 return new SwShellCrsr( *GetShell(), *GetPoint(), GetPtPos(), pRing ); 802 } 803 804 805 short SwShellCrsr::MaxReplaceArived() 806 { 807 short nRet = RET_YES; 808 Window* pDlg = LAYOUT_THIS_WINDOW (::GetSearchDialog()); 809 if( pDlg ) 810 { 811 // alte Actions beenden; die Tabellen-Frames werden angelegt und 812 // eine SSelection kann erzeugt werden 813 SvUShorts aArr; 814 sal_uInt16 nActCnt; 815 ViewShell *pShell = const_cast< SwCrsrShell* >( GetShell() ), 816 *pSh = pShell; 817 do { 818 for( nActCnt = 0; pSh->ActionPend(); ++nActCnt ) 819 pSh->EndAction(); 820 aArr.Insert( nActCnt, aArr.Count() ); 821 } while( pShell != ( pSh = (ViewShell*)pSh->GetNext() ) ); 822 823 { 824 nRet = QueryBox( pDlg, SW_RES( MSG_COMCORE_ASKSEARCH )).Execute(); 825 } 826 827 for( sal_uInt16 n = 0; n < aArr.Count(); ++n ) 828 { 829 for( nActCnt = aArr[n]; nActCnt--; ) 830 pSh->StartAction(); 831 pSh = (ViewShell*)pSh->GetNext(); 832 } //swmod 071107//swmod 071225 833 } 834 else 835 // ansonsten aus dem Basic, und dann auf RET_YES schalten 836 nRet = RET_YES; 837 838 return nRet; 839 } 840 841 void SwShellCrsr::SaveTblBoxCntnt( const SwPosition* pPos ) 842 { 843 ((SwCrsrShell*)GetShell())->SaveTblBoxCntnt( pPos ); 844 } 845 846 sal_Bool SwShellCrsr::UpDown( sal_Bool bUp, sal_uInt16 nCnt ) 847 { 848 return SwCursor::UpDown( bUp, nCnt, 849 &GetPtPos(), GetShell()->GetUpDownX() ); 850 } 851 852 #ifdef DBG_UTIL 853 854 // JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung 855 // am sichtbaren Cursor 856 857 sal_Bool SwShellCrsr::IsSelOvr( int eFlags ) 858 { 859 return SwCursor::IsSelOvr( eFlags ); 860 } 861 862 #endif 863 864 // sal_True: an die Position kann der Cursor gesetzt werden 865 sal_Bool SwShellCrsr::IsAtValidPos( sal_Bool bPoint ) const 866 { 867 if( GetShell() && ( GetShell()->IsAllProtect() || 868 GetShell()->GetViewOptions()->IsReadonly() || 869 ( GetShell()->Imp()->GetDrawView() && 870 GetShell()->Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ))) 871 return sal_True; 872 873 return SwCursor::IsAtValidPos( bPoint ); 874 } 875 876 /* */ 877 878 SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh, 879 const SwPosition& rPos ) 880 : SwCursor(rPos,0,false), SwShellCrsr(rCrsrSh, rPos), SwTableCursor(rPos) 881 { 882 } 883 884 SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh, 885 const SwPosition& rMkPos, const Point& rMkPt, 886 const SwPosition& rPtPos, const Point& rPtPt ) 887 : SwCursor(rPtPos,0,false), SwShellCrsr(rCrsrSh, rPtPos), SwTableCursor(rPtPos) 888 { 889 SetMark(); 890 *GetMark() = rMkPos; 891 GetMkPos() = rMkPt; 892 GetPtPos() = rPtPt; 893 } 894 895 SwShellTableCrsr::~SwShellTableCrsr() {} 896 897 void SwShellTableCrsr::SetMark() { SwShellCrsr::SetMark(); } 898 899 SwCursor* SwShellTableCrsr::Create( SwPaM* pRing ) const 900 { 901 return SwShellCrsr::Create( pRing ); 902 } 903 short SwShellTableCrsr::MaxReplaceArived() 904 { 905 return SwShellCrsr::MaxReplaceArived(); 906 } 907 void SwShellTableCrsr::SaveTblBoxCntnt( const SwPosition* pPos ) 908 { 909 SwShellCrsr::SaveTblBoxCntnt( pPos ); 910 } 911 912 913 void SwShellTableCrsr::FillRects() 914 { 915 // die neuen Rechtecke berechnen 916 // JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!! 917 if( !aSelBoxes.Count() || bParked || 918 !GetPoint()->nNode.GetIndex() ) 919 return; 920 921 SwRegionRects aReg( GetShell()->VisArea() ); 922 SwNodes& rNds = GetDoc()->GetNodes(); 923 for( sal_uInt16 n = 0; n < aSelBoxes.Count(); ++n ) 924 { 925 const SwStartNode* pSttNd = (*(aSelBoxes.GetData() + n ))->GetSttNd(); 926 const SwTableNode* pSelTblNd = pSttNd->FindTableNode(); 927 928 SwNodeIndex aIdx( *pSttNd ); 929 SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False ); 930 931 // TABLE IN TABLE 932 // (see also lcl_FindTopLevelTable in unoobj2.cxx for a different 933 // version to do this) 934 const SwTableNode* pCurTblNd = pCNd->FindTableNode(); 935 while ( pSelTblNd != pCurTblNd && pCurTblNd ) 936 { 937 aIdx = pCurTblNd->EndOfSectionIndex(); 938 pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False ); 939 pCurTblNd = pCNd->FindTableNode(); 940 } 941 942 if( !pCNd ) 943 continue; 944 945 SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetSttPos() ); 946 while( pFrm && !pFrm->IsCellFrm() ) 947 pFrm = pFrm->GetUpper(); 948 949 ASSERT( pFrm, "Node nicht in einer Tabelle" ); 950 951 while ( pFrm ) 952 { 953 if( pFrm && aReg.GetOrigin().IsOver( pFrm->Frm() ) ) 954 aReg -= pFrm->Frm(); 955 956 pFrm = pFrm->GetNextCellLeaf( MAKEPAGE_NONE ); 957 } 958 } 959 aReg.Invert(); 960 Insert( &aReg, 0 ); 961 } 962 963 964 // Pruefe, ob sich der SPoint innerhalb der Tabellen-SSelection befindet 965 sal_Bool SwShellTableCrsr::IsInside( const Point& rPt ) const 966 { 967 // die neuen Rechtecke berechnen 968 // JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!! 969 if( !aSelBoxes.Count() || bParked || 970 !GetPoint()->nNode.GetIndex() ) 971 return sal_False; 972 973 SwNodes& rNds = GetDoc()->GetNodes(); 974 for( sal_uInt16 n = 0; n < aSelBoxes.Count(); ++n ) 975 { 976 SwNodeIndex aIdx( *(*(aSelBoxes.GetData() + n ))->GetSttNd() ); 977 SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False ); 978 if( !pCNd ) 979 continue; 980 981 SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetPtPos() ); 982 while( pFrm && !pFrm->IsCellFrm() ) 983 pFrm = pFrm->GetUpper(); 984 ASSERT( pFrm, "Node nicht in einer Tabelle" ); 985 if( pFrm && pFrm->Frm().IsInside( rPt ) ) 986 return sal_True; 987 } 988 return sal_False; 989 } 990 991 #ifdef DBG_UTIL 992 993 // JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung 994 // am sichtbaren Cursor 995 sal_Bool SwShellTableCrsr::IsSelOvr( int eFlags ) 996 { 997 return SwShellCrsr::IsSelOvr( eFlags ); 998 } 999 1000 #endif 1001 1002 sal_Bool SwShellTableCrsr::IsAtValidPos( sal_Bool bPoint ) const 1003 { 1004 return SwShellCrsr::IsAtValidPos( bPoint ); 1005 } 1006 1007