xref: /trunk/main/sw/source/core/crsr/viscrs.cxx (revision 5c0a9181)
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