xref: /AOO41X/main/sw/source/core/crsr/viscrs.cxx (revision cf4248c2d8a863006f561ef6552aa38d8e15838f)
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_sw.hxx"
26 
27 
28 #ifndef _SVSTDARR_HXX
29 #define _SVSTDARR_USHORTS
30 #include <svl/svstdarr.hxx>
31 #endif
32 
33 #include <vcl/dialog.hxx>
34 #include <vcl/msgbox.hxx>
35 #include <vcl/wrkwin.hxx>
36 #include <viewopt.hxx>
37 #include <frmtool.hxx>
38 #include <viscrs.hxx>
39 #include <crsrsh.hxx>
40 #include <doc.hxx>
41 #include <swtable.hxx>
42 #include <viewimp.hxx>
43 #include <dview.hxx>
44 #include <rootfrm.hxx>
45 #include <txtfrm.hxx>
46 #include <docary.hxx>
47 #include <extinput.hxx>
48 #include <ndtxt.hxx>
49 #include <txtfld.hxx>
50 #include <scriptinfo.hxx>
51 #include <mdiexp.hxx>
52 #ifndef _COMCORE_HRC
53 #include <comcore.hrc>          // ResId fuer Abfrage wenn zu Search & Replaces
54 #endif
55 
56 #include <svx/sdr/overlay/overlaymanager.hxx>
57 #include <svx/sdrpaintwindow.hxx>
58 #include <vcl/svapp.hxx>
59 #include <svx/sdr/overlay/overlayselection.hxx>
60 #include <overlayrangesoutline.hxx>
61 
62 #include <boost/scoped_ptr.hpp>
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:
SwRedlineRects(const SwCrsrShell & rSh,sal_uInt16 nName,sal_uInt16 n)184     SwRedlineRects( const SwCrsrShell& rSh, sal_uInt16 nName, sal_uInt16 n )
185         : SwSelPaintRects( rSh ), nMode( n ), nNm( nName )
186     {}
187 };
188 
Paint(const Rectangle & rRect)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 
FillRects()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 
ShowRedlines(const SwCrsrShell * pSh,int nAction,const SwRect * pRect=0)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 
SwVisCrsr(const SwCrsrShell * pCShell)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 
~SwVisCrsr()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 
Show()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 
Hide()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 
Timeout()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 
ChgCrsrTimerFlag(sal_Bool bTimerOn)404 sal_Bool SwCrsrShell::ChgCrsrTimerFlag( sal_Bool bTimerOn )
405 {
406     return pVisCrsr->ChgTimerFlag( bTimerOn );
407 }
408 
409 
ChgTimerFlag(sal_Bool bFlag)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 
_SetPosAndShow()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 
SwSelPaintRects(const SwCrsrShell & rCSh)516 SwSelPaintRects::SwSelPaintRects( const SwCrsrShell& rCSh )
517     : SwRects( 0 )
518     , pCShell( &rCSh )
519     , mpCursorOverlay( 0 )
520     , mbShowTxtInputFldOverlay( true )
521     , mpTxtInputFldOverlay( NULL )
522 {
523 }
524 
~SwSelPaintRects()525 SwSelPaintRects::~SwSelPaintRects()
526 {
527     Hide();
528 }
529 
swapContent(SwSelPaintRects & rSwap)530 void SwSelPaintRects::swapContent(SwSelPaintRects& rSwap)
531 {
532     SwRects aTempRects;
533     aTempRects.Insert(this, 0);
534 
535     Remove(0, Count());
536     Insert(&rSwap, 0);
537 
538     rSwap.Remove(0, rSwap.Count());
539     rSwap.Insert(&aTempRects, 0);
540 
541     // #i75172# also swap mpCursorOverlay
542     sdr::overlay::OverlayObject* pTempOverlay = getCursorOverlay();
543     setCursorOverlay(rSwap.getCursorOverlay());
544     rSwap.setCursorOverlay(pTempOverlay);
545 
546     const bool bTempShowTxtInputFldOverlay = mbShowTxtInputFldOverlay;
547     mbShowTxtInputFldOverlay = rSwap.mbShowTxtInputFldOverlay;
548     rSwap.mbShowTxtInputFldOverlay = bTempShowTxtInputFldOverlay;
549 
550     sw::overlay::OverlayRangesOutline* pTempTxtInputFldOverlay = mpTxtInputFldOverlay;
551     mpTxtInputFldOverlay = rSwap.mpTxtInputFldOverlay;
552     rSwap.mpTxtInputFldOverlay = pTempTxtInputFldOverlay;
553 }
554 
Hide()555 void SwSelPaintRects::Hide()
556 {
557     if(mpCursorOverlay)
558     {
559         delete mpCursorOverlay;
560         mpCursorOverlay = 0;
561     }
562 
563     if ( mpTxtInputFldOverlay != NULL )
564     {
565         delete mpTxtInputFldOverlay;
566         mpTxtInputFldOverlay = NULL;
567     }
568 
569     SwRects::Remove( 0, Count() );
570 }
571 
Show()572 void SwSelPaintRects::Show()
573 {
574     SdrView* pView = (SdrView*)pCShell->GetDrawView();
575 
576     if(pView && pView->PaintWindowCount())
577     {
578         // reset rects
579         SwRects::Remove( 0, SwRects::Count() );
580         FillRects();
581 
582         // get new rects
583         std::vector< basegfx::B2DRange > aNewRanges;
584 
585         for(sal_uInt16 a(0); a < Count(); a++)
586         {
587             const SwRect aNextRect((*this)[a]);
588             const Rectangle aPntRect(aNextRect.SVRect());
589 
590             aNewRanges.push_back(basegfx::B2DRange(
591                 aPntRect.Left(), aPntRect.Top(),
592                 aPntRect.Right() + 1, aPntRect.Bottom() + 1));
593         }
594 
595         if(mpCursorOverlay)
596         {
597             if(aNewRanges.size())
598             {
599                 static_cast< sdr::overlay::OverlaySelection* >(mpCursorOverlay)->setRanges(aNewRanges);
600             }
601             else
602             {
603                 delete mpCursorOverlay;
604                 mpCursorOverlay = 0;
605             }
606         }
607         else if(Count())
608         {
609             SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
610             sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
611 
612             if(pTargetOverlay)
613             {
614                 // get the system's hilight color
615                 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
616                 const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
617 
618                 // create correct selection
619                 mpCursorOverlay = new sdr::overlay::OverlaySelection(
620                     sdr::overlay::OVERLAY_TRANSPARENT,
621                     aHighlight,
622                     aNewRanges,
623                     true);
624 
625                 pTargetOverlay->add(*mpCursorOverlay);
626             }
627         }
628 
629         HighlightInputFld();
630     }
631 }
632 
633 
HighlightInputFld()634 void SwSelPaintRects::HighlightInputFld()
635 {
636     std::vector< basegfx::B2DRange > aInputFldRanges;
637 
638     if ( mbShowTxtInputFldOverlay )
639     {
640         SwTxtInputFld* pCurTxtInputFldAtCrsr =
641             dynamic_cast<SwTxtInputFld*>(GetShell()->GetTxtFldAtPos( GetShell()->GetCrsr()->Start(), false ));
642         if ( pCurTxtInputFldAtCrsr != NULL )
643         {
644             SwTxtNode* pTxtNode = pCurTxtInputFldAtCrsr->GetpTxtNode();
645             ::boost::scoped_ptr<SwShellCrsr> pCrsrForInputTxtFld(
646                 new SwShellCrsr( *GetShell(), SwPosition( *pTxtNode, *(pCurTxtInputFldAtCrsr->GetStart()) ) ) );
647             pCrsrForInputTxtFld->SetMark();
648             pCrsrForInputTxtFld->GetMark()->nNode = *pTxtNode;
649             pCrsrForInputTxtFld->GetMark()->nContent.Assign( pTxtNode, *(pCurTxtInputFldAtCrsr->End()) );
650 
651             pCrsrForInputTxtFld->FillRects();
652 
653             for( sal_uInt16 a(0); a < pCrsrForInputTxtFld->Count(); ++a )
654             {
655                 const SwRect aNextRect((*pCrsrForInputTxtFld)[a]);
656                 const Rectangle aPntRect(aNextRect.SVRect());
657 
658                 aInputFldRanges.push_back(basegfx::B2DRange(
659                     aPntRect.Left(), aPntRect.Top(),
660                     aPntRect.Right() + 1, aPntRect.Bottom() + 1));
661             }
662         }
663     }
664 
665     if ( aInputFldRanges.size() > 0 )
666     {
667         if ( mpTxtInputFldOverlay != NULL )
668         {
669             mpTxtInputFldOverlay->setRanges( aInputFldRanges );
670         }
671         else
672         {
673             SdrView* pView = (SdrView*)GetShell()->GetDrawView();
674             SdrPaintWindow* pCandidate = pView->GetPaintWindow(0);
675             sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
676 
677             if(pTargetOverlay)
678             {
679                 // use system's hilight color with decreased luminance as highlight color
680                 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
681                 Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
682                 aHighlight.DecreaseLuminance( 128 );
683 
684                 mpTxtInputFldOverlay = new sw::overlay::OverlayRangesOutline( aHighlight, aInputFldRanges );
685                 pTargetOverlay->add( *mpTxtInputFldOverlay );
686             }
687         }
688     }
689     else
690     {
691         if ( mpTxtInputFldOverlay != NULL )
692         {
693             delete mpTxtInputFldOverlay;
694             mpTxtInputFldOverlay = NULL;
695         }
696     }
697 }
698 
699 
Invalidate(const SwRect & rRect)700 void SwSelPaintRects::Invalidate( const SwRect& rRect )
701 {
702     sal_uInt16 nSz = Count();
703     if( !nSz )
704         return;
705 
706     SwRegionRects aReg( GetShell()->VisArea() );
707     aReg.Remove( 0, aReg.Count() );
708     aReg.Insert( this, 0 );
709     aReg -= rRect;
710     SwRects::Remove( 0, nSz );
711     SwRects::Insert( &aReg, 0 );
712 
713     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
714     // Liegt die Selection rechts oder unten ausserhalb des sichtbaren
715     // Bereiches, so ist diese nie auf eine Pixel rechts/unten aligned.
716     // Das muss hier erkannt und ggf. das Rechteckt erweitert werden.
717     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
718     if( GetShell()->bVisPortChgd && 0 != ( nSz = Count()) )
719     {
720         SwSelPaintRects::Get1PixelInLogic( *GetShell() );
721         SwRect* pRect = (SwRect*)GetData();
722         for( ; nSz--; ++pRect )
723         {
724             if( pRect->Right() == GetShell()->aOldRBPos.X() )
725                 pRect->Right( pRect->Right() + nPixPtX );
726             if( pRect->Bottom() == GetShell()->aOldRBPos.Y() )
727                 pRect->Bottom( pRect->Bottom() + nPixPtY );
728         }
729     }
730 }
731 
Paint(const Rectangle &)732 void SwSelPaintRects::Paint( const Rectangle& /*rRect*/ )
733 {
734     // nothing to do with overlays
735 }
736 
737 
738 // check current MapMode of the shell and set possibly the static members.
739 // Optional set the parameters pX, pY
Get1PixelInLogic(const ViewShell & rSh,long * pX,long * pY)740 void SwSelPaintRects::Get1PixelInLogic( const ViewShell& rSh,
741                                         long* pX, long* pY )
742 {
743     const OutputDevice* pOut = rSh.GetWin();
744     if ( ! pOut )
745         pOut = rSh.GetOut();
746 
747     const MapMode& rMM = pOut->GetMapMode();
748     if( pMapMode->GetMapUnit() != rMM.GetMapUnit() ||
749         pMapMode->GetScaleX() != rMM.GetScaleX() ||
750         pMapMode->GetScaleY() != rMM.GetScaleY() )
751     {
752         *pMapMode = rMM;
753         Size aTmp( 1, 1 );
754         aTmp = pOut->PixelToLogic( aTmp );
755         nPixPtX = aTmp.Width();
756         nPixPtY = aTmp.Height();
757     }
758     if( pX )
759         *pX = nPixPtX;
760     if( pY )
761         *pY = nPixPtY;
762 }
763 
764 
765 /*  */
766 
SwShellCrsr(const SwCrsrShell & rCShell,const SwPosition & rPos)767 SwShellCrsr::SwShellCrsr(
768     const SwCrsrShell& rCShell,
769     const SwPosition &rPos )
770     : SwCursor(rPos,0,false)
771     , SwSelPaintRects(rCShell)
772     , pPt(SwPaM::GetPoint())
773 {}
774 
775 
SwShellCrsr(const SwCrsrShell & rCShell,const SwPosition & rPos,const Point & rPtPos,SwPaM * pRing)776 SwShellCrsr::SwShellCrsr(
777     const SwCrsrShell& rCShell,
778     const SwPosition &rPos,
779     const Point& rPtPos,
780     SwPaM* pRing )
781     : SwCursor(rPos, pRing, false)
782     , SwSelPaintRects(rCShell)
783     , aMkPt(rPtPos)
784     , aPtPt(rPtPos)
785     , pPt(SwPaM::GetPoint())
786 {}
787 
788 
SwShellCrsr(SwShellCrsr & rICrsr)789 SwShellCrsr::SwShellCrsr( SwShellCrsr& rICrsr )
790     : SwCursor(rICrsr)
791     , SwSelPaintRects(*rICrsr.GetShell())
792     , aMkPt(rICrsr.GetMkPos())
793     , aPtPt(rICrsr.GetPtPos())
794     , pPt(SwPaM::GetPoint())
795 {}
796 
~SwShellCrsr()797 SwShellCrsr::~SwShellCrsr()
798 {}
799 
800 
IsReadOnlyAvailable() const801 bool SwShellCrsr::IsReadOnlyAvailable() const
802 {
803     return GetShell()->IsReadOnlyAvailable();
804 }
805 
SetMark()806 void SwShellCrsr::SetMark()
807 {
808     if( SwPaM::GetPoint() == pPt )
809         aMkPt = aPtPt;
810     else
811         aPtPt = aMkPt;
812     SwPaM::SetMark();
813 }
814 
FillRects()815 void SwShellCrsr::FillRects()
816 {
817     // die neuen Rechtecke berechnen
818     if ( HasMark()
819          && GetPoint()->nNode.GetNode().IsCntntNode()
820          && GetPoint()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() )
821          && ( GetMark()->nNode == GetPoint()->nNode
822               || ( GetMark()->nNode.GetNode().IsCntntNode()
823                    && GetMark()->nNode.GetNode().GetCntntNode()->getLayoutFrm( GetShell()->GetLayout() ) ) ) )
824     {
825         GetShell()->GetLayout()->CalcFrmRects( *this );
826     }
827 }
828 
829 
Show()830 void SwShellCrsr::Show()
831 {
832     SwShellCrsr * pTmp = this;
833     do {
834         pTmp->SwSelPaintRects::Show();
835     } while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) );
836 
837     SHOWBOOKMARKS1( 1 )
838     SHOWREDLINES1( 1 )
839 }
840 
841 
842     // Dieses Rechteck wird neu gepaintet, also ist die SSelection in
843     // dem Bereich ungueltig
Invalidate(const SwRect & rRect)844 void SwShellCrsr::Invalidate( const SwRect& rRect )
845 {
846     SwShellCrsr * pTmp = this;
847 
848     do
849     {
850         pTmp->SwSelPaintRects::Invalidate( rRect );
851 
852         // --> FME 2005-08-18 #125102#
853         // skip any non SwShellCrsr objects in the ring
854         // (see:SwAutoFormat::DeleteSel()
855         // <--
856         Ring* pTmpRing = pTmp;
857         pTmp = 0;
858         do
859         {
860             pTmpRing = pTmpRing->GetNext();
861             pTmp = dynamic_cast<SwShellCrsr*>(pTmpRing);
862         }
863         while ( !pTmp );
864     }
865     while( this != pTmp );
866 
867     SHOWBOOKMARKS2( 3, &rRect )
868     SHOWREDLINES2( 3, &rRect )
869 }
870 
871 
Hide()872 void SwShellCrsr::Hide()
873 {
874     SwShellCrsr * pTmp = this;
875     do {
876         pTmp->SwSelPaintRects::Hide();
877     } while( this != ( pTmp = dynamic_cast<SwShellCrsr*>(pTmp->GetNext()) ) );
878 
879     SHOWBOOKMARKS1( 2 )
880     SHOWREDLINES1( 2 )
881 }
882 
Create(SwPaM * pRing) const883 SwCursor* SwShellCrsr::Create( SwPaM* pRing ) const
884 {
885     return new SwShellCrsr( *GetShell(), *GetPoint(), GetPtPos(), pRing );
886 }
887 
888 
MaxReplaceArived()889 short SwShellCrsr::MaxReplaceArived()
890 {
891     short nRet = RET_YES;
892     Window* pDlg = LAYOUT_THIS_WINDOW (::GetSearchDialog());
893     if( pDlg )
894     {
895         // alte Actions beenden; die Tabellen-Frames werden angelegt und
896         // eine SSelection kann erzeugt werden
897         SvUShorts aArr;
898         sal_uInt16 nActCnt;
899         ViewShell *pShell = const_cast< SwCrsrShell* >( GetShell() ),
900                   *pSh = pShell;
901         do {
902             for( nActCnt = 0; pSh->ActionPend(); ++nActCnt )
903                 pSh->EndAction();
904             aArr.Insert( nActCnt, aArr.Count() );
905         } while( pShell != ( pSh = (ViewShell*)pSh->GetNext() ) );
906 
907         {
908             nRet = QueryBox( pDlg, SW_RES( MSG_COMCORE_ASKSEARCH )).Execute();
909         }
910 
911         for( sal_uInt16 n = 0; n < aArr.Count(); ++n )
912         {
913             for( nActCnt = aArr[n]; nActCnt--; )
914                 pSh->StartAction();
915             pSh = (ViewShell*)pSh->GetNext();
916         }   //swmod 071107//swmod 071225
917     }
918     else
919         // ansonsten aus dem Basic, und dann auf RET_YES schalten
920         nRet = RET_YES;
921 
922     return nRet;
923 }
924 
SaveTblBoxCntnt(const SwPosition * pPos)925 void SwShellCrsr::SaveTblBoxCntnt( const SwPosition* pPos )
926 {
927     ((SwCrsrShell*)GetShell())->SaveTblBoxCntnt( pPos );
928 }
929 
UpDown(sal_Bool bUp,sal_uInt16 nCnt)930 sal_Bool SwShellCrsr::UpDown( sal_Bool bUp, sal_uInt16 nCnt )
931 {
932     return SwCursor::UpDown( bUp, nCnt,
933                             &GetPtPos(), GetShell()->GetUpDownX() );
934 }
935 
936 #ifdef DBG_UTIL
937 
938 // JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung
939 //              am sichtbaren Cursor
940 
IsSelOvr(int eFlags)941 sal_Bool SwShellCrsr::IsSelOvr( int eFlags )
942 {
943     return SwCursor::IsSelOvr( eFlags );
944 }
945 
946 #endif
947 
948 // sal_True: an die Position kann der Cursor gesetzt werden
IsAtValidPos(sal_Bool bPoint) const949 sal_Bool SwShellCrsr::IsAtValidPos( sal_Bool bPoint ) const
950 {
951     if( GetShell() && ( GetShell()->IsAllProtect() ||
952         GetShell()->GetViewOptions()->IsReadonly() ||
953         ( GetShell()->Imp()->GetDrawView() &&
954           GetShell()->Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() )))
955         return sal_True;
956 
957     return SwCursor::IsAtValidPos( bPoint );
958 }
959 
960 /*  */
961 
SwShellTableCrsr(const SwCrsrShell & rCrsrSh,const SwPosition & rPos)962 SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh,
963                                     const SwPosition& rPos )
964     : SwCursor(rPos,0,false), SwShellCrsr(rCrsrSh, rPos), SwTableCursor(rPos)
965 {
966 }
967 
SwShellTableCrsr(const SwCrsrShell & rCrsrSh,const SwPosition & rMkPos,const Point & rMkPt,const SwPosition & rPtPos,const Point & rPtPt)968 SwShellTableCrsr::SwShellTableCrsr( const SwCrsrShell& rCrsrSh,
969                     const SwPosition& rMkPos, const Point& rMkPt,
970                     const SwPosition& rPtPos, const Point& rPtPt )
971     : SwCursor(rPtPos,0,false), SwShellCrsr(rCrsrSh, rPtPos), SwTableCursor(rPtPos)
972 {
973     SetMark();
974     *GetMark() = rMkPos;
975     GetMkPos() = rMkPt;
976     GetPtPos() = rPtPt;
977 }
978 
~SwShellTableCrsr()979 SwShellTableCrsr::~SwShellTableCrsr() {}
980 
SetMark()981 void SwShellTableCrsr::SetMark()                { SwShellCrsr::SetMark(); }
982 
Create(SwPaM * pRing) const983 SwCursor* SwShellTableCrsr::Create( SwPaM* pRing ) const
984 {
985     return SwShellCrsr::Create( pRing );
986 }
MaxReplaceArived()987 short SwShellTableCrsr::MaxReplaceArived()
988 {
989     return SwShellCrsr::MaxReplaceArived();
990 }
SaveTblBoxCntnt(const SwPosition * pPos)991 void SwShellTableCrsr::SaveTblBoxCntnt( const SwPosition* pPos )
992 {
993     SwShellCrsr::SaveTblBoxCntnt( pPos );
994 }
995 
996 
FillRects()997 void SwShellTableCrsr::FillRects()
998 {
999     // die neuen Rechtecke berechnen
1000     // JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!!
1001     if( !aSelBoxes.Count() || bParked ||
1002         !GetPoint()->nNode.GetIndex() )
1003         return;
1004 
1005     SwRegionRects aReg( GetShell()->VisArea() );
1006     SwNodes& rNds = GetDoc()->GetNodes();
1007     for( sal_uInt16 n = 0; n < aSelBoxes.Count(); ++n )
1008     {
1009         const SwStartNode* pSttNd = (*(aSelBoxes.GetData() + n ))->GetSttNd();
1010         const SwTableNode* pSelTblNd = pSttNd->FindTableNode();
1011 
1012         SwNodeIndex aIdx( *pSttNd );
1013         SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False );
1014 
1015         // TABLE IN TABLE
1016         // (see also lcl_FindTopLevelTable in unoobj2.cxx for a different
1017         // version to do this)
1018         const SwTableNode* pCurTblNd = pCNd->FindTableNode();
1019         while ( pSelTblNd != pCurTblNd && pCurTblNd )
1020         {
1021             aIdx = pCurTblNd->EndOfSectionIndex();
1022             pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False );
1023             pCurTblNd = pCNd->FindTableNode();
1024         }
1025 
1026         if( !pCNd )
1027             continue;
1028 
1029         SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetSttPos() );
1030         while( pFrm && !pFrm->IsCellFrm() )
1031             pFrm = pFrm->GetUpper();
1032 
1033         ASSERT( pFrm, "Node nicht in einer Tabelle" );
1034 
1035         while ( pFrm )
1036         {
1037             if( pFrm && aReg.GetOrigin().IsOver( pFrm->Frm() ) )
1038                 aReg -= pFrm->Frm();
1039 
1040             pFrm = pFrm->GetNextCellLeaf( MAKEPAGE_NONE );
1041         }
1042     }
1043     aReg.Invert();
1044     Insert( &aReg, 0 );
1045 }
1046 
1047 
1048 // Pruefe, ob sich der SPoint innerhalb der Tabellen-SSelection befindet
IsInside(const Point & rPt) const1049 sal_Bool SwShellTableCrsr::IsInside( const Point& rPt ) const
1050 {
1051     // die neuen Rechtecke berechnen
1052     // JP 16.01.98: wenn der Cursor noch "geparkt" ist nichts machen!!
1053     if( !aSelBoxes.Count() || bParked ||
1054         !GetPoint()->nNode.GetIndex()  )
1055         return sal_False;
1056 
1057     SwNodes& rNds = GetDoc()->GetNodes();
1058     for( sal_uInt16 n = 0; n < aSelBoxes.Count(); ++n )
1059     {
1060         SwNodeIndex aIdx( *(*(aSelBoxes.GetData() + n ))->GetSttNd() );
1061         SwCntntNode* pCNd = rNds.GoNextSection( &aIdx, sal_True, sal_False );
1062         if( !pCNd )
1063             continue;
1064 
1065         SwFrm* pFrm = pCNd->getLayoutFrm( GetShell()->GetLayout(), &GetPtPos() );
1066         while( pFrm && !pFrm->IsCellFrm() )
1067             pFrm = pFrm->GetUpper();
1068         ASSERT( pFrm, "Node nicht in einer Tabelle" );
1069         if( pFrm && pFrm->Frm().IsInside( rPt ) )
1070             return sal_True;
1071     }
1072     return sal_False;
1073 }
1074 
1075 #ifdef DBG_UTIL
1076 
1077 // JP 05.03.98: zum Testen des UNO-Crsr Verhaltens hier die Implementierung
1078 //              am sichtbaren Cursor
IsSelOvr(int eFlags)1079 sal_Bool SwShellTableCrsr::IsSelOvr( int eFlags )
1080 {
1081     return SwShellCrsr::IsSelOvr( eFlags );
1082 }
1083 
1084 #endif
1085 
IsAtValidPos(sal_Bool bPoint) const1086 sal_Bool SwShellTableCrsr::IsAtValidPos( sal_Bool bPoint ) const
1087 {
1088     return SwShellCrsr::IsAtValidPos( bPoint );
1089 }
1090 
1091