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