xref: /aoo42x/main/sc/source/ui/view/tabview3.cxx (revision 4e8031e0)
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_sc.hxx"
26 
27 // System - Includes -----------------------------------------------------
28 
29 
30 
31 // INCLUDE ---------------------------------------------------------------
32 #include <rangelst.hxx>
33 #include "scitems.hxx"
34 #include <editeng/eeitem.hxx>
35 
36 
37 #include <editeng/brshitem.hxx>
38 #include <editeng/editview.hxx>
39 #include <svx/fmshell.hxx>
40 #include <svx/svdoole2.hxx>
41 #include <sfx2/bindings.hxx>
42 #include <sfx2/viewfrm.hxx>
43 #include <vcl/cursor.hxx>
44 
45 #include "tabview.hxx"
46 #include "tabvwsh.hxx"
47 #include "docsh.hxx"
48 #include "gridwin.hxx"
49 #include "olinewin.hxx"
50 #include "colrowba.hxx"
51 #include "tabcont.hxx"
52 #include "scmod.hxx"
53 #include "uiitems.hxx"
54 #include "sc.hrc"
55 #include "viewutil.hxx"
56 #include "editutil.hxx"
57 #include "inputhdl.hxx"
58 #include "inputwin.hxx"
59 #include "validat.hxx"
60 #include "hintwin.hxx"
61 #include "inputopt.hxx"
62 #include "rfindlst.hxx"
63 #include "hiranges.hxx"
64 #include "viewuno.hxx"
65 #include "chartarr.hxx"
66 #include "anyrefdg.hxx"
67 #include "dpobject.hxx"
68 #include "patattr.hxx"
69 #include "dociter.hxx"
70 #include "seltrans.hxx"
71 #include "fillinfo.hxx"
72 #include "AccessibilityHints.hxx"
73 #include "rangeutl.hxx"
74 #include "client.hxx"
75 #include "tabprotection.hxx"
76 
77 #include <com/sun/star/chart2/data/HighlightedRange.hpp>
78 
79 namespace
80 {
81 
82 ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
83 {
84     ScAddress aResult( rRange.aStart );
85 
86     SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
87     SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
88     SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
89     if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
90     {
91         // row by row from first to last sheet
92         sal_Int32 nArea = nWidth * nHeight;
93         aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
94         aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
95         aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
96         if( !rRange.In( aResult ) )
97             aResult = rRange.aStart;
98     }
99 
100     return ScRange( aResult );
101 }
102 
103 } // anonymous namespace
104 
105 using namespace com::sun::star;
106 
107 // -----------------------------------------------------------------------
108 
109 //
110 // ---	Public-Funktionen
111 //
112 
113 void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bControl )
114 {
115 	ScDocument* pDoc = aViewData.GetDocument();
116 	SCTAB nTab = aViewData.GetTabNo();
117 	while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))		//! ViewData !!!
118 		--nPosX;
119 	while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
120 		--nPosY;
121 
122 	sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
123 
124 	if ( bRefMode )
125 	{
126 		DoneRefMode( sal_False );
127 
128 		if (bControl)
129 			SC_MOD()->AddRefEntry();
130 
131 		InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
132 	}
133 	else
134 	{
135 		DoneBlockMode( bControl );
136 		aViewData.ResetOldCursor();
137 		SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
138 	}
139 }
140 
141 void ScTabView::UpdateAutoFillMark()
142 {
143     // single selection or cursor
144 	ScRange aMarkRange;
145 	sal_Bool bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
146 
147 	sal_uInt16 i;
148 	for (i=0; i<4; i++)
149 		if (pGridWin[i] && pGridWin[i]->IsVisible())
150 			pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
151 
152 	for (i=0; i<2; i++)
153 	{
154 		if (pColBar[i] && pColBar[i]->IsVisible())
155 			pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
156 		if (pRowBar[i] && pRowBar[i]->IsVisible())
157 			pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
158 	}
159 
160 	//	selection transfer object is checked together with AutoFill marks,
161 	//	because it has the same requirement of a single continuous block.
162 	CheckSelectionTransfer();	// update selection transfer object
163 }
164 
165 void ScTabView::FakeButtonUp( ScSplitPos eWhich )
166 {
167 	if (pGridWin[eWhich])
168 		pGridWin[eWhich]->FakeButtonUp();
169 }
170 
171 void ScTabView::HideAllCursors()
172 {
173 	for (sal_uInt16 i=0; i<4; i++)
174 		if (pGridWin[i])
175 			if (pGridWin[i]->IsVisible())
176 			{
177 				Cursor* pCur = pGridWin[i]->GetCursor();
178 				if (pCur)
179 					if (pCur->IsVisible())
180 						pCur->Hide();
181 				pGridWin[i]->HideCursor();
182 			}
183 }
184 
185 void ScTabView::ShowAllCursors()
186 {
187 	for (sal_uInt16 i=0; i<4; i++)
188 		if (pGridWin[i])
189 			if (pGridWin[i]->IsVisible())
190 			{
191 				pGridWin[i]->ShowCursor();
192 
193 				// #114409#
194 				pGridWin[i]->CursorChanged();
195 			}
196 }
197 
198 void ScTabView::HideCursor()
199 {
200 	pGridWin[aViewData.GetActivePart()]->HideCursor();
201 }
202 
203 void ScTabView::ShowCursor()
204 {
205 	pGridWin[aViewData.GetActivePart()]->ShowCursor();
206 
207 	// #114409#
208 	pGridWin[aViewData.GetActivePart()]->CursorChanged();
209 }
210 
211 void ScTabView::InvalidateAttribs()
212 {
213 	SfxBindings& rBindings = aViewData.GetBindings();
214 
215 	rBindings.Invalidate( SID_STYLE_APPLY );
216 	rBindings.Invalidate( SID_STYLE_FAMILY2 );
217 	// StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen
218 
219 	rBindings.Invalidate( SID_ATTR_CHAR_FONT );
220 	rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
221 	rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
222 
223 	rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
224 	rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
225 	rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
226 	rBindings.Invalidate( SID_ULINE_VAL_NONE );
227 	rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
228 	rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
229 	rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
230 
231 	rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
232 
233 	rBindings.Invalidate( SID_ALIGNLEFT );
234 	rBindings.Invalidate( SID_ALIGNRIGHT );
235 	rBindings.Invalidate( SID_ALIGNBLOCK );
236 	rBindings.Invalidate( SID_ALIGNCENTERHOR );
237 
238 	rBindings.Invalidate( SID_ALIGNTOP );
239 	rBindings.Invalidate( SID_ALIGNBOTTOM );
240 	rBindings.Invalidate( SID_ALIGNCENTERVER );
241 
242     // stuff for sidebar panels
243     {
244         rBindings.Invalidate( SID_H_ALIGNCELL );
245         rBindings.Invalidate( SID_V_ALIGNCELL );
246         rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
247         rBindings.Invalidate( SID_FRAME_LINECOLOR );
248         rBindings.Invalidate( SID_FRAME_LINESTYLE );
249         rBindings.Invalidate( SID_ATTR_BORDER_OUTER );
250         rBindings.Invalidate( SID_ATTR_BORDER_INNER );
251         rBindings.Invalidate( SID_SCGRIDSHOW );
252         rBindings.Invalidate( SID_ATTR_BORDER_DIAG_TLBR );
253         rBindings.Invalidate( SID_ATTR_BORDER_DIAG_BLTR );
254         rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT );
255     }
256 
257     rBindings.Invalidate( SID_BACKGROUND_COLOR );
258 
259 	rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
260 	rBindings.Invalidate( SID_NUMBER_FORMAT );
261 
262     rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
263     rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
264     rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
265     rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
266 
267     // pseudo slots for Format menu
268     rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
269     rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
270     rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
271     rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
272     rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
273     rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
274     rBindings.Invalidate( SID_ALIGN_ANY_TOP );
275     rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
276     rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
277 
278 //	rBindings.Invalidate( SID_RANGE_VALUE );
279 //	rBindings.Invalidate( SID_RANGE_FORMULA );
280 }
281 
282 //		SetCursor - Cursor setzen, zeichnen, InputWin updaten
283 //					oder Referenz verschicken
284 //		ohne Optimierung wegen BugId 29307
285 
286 #ifdef _MSC_VER
287 #pragma optimize ( "", off )
288 #endif
289 
290 void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bNew )
291 {
292 	SCCOL nOldX = aViewData.GetCurX();
293 	SCROW nOldY = aViewData.GetCurY();
294 
295 	//	DeactivateIP nur noch bei MarkListHasChanged
296 
297 	if ( nPosX != nOldX || nPosY != nOldY || bNew )
298 	{
299         ScTabViewShell* pViewShell = aViewData.GetViewShell();
300         bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
301         if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 oder so
302         {
303             UpdateInputLine();
304         }
305 
306 		HideAllCursors();
307 
308 		aViewData.SetCurX( nPosX );
309 		aViewData.SetCurY( nPosY );
310 
311 		ShowAllCursors();
312 
313 		CursorPosChanged();
314 	}
315 }
316 
317 #ifdef _MSC_VER
318 #pragma optimize ( "", on )
319 #endif
320 
321 void ScTabView::CheckSelectionTransfer()
322 {
323 	if ( aViewData.IsActive() )		// only for active view
324 	{
325 		ScModule* pScMod = SC_MOD();
326 		ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
327 		if ( pOld && pOld->GetView() == this && pOld->StillValid() )
328 		{
329 			// selection not changed - nothing to do
330 		}
331 		else
332 		{
333 			ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
334 			if ( pNew )
335 			{
336 				//	create new selection
337 
338 				if (pOld)
339 					pOld->ForgetView();
340 
341 				uno::Reference<datatransfer::XTransferable> xRef( pNew );
342 				pScMod->SetSelectionTransfer( pNew );
343 				pNew->CopyToSelection( GetActiveWin() );					// may delete pOld
344 			}
345 			else if ( pOld && pOld->GetView() == this )
346 			{
347 				//	remove own selection
348 
349 				pOld->ForgetView();
350 				pScMod->SetSelectionTransfer( NULL );
351 				TransferableHelper::ClearSelection( GetActiveWin() );		// may delete pOld
352 			}
353 			// else: selection from outside: leave unchanged
354 		}
355 	}
356 }
357 
358 // Eingabezeile / Menues updaten
359 //	CursorPosChanged ruft SelectionChanged
360 //	SelectionChanged ruft CellContentChanged
361 
362 void ScTabView::CellContentChanged()
363 {
364 	SfxBindings& rBindings = aViewData.GetBindings();
365 
366 	rBindings.Invalidate( SID_ATTR_SIZE );		// -> Fehlermeldungen anzeigen
367 	rBindings.Invalidate( SID_THESAURUS );
368 	rBindings.Invalidate( SID_HYPERLINK_GETLINK );
369 
370 	InvalidateAttribs();					// Attribut-Updates
371 	TestHintWindow();						// Eingabemeldung (Gueltigkeit)
372 
373 	aViewData.GetViewShell()->UpdateInputHandler();
374 }
375 
376 void ScTabView::SelectionChanged()
377 {
378 	SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
379 	if (pViewFrame)
380 	{
381 		uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
382 		if (xController.is())
383 		{
384 			ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
385 			if (pImp)
386 				pImp->SelectionChanged();
387 		}
388 	}
389 
390 	UpdateAutoFillMark();	// also calls CheckSelectionTransfer
391 
392 	SfxBindings& rBindings = aViewData.GetBindings();
393 
394 	rBindings.Invalidate( SID_CURRENTCELL );	// -> Navigator
395 	rBindings.Invalidate( SID_AUTO_FILTER );	// -> Menue
396 	rBindings.Invalidate( FID_NOTE_VISIBLE );
397     rBindings.Invalidate( SID_DELETE_NOTE );
398 
399 		//	Funktionen, die evtl disabled werden muessen
400 
401 	rBindings.Invalidate( FID_INS_ROWBRK );
402 	rBindings.Invalidate( FID_INS_COLBRK );
403 	rBindings.Invalidate( FID_DEL_ROWBRK );
404 	rBindings.Invalidate( FID_DEL_COLBRK );
405 	rBindings.Invalidate( FID_MERGE_ON );
406 	rBindings.Invalidate( FID_MERGE_OFF );
407     rBindings.Invalidate( FID_MERGE_TOGGLE );
408 	rBindings.Invalidate( SID_AUTOFILTER_HIDE );
409 	rBindings.Invalidate( SID_UNFILTER );
410 //	rBindings.Invalidate( SID_IMPORT_DATA );		// jetzt wieder immer moeglich
411 	rBindings.Invalidate( SID_REIMPORT_DATA );
412 	rBindings.Invalidate( SID_REFRESH_DBAREA );
413 	rBindings.Invalidate( SID_OUTLINE_SHOW );
414 	rBindings.Invalidate( SID_OUTLINE_HIDE );
415 	rBindings.Invalidate( SID_OUTLINE_REMOVE );
416 	rBindings.Invalidate( FID_FILL_TO_BOTTOM );
417 	rBindings.Invalidate( FID_FILL_TO_RIGHT );
418 	rBindings.Invalidate( FID_FILL_TO_TOP );
419 	rBindings.Invalidate( FID_FILL_TO_LEFT );
420 	rBindings.Invalidate( FID_FILL_SERIES );
421 	rBindings.Invalidate( SID_SCENARIOS );
422 	rBindings.Invalidate( SID_AUTOFORMAT );
423 	rBindings.Invalidate( SID_OPENDLG_TABOP );
424 	rBindings.Invalidate( SID_DATA_SELECT );
425 
426 	rBindings.Invalidate( SID_CUT );
427 	rBindings.Invalidate( SID_COPY );
428 	rBindings.Invalidate( SID_PASTE );
429     rBindings.Invalidate( SID_PASTE_SPECIAL );
430 
431 	rBindings.Invalidate( FID_INS_ROW );
432 	rBindings.Invalidate( FID_INS_COLUMN );
433 	rBindings.Invalidate( FID_INS_CELL );
434 	rBindings.Invalidate( FID_INS_CELLSDOWN	);
435 	rBindings.Invalidate( FID_INS_CELLSRIGHT );
436 
437 	rBindings.Invalidate( FID_CHG_COMMENT );
438 
439 		//	nur wegen Zellschutz:
440 
441 	rBindings.Invalidate( SID_CELL_FORMAT_RESET );
442 	rBindings.Invalidate( SID_DELETE );
443 	rBindings.Invalidate( SID_DELETE_CONTENTS );
444 	rBindings.Invalidate( FID_DELETE_CELL );
445 	rBindings.Invalidate( FID_CELL_FORMAT );
446 	rBindings.Invalidate( SID_ENABLE_HYPHENATION );
447 	rBindings.Invalidate( SID_INSERT_POSTIT );
448 	rBindings.Invalidate( SID_CHARMAP );
449 	rBindings.Invalidate( SID_OPENDLG_FUNCTION );
450 //	rBindings.Invalidate( FID_CONDITIONAL_FORMAT );
451 	rBindings.Invalidate( SID_OPENDLG_CONDFRMT );
452 	rBindings.Invalidate( FID_VALIDATION );
453 	rBindings.Invalidate( SID_EXTERNAL_SOURCE );
454     rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
455     rBindings.Invalidate( SID_SORT_ASCENDING );
456     rBindings.Invalidate( SID_SORT_DESCENDING );
457 
458 	if (aViewData.GetViewShell()->HasAccessibilityObjects())
459 		aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_CURSORCHANGED));
460 
461 	CellContentChanged();
462 }
463 
464 void ScTabView::CursorPosChanged()
465 {
466 	sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
467 	if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
468 		aViewData.GetDocShell()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
469 
470 	//	Broadcast, damit andere Views des Dokuments auch umschalten
471 
472 	ScDocument* pDoc = aViewData.GetDocument();
473 	bool bDP = NULL != pDoc->GetDPAtCursor(
474 		aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
475 	aViewData.GetViewShell()->SetPivotShell(bDP);
476 
477 	//	UpdateInputHandler jetzt in CellContentChanged
478 
479 	SelectionChanged();
480 
481 	aViewData.SetTabStartCol( SC_TABSTART_NONE );
482 }
483 
484 void ScTabView::TestHintWindow()
485 {
486     //  show input help window and list drop-down button for validity
487 
488     sal_Bool bListValButton = sal_False;
489     ScAddress aListValPos;
490 
491 	ScDocument* pDoc = aViewData.GetDocument();
492 	const SfxUInt32Item* pItem = (const SfxUInt32Item*)
493 										pDoc->GetAttr( aViewData.GetCurX(),
494 													   aViewData.GetCurY(),
495 													   aViewData.GetTabNo(),
496 													   ATTR_VALIDDATA );
497 	if ( pItem->GetValue() )
498 	{
499 		const ScValidationData*	pData = pDoc->GetValidationEntry( pItem->GetValue() );
500 		DBG_ASSERT(pData,"ValidationData nicht gefunden");
501 		String aTitle, aMessage;
502 		if ( pData && pData->GetInput( aTitle, aMessage ) && aMessage.Len() > 0 )
503 		{
504 			//!	Abfrage, ob an gleicher Stelle !!!!
505 
506 			DELETEZ(pInputHintWindow);
507 
508 			ScSplitPos eWhich = aViewData.GetActivePart();
509 			Window* pWin = pGridWin[eWhich];
510 			SCCOL nCol = aViewData.GetCurX();
511 			SCROW nRow = aViewData.GetCurY();
512 			Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
513 			Size aWinSize = pWin->GetOutputSizePixel();
514 			//	Cursor sichtbar?
515 			if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
516 				 nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
517 				 aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
518 			{
519 				aPos += pWin->GetPosPixel();								// Position auf Frame
520 				long nSizeXPix;
521 				long nSizeYPix;
522 				aViewData.GetMergeSizePixel( nCol, nRow, nSizeXPix, nSizeYPix );
523 
524 				// HintWindow anlegen, bestimmt seine Groesse selbst
525 				pInputHintWindow = new ScHintWindow( pFrameWin, aTitle, aMessage );
526 				Size aHintSize = pInputHintWindow->GetSizePixel();
527 				Size aFrameWinSize = pFrameWin->GetOutputSizePixel();
528 
529 				// passende Position finden
530 				//	erster Versuch: unter dem Cursor
531 				Point aHintPos( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
532 				if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
533 				{
534 					// zweiter Versuch: rechts vom Cursor
535 					aHintPos = Point( aPos.X() + nSizeXPix + 3, aPos.Y() + nSizeYPix / 2 );
536 					if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
537 					{
538 						// dritter Versuch: ueber dem Cursor
539 						aHintPos = Point( aPos.X() + nSizeXPix / 2,
540 											aPos.Y() - aHintSize.Height() - 3 );
541 						if ( aHintPos.Y() < 0 )
542 						{
543 							// oben und unten kein Platz - dann Default und abschneiden
544 							aHintPos = Point( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
545 							aHintSize.Height() = aFrameWinSize.Height() - aHintPos.Y();
546 							pInputHintWindow->SetSizePixel( aHintSize );
547 						}
548 					}
549 				}
550 
551 				//	X anpassen
552 				if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
553 					aHintPos.X() = aFrameWinSize.Width() - aHintSize.Width();
554 				//	Y anpassen
555 				if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
556 					aHintPos.Y() = aFrameWinSize.Height() - aHintSize.Height();
557 
558 				pInputHintWindow->SetPosPixel( aHintPos );
559 				pInputHintWindow->ToTop();
560 				pInputHintWindow->Show();
561 			}
562 		}
563 		else
564 			DELETEZ(pInputHintWindow);
565 
566         // list drop-down button
567         if ( pData && pData->HasSelectionList() )
568         {
569             aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
570             bListValButton = sal_True;
571         }
572 	}
573 	else
574 		DELETEZ(pInputHintWindow);
575 
576     for ( sal_uInt16 i=0; i<4; i++ )
577         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
578             pGridWin[i]->UpdateListValPos( bListValButton, aListValPos );
579 }
580 
581 void ScTabView::RemoveHintWindow()
582 {
583 	DELETEZ(pInputHintWindow);
584 }
585 
586 
587 // find window that should not be over the cursor
588 Window* lcl_GetCareWin(SfxViewFrame* pViewFrm)
589 {
590 	//!	auch Spelling ??? (dann beim Aufruf Membervariable setzen)
591 
592 	//	Suchen & Ersetzen
593 	if ( pViewFrm->HasChildWindow(SID_SEARCH_DLG) )
594 	{
595 		SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
596 		if (pChild)
597 		{
598 			Window* pWin = pChild->GetWindow();
599 			if (pWin && pWin->IsVisible())
600 				return pWin;
601 		}
602 	}
603 
604 	//	Aenderungen uebernehmen
605 	if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
606 	{
607 		SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
608 		if (pChild)
609 		{
610 			Window* pWin = pChild->GetWindow();
611 			if (pWin && pWin->IsVisible())
612 				return pWin;
613 		}
614 	}
615 
616 	return NULL;
617 }
618 
619 	//
620 	//	Bildschirm an Cursorposition anpassen
621 	//
622 
623 void ScTabView::AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
624 								const ScSplitPos* pWhich )
625 {
626 	//
627 	//	aktiven Teil umschalten jetzt hier
628 	//
629 
630 	ScSplitPos eActive = aViewData.GetActivePart();
631 	ScHSplitPos eActiveX = WhichH(eActive);
632 	ScVSplitPos eActiveY = WhichV(eActive);
633 	sal_Bool bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
634 	sal_Bool bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
635 	if (bHFix)
636 		if (eActiveX == SC_SPLIT_LEFT && nCurX >= (SCsCOL)aViewData.GetFixPosX())
637 		{
638 			ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
639 			eActiveX = SC_SPLIT_RIGHT;
640 		}
641 	if (bVFix)
642 		if (eActiveY == SC_SPLIT_TOP && nCurY >= (SCsROW)aViewData.GetFixPosY())
643 		{
644 			ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
645 			eActiveY = SC_SPLIT_BOTTOM;
646 		}
647 
648 	//
649 	//	eigentliches Align
650 	//
651 
652 	if ( eMode != SC_FOLLOW_NONE )
653 	{
654 		ScSplitPos eAlign;
655 		if (pWhich)
656 			eAlign = *pWhich;
657 		else
658 			eAlign = aViewData.GetActivePart();
659 		ScHSplitPos eAlignX = WhichH(eAlign);
660 		ScVSplitPos eAlignY = WhichV(eAlign);
661 
662 		SCsCOL nDeltaX = (SCsCOL) aViewData.GetPosX(eAlignX);
663 		SCsROW nDeltaY = (SCsROW) aViewData.GetPosY(eAlignY);
664 		SCsCOL nSizeX = (SCsCOL) aViewData.VisibleCellsX(eAlignX);
665 		SCsROW nSizeY = (SCsROW) aViewData.VisibleCellsY(eAlignY);
666 
667 		long nCellSizeX;
668 		long nCellSizeY;
669 		if ( nCurX >= 0 && nCurY >= 0 )
670 			aViewData.GetMergeSizePixel( (SCCOL)nCurX, (SCROW)nCurY, nCellSizeX, nCellSizeY );
671 		else
672 			nCellSizeX = nCellSizeY = 0;
673 		Size aScrSize = aViewData.GetScrSize();
674 		long nSpaceX = ( aScrSize.Width()  - nCellSizeX ) / 2;
675 		long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
676 		//	nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
677 
678 		sal_Bool bForceNew = sal_False;		// force new calculation of JUMP position (vertical only)
679 
680 		// VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
681 
682 		//-------------------------------------------------------------------------------
683 		//	falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
684 		//	wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs
685 
686 		//!	nicht, wenn schon komplett sichtbar
687 
688 		if ( eMode == SC_FOLLOW_JUMP )
689 		{
690 			Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
691 			if (pCare)
692 			{
693 				sal_Bool bLimit = sal_False;
694 				Rectangle aDlgPixel;
695 				Size aWinSize;
696 				Window* pWin = GetActiveWin();
697 				if (pWin)
698 				{
699 					aDlgPixel = pCare->GetWindowExtentsRelative( pWin );
700 					aWinSize = pWin->GetOutputSizePixel();
701 					//	ueberdeckt der Dialog das GridWin?
702 					if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
703 					{
704 						if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
705 							 nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
706 							bLimit = sal_True;			// es wird sowieso gescrollt
707 						else
708 						{
709 							//	Cursor ist auf dem Bildschirm
710 							Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
711 							long nCSX, nCSY;
712 							aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
713 							Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
714 							if ( aCursor.IsOver( aDlgPixel ) )
715 								bLimit = sal_True;		// Zelle vom Dialog ueberdeckt
716 						}
717 					}
718 				}
719 
720 				if (bLimit)
721 				{
722 					sal_Bool bBottom = sal_False;
723 					long nTopSpace = aDlgPixel.Top();
724 					long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
725 					if ( nBotSpace > 0 && nBotSpace > nTopSpace )
726 					{
727 						long nDlgBot = aDlgPixel.Bottom();
728                         SCsCOL nWPosX;
729                         SCsROW nWPosY;
730                         aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
731 						++nWPosY;	// unter der letzten betroffenen Zelle
732 
733 						SCsROW nDiff = nWPosY - nDeltaY;
734 						if ( nCurY >= nDiff )			// Pos. kann nicht negativ werden
735 						{
736 							nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
737 							bBottom = sal_True;
738 							bForceNew = sal_True;
739 						}
740 					}
741 					if ( !bBottom && nTopSpace > 0 )
742 					{
743 						nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
744 						bForceNew = sal_True;
745 					}
746 				}
747 			}
748 		}
749 		//-------------------------------------------------------------------------------
750 
751 		SCsCOL nNewDeltaX = nDeltaX;
752 		SCsROW nNewDeltaY = nDeltaY;
753 		sal_Bool bDoLine = sal_False;
754 
755 		switch (eMode)
756 		{
757 			case SC_FOLLOW_JUMP:
758 				if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
759 				{
760 					nNewDeltaX = nCurX - static_cast<SCsCOL>(aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<sal_uInt16>(nSpaceX) ));
761 					if (nNewDeltaX < 0) nNewDeltaX = 0;
762 					nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
763 				}
764 				if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
765 				{
766 					nNewDeltaY = nCurY - static_cast<SCsROW>(aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<sal_uInt16>(nSpaceY) ));
767 					if (nNewDeltaY < 0) nNewDeltaY = 0;
768 					nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
769 				}
770 				bDoLine = sal_True;
771 				break;
772 
773 			case SC_FOLLOW_LINE:
774 				bDoLine = sal_True;
775 				break;
776 
777 			case SC_FOLLOW_FIX:
778 				if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
779 				{
780 					nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
781                     if (nNewDeltaX < 0) nNewDeltaX = 0;
782 					nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
783 				}
784 				if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
785 				{
786 					nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
787                     if (nNewDeltaY < 0) nNewDeltaY = 0;
788 					nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
789 				}
790 
791 				//	like old version of SC_FOLLOW_JUMP:
792 
793 				if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
794 				{
795 					nNewDeltaX = nCurX - (nSizeX / 2);
796                     if (nNewDeltaX < 0) nNewDeltaX = 0;
797 					nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
798 				}
799 				if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
800 				{
801 					nNewDeltaY = nCurY - (nSizeY / 2);
802 					if (nNewDeltaY < 0) nNewDeltaY = 0;
803 					nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
804 				}
805 
806 				bDoLine = sal_True;
807 				break;
808 
809 			case SC_FOLLOW_NONE:
810 				break;
811 			default:
812 				DBG_ERROR("Falscher Cursormodus");
813 				break;
814 		}
815 
816 		if (bDoLine)
817 		{
818 			while ( nCurX >= nNewDeltaX+nSizeX )
819 			{
820 				nNewDeltaX = nCurX-nSizeX+1;
821 				ScDocument* pDoc = aViewData.GetDocument();
822 				SCTAB nTab = aViewData.GetTabNo();
823 				while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
824 					++nNewDeltaX;
825 				nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
826 			}
827 			while ( nCurY >= nNewDeltaY+nSizeY )
828 			{
829 				nNewDeltaY = nCurY-nSizeY+1;
830 				ScDocument* pDoc = aViewData.GetDocument();
831 				SCTAB nTab = aViewData.GetTabNo();
832 				while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
833 					++nNewDeltaY;
834 				nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
835 			}
836 			if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
837 			if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
838 		}
839 
840 		if ( nNewDeltaX != nDeltaX )
841 			nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
842 		if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
843 		if (nNewDeltaX < 0) nNewDeltaX = 0;
844 
845 		if ( nNewDeltaY != nDeltaY )
846 			nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
847 		if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
848 		if (nNewDeltaY < 0) nNewDeltaY = 0;
849 
850 		if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
851 		if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
852 	}
853 
854 	//
855 	//	nochmal aktiven Teil umschalten
856 	//
857 
858 	if (bHFix)
859 		if (eActiveX == SC_SPLIT_RIGHT && nCurX < (SCsCOL)aViewData.GetFixPosX())
860 		{
861 			ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
862 			eActiveX = SC_SPLIT_LEFT;
863 		}
864 	if (bVFix)
865 		if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (SCsROW)aViewData.GetFixPosY())
866 		{
867 			ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
868 			eActiveY = SC_SPLIT_TOP;
869 		}
870 }
871 
872 sal_Bool ScTabView::SelMouseButtonDown( const MouseEvent& rMEvt )
873 {
874 	sal_Bool bRet = sal_False;
875 
876 	// #i3875# *Hack*
877 	sal_Bool bMod1Locked = aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1 ? sal_True : sal_False;
878 	aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );
879 
880 	if ( pSelEngine )
881 	{
882 		bMoveIsShift = rMEvt.IsShift();
883 		bRet = pSelEngine->SelMouseButtonDown( rMEvt );
884 		bMoveIsShift = sal_False;
885 	}
886 
887 	aViewData.SetSelCtrlMouseClick( sal_False ); // #i3875# *Hack*
888 
889 	return bRet;
890 }
891 
892 	//
893 	//	MoveCursor - mit Anpassung des Bildausschnitts
894 	//
895 
896 void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
897 								sal_Bool bShift, sal_Bool bControl, sal_Bool bKeepOld, sal_Bool bKeepSel )
898 {
899 	if (!bKeepOld)
900 		aViewData.ResetOldCursor();
901 
902 	if (nCurX < 0) nCurX = 0;
903 	if (nCurY < 0) nCurY = 0;
904 	if (nCurX > MAXCOL) nCurX = MAXCOL;
905 	if (nCurY > MAXROW) nCurY = MAXROW;
906 
907 	HideAllCursors();
908 
909 	if ( bShift && bNewStartIfMarking && IsBlockMode() )
910 	{
911 		//	used for ADD selection mode: start a new block from the cursor position
912 		DoneBlockMode( sal_True );
913 		InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), sal_True );
914 	}
915 
916 		//	aktiven Teil umschalten jetzt in AlignToCursor
917 
918 	AlignToCursor( nCurX, nCurY, eMode );
919 	//!		auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
920 
921 	if (bKeepSel)
922 		SetCursor( nCurX, nCurY );		// Markierung stehenlassen
923 	else
924 	{
925 		sal_Bool bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
926 		bMoveIsShift = bShift;
927 		pSelEngine->CursorPosChanging( bShift, bControl );
928 		bMoveIsShift = sal_False;
929 		aFunctionSet.SetCursorAtCell( nCurX, nCurY, sal_False );
930 
931 		//	Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
932 		//	Aufheben der Selektion hier einzeln passieren:
933 		if (bSame)
934 			SelectionChanged();
935 	}
936 
937 	ShowAllCursors();
938 }
939 
940 void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
941 									sal_Bool bShift, sal_Bool bKeepSel )
942 {
943 	ScDocument* pDoc = aViewData.GetDocument();
944 	SCTAB nTab = aViewData.GetTabNo();
945 
946     bool bSkipProtected = false, bSkipUnprotected = false;
947     ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
948     if ( pProtect && pProtect->isProtected() )
949     {
950         bSkipProtected   = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
951         bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
952     }
953 
954     if ( bSkipProtected && bSkipUnprotected )
955         return;
956 
957 	SCsCOL nOldX;
958 	SCsROW nOldY;
959 	SCsCOL nCurX;
960 	SCsROW nCurY;
961 	if ( aViewData.IsRefMode() )
962 	{
963 		nOldX = (SCsCOL) aViewData.GetRefEndX();
964 		nOldY = (SCsROW) aViewData.GetRefEndY();
965 		nCurX = nOldX + nMovX;
966 		nCurY = nOldY + nMovY;
967 	}
968 	else
969 	{
970 		nOldX = (SCsCOL) aViewData.GetCurX();
971 		nOldY = (SCsROW) aViewData.GetCurY();
972 		nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
973 		nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
974 	}
975 
976 	sal_Bool bSkipCell = sal_False;
977 	aViewData.ResetOldCursor();
978 
979 	if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
980 	{
981 		sal_Bool bHFlip = sal_False;
982 		do
983 		{
984 			SCCOL nLastCol = -1;
985             bSkipCell = pDoc->ColHidden(nCurX, nTab, nLastCol) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
986             if (bSkipProtected && !bSkipCell)
987                 bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
988             if (bSkipUnprotected && !bSkipCell)
989                 bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
990 
991 			if (bSkipCell)
992 			{
993 				if ( nCurX<=0 || nCurX>=MAXCOL )
994 				{
995 					if (bHFlip)
996 					{
997 						nCurX = nOldX;
998 						bSkipCell = sal_False;
999 					}
1000 					else
1001 					{
1002 						nMovX = -nMovX;
1003 						if (nMovX > 0) ++nCurX; else --nCurX;		// zuruecknehmen
1004 						bHFlip = sal_True;
1005 					}
1006 				}
1007 				else
1008 					if (nMovX > 0) ++nCurX; else --nCurX;
1009 			}
1010 		}
1011 		while (bSkipCell);
1012 
1013 		if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
1014 		{
1015 			aViewData.SetOldCursor( nCurX,nCurY );
1016 			while (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
1017 				--nCurY;
1018 		}
1019 	}
1020 
1021 	if (nMovY != 0 && VALIDCOLROW(nCurX,nCurY))
1022 	{
1023 		sal_Bool bVFlip = sal_False;
1024 		do
1025 		{
1026 			SCROW nLastRow = -1;
1027             bSkipCell = pDoc->RowHidden(nCurY, nTab, nLastRow) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
1028             if (bSkipProtected && !bSkipCell)
1029                 bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1030             if (bSkipUnprotected && !bSkipCell)
1031                 bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1032 
1033 			if (bSkipCell)
1034 			{
1035 				if ( nCurY<=0 || nCurY>=MAXROW )
1036 				{
1037 					if (bVFlip)
1038 					{
1039 						nCurY = nOldY;
1040 						bSkipCell = sal_False;
1041 					}
1042 					else
1043 					{
1044 						nMovY = -nMovY;
1045 						if (nMovY > 0) ++nCurY; else --nCurY;		// zuruecknehmen
1046 						bVFlip = sal_True;
1047 					}
1048 				}
1049 				else
1050 					if (nMovY > 0) ++nCurY; else --nCurY;
1051 			}
1052 		}
1053 		while (bSkipCell);
1054 
1055 		if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
1056 		{
1057 			aViewData.SetOldCursor( nCurX,nCurY );
1058 			while (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
1059 				--nCurX;
1060 		}
1061 	}
1062 
1063 	MoveCursorAbs( nCurX, nCurY, eMode, bShift, sal_False, sal_True, bKeepSel );
1064 }
1065 
1066 void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
1067 {
1068 	SCCOL nCurX;
1069 	SCROW nCurY;
1070 	aViewData.GetMoveCursor( nCurX,nCurY );
1071 
1072 	ScSplitPos eWhich = aViewData.GetActivePart();
1073 	ScHSplitPos eWhichX = WhichH( eWhich );
1074 	ScVSplitPos eWhichY = WhichV( eWhich );
1075 
1076 	SCsCOL nPageX;
1077 	SCsROW nPageY;
1078 	if (nMovX >= 0)
1079 		nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
1080 	else
1081 		nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
1082 
1083 	if (nMovY >= 0)
1084 		nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
1085 	else
1086 		nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
1087 
1088 	if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
1089 	if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
1090 
1091 	MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
1092 }
1093 
1094 void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
1095 {
1096 	SCCOL nCurX;
1097 	SCROW nCurY;
1098 	aViewData.GetMoveCursor( nCurX,nCurY );
1099 	SCCOL nNewX = nCurX;
1100 	SCROW nNewY = nCurY;
1101 
1102 	ScDocument* pDoc = aViewData.GetDocument();
1103 	SCTAB nTab = aViewData.GetTabNo();
1104 
1105 	//	FindAreaPos kennt nur -1 oder 1 als Richtung
1106 
1107 	SCsCOLROW i;
1108 	if ( nMovX > 0 )
1109 		for ( i=0; i<nMovX; i++ )
1110 			pDoc->FindAreaPos( nNewX, nNewY, nTab,  1,  0 );
1111 	if ( nMovX < 0 )
1112 		for ( i=0; i<-nMovX; i++ )
1113 			pDoc->FindAreaPos( nNewX, nNewY, nTab, -1,  0 );
1114 	if ( nMovY > 0 )
1115 		for ( i=0; i<nMovY; i++ )
1116 			pDoc->FindAreaPos( nNewX, nNewY, nTab,  0,  1 );
1117 	if ( nMovY < 0 )
1118 		for ( i=0; i<-nMovY; i++ )
1119 			pDoc->FindAreaPos( nNewX, nNewY, nTab,  0, -1 );
1120 
1121 	if (eMode==SC_FOLLOW_JUMP)					// unten/rechts nicht zuviel grau anzeigen
1122 	{
1123 		if (nMovX != 0 && nNewX == MAXCOL)
1124 			eMode = SC_FOLLOW_LINE;
1125 		if (nMovY != 0 && nNewY == MAXROW)
1126 			eMode = SC_FOLLOW_LINE;
1127 	}
1128 
1129 	MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
1130 }
1131 
1132 void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
1133 {
1134 	ScDocument* pDoc = aViewData.GetDocument();
1135 	SCTAB nTab = aViewData.GetTabNo();
1136 
1137 	SCCOL nCurX;
1138 	SCROW nCurY;
1139 	aViewData.GetMoveCursor( nCurX,nCurY );
1140 	SCCOL nNewX = nCurX;
1141 	SCROW nNewY = nCurY;
1142 
1143 	SCCOL nUsedX = 0;
1144 	SCROW nUsedY = 0;
1145 	if ( nMovX > 0 || nMovY > 0 )
1146 		pDoc->GetPrintArea( nTab, nUsedX, nUsedY );		// Ende holen
1147 
1148 	if (nMovX<0)
1149 		nNewX=0;
1150 	else if (nMovX>0)
1151 		nNewX=nUsedX;									// letzter benutzter Bereich
1152 
1153 	if (nMovY<0)
1154 		nNewY=0;
1155 	else if (nMovY>0)
1156 		nNewY=nUsedY;
1157 
1158 	aViewData.ResetOldCursor();
1159 	MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
1160 }
1161 
1162 void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift )
1163 {
1164 	ScDocument* pDoc = aViewData.GetDocument();
1165 	SCTAB nTab = aViewData.GetTabNo();
1166 
1167 	SCCOL nCurX;
1168 	SCROW nCurY;
1169 	aViewData.GetMoveCursor( nCurX,nCurY );
1170 	SCCOL nNewX = nCurX;
1171 	SCROW nNewY = nCurY;
1172 
1173 	ScSplitPos eWhich = aViewData.GetActivePart();
1174 	SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
1175 	SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );
1176 
1177 	SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
1178 	if (nAddX != 0)
1179 		--nAddX;
1180 	SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
1181 	if (nAddY != 0)
1182 		--nAddY;
1183 
1184 	if (nMovX<0)
1185 		nNewX=nPosX;
1186 	else if (nMovX>0)
1187 		nNewX=nPosX+nAddX;
1188 
1189 	if (nMovY<0)
1190 		nNewY=nPosY;
1191 	else if (nMovY>0)
1192 		nNewY=nPosY+nAddY;
1193 
1194 //	aViewData.ResetOldCursor();
1195 	aViewData.SetOldCursor( nNewX,nNewY );
1196 
1197 	while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
1198 		--nNewX;
1199 	while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
1200 		--nNewY;
1201 
1202 	MoveCursorAbs( nNewX, nNewY, eMode, bShift, sal_False, sal_True );
1203 }
1204 
1205 void ScTabView::MoveCursorEnter( sal_Bool bShift )			// bShift -> hoch/runter
1206 {
1207 	const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
1208 	if (!rOpt.GetMoveSelection())
1209 	{
1210 		aViewData.UpdateInputHandler(sal_True);
1211 		return;
1212 	}
1213 
1214 	SCsCOL nMoveX = 0;
1215 	SCsROW nMoveY = 0;
1216 	switch ((ScDirection)rOpt.GetMoveDir())
1217 	{
1218 		case DIR_BOTTOM:
1219 			nMoveY = bShift ? -1 : 1;
1220 			break;
1221 		case DIR_RIGHT:
1222 			nMoveX = bShift ? -1 : 1;
1223 			break;
1224 		case DIR_TOP:
1225 			nMoveY = bShift ? 1 : -1;
1226 			break;
1227 		case DIR_LEFT:
1228 			nMoveX = bShift ? 1 : -1;
1229 			break;
1230 	}
1231 
1232 	ScMarkData& rMark = aViewData.GetMarkData();
1233 	if (rMark.IsMarked() || rMark.IsMultiMarked())
1234 	{
1235 		SCCOL nCurX;
1236 		SCROW nCurY;
1237 		aViewData.GetMoveCursor( nCurX,nCurY );
1238 		SCCOL nNewX = nCurX;
1239 		SCROW nNewY = nCurY;
1240 		SCTAB nTab = aViewData.GetTabNo();
1241 
1242 		ScDocument* pDoc = aViewData.GetDocument();
1243 		pDoc->GetNextPos( nNewX,nNewY, nTab, nMoveX,nMoveY, sal_True,sal_False, rMark );
1244 
1245 		MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1246 							SC_FOLLOW_LINE, sal_False, sal_True );
1247 
1248 		//	update input line even if cursor was not moved
1249 		if ( nNewX == nCurX && nNewY == nCurY )
1250 			aViewData.UpdateInputHandler(sal_True);
1251 	}
1252 	else
1253 	{
1254 		if ( nMoveY != 0 && !nMoveX )
1255 		{
1256 			//	nach Tab und Enter wieder zur Ausgangsspalte
1257 			SCCOL nTabCol = aViewData.GetTabStartCol();
1258 			if (nTabCol != SC_TABSTART_NONE)
1259 			{
1260 				SCCOL nCurX;
1261 				SCROW nCurY;
1262 				aViewData.GetMoveCursor( nCurX,nCurY );
1263 				nMoveX = ((SCsCOL)nTabCol)-(SCsCOL)nCurX;
1264 			}
1265 		}
1266 
1267 		MoveCursorRel( nMoveX,nMoveY, SC_FOLLOW_LINE, sal_False );
1268 	}
1269 }
1270 
1271 
1272 sal_Bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
1273 {
1274     const KeyCode& rKCode = rKeyEvent.GetKeyCode();
1275 
1276     enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
1277         rKCode.IsMod1() ?
1278             (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
1279             (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
1280 
1281     sal_Bool bSel = rKCode.IsShift();
1282     sal_uInt16 nCode = rKCode.GetCode();
1283 
1284     // CURSOR keys
1285     SCsCOL nDX = 0;
1286     SCsROW nDY = 0;
1287     switch( nCode )
1288     {
1289         case KEY_LEFT:  nDX = -1;   break;
1290         case KEY_RIGHT: nDX = 1;    break;
1291         case KEY_UP:    nDY = -1;   break;
1292         case KEY_DOWN:  nDY = 1;    break;
1293     }
1294     if( nDX != 0 || nDY != 0 )
1295     {
1296         switch( eModifier )
1297         {
1298             case MOD_NONE:  MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel );    break;
1299             case MOD_CTRL:  MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel );   break;
1300             default:
1301             {
1302                 // added to avoid warnings
1303             }
1304         }
1305         // always sal_True to suppress changes of col/row size (ALT+CURSOR)
1306         return sal_True;
1307     }
1308 
1309     // PAGEUP/PAGEDOWN
1310     if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
1311     {
1312         nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
1313         switch( eModifier )
1314         {
1315             case MOD_NONE:  MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel );  break;
1316             case MOD_ALT:   MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel );  break;
1317             case MOD_CTRL:  SelectNextTab( nDX );                           break;
1318             default:
1319             {
1320                 // added to avoid warnings
1321             }
1322         }
1323         return sal_True;
1324     }
1325 
1326     // HOME/END
1327     if( (nCode == KEY_HOME) || (nCode == KEY_END) )
1328     {
1329         nDX = (nCode == KEY_HOME) ? -1 : 1;
1330         ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
1331         switch( eModifier )
1332         {
1333             case MOD_NONE:  MoveCursorEnd( nDX, 0, eMode, bSel );   break;
1334             case MOD_CTRL:  MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
1335             default:
1336             {
1337                 // added to avoid warnings
1338             }
1339         }
1340         return sal_True;
1341     }
1342 
1343     return sal_False;
1344 }
1345 
1346 
1347 		// naechste/vorherige nicht geschuetzte Zelle
1348 void ScTabView::FindNextUnprot( sal_Bool bShift, sal_Bool bInSelection )
1349 {
1350 	short nMove = bShift ? -1 : 1;
1351 
1352 	ScMarkData& rMark = aViewData.GetMarkData();
1353 	sal_Bool bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
1354 
1355 	SCCOL nCurX;
1356 	SCROW nCurY;
1357 	aViewData.GetMoveCursor( nCurX,nCurY );
1358 	SCCOL nNewX = nCurX;
1359 	SCROW nNewY = nCurY;
1360 	SCTAB nTab = aViewData.GetTabNo();
1361 
1362 	ScDocument* pDoc = aViewData.GetDocument();
1363 	pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked,sal_True, rMark );
1364 
1365 	SCCOL nTabCol = aViewData.GetTabStartCol();
1366 	if ( nTabCol == SC_TABSTART_NONE )
1367 		nTabCol = nCurX;					// auf diese Spalte zurueck bei Enter
1368 
1369 	MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1370 						SC_FOLLOW_LINE, sal_False, sal_True );
1371 
1372 	//	in MoveCursorRel wird die TabCol zurueckgesetzt...
1373 	aViewData.SetTabStartCol( nTabCol );
1374 }
1375 
1376 void ScTabView::MarkColumns()
1377 {
1378 	SCCOL nStartCol;
1379 	SCCOL nEndCol;
1380 
1381 	ScMarkData& rMark = aViewData.GetMarkData();
1382 	if (rMark.IsMarked())
1383 	{
1384 		ScRange aMarkRange;
1385 		rMark.GetMarkArea( aMarkRange );
1386 		nStartCol = aMarkRange.aStart.Col();
1387 		nEndCol = aMarkRange.aEnd.Col();
1388 	}
1389 	else
1390 	{
1391 		SCROW nDummy;
1392 		aViewData.GetMoveCursor( nStartCol, nDummy );
1393 		nEndCol=nStartCol;
1394 	}
1395 
1396 	SCTAB nTab = aViewData.GetTabNo();
1397 	DoneBlockMode();
1398 	InitBlockMode( nStartCol,0, nTab );
1399 	MarkCursor( nEndCol,MAXROW, nTab );
1400 	SelectionChanged();
1401 }
1402 
1403 void ScTabView::MarkRows()
1404 {
1405 	SCROW nStartRow;
1406 	SCROW nEndRow;
1407 
1408 	ScMarkData& rMark = aViewData.GetMarkData();
1409 	if (rMark.IsMarked())
1410 	{
1411 		ScRange aMarkRange;
1412 		rMark.GetMarkArea( aMarkRange );
1413 		nStartRow = aMarkRange.aStart.Row();
1414 		nEndRow = aMarkRange.aEnd.Row();
1415 	}
1416 	else
1417 	{
1418 		SCCOL nDummy;
1419 		aViewData.GetMoveCursor( nDummy, nStartRow );
1420 		nEndRow=nStartRow;
1421 	}
1422 
1423 	SCTAB nTab = aViewData.GetTabNo();
1424 	DoneBlockMode();
1425 	InitBlockMode( 0,nStartRow, nTab );
1426 	MarkCursor( MAXCOL,nEndRow, nTab );
1427 	SelectionChanged();
1428 }
1429 
1430 void ScTabView::MarkDataArea( sal_Bool bIncludeCursor )
1431 {
1432 	ScDocument* pDoc = aViewData.GetDocument();
1433 	SCTAB nTab = aViewData.GetTabNo();
1434 	SCCOL nStartCol = aViewData.GetCurX();
1435 	SCROW nStartRow = aViewData.GetCurY();
1436 	SCCOL nEndCol = nStartCol;
1437 	SCROW nEndRow = nStartRow;
1438 
1439 	pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );
1440 
1441 	HideAllCursors();
1442 	DoneBlockMode();
1443 	InitBlockMode( nStartCol, nStartRow, nTab );
1444 	MarkCursor( nEndCol, nEndRow, nTab );
1445 	ShowAllCursors();
1446 
1447 	SelectionChanged();
1448 }
1449 
1450 void ScTabView::MarkMatrixFormula()
1451 {
1452 	ScDocument* pDoc = aViewData.GetDocument();
1453 	ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
1454 	ScRange aMatrix;
1455 	if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
1456 	{
1457 		MarkRange( aMatrix, sal_False );		// cursor is already within the range
1458 	}
1459 }
1460 
1461 void ScTabView::MarkRange( const ScRange& rRange, sal_Bool bSetCursor, sal_Bool bContinue )
1462 {
1463 	SCTAB nTab = rRange.aStart.Tab();
1464 	SetTabNo( nTab );
1465 
1466 	HideAllCursors();
1467     DoneBlockMode( bContinue ); // bContinue==sal_True -> clear old mark
1468     if (bSetCursor)             // Wenn Cursor gesetzt wird, immer auch alignen
1469 	{
1470 		SCCOL nAlignX = rRange.aStart.Col();
1471 		SCROW nAlignY = rRange.aStart.Row();
1472 		if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
1473 			nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
1474 		if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
1475 			nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
1476 		AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
1477 	}
1478 	InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
1479 	MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
1480 	if (bSetCursor)
1481 	{
1482 		SCCOL nPosX = rRange.aStart.Col();
1483 		SCROW nPosY = rRange.aStart.Row();
1484 		ScDocument* pDoc = aViewData.GetDocument();
1485 
1486 		while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))		//! ViewData !!!
1487 			--nPosX;
1488 		while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
1489 			--nPosY;
1490 
1491 		aViewData.ResetOldCursor();
1492 		SetCursor( nPosX, nPosY );
1493 	}
1494 	ShowAllCursors();
1495 
1496 	SelectionChanged();
1497 }
1498 
1499 void ScTabView::Unmark()
1500 {
1501 	ScMarkData& rMark = aViewData.GetMarkData();
1502 	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1503 	{
1504 		SCCOL nCurX;
1505 		SCROW nCurY;
1506 		aViewData.GetMoveCursor( nCurX,nCurY );
1507 		MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, sal_False, sal_False );
1508 
1509 		SelectionChanged();
1510 	}
1511 }
1512 
1513 void ScTabView::SetMarkData( const ScMarkData& rNew )
1514 {
1515     DoneBlockMode();
1516     InitOwnBlockMode();
1517     aViewData.GetMarkData() = rNew;
1518 
1519     MarkDataChanged();
1520 }
1521 
1522 void ScTabView::MarkDataChanged()
1523 {
1524     // has to be called after making direct changes to mark data (not via MarkCursor etc)
1525 
1526     UpdateSelectionOverlay();
1527 }
1528 
1529 void ScTabView::SelectNextTab( short nDir, sal_Bool bExtendSelection )
1530 {
1531 	if (!nDir) return;
1532 	DBG_ASSERT( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");
1533 
1534 	ScDocument* pDoc = aViewData.GetDocument();
1535 	SCTAB nTab = aViewData.GetTabNo();
1536 	if (nDir<0)
1537 	{
1538 		if (!nTab) return;
1539 		--nTab;
1540 		while (!pDoc->IsVisible(nTab))
1541 		{
1542 			if (!nTab) return;
1543 			--nTab;
1544 		}
1545 	}
1546 	else
1547 	{
1548 		SCTAB nCount = pDoc->GetTableCount();
1549 		++nTab;
1550 		if (nTab >= nCount) return;
1551 		while (!pDoc->IsVisible(nTab))
1552 		{
1553 			++nTab;
1554 			if (nTab >= nCount) return;
1555 		}
1556 	}
1557 
1558     SetTabNo( nTab, sal_False, bExtendSelection );
1559 	PaintExtras();
1560 }
1561 
1562 void ScTabView::UpdateVisibleRange()
1563 {
1564     for (sal_uInt16 i=0; i<4; i++)
1565         if (pGridWin[i] && pGridWin[i]->IsVisible())
1566             pGridWin[i]->UpdateVisibleRange();
1567 }
1568 
1569 //	SetTabNo	- angezeigte Tabelle
1570 
1571 void ScTabView::SetTabNo( SCTAB nTab, sal_Bool bNew, sal_Bool bExtendSelection, bool bSameTabButMoved )
1572 {
1573 	if ( !ValidTab(nTab) )
1574 	{
1575 		DBG_ERROR("SetTabNo: falsche Tabelle");
1576 		return;
1577 	}
1578 
1579 	if ( nTab != aViewData.GetTabNo() || bNew )
1580 	{
1581 		//	#57724# Die FormShell moechte vor dem Umschalten benachrichtigt werden
1582 		FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
1583 		if (pFormSh)
1584 		{
1585             sal_Bool bAllowed = sal::static_int_cast<sal_Bool>( pFormSh->PrepareClose( sal_True ) );
1586 			if (!bAllowed)
1587 			{
1588 				//!	Fehlermeldung? oder macht das die FormShell selber?
1589 				//!	Fehler-Flag zurueckgeben und Aktionen abbrechen
1590 
1591 				return;		// Die FormShell sagt, es kann nicht umgeschaltet werden
1592 			}
1593 		}
1594 
1595 										//	nicht InputEnterHandler wegen Referenzeingabe !
1596 
1597 		ScDocument* pDoc = aViewData.GetDocument();
1598 		pDoc->MakeTable( nTab );
1599 
1600         // Update pending row heights before switching the sheet, so Reschedule from the progress bar
1601         // doesn't paint the new sheet with old heights
1602         aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
1603 
1604 		SCTAB nTabCount = pDoc->GetTableCount();
1605 		SCTAB nOldPos = nTab;
1606 		while (!pDoc->IsVisible(nTab))				// naechste sichtbare suchen
1607 		{
1608 			sal_Bool bUp = (nTab>=nOldPos);
1609 			if (bUp)
1610 			{
1611 				++nTab;
1612 				if (nTab>=nTabCount)
1613 				{
1614 					nTab = nOldPos;
1615 					bUp = sal_False;
1616 				}
1617 			}
1618 
1619 			if (!bUp)
1620 			{
1621 				if (nTab != 0)
1622 					--nTab;
1623 				else
1624 				{
1625 					DBG_ERROR("keine sichtbare Tabelle");
1626 					pDoc->SetVisible( 0, sal_True );
1627 				}
1628 			}
1629 		}
1630 
1631         // #i71490# Deselect drawing objects before changing the sheet number in view data,
1632         // so the handling of notes still has the sheet selected on which the notes are.
1633         DrawDeselectAll();
1634 
1635         ScModule* pScMod = SC_MOD();
1636 		sal_Bool bRefMode = pScMod->IsFormulaMode();
1637 		if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
1638 		{
1639 			DoneBlockMode();
1640 			pSelEngine->Reset();				// reset all flags, including locked modifiers
1641 			aViewData.SetRefTabNo( nTab );
1642 		}
1643 
1644         ScSplitPos eOldActive = aViewData.GetActivePart();      // before switching
1645         sal_Bool bFocus = pGridWin[eOldActive]->HasFocus();
1646 
1647 		aViewData.SetTabNo( nTab );
1648 		//	UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
1649 		//	Fenster findet (wird aus SetCursor gerufen)
1650 		UpdateShow();
1651 		aViewData.ResetOldCursor();
1652 		SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), sal_True );
1653 
1654 		SfxBindings& rBindings = aViewData.GetBindings();
1655 		ScMarkData& rMark = aViewData.GetMarkData();
1656 
1657         bool bAllSelected = true;
1658         for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
1659         {
1660             if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
1661             {
1662                 if (nTab == nSelTab)
1663                     // This tab is already in selection.  Keep the current
1664                     // selection.
1665                     bExtendSelection = true;
1666             }
1667             else
1668             {
1669                 bAllSelected = false;
1670                 if (bExtendSelection)
1671                     // We got what we need.  No need to stay in the loop.
1672                     break;
1673             }
1674         }
1675         if (bAllSelected && !bNew)
1676             // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
1677             // (not if called with bNew to update settings)
1678             bExtendSelection = false;
1679 
1680         if (bExtendSelection)
1681             rMark.SelectTable( nTab, sal_True );
1682         else
1683 		{
1684 			rMark.SelectOneTable( nTab );
1685 			rBindings.Invalidate( FID_FILL_TAB );
1686             rBindings.Invalidate( FID_TAB_DESELECTALL );
1687 		}
1688 
1689         bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
1690 
1691         // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
1692         RefreshZoom();
1693         UpdateVarZoom();
1694 
1695         if ( bRefMode )     // hide EditView if necessary (after aViewData.SetTabNo !)
1696 		{
1697 			for ( sal_uInt16 i=0; i<4; i++ )
1698 				if ( pGridWin[i] )
1699 					if ( pGridWin[i]->IsVisible() )
1700 						pGridWin[i]->UpdateEditViewPos();
1701 		}
1702 
1703 		TabChanged( bSameTabButMoved );										// DrawView
1704 
1705 		aViewData.GetViewShell()->WindowChanged();			// falls das aktive Fenster anders ist
1706         if ( !bUnoRefDialog )
1707             aViewData.GetViewShell()->DisconnectAllClients();   // important for floating frames
1708         else
1709         {
1710             // hide / show inplace client
1711 
1712             ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
1713             if ( pClient && pClient->IsObjectInPlaceActive() )
1714             {
1715                 Rectangle aObjArea = pClient->GetObjArea();
1716                 if ( nTab == aViewData.GetRefTabNo() )
1717                 {
1718                     // move to its original position
1719 
1720                     SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
1721                     if ( pDrawObj )
1722                     {
1723                         Rectangle aRect = pDrawObj->GetLogicRect();
1724                         MapMode aMapMode( MAP_100TH_MM );
1725                         Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
1726                         aRect.SetSize( aOleSize );
1727                         aObjArea = aRect;
1728                     }
1729                 }
1730                 else
1731                 {
1732                     // move to an invisible position
1733 
1734                     aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
1735                 }
1736                 pClient->SetObjArea( aObjArea );
1737             }
1738         }
1739 
1740         if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
1741             ActiveGrabFocus();      // grab focus to the pane that's active now
1742 
1743 			//	Fixierungen
1744 
1745 		sal_Bool bResize = sal_False;
1746 		if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1747 			if (aViewData.UpdateFixX())
1748 				bResize = sal_True;
1749 		if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1750 			if (aViewData.UpdateFixY())
1751 				bResize = sal_True;
1752 		if (bResize)
1753 			RepeatResize();
1754 		InvalidateSplit();
1755 
1756         // #163911# Update the visible range in each GridWin directly, don't wait for the repaint event.
1757         UpdateVisibleRange();
1758 
1759 		if ( aViewData.IsPagebreakMode() )
1760 			UpdatePageBreakData();				//! asynchron ??
1761 
1762 		//	#53551# Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle kennen
1763 		//	dafuer muss hier schon der MapMode stimmen
1764 		for (sal_uInt16 i=0; i<4; i++)
1765 			if (pGridWin[i])
1766 				pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1767 		SetNewVisArea();
1768 
1769 		PaintGrid();
1770 		PaintTop();
1771 		PaintLeft();
1772 		PaintExtras();
1773 
1774 		DoResize( aBorderPos, aFrameSize );
1775 		rBindings.Invalidate( SID_DELETE_PRINTAREA );	// Menue
1776 		rBindings.Invalidate( FID_DEL_MANUALBREAKS );
1777 		rBindings.Invalidate( FID_RESET_PRINTZOOM );
1778 		rBindings.Invalidate( SID_STATUS_DOCPOS );		// Statusbar
1779 		rBindings.Invalidate( SID_STATUS_PAGESTYLE );	// Statusbar
1780 		rBindings.Invalidate( SID_CURRENTTAB );			// Navigator
1781 		rBindings.Invalidate( SID_STYLE_FAMILY2 );	// Gestalter
1782 		rBindings.Invalidate( SID_STYLE_FAMILY4 );	// Gestalter
1783 		rBindings.Invalidate( SID_TABLES_COUNT );
1784 
1785 		if(pScMod->IsRefDialogOpen())
1786 		{
1787 			sal_uInt16 nCurRefDlgId=pScMod->GetCurRefDlgId();
1788 			SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
1789 			SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
1790 			if ( pChildWnd )
1791 			{
1792 				IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
1793 				pRefDlg->ViewShellChanged(NULL);
1794 			}
1795 		}
1796 	}
1797 }
1798 
1799 //
1800 //	Paint-Funktionen - nur fuer diese View
1801 //
1802 
1803 void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
1804 {
1805 	DrawDeselectAll();
1806 
1807 	if (pDrawView)
1808 		DrawEnableAnim( sal_False );
1809 
1810     EditView* pSpellingView = aViewData.GetSpellingView();
1811 
1812 	for (sal_uInt16 i=0; i<4; i++)
1813 		if (pGridWin[i])
1814 			if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
1815 			{
1816 				ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1817 				ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1818 				SCCOL nScrX = aViewData.GetPosX( eHWhich );
1819 				SCROW nScrY = aViewData.GetPosY( eVWhich );
1820 
1821 				sal_Bool bPosVisible =
1822 					 ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
1823 					   nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
1824 
1825 				//	#102421# for the active part, create edit view even if outside the visible area,
1826 				//	so input isn't lost (and the edit view may be scrolled into the visible area)
1827 
1828                 //  #i26433# during spelling, the spelling view must be active
1829 				if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
1830 				     ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
1831 				{
1832 					pGridWin[i]->HideCursor();
1833 
1834 					pGridWin[i]->DeleteCursorOverlay();
1835 					pGridWin[i]->DeleteAutoFillOverlay();
1836 
1837 					// flush OverlayManager before changing MapMode to text edit
1838 					pGridWin[i]->flushOverlayManager();
1839 
1840 					// MapMode must be set after HideCursor
1841 					pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
1842 
1843 					aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );
1844 
1845 					if ( !bPosVisible )
1846 					{
1847 						//	move the edit view area to the real (possibly negative) position,
1848 						//	or hide if completely above or left of the window
1849 						pGridWin[i]->UpdateEditViewPos();
1850 					}
1851 				}
1852 			}
1853 
1854 	if (aViewData.GetViewShell()->HasAccessibilityObjects())
1855 		aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_ENTEREDITMODE));
1856 }
1857 
1858 void ScTabView::UpdateEditView()
1859 {
1860 	ScSplitPos eActive = aViewData.GetActivePart();
1861 	for (sal_uInt16 i=0; i<4; i++)
1862 		if (aViewData.HasEditView( (ScSplitPos) i ))
1863 		{
1864 			EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
1865 			aViewData.SetEditEngine( (ScSplitPos) i,
1866 				static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
1867 				pGridWin[i], GetViewData()->GetCurX(), GetViewData()->GetCurY() );
1868 			if ( (ScSplitPos)i == eActive )
1869 				pEditView->ShowCursor( sal_False );
1870 		}
1871 }
1872 
1873 void ScTabView::KillEditView( sal_Bool bNoPaint )
1874 {
1875 	sal_uInt16 i;
1876     SCCOL nCol1 = aViewData.GetEditStartCol();
1877     SCROW nRow1 = aViewData.GetEditStartRow();
1878     SCCOL nCol2 = aViewData.GetEditEndCol();
1879     SCROW nRow2 = aViewData.GetEditEndRow();
1880 	sal_Bool bPaint[4];
1881     sal_Bool bNotifyAcc(false);
1882 
1883     sal_Bool bExtended = nRow1 != nRow2;                    // Col wird sowieso bis zum Ende gezeichnet
1884     sal_Bool bAtCursor = nCol1 <= aViewData.GetCurX() &&
1885                      nCol2 >= aViewData.GetCurX() &&
1886                      nRow1 == aViewData.GetCurY();
1887 	for (i=0; i<4; i++)
1888     {
1889 		bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
1890         if (bPaint[i])
1891             bNotifyAcc = true;
1892     }
1893 
1894     // #108931#; notify accessibility before all things happen
1895     if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
1896 		aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
1897 
1898 	aViewData.ResetEditView();
1899 	for (i=0; i<4; i++)
1900 		if (pGridWin[i] && bPaint[i])
1901 			if (pGridWin[i]->IsVisible())
1902 			{
1903 				pGridWin[i]->ShowCursor();
1904 
1905 				pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
1906 
1907                 // #i73567# the cell still has to be repainted
1908                 if (bExtended || ( bAtCursor && !bNoPaint ))
1909                 {
1910                     pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
1911                     pGridWin[i]->UpdateSelectionOverlay();
1912                 }
1913 			}
1914 
1915 	if (pDrawView)
1916 		DrawEnableAnim( sal_True );
1917 
1918 		//	GrabFocus immer dann, wenn diese View aktiv ist und
1919 		//	die Eingabezeile den Focus hat
1920 
1921 	sal_Bool bGrabFocus = sal_False;
1922 	if (aViewData.IsActive())
1923 	{
1924 		ScInputHandler*	pInputHdl = SC_MOD()->GetInputHdl();
1925 		if ( pInputHdl )
1926 		{
1927 			ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
1928 			if (pInputWin && pInputWin->IsInputActive())
1929 				bGrabFocus = sal_True;
1930 		}
1931 	}
1932 
1933 	if (bGrabFocus)
1934 	{
1935 //		So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
1936 //!		aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1937 //		deshalb erstmal so:
1938 		GetActiveWin()->GrabFocus();
1939 	}
1940 
1941 	//	Cursor-Abfrage erst nach GrabFocus
1942 
1943 	for (i=0; i<4; i++)
1944 		if (pGridWin[i] && pGridWin[i]->IsVisible())
1945 		{
1946 			Cursor* pCur = pGridWin[i]->GetCursor();
1947 			if (pCur && pCur->IsVisible())
1948 				pCur->Hide();
1949 
1950 			if(bPaint[i])
1951 			{
1952 	            pGridWin[i]->UpdateCursorOverlay();
1953 		        pGridWin[i]->UpdateAutoFillOverlay();
1954 			    // pGridWin[i]->UpdateAllOverlays();
1955 			}
1956 		}
1957 }
1958 
1959 void ScTabView::UpdateFormulas()
1960 {
1961 	if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
1962 		return ;
1963 
1964 	sal_uInt16 i;
1965 	for (i=0; i<4; i++)
1966 		if (pGridWin[i])
1967 			if (pGridWin[i]->IsVisible())
1968 				pGridWin[i]->UpdateFormulas();
1969 
1970 	if ( aViewData.IsPagebreakMode() )
1971 		UpdatePageBreakData();				//! asynchron
1972 
1973 	UpdateHeaderWidth();
1974 
1975 	//	if in edit mode, adjust edit view area because widths/heights may have changed
1976 	if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
1977 		UpdateEditView();
1978 }
1979 
1980 //	PaintArea -Block neu zeichnen
1981 
1982 void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1983 							ScUpdateMode eMode )
1984 {
1985 	sal_uInt16 i;
1986 	SCCOL nCol1;
1987 	SCROW nRow1;
1988 	SCCOL nCol2;
1989 	SCROW nRow2;
1990 
1991 	PutInOrder( nStartCol, nEndCol );
1992 	PutInOrder( nStartRow, nEndRow );
1993 
1994 	for (i=0; i<4; i++)
1995 		if (pGridWin[i])
1996 			if (pGridWin[i]->IsVisible())
1997 			{
1998 				ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1999 				ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
2000 				sal_Bool bOut = sal_False;
2001 
2002 				nCol1 = nStartCol;
2003 				nRow1 = nStartRow;
2004 				nCol2 = nEndCol;
2005 				nRow2 = nEndRow;
2006 
2007 				SCCOL nScrX = aViewData.GetPosX( eHWhich );
2008 				SCROW nScrY = aViewData.GetPosY( eVWhich );
2009 				if (nCol1 < nScrX) nCol1 = nScrX;
2010 				if (nCol2 < nScrX)
2011 				{
2012 					if ( eMode == SC_UPDATE_ALL )	// #91240# for UPDATE_ALL, paint anyway
2013 						nCol2 = nScrX;				// (because of extending strings to the right)
2014 					else
2015 						bOut = sal_True;				// completely outside the window
2016 				}
2017 				if (nRow1 < nScrY) nRow1 = nScrY;
2018 				if (nRow2 < nScrY) bOut = sal_True;
2019 
2020 				SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
2021 				SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
2022 				if (nCol1 > nLastX) bOut = sal_True;
2023 				if (nCol2 > nLastX) nCol2 = nLastX;
2024 				if (nRow1 > nLastY) bOut = sal_True;
2025 				if (nRow2 > nLastY) nRow2 = nLastY;
2026 
2027 				if (!bOut)
2028 				{
2029 					if ( eMode == SC_UPDATE_CHANGED )
2030 						pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
2031 					else	// ALL oder MARKS
2032 					{
2033 						sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2034 						long nLayoutSign = bLayoutRTL ? -1 : 1;
2035 
2036 						Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
2037 						Point aEnd   = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
2038 						if ( eMode == SC_UPDATE_ALL )
2039 							aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
2040 						aEnd.X() -= nLayoutSign;
2041 						aEnd.Y() -= 1;
2042 
2043                         // #i85232# include area below cells (could be done in GetScrPos?)
2044                         if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
2045                             aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();
2046 
2047 						sal_Bool bShowChanges = sal_True;			//! ...
2048 						if (bShowChanges)
2049 						{
2050 							aStart.X() -= nLayoutSign;		// include change marks
2051 							aStart.Y() -= 1;
2052 						}
2053 
2054 						sal_Bool bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
2055 						if (bMarkClipped)
2056 						{
2057 							//	dazu muesste ScColumn::IsEmptyBlock optimiert werden
2058 							//	(auf Search() umstellen)
2059 							//!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
2060 							//!						aViewData.GetTabNo(),
2061 							//!						0, nRow1, nCol1-1, nRow2 ) )
2062 							{
2063 								long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
2064 								aStart.X() -= nMarkPixel * nLayoutSign;
2065 								if (!bShowChanges)
2066 									aStart.X() -= nLayoutSign;		// cell grid
2067 							}
2068 						}
2069 
2070 						pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
2071 					}
2072 				}
2073 			}
2074 
2075     // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
2076     // with a wrong MapMode if editing in a cell (reference input).
2077     // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
2078     // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
2079     // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
2080     // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
2081     // is set (width or height changed).
2082 }
2083 
2084 void ScTabView::PaintRangeFinder( long nNumber )
2085 {
2086 	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
2087 	if (pHdl)
2088 	{
2089 		ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
2090 		if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
2091 		{
2092 			SCTAB nTab = aViewData.GetTabNo();
2093 			sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
2094 			for (sal_uInt16 i=0; i<nCount; i++)
2095 				if ( nNumber < 0 || nNumber == i )
2096 				{
2097 					ScRangeFindData* pData = pRangeFinder->GetObject(i);
2098 					if (pData)
2099 					{
2100 						ScRange aRef = pData->aRef;
2101 						aRef.Justify();					// Justify fuer die Abfragen unten
2102 
2103 						if ( aRef.aStart == aRef.aEnd )		//! Tab ignorieren?
2104 							aViewData.GetDocument()->ExtendMerge(aRef);
2105 
2106 						if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
2107 						{
2108 							SCCOL nCol1 = aRef.aStart.Col();
2109 							SCROW nRow1 = aRef.aStart.Row();
2110 							SCCOL nCol2 = aRef.aEnd.Col();
2111 							SCROW nRow2 = aRef.aEnd.Row();
2112 
2113 							//	wegnehmen -> Repaint
2114 							//	SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende
2115 
2116 							sal_Bool bHiddenEdge = sal_False;
2117                             SCROW nTmp;
2118 							ScDocument* pDoc = aViewData.GetDocument();
2119 							SCCOL nLastCol = -1;
2120 							while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) )
2121 							{
2122 								--nCol1;
2123 								bHiddenEdge = sal_True;
2124 							}
2125 							while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) )
2126 							{
2127 								++nCol2;
2128 								bHiddenEdge = sal_True;
2129 							}
2130                             nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
2131                             if (!ValidRow(nTmp))
2132                                 nTmp = 0;
2133                             if (nTmp < nRow1)
2134                             {
2135                                 nRow1 = nTmp;
2136                                 bHiddenEdge = sal_True;
2137                             }
2138                             nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
2139                             if (!ValidRow(nTmp))
2140                                 nTmp = MAXROW;
2141                             if (nTmp > nRow2)
2142                             {
2143                                 nRow2 = nTmp;
2144                                 bHiddenEdge = sal_True;
2145                             }
2146 
2147 							if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
2148 							{
2149 								//	nur an den Raendern entlang
2150 								PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
2151 								PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
2152 								PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
2153 								PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
2154 							}
2155 							else	// alles am Stueck
2156 								PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
2157 						}
2158 					}
2159 				}
2160 		}
2161 	}
2162 }
2163 
2164 //	fuer Chart-Daten-Markierung
2165 
2166 void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
2167 {
2168 	if (!pHighlightRanges)
2169 		pHighlightRanges = new ScHighlightRanges;
2170 	pHighlightRanges->Insert( new ScHighlightEntry( rRange, rColor ) );
2171 
2172 	SCTAB nTab = aViewData.GetTabNo();
2173 	if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
2174 		PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
2175 					rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
2176 }
2177 
2178 void ScTabView::ClearHighlightRanges()
2179 {
2180 	if (pHighlightRanges)
2181 	{
2182 		ScHighlightRanges* pTemp = pHighlightRanges;
2183 		pHighlightRanges = NULL;	// Repaint ohne Highlight
2184 
2185 		SCTAB nTab = aViewData.GetTabNo();
2186 		sal_uLong nCount = pTemp->Count();
2187 		for (sal_uLong i=0; i<nCount; i++)
2188 		{
2189 			ScHighlightEntry* pEntry = pTemp->GetObject( i );
2190 			if (pEntry)
2191 			{
2192 				ScRange aRange = pEntry->aRef;
2193 				if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
2194 					PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
2195 							   aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
2196 			}
2197 		}
2198 		delete pTemp;
2199 	}
2200 }
2201 
2202 void ScTabView::DoChartSelection(
2203     const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
2204 {
2205     ClearHighlightRanges();
2206 
2207     for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
2208     {
2209         Color aSelColor( rHilightRanges[i].PreferredColor );
2210         ScRangeList aRangeList;
2211         ScDocument* pDoc = aViewData.GetDocShell()->GetDocument();
2212         if( ScRangeStringConverter::GetRangeListFromString(
2213                 aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), ';' ))
2214         {
2215             for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
2216             {
2217                 if( rHilightRanges[i].Index == - 1 )
2218                     AddHighlightRange( *p, aSelColor );
2219                 else
2220                     AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
2221             }
2222         }
2223     }
2224 }
2225 
2226 //	DrawDragRect - Drag&Drop-Rechteck zeichnen (XOR)
2227 
2228 //UNUSED2008-05  void ScTabView::DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
2229 //UNUSED2008-05                                ScSplitPos ePos )
2230 //UNUSED2008-05  {
2231 //UNUSED2008-05      if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
2232 //UNUSED2008-05      {
2233 //UNUSED2008-05          for (sal_uInt16  i=0; i<4; i++)
2234 //UNUSED2008-05              if (pGridWin[i])
2235 //UNUSED2008-05                  if (pGridWin[i]->IsVisible())
2236 //UNUSED2008-05                      pGridWin[i]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
2237 //UNUSED2008-05      }
2238 //UNUSED2008-05      else
2239 //UNUSED2008-05          pGridWin[ePos]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
2240 //UNUSED2008-05  }
2241 //UNUSED2008-05
2242 //UNUSED2008-05  //	PaintCell - einzelne Zelle neu zeichnen
2243 //UNUSED2008-05
2244 //UNUSED2008-05  void ScTabView::PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
2245 //UNUSED2008-05  {
2246 //UNUSED2008-05      if ( aViewData.GetTabNo() == nTab )
2247 //UNUSED2008-05      {
2248 //UNUSED2008-05          sal_uInt16 i;
2249 //UNUSED2008-05          for (i=0; i<4; i++)
2250 //UNUSED2008-05              if (pGridWin[i])
2251 //UNUSED2008-05                  if (pGridWin[i]->IsVisible())
2252 //UNUSED2008-05                      pGridWin[i]->Draw( nCol, nRow, nCol, nRow );
2253 //UNUSED2008-05      }
2254 //UNUSED2008-05  }
2255 //UNUSED2008-05
2256 //UNUSED2008-05  void ScTabView::PaintLeftRow( SCROW nRow )
2257 //UNUSED2008-05  {
2258 //UNUSED2008-05      PaintLeftArea( nRow, nRow );
2259 //UNUSED2008-05  }
2260 //UNUSED2008-05
2261 //UNUSED2008-05  void ScTabView::PaintTopCol( SCCOL nCol )
2262 //UNUSED2008-05  {
2263 //UNUSED2008-05      PaintTopArea( nCol, nCol );
2264 //UNUSED2008-05  }
2265 
2266 //	PaintGrid - Datenbereiche neu zeichnen
2267 
2268 void ScTabView::PaintGrid()
2269 {
2270 	sal_uInt16 i;
2271 	for (i=0; i<4; i++)
2272 		if (pGridWin[i])
2273 			if (pGridWin[i]->IsVisible())
2274 				pGridWin[i]->Invalidate();
2275 }
2276 
2277 //	PaintTop - obere Kontrollelemente neu zeichnen
2278 
2279 void ScTabView::PaintTop()
2280 {
2281 	sal_uInt16 i;
2282 	for (i=0; i<2; i++)
2283 	{
2284 		if (pColBar[i])
2285 			pColBar[i]->Invalidate();
2286 		if (pColOutline[i])
2287 			pColOutline[i]->Invalidate();
2288 	}
2289 }
2290 
2291 void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
2292 {
2293 	sal_uInt16 i;
2294 
2295 	for(i=0; i<4; i++)
2296 	{
2297 		if(pGridWin[i])
2298 		{
2299 			if(pGridWin[i]->IsVisible())
2300 			{
2301 				pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
2302 			}
2303 		}
2304 	}
2305 }
2306 
2307 void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
2308 {
2309 		//	Pixel-Position der linken Kante
2310 
2311 	if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
2312 		 nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
2313 		aViewData.RecalcPixPos();
2314 
2315 		//	Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
2316 
2317 	if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
2318 		if (aViewData.UpdateFixX())
2319 			RepeatResize();
2320 
2321 		//	zeichnen
2322 
2323 	if (nStartCol>0)
2324 		--nStartCol;				//! allgemeiner ?
2325 
2326 	sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2327 	long nLayoutSign = bLayoutRTL ? -1 : 1;
2328 
2329 	for (sal_uInt16 i=0; i<2; i++)
2330 	{
2331 		ScHSplitPos eWhich = (ScHSplitPos) i;
2332 		if (pColBar[eWhich])
2333 		{
2334 			Size aWinSize = pColBar[eWhich]->GetSizePixel();
2335 			long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
2336 			long nEndX;
2337 			if (nEndCol >= MAXCOL)
2338 				nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
2339 			else
2340 				nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
2341 			pColBar[eWhich]->Invalidate(
2342 					Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
2343 		}
2344 		if (pColOutline[eWhich])
2345 			pColOutline[eWhich]->Invalidate();
2346 	}
2347 }
2348 
2349 
2350 //	PaintLeft - linke Kontrollelemente neu zeichnen
2351 
2352 void ScTabView::PaintLeft()
2353 {
2354 	sal_uInt16 i;
2355 	for (i=0; i<2; i++)
2356 	{
2357 		if (pRowBar[i])
2358 			pRowBar[i]->Invalidate();
2359 		if (pRowOutline[i])
2360 			pRowOutline[i]->Invalidate();
2361 	}
2362 }
2363 
2364 void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
2365 {
2366 		//	Pixel-Position der oberen Kante
2367 
2368 	if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
2369 		 nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
2370 		aViewData.RecalcPixPos();
2371 
2372 		//	Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
2373 
2374 	if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
2375 		if (aViewData.UpdateFixY())
2376 			RepeatResize();
2377 
2378 		//	zeichnen
2379 
2380 	if (nStartRow>0)
2381 		--nStartRow;
2382 
2383 	for (sal_uInt16 i=0; i<2; i++)
2384 	{
2385 		ScVSplitPos eWhich = (ScVSplitPos) i;
2386 		if (pRowBar[eWhich])
2387 		{
2388 			Size aWinSize = pRowBar[eWhich]->GetSizePixel();
2389 			long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
2390 			long nEndY;
2391 			if (nEndRow >= MAXROW)
2392 				nEndY = aWinSize.Height()-1;
2393 			else
2394 				nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
2395 			pRowBar[eWhich]->Invalidate(
2396 					Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
2397 		}
2398 		if (pRowOutline[eWhich])
2399 			pRowOutline[eWhich]->Invalidate();
2400 	}
2401 }
2402 
2403 //	InvertBlockMark - Block invertieren
2404 
2405 void ScTabView::InvertBlockMark(SCCOL nStartX, SCROW nStartY,
2406 								SCCOL nEndX, SCROW nEndY)
2407 {
2408 	if ( !aViewData.IsActive() )
2409 		return;									// invertiert wird nur auf aktiver View
2410 
2411 	PutInOrder( nStartX, nEndX );
2412 	PutInOrder( nStartY, nEndY );
2413 
2414 	ScMarkData& rMark = aViewData.GetMarkData();
2415 	ScDocShell* pDocSh = aViewData.GetDocShell();
2416 	ScDocument* pDoc = pDocSh->GetDocument();
2417 	SCTAB nTab = aViewData.GetTabNo();
2418 
2419 	if ( pDocSh->GetLockCount() )
2420 	{
2421 		//	if paint is locked, avoid repeated inverting
2422 		//	add repaint areas to paint lock data instead
2423 		pDocSh->PostPaint( nStartX,nStartY,nTab, nEndX,nEndY,nTab, PAINT_GRID );
2424 		return;
2425 	}
2426 
2427 	sal_Bool bSingle = rMark.IsMultiMarked();
2428 	sal_Bool bMerge = pDoc->HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
2429 									HASATTR_MERGED | HASATTR_OVERLAPPED );
2430 
2431 	sal_uInt16 i;
2432 	if ( bMerge || bSingle )
2433 	{
2434 		for (i=0; i<4; i++)
2435 			if (pGridWin[i])
2436 				if (pGridWin[i]->IsVisible())
2437 					pGridWin[i]->InvertSimple( nStartX, nStartY, nEndX, nEndY,
2438 												bMerge, bBlockNeg );
2439 	}
2440 	else
2441 	{
2442 		for (i=0; i<4; i++)
2443 			if (pGridWin[i])
2444 				if (pGridWin[i]->IsVisible())
2445 				{
2446 					ScSplitPos ePos = (ScSplitPos) i;
2447 					Point aStartPoint = aViewData.GetScrPos( nStartX, nStartY, ePos );
2448 					Point aEndPoint = aViewData.GetScrPos( nEndX+1, nEndY+1, ePos );
2449 					if ( pDoc->IsLayoutRTL( nTab ) )
2450 					{
2451 						long nTemp = aStartPoint.X();
2452 						aStartPoint.X() = aEndPoint.X() + 1;	// +1 - excluding start of nEndX+1
2453 						aEndPoint.X() = nTemp;
2454 					}
2455 					else
2456 						aEndPoint.X() -= 1;
2457 					aEndPoint.Y() -= 1;
2458 					if ( aEndPoint.X() >= aStartPoint.X() && aEndPoint.Y() >= aStartPoint.Y() )
2459 					{
2460 						MapMode aOld = pGridWin[ePos]->GetMapMode();
2461 						pGridWin[ePos]->SetMapMode(MAP_PIXEL);
2462 						pGridWin[ePos]->Invert( Rectangle(aStartPoint,aEndPoint), INVERT_HIGHLIGHT );
2463 						pGridWin[ePos]->SetMapMode(aOld);
2464 						pGridWin[ePos]->CheckInverted();
2465 					}
2466 				}
2467 	}
2468 
2469 		//
2470 		//	wenn Controls betroffen, neu malen
2471 		//
2472 
2473 	sal_Bool bHide = sal_True;					// wird Teil der Markierung aufgehoben ?
2474 	if (rMark.IsMarked())
2475 	{
2476 		ScRange aMarkRange;
2477 		rMark.GetMarkArea( aMarkRange );
2478 		if ( aMarkRange.aStart.Col() <= nStartX && aMarkRange.aEnd.Col() >= nEndX &&
2479 			 aMarkRange.aStart.Row() <= nStartY && aMarkRange.aEnd.Row() >= nEndY )
2480 		{
2481 			bHide = sal_False;				// der ganze Bereich ist markiert
2482 		}
2483 	}
2484 }
2485 
2486 sal_Bool ScTabView::PaintExtras()
2487 {
2488 	sal_Bool bRet = sal_False;
2489 	ScDocument* pDoc = aViewData.GetDocument();
2490 	SCTAB nTab = aViewData.GetTabNo();
2491 	if (!pDoc->HasTable(nTab))					// Tabelle geloescht ?
2492 	{
2493 		SCTAB nCount = pDoc->GetTableCount();
2494 		aViewData.SetTabNo(nCount-1);
2495 		bRet = sal_True;
2496 	}
2497 	pTabControl->UpdateStatus();						// sal_True = active
2498 	return bRet;
2499 }
2500 
2501 void ScTabView::RecalcPPT()
2502 {
2503 	//	called after changes that require the PPT values to be recalculated
2504 	//	(currently from detective operations)
2505 
2506 	double nOldX = aViewData.GetPPTX();
2507 	double nOldY = aViewData.GetPPTY();
2508 
2509     aViewData.RefreshZoom();                            // pre-calculate new PPT values
2510 
2511 	sal_Bool bChangedX = ( aViewData.GetPPTX() != nOldX );
2512 	sal_Bool bChangedY = ( aViewData.GetPPTY() != nOldY );
2513 	if ( bChangedX || bChangedY )
2514 	{
2515 		//	call view SetZoom (including draw scale, split update etc)
2516 		//	and paint only if values changed
2517 
2518         Fraction aZoomX = aViewData.GetZoomX();
2519         Fraction aZoomY = aViewData.GetZoomY();
2520         SetZoom( aZoomX, aZoomY, sal_False );
2521 
2522 		PaintGrid();
2523 		if (bChangedX)
2524 			PaintTop();
2525 		if (bChangedY)
2526 			PaintLeft();
2527 	}
2528 }
2529 
2530 void ScTabView::ActivateView( sal_Bool bActivate, sal_Bool bFirst )
2531 {
2532 	if ( bActivate == aViewData.IsActive() && !bFirst )
2533 	{
2534 		//	keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
2535 		//	auf ein anderes Dokument umgeschaltet wurde
2536 		return;
2537 	}
2538 
2539 	// wird nur bei MDI-(De)Activate gerufen
2540 	// aViewData.Activate hinten wegen Cursor-Show bei KillEditView
2541 	//	Markierung nicht mehr loeschen - wenn an der ViewData Activate(sal_False) gesetzt ist,
2542 	//	wird die Markierung nicht ausgegeben
2543 
2544 	if (!bActivate)
2545 	{
2546 		ScModule* pScMod = SC_MOD();
2547 		sal_Bool bRefMode = pScMod->IsFormulaMode();
2548 
2549 			//	Referenzeingabe nicht abbrechen, um Referenzen auf
2550 			//	andere Dokumente zuzulassen
2551 
2552 		if (!bRefMode)
2553 		{
2554 			//pScMod->InputEnterHandler();
2555 
2556 			//	#80843# pass view to GetInputHdl, this view may not be current anymore
2557 			ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2558 			if (pHdl)
2559 				pHdl->EnterHandler();
2560 		}
2561 	}
2562 	pTabControl->ActivateView(bActivate);
2563 	PaintExtras();
2564 
2565 	aViewData.Activate(bActivate);
2566 
2567 	PaintBlock(sal_False);					// Repaint, Markierung je nach Active-Status
2568 
2569 	if (!bActivate)
2570 		HideAllCursors();				// Cursor
2571 	else if (!bFirst)
2572 		ShowAllCursors();
2573 
2574 	//HMHif (pDrawView)
2575 	//HMH	DrawShowMarkHdl(bActivate);		// Drawing-Markierung
2576 
2577 	if (bActivate)
2578 	{
2579 		if ( bFirst )
2580 		{
2581 			ScSplitPos eWin = aViewData.GetActivePart();
2582 			DBG_ASSERT( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
2583 			if ( !pGridWin[eWin] )
2584 			{
2585 				eWin = SC_SPLIT_BOTTOMLEFT;
2586 				if ( !pGridWin[eWin] )
2587 				{
2588 					short i;
2589 					for ( i=0; i<4; i++ )
2590 					{
2591 						if ( pGridWin[i] )
2592 						{
2593 							eWin = (ScSplitPos) i;
2594 							break;	// for
2595 						}
2596 					}
2597 					DBG_ASSERT( i<4, "und BUMM" );
2598 				}
2599 				aViewData.SetActivePart( eWin );
2600 			}
2601 		}
2602 		//	hier nicht mehr selber GrabFocus rufen!
2603 		//	Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
2604 		//	Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)
2605 
2606 		UpdateInputContext();
2607 	}
2608 	else
2609 		pGridWin[aViewData.GetActivePart()]->ClickExtern();
2610 }
2611 
2612 void ScTabView::ActivatePart( ScSplitPos eWhich )
2613 {
2614 	ScSplitPos eOld = aViewData.GetActivePart();
2615 	if ( eOld != eWhich )
2616 	{
2617 		bInActivatePart = sal_True;
2618 
2619 		sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
2620 
2621 		//	#40565# the HasEditView call during SetCursor would fail otherwise
2622 		if ( aViewData.HasEditView(eOld) && !bRefMode )
2623 			UpdateInputLine();
2624 
2625 		ScHSplitPos eOldH = WhichH(eOld);
2626 		ScVSplitPos eOldV = WhichV(eOld);
2627 		ScHSplitPos eNewH = WhichH(eWhich);
2628 		ScVSplitPos eNewV = WhichV(eWhich);
2629 		sal_Bool bTopCap  = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
2630 		sal_Bool bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
2631 
2632 		sal_Bool bFocus = pGridWin[eOld]->HasFocus();
2633 		sal_Bool bCapture = pGridWin[eOld]->IsMouseCaptured();
2634 		if (bCapture)
2635 			pGridWin[eOld]->ReleaseMouse();
2636 		pGridWin[eOld]->ClickExtern();
2637 		pGridWin[eOld]->HideCursor();
2638 		pGridWin[eWhich]->HideCursor();
2639 		aViewData.SetActivePart( eWhich );
2640 
2641 		ScTabViewShell* pShell = aViewData.GetViewShell();
2642 		pShell->WindowChanged();
2643 
2644 		pSelEngine->SetWindow(pGridWin[eWhich]);
2645 		pSelEngine->SetWhich(eWhich);
2646 		pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
2647 
2648 		pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
2649 
2650 		if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
2651 		{
2652 			//	Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
2653 			//	(SelectionEngine ruft CaptureMouse beim SetWindow)
2654 			//!	Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
2655 			pGridWin[eWhich]->ReleaseMouse();
2656 			pGridWin[eWhich]->StartTracking();
2657 		}
2658 
2659 		if ( bTopCap && pColBar[eNewH] )
2660 		{
2661 			pColBar[eOldH]->SetIgnoreMove(sal_True);
2662 			pColBar[eNewH]->SetIgnoreMove(sal_False);
2663 			pHdrSelEng->SetWindow( pColBar[eNewH] );
2664 			long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
2665 			pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
2666 			pColBar[eNewH]->CaptureMouse();
2667 		}
2668 		if ( bLeftCap && pRowBar[eNewV] )
2669 		{
2670 			pRowBar[eOldV]->SetIgnoreMove(sal_True);
2671 			pRowBar[eNewV]->SetIgnoreMove(sal_False);
2672 			pHdrSelEng->SetWindow( pRowBar[eNewV] );
2673 			long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
2674 			pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
2675 			pRowBar[eNewV]->CaptureMouse();
2676 		}
2677 		aHdrFunc.SetWhich(eWhich);
2678 
2679 		pGridWin[eOld]->ShowCursor();
2680 		pGridWin[eWhich]->ShowCursor();
2681 
2682         SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
2683         sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
2684 
2685 		//	#103823# don't switch ViewShell's active window during RefInput, because the focus
2686 		//	might change, and subsequent SetReference calls wouldn't find the right EditView
2687         if ( !bRefMode && !bOleActive )
2688 			aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
2689 
2690 		if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
2691 		{
2692 			//	GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
2693 			//	(z.B. wegen Suchen & Ersetzen)
2694 //!			aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
2695 			pGridWin[eWhich]->GrabFocus();
2696 		}
2697 
2698 		bInActivatePart = sal_False;
2699 	}
2700 }
2701 
2702 void ScTabView::HideListBox()
2703 {
2704 	for (sal_uInt16 i=0; i<4; i++)
2705 		if (pGridWin[i])
2706 			pGridWin[i]->ClickExtern();
2707 }
2708 
2709 void ScTabView::UpdateInputContext()
2710 {
2711 	ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2712 	if (pWin)
2713 		pWin->UpdateInputContext();
2714 }
2715 
2716 //	GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)
2717 
2718 long ScTabView::GetGridWidth( ScHSplitPos eWhich )
2719 {
2720 	ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2721 	if (pGridWin[eGridWhich])
2722 		return pGridWin[eGridWhich]->GetSizePixel().Width();
2723 	else
2724 		return 0;
2725 }
2726 
2727 //	GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)
2728 
2729 long ScTabView::GetGridHeight( ScVSplitPos eWhich )
2730 {
2731 	ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2732 	if (pGridWin[eGridWhich])
2733 		return pGridWin[eGridWhich]->GetSizePixel().Height();
2734 	else
2735 		return 0;
2736 }
2737 
2738 void ScTabView::UpdateInputLine()
2739 {
2740 	SC_MOD()->InputEnterHandler();
2741 }
2742 
2743 void ScTabView::ZoomChanged()
2744 {
2745 	ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2746 	if (pHdl)
2747 		pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
2748 
2749 	UpdateFixPos();
2750 
2751 	UpdateScrollBars();
2752 
2753 	//	VisArea...
2754 	// AW: Discussed with NN if there is a reason that new map mode was only set for one window,
2755 	// but is not. Setting only on one window causes the first repaint to have the old mapMode
2756 	// in three of four views, so the overlay will save the wrong content e.g. when zooming out.
2757 	// Changing to setting map mode at all windows.
2758 	sal_uInt32 a;
2759 
2760 	for(a = 0L; a < 4L; a++)
2761 	{
2762 		if(pGridWin[a])
2763 		{
2764 			pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
2765 		}
2766 	}
2767 
2768 	SetNewVisArea();
2769 
2770 	/* the old code
2771 	ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2772 	if (pWin)
2773 	{
2774 		pWin->SetMapMode( pWin->GetDrawMapMode() );	// mit neuem Zoom
2775 		SetNewVisArea();							// benutzt den gesetzten MapMode
2776 	} */
2777 
2778 	InterpretVisible();		// #69343# have everything calculated before painting
2779 
2780 	SfxBindings& rBindings = aViewData.GetBindings();
2781 	rBindings.Invalidate( SID_ATTR_ZOOM );
2782     rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
2783 
2784 	HideNoteMarker();
2785 
2786 	// AW: To not change too much, use pWin here
2787 	ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2788 
2789 	if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
2790 	{
2791 		// flush OverlayManager before changing the MapMode
2792 		pWin->flushOverlayManager();
2793 
2794 		//	#93650# make sure the EditView's position and size are updated
2795 		//	with the right (logic, not drawing) MapMode
2796 		pWin->SetMapMode( aViewData.GetLogicMode() );
2797 		UpdateEditView();
2798 	}
2799 }
2800 
2801 void ScTabView::CheckNeedsRepaint()
2802 {
2803 	sal_uInt16 i;
2804 	for (i=0; i<4; i++)
2805 		if ( pGridWin[i] && pGridWin[i]->IsVisible() )
2806 			pGridWin[i]->CheckNeedsRepaint();
2807 }
2808 
2809 
2810 
2811 
2812 
2813