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