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