xref: /AOO41X/main/sc/source/ui/view/tabview3.cxx (revision 5443dcac4da55ae8863c5c80e8907938642a7f1b)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 // System - Includes -----------------------------------------------------
28 
29 
30 
31 // INCLUDE ---------------------------------------------------------------
32 #include <rangelst.hxx>
33 #include "scitems.hxx"
34 #include <editeng/eeitem.hxx>
35 
36 
37 #include <editeng/brshitem.hxx>
38 #include <editeng/editview.hxx>
39 #include <svx/fmshell.hxx>
40 #include <svx/svdoole2.hxx>
41 #include <sfx2/bindings.hxx>
42 #include <sfx2/viewfrm.hxx>
43 #include <vcl/cursor.hxx>
44 
45 #include "tabview.hxx"
46 #include "tabvwsh.hxx"
47 #include "docsh.hxx"
48 #include "gridwin.hxx"
49 #include "olinewin.hxx"
50 #include "colrowba.hxx"
51 #include "tabcont.hxx"
52 #include "scmod.hxx"
53 #include "uiitems.hxx"
54 #include "sc.hrc"
55 #include "viewutil.hxx"
56 #include "editutil.hxx"
57 #include "inputhdl.hxx"
58 #include "inputwin.hxx"
59 #include "validat.hxx"
60 #include "hintwin.hxx"
61 #include "inputopt.hxx"
62 #include "rfindlst.hxx"
63 #include "hiranges.hxx"
64 #include "viewuno.hxx"
65 #include "chartarr.hxx"
66 #include "anyrefdg.hxx"
67 #include "dpobject.hxx"
68 #include "patattr.hxx"
69 #include "dociter.hxx"
70 #include "seltrans.hxx"
71 #include "fillinfo.hxx"
72 #include "AccessibilityHints.hxx"
73 #include "rangeutl.hxx"
74 #include "client.hxx"
75 #include "tabprotection.hxx"
76 
77 #include <com/sun/star/chart2/data/HighlightedRange.hpp>
78 
79 namespace
80 {
81 
82 ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
83 {
84     ScAddress aResult( rRange.aStart );
85 
86     SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
87     SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
88     SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
89     if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
90     {
91         // row by row from first to last sheet
92         sal_Int32 nArea = nWidth * nHeight;
93         aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
94         aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
95         aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
96         if( !rRange.In( aResult ) )
97             aResult = rRange.aStart;
98     }
99 
100     return ScRange( aResult );
101 }
102 
103 } // anonymous namespace
104 
105 using namespace com::sun::star;
106 
107 // -----------------------------------------------------------------------
108 
109 //
110 // ---  Public-Funktionen
111 //
112 
113 void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bControl )
114 {
115     ScDocument* pDoc = aViewData.GetDocument();
116     SCTAB nTab = aViewData.GetTabNo();
117     while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))     //! ViewData !!!
118         --nPosX;
119     while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
120         --nPosY;
121 
122     sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
123 
124     if ( bRefMode )
125     {
126         DoneRefMode( sal_False );
127 
128         if (bControl)
129             SC_MOD()->AddRefEntry();
130 
131         InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
132     }
133     else
134     {
135         DoneBlockMode( bControl );
136         aViewData.ResetOldCursor();
137         SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
138     }
139 }
140 
141 void ScTabView::UpdateAutoFillMark()
142 {
143     // single selection or cursor
144     ScRange aMarkRange;
145     sal_Bool bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
146 
147     sal_uInt16 i;
148     for (i=0; i<4; i++)
149         if (pGridWin[i] && pGridWin[i]->IsVisible())
150             pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
151 
152     for (i=0; i<2; i++)
153     {
154         if (pColBar[i] && pColBar[i]->IsVisible())
155             pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
156         if (pRowBar[i] && pRowBar[i]->IsVisible())
157             pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
158     }
159 
160     //  selection transfer object is checked together with AutoFill marks,
161     //  because it has the same requirement of a single continuous block.
162     CheckSelectionTransfer();   // update selection transfer object
163 }
164 
165 void ScTabView::FakeButtonUp( ScSplitPos eWhich )
166 {
167     if (pGridWin[eWhich])
168         pGridWin[eWhich]->FakeButtonUp();
169 }
170 
171 void ScTabView::HideAllCursors()
172 {
173     for (sal_uInt16 i=0; i<4; i++)
174         if (pGridWin[i])
175             if (pGridWin[i]->IsVisible())
176             {
177                 Cursor* pCur = pGridWin[i]->GetCursor();
178                 if (pCur)
179                     if (pCur->IsVisible())
180                         pCur->Hide();
181                 pGridWin[i]->HideCursor();
182             }
183 }
184 
185 void ScTabView::ShowAllCursors()
186 {
187     for (sal_uInt16 i=0; i<4; i++)
188         if (pGridWin[i])
189             if (pGridWin[i]->IsVisible())
190             {
191                 pGridWin[i]->ShowCursor();
192 
193                 // #114409#
194                 pGridWin[i]->CursorChanged();
195             }
196 }
197 
198 void ScTabView::HideCursor()
199 {
200     pGridWin[aViewData.GetActivePart()]->HideCursor();
201 }
202 
203 void ScTabView::ShowCursor()
204 {
205     pGridWin[aViewData.GetActivePart()]->ShowCursor();
206 
207     // #114409#
208     pGridWin[aViewData.GetActivePart()]->CursorChanged();
209 }
210 
211 void ScTabView::InvalidateAttribs()
212 {
213     SfxBindings& rBindings = aViewData.GetBindings();
214 
215     rBindings.Invalidate( SID_STYLE_APPLY );
216     rBindings.Invalidate( SID_STYLE_FAMILY2 );
217     // StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen
218 
219     rBindings.Invalidate( SID_ATTR_CHAR_FONT );
220     rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
221     rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
222 
223     rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
224     rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
225     rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
226     rBindings.Invalidate( SID_ULINE_VAL_NONE );
227     rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
228     rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
229     rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
230 
231     rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
232 
233     rBindings.Invalidate( SID_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 
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 
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 
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 
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 
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 
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 
593 void ScTabView::RemoveHintWindow()
594 {
595     DELETEZ(pInputHintWindow);
596 }
597 
598 
599 // find window that should not be over the cursor
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 
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 
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 
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     if (nCurX < 0) nCurX = 0;
915     if (nCurY < 0) nCurY = 0;
916     if (nCurX > MAXCOL) nCurX = MAXCOL;
917     if (nCurY > MAXROW) nCurY = MAXROW;
918 
919     HideAllCursors();
920 
921     if ( bShift && bNewStartIfMarking && IsBlockMode() )
922     {
923         //  used for ADD selection mode: start a new block from the cursor position
924         DoneBlockMode( sal_True );
925         InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), sal_True );
926     }
927 
928         //  aktiven Teil umschalten jetzt in AlignToCursor
929 
930     AlignToCursor( nCurX, nCurY, eMode );
931     //!     auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
932 
933     if (bKeepSel)
934         SetCursor( nCurX, nCurY );      // Markierung stehenlassen
935     else
936     {
937         sal_Bool bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
938         bMoveIsShift = bShift;
939         pSelEngine->CursorPosChanging( bShift, bControl );
940         bMoveIsShift = sal_False;
941         aFunctionSet.SetCursorAtCell( nCurX, nCurY, sal_False );
942 
943         //  Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
944         //  Aufheben der Selektion hier einzeln passieren:
945         if (bSame)
946             SelectionChanged();
947     }
948 
949     ShowAllCursors();
950 }
951 
952 void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
953                                     sal_Bool bShift, sal_Bool bKeepSel )
954 {
955     ScDocument* pDoc = aViewData.GetDocument();
956     SCTAB nTab = aViewData.GetTabNo();
957 
958     bool bSkipProtected = false, bSkipUnprotected = false;
959     ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
960     if ( pProtect && pProtect->isProtected() )
961     {
962         bSkipProtected   = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
963         bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
964     }
965 
966     if ( bSkipProtected && bSkipUnprotected )
967         return;
968 
969     SCsCOL nOldX;
970     SCsROW nOldY;
971     SCsCOL nCurX;
972     SCsROW nCurY;
973     if ( aViewData.IsRefMode() )
974     {
975         nOldX = (SCsCOL) aViewData.GetRefEndX();
976         nOldY = (SCsROW) aViewData.GetRefEndY();
977         nCurX = nOldX + nMovX;
978         nCurY = nOldY + nMovY;
979     }
980     else
981     {
982         nOldX = (SCsCOL) aViewData.GetCurX();
983         nOldY = (SCsROW) aViewData.GetCurY();
984         nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
985         nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
986     }
987 
988     sal_Bool bSkipCell = sal_False;
989     aViewData.ResetOldCursor();
990 
991     if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
992     {
993         sal_Bool bHFlip = sal_False;
994         do
995         {
996             SCCOL nLastCol = -1;
997             bSkipCell = pDoc->ColHidden(nCurX, nTab, nLastCol) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
998             if (bSkipProtected && !bSkipCell)
999                 bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1000             if (bSkipUnprotected && !bSkipCell)
1001                 bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1002 
1003             if (bSkipCell)
1004             {
1005                 if ( nCurX<=0 || nCurX>=MAXCOL )
1006                 {
1007                     if (bHFlip)
1008                     {
1009                         nCurX = nOldX;
1010                         bSkipCell = sal_False;
1011                     }
1012                     else
1013                     {
1014                         nMovX = -nMovX;
1015                         if (nMovX > 0) ++nCurX; else --nCurX;       // zuruecknehmen
1016                         bHFlip = sal_True;
1017                     }
1018                 }
1019                 else
1020                     if (nMovX > 0) ++nCurX; else --nCurX;
1021             }
1022         }
1023         while (bSkipCell);
1024 
1025         if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
1026         {
1027             aViewData.SetOldCursor( nCurX,nCurY );
1028             while (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
1029                 --nCurY;
1030         }
1031     }
1032 
1033     if (nMovY != 0 && VALIDCOLROW(nCurX,nCurY))
1034     {
1035         sal_Bool bVFlip = sal_False;
1036         do
1037         {
1038             SCROW nLastRow = -1;
1039             bSkipCell = pDoc->RowHidden(nCurY, nTab, nLastRow) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
1040             if (bSkipProtected && !bSkipCell)
1041                 bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1042             if (bSkipUnprotected && !bSkipCell)
1043                 bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1044 
1045             if (bSkipCell)
1046             {
1047                 if ( nCurY<=0 || nCurY>=MAXROW )
1048                 {
1049                     if (bVFlip)
1050                     {
1051                         nCurY = nOldY;
1052                         bSkipCell = sal_False;
1053                     }
1054                     else
1055                     {
1056                         nMovY = -nMovY;
1057                         if (nMovY > 0) ++nCurY; else --nCurY;       // zuruecknehmen
1058                         bVFlip = sal_True;
1059                     }
1060                 }
1061                 else
1062                     if (nMovY > 0) ++nCurY; else --nCurY;
1063             }
1064         }
1065         while (bSkipCell);
1066 
1067         if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
1068         {
1069             aViewData.SetOldCursor( nCurX,nCurY );
1070             while (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
1071                 --nCurX;
1072         }
1073     }
1074 
1075     MoveCursorAbs( nCurX, nCurY, eMode, bShift, sal_False, sal_True, bKeepSel );
1076 }
1077 
1078 void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
1079 {
1080     SCCOL nCurX;
1081     SCROW nCurY;
1082     aViewData.GetMoveCursor( nCurX,nCurY );
1083 
1084     ScSplitPos eWhich = aViewData.GetActivePart();
1085     ScHSplitPos eWhichX = WhichH( eWhich );
1086     ScVSplitPos eWhichY = WhichV( eWhich );
1087 
1088     SCsCOL nPageX;
1089     SCsROW nPageY;
1090     if (nMovX >= 0)
1091         nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
1092     else
1093         nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
1094 
1095     if (nMovY >= 0)
1096         nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
1097     else
1098         nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
1099 
1100     if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
1101     if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
1102 
1103     MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
1104 }
1105 
1106 void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
1107 {
1108     SCCOL nCurX;
1109     SCROW nCurY;
1110     aViewData.GetMoveCursor( nCurX,nCurY );
1111     SCCOL nNewX = nCurX;
1112     SCROW nNewY = nCurY;
1113 
1114     ScDocument* pDoc = aViewData.GetDocument();
1115     SCTAB nTab = aViewData.GetTabNo();
1116 
1117     //  FindAreaPos kennt nur -1 oder 1 als Richtung
1118 
1119     SCsCOLROW i;
1120     if ( nMovX > 0 )
1121         for ( i=0; i<nMovX; i++ )
1122             pDoc->FindAreaPos( nNewX, nNewY, nTab,  1,  0 );
1123     if ( nMovX < 0 )
1124         for ( i=0; i<-nMovX; i++ )
1125             pDoc->FindAreaPos( nNewX, nNewY, nTab, -1,  0 );
1126     if ( nMovY > 0 )
1127         for ( i=0; i<nMovY; i++ )
1128             pDoc->FindAreaPos( nNewX, nNewY, nTab,  0,  1 );
1129     if ( nMovY < 0 )
1130         for ( i=0; i<-nMovY; i++ )
1131             pDoc->FindAreaPos( nNewX, nNewY, nTab,  0, -1 );
1132 
1133     if (eMode==SC_FOLLOW_JUMP)                  // unten/rechts nicht zuviel grau anzeigen
1134     {
1135         if (nMovX != 0 && nNewX == MAXCOL)
1136             eMode = SC_FOLLOW_LINE;
1137         if (nMovY != 0 && nNewY == MAXROW)
1138             eMode = SC_FOLLOW_LINE;
1139     }
1140 
1141     MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
1142 }
1143 
1144 void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
1145 {
1146     ScDocument* pDoc = aViewData.GetDocument();
1147     SCTAB nTab = aViewData.GetTabNo();
1148 
1149     SCCOL nCurX;
1150     SCROW nCurY;
1151     aViewData.GetMoveCursor( nCurX,nCurY );
1152     SCCOL nNewX = nCurX;
1153     SCROW nNewY = nCurY;
1154 
1155     SCCOL nUsedX = 0;
1156     SCROW nUsedY = 0;
1157     if ( nMovX > 0 || nMovY > 0 )
1158         pDoc->GetPrintArea( nTab, nUsedX, nUsedY );     // Ende holen
1159 
1160     if (nMovX<0)
1161         nNewX=0;
1162     else if (nMovX>0)
1163         nNewX=nUsedX;                                   // letzter benutzter Bereich
1164 
1165     if (nMovY<0)
1166         nNewY=0;
1167     else if (nMovY>0)
1168         nNewY=nUsedY;
1169 
1170     aViewData.ResetOldCursor();
1171     MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
1172 }
1173 
1174 void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift )
1175 {
1176     ScDocument* pDoc = aViewData.GetDocument();
1177     SCTAB nTab = aViewData.GetTabNo();
1178 
1179     SCCOL nCurX;
1180     SCROW nCurY;
1181     aViewData.GetMoveCursor( nCurX,nCurY );
1182     SCCOL nNewX = nCurX;
1183     SCROW nNewY = nCurY;
1184 
1185     ScSplitPos eWhich = aViewData.GetActivePart();
1186     SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
1187     SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );
1188 
1189     SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
1190     if (nAddX != 0)
1191         --nAddX;
1192     SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
1193     if (nAddY != 0)
1194         --nAddY;
1195 
1196     if (nMovX<0)
1197         nNewX=nPosX;
1198     else if (nMovX>0)
1199         nNewX=nPosX+nAddX;
1200 
1201     if (nMovY<0)
1202         nNewY=nPosY;
1203     else if (nMovY>0)
1204         nNewY=nPosY+nAddY;
1205 
1206 //  aViewData.ResetOldCursor();
1207     aViewData.SetOldCursor( nNewX,nNewY );
1208 
1209     while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
1210         --nNewX;
1211     while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
1212         --nNewY;
1213 
1214     MoveCursorAbs( nNewX, nNewY, eMode, bShift, sal_False, sal_True );
1215 }
1216 
1217 void ScTabView::MoveCursorEnter( sal_Bool bShift )          // bShift -> hoch/runter
1218 {
1219     const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
1220     if (!rOpt.GetMoveSelection())
1221     {
1222         aViewData.UpdateInputHandler(sal_True);
1223         return;
1224     }
1225 
1226     SCsCOL nMoveX = 0;
1227     SCsROW nMoveY = 0;
1228     switch ((ScDirection)rOpt.GetMoveDir())
1229     {
1230         case DIR_BOTTOM:
1231             nMoveY = bShift ? -1 : 1;
1232             break;
1233         case DIR_RIGHT:
1234             nMoveX = bShift ? -1 : 1;
1235             break;
1236         case DIR_TOP:
1237             nMoveY = bShift ? 1 : -1;
1238             break;
1239         case DIR_LEFT:
1240             nMoveX = bShift ? 1 : -1;
1241             break;
1242     }
1243 
1244     ScMarkData& rMark = aViewData.GetMarkData();
1245     if (rMark.IsMarked() || rMark.IsMultiMarked())
1246     {
1247         SCCOL nCurX;
1248         SCROW nCurY;
1249         aViewData.GetMoveCursor( nCurX,nCurY );
1250         SCCOL nNewX = nCurX;
1251         SCROW nNewY = nCurY;
1252         SCTAB nTab = aViewData.GetTabNo();
1253 
1254         ScDocument* pDoc = aViewData.GetDocument();
1255         pDoc->GetNextPos( nNewX,nNewY, nTab, nMoveX,nMoveY, sal_True,sal_False, rMark );
1256 
1257         MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1258                             SC_FOLLOW_LINE, sal_False, sal_True );
1259 
1260         //  update input line even if cursor was not moved
1261         if ( nNewX == nCurX && nNewY == nCurY )
1262             aViewData.UpdateInputHandler(sal_True);
1263     }
1264     else
1265     {
1266         if ( nMoveY != 0 && !nMoveX )
1267         {
1268             //  nach Tab und Enter wieder zur Ausgangsspalte
1269             SCCOL nTabCol = aViewData.GetTabStartCol();
1270             if (nTabCol != SC_TABSTART_NONE)
1271             {
1272                 SCCOL nCurX;
1273                 SCROW nCurY;
1274                 aViewData.GetMoveCursor( nCurX,nCurY );
1275                 nMoveX = ((SCsCOL)nTabCol)-(SCsCOL)nCurX;
1276             }
1277         }
1278 
1279         MoveCursorRel( nMoveX,nMoveY, SC_FOLLOW_LINE, sal_False );
1280     }
1281 }
1282 
1283 
1284 sal_Bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
1285 {
1286     const KeyCode& rKCode = rKeyEvent.GetKeyCode();
1287 
1288     enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
1289         rKCode.IsMod1() ?
1290             (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
1291             (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
1292 
1293     sal_Bool bSel = rKCode.IsShift();
1294     sal_uInt16 nCode = rKCode.GetCode();
1295 
1296     // CURSOR keys
1297     SCsCOL nDX = 0;
1298     SCsROW nDY = 0;
1299     switch( nCode )
1300     {
1301         case KEY_LEFT:  nDX = -1;   break;
1302         case KEY_RIGHT: nDX = 1;    break;
1303         case KEY_UP:    nDY = -1;   break;
1304         case KEY_DOWN:  nDY = 1;    break;
1305     }
1306     if( nDX != 0 || nDY != 0 )
1307     {
1308         switch( eModifier )
1309         {
1310             case MOD_NONE:  MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel );    break;
1311             case MOD_CTRL:  MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel );   break;
1312             default:
1313             {
1314                 // added to avoid warnings
1315             }
1316         }
1317         // always sal_True to suppress changes of col/row size (ALT+CURSOR)
1318         return sal_True;
1319     }
1320 
1321     // PAGEUP/PAGEDOWN
1322     if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
1323     {
1324         nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
1325         switch( eModifier )
1326         {
1327             case MOD_NONE:  MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel );  break;
1328             case MOD_ALT:   MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel );  break;
1329             case MOD_CTRL:  SelectNextTab( nDX );                           break;
1330             default:
1331             {
1332                 // added to avoid warnings
1333             }
1334         }
1335         return sal_True;
1336     }
1337 
1338     // HOME/END
1339     if( (nCode == KEY_HOME) || (nCode == KEY_END) )
1340     {
1341         nDX = (nCode == KEY_HOME) ? -1 : 1;
1342         ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
1343         switch( eModifier )
1344         {
1345             case MOD_NONE:  MoveCursorEnd( nDX, 0, eMode, bSel );   break;
1346             case MOD_CTRL:  MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
1347             default:
1348             {
1349                 // added to avoid warnings
1350             }
1351         }
1352         return sal_True;
1353     }
1354 
1355     return sal_False;
1356 }
1357 
1358 
1359         // naechste/vorherige nicht geschuetzte Zelle
1360 void ScTabView::FindNextUnprot( sal_Bool bShift, sal_Bool bInSelection )
1361 {
1362     short nMove = bShift ? -1 : 1;
1363 
1364     ScMarkData& rMark = aViewData.GetMarkData();
1365     sal_Bool bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
1366 
1367     SCCOL nCurX;
1368     SCROW nCurY;
1369     aViewData.GetMoveCursor( nCurX,nCurY );
1370     SCCOL nNewX = nCurX;
1371     SCROW nNewY = nCurY;
1372     SCTAB nTab = aViewData.GetTabNo();
1373 
1374     ScDocument* pDoc = aViewData.GetDocument();
1375     pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked,sal_True, rMark );
1376 
1377     SCCOL nTabCol = aViewData.GetTabStartCol();
1378     if ( nTabCol == SC_TABSTART_NONE )
1379         nTabCol = nCurX;                    // auf diese Spalte zurueck bei Enter
1380 
1381     MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1382                         SC_FOLLOW_LINE, sal_False, sal_True );
1383 
1384     //  in MoveCursorRel wird die TabCol zurueckgesetzt...
1385     aViewData.SetTabStartCol( nTabCol );
1386 }
1387 
1388 void ScTabView::MarkColumns()
1389 {
1390     SCCOL nStartCol;
1391     SCCOL nEndCol;
1392 
1393     ScMarkData& rMark = aViewData.GetMarkData();
1394     if (rMark.IsMarked())
1395     {
1396         ScRange aMarkRange;
1397         rMark.GetMarkArea( aMarkRange );
1398         nStartCol = aMarkRange.aStart.Col();
1399         nEndCol = aMarkRange.aEnd.Col();
1400     }
1401     else
1402     {
1403         SCROW nDummy;
1404         aViewData.GetMoveCursor( nStartCol, nDummy );
1405         nEndCol=nStartCol;
1406     }
1407 
1408     SCTAB nTab = aViewData.GetTabNo();
1409     DoneBlockMode();
1410     InitBlockMode( nStartCol,0, nTab );
1411     MarkCursor( nEndCol,MAXROW, nTab );
1412     SelectionChanged();
1413 }
1414 
1415 void ScTabView::MarkRows()
1416 {
1417     SCROW nStartRow;
1418     SCROW nEndRow;
1419 
1420     ScMarkData& rMark = aViewData.GetMarkData();
1421     if (rMark.IsMarked())
1422     {
1423         ScRange aMarkRange;
1424         rMark.GetMarkArea( aMarkRange );
1425         nStartRow = aMarkRange.aStart.Row();
1426         nEndRow = aMarkRange.aEnd.Row();
1427     }
1428     else
1429     {
1430         SCCOL nDummy;
1431         aViewData.GetMoveCursor( nDummy, nStartRow );
1432         nEndRow=nStartRow;
1433     }
1434 
1435     SCTAB nTab = aViewData.GetTabNo();
1436     DoneBlockMode();
1437     InitBlockMode( 0,nStartRow, nTab );
1438     MarkCursor( MAXCOL,nEndRow, nTab );
1439     SelectionChanged();
1440 }
1441 
1442 void ScTabView::MarkDataArea( sal_Bool bIncludeCursor )
1443 {
1444     ScDocument* pDoc = aViewData.GetDocument();
1445     SCTAB nTab = aViewData.GetTabNo();
1446     SCCOL nStartCol = aViewData.GetCurX();
1447     SCROW nStartRow = aViewData.GetCurY();
1448     SCCOL nEndCol = nStartCol;
1449     SCROW nEndRow = nStartRow;
1450 
1451     pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );
1452 
1453     HideAllCursors();
1454     DoneBlockMode();
1455     InitBlockMode( nStartCol, nStartRow, nTab );
1456     MarkCursor( nEndCol, nEndRow, nTab );
1457     ShowAllCursors();
1458 
1459     SelectionChanged();
1460 }
1461 
1462 void ScTabView::MarkMatrixFormula()
1463 {
1464     ScDocument* pDoc = aViewData.GetDocument();
1465     ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
1466     ScRange aMatrix;
1467     if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
1468     {
1469         MarkRange( aMatrix, sal_False );        // cursor is already within the range
1470     }
1471 }
1472 
1473 void ScTabView::MarkRange( const ScRange& rRange, sal_Bool bSetCursor, sal_Bool bContinue )
1474 {
1475     SCTAB nTab = rRange.aStart.Tab();
1476     SetTabNo( nTab );
1477 
1478     HideAllCursors();
1479     DoneBlockMode( bContinue ); // bContinue==sal_True -> clear old mark
1480     if (bSetCursor)             // Wenn Cursor gesetzt wird, immer auch alignen
1481     {
1482         SCCOL nAlignX = rRange.aStart.Col();
1483         SCROW nAlignY = rRange.aStart.Row();
1484         if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
1485             nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
1486         if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
1487             nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
1488         AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
1489     }
1490     InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
1491     MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
1492     if (bSetCursor)
1493     {
1494         SCCOL nPosX = rRange.aStart.Col();
1495         SCROW nPosY = rRange.aStart.Row();
1496         ScDocument* pDoc = aViewData.GetDocument();
1497 
1498         while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))     //! ViewData !!!
1499             --nPosX;
1500         while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
1501             --nPosY;
1502 
1503         aViewData.ResetOldCursor();
1504         SetCursor( nPosX, nPosY );
1505     }
1506     ShowAllCursors();
1507 
1508     SelectionChanged();
1509 }
1510 
1511 void ScTabView::Unmark()
1512 {
1513     ScMarkData& rMark = aViewData.GetMarkData();
1514     if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1515     {
1516         SCCOL nCurX;
1517         SCROW nCurY;
1518         aViewData.GetMoveCursor( nCurX,nCurY );
1519         MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, sal_False, sal_False );
1520 
1521         SelectionChanged();
1522     }
1523 }
1524 
1525 void ScTabView::SetMarkData( const ScMarkData& rNew )
1526 {
1527     DoneBlockMode();
1528     InitOwnBlockMode();
1529     aViewData.GetMarkData() = rNew;
1530 
1531     MarkDataChanged();
1532 }
1533 
1534 void ScTabView::MarkDataChanged()
1535 {
1536     // has to be called after making direct changes to mark data (not via MarkCursor etc)
1537 
1538     UpdateSelectionOverlay();
1539 }
1540 
1541 void ScTabView::SelectNextTab( short nDir, sal_Bool bExtendSelection )
1542 {
1543     if (!nDir) return;
1544     DBG_ASSERT( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");
1545 
1546     ScDocument* pDoc = aViewData.GetDocument();
1547     SCTAB nTab = aViewData.GetTabNo();
1548     if (nDir<0)
1549     {
1550         if (!nTab) return;
1551         --nTab;
1552         while (!pDoc->IsVisible(nTab))
1553         {
1554             if (!nTab) return;
1555             --nTab;
1556         }
1557     }
1558     else
1559     {
1560         SCTAB nCount = pDoc->GetTableCount();
1561         ++nTab;
1562         if (nTab >= nCount) return;
1563         while (!pDoc->IsVisible(nTab))
1564         {
1565             ++nTab;
1566             if (nTab >= nCount) return;
1567         }
1568     }
1569 
1570     SetTabNo( nTab, sal_False, bExtendSelection );
1571     PaintExtras();
1572 }
1573 
1574 void ScTabView::UpdateVisibleRange()
1575 {
1576     for (sal_uInt16 i=0; i<4; i++)
1577         if (pGridWin[i] && pGridWin[i]->IsVisible())
1578             pGridWin[i]->UpdateVisibleRange();
1579 }
1580 
1581 //  SetTabNo    - angezeigte Tabelle
1582 
1583 void ScTabView::SetTabNo( SCTAB nTab, sal_Bool bNew, sal_Bool bExtendSelection, bool bSameTabButMoved )
1584 {
1585     if ( !ValidTab(nTab) )
1586     {
1587         DBG_ERROR("SetTabNo: falsche Tabelle");
1588         return;
1589     }
1590 
1591     if ( nTab != aViewData.GetTabNo() || bNew )
1592     {
1593         //  #57724# Die FormShell moechte vor dem Umschalten benachrichtigt werden
1594         FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
1595         if (pFormSh)
1596         {
1597             sal_Bool bAllowed = sal::static_int_cast<sal_Bool>( pFormSh->PrepareClose( sal_True ) );
1598             if (!bAllowed)
1599             {
1600                 //! Fehlermeldung? oder macht das die FormShell selber?
1601                 //! Fehler-Flag zurueckgeben und Aktionen abbrechen
1602 
1603                 return;     // Die FormShell sagt, es kann nicht umgeschaltet werden
1604             }
1605         }
1606 
1607                                         //  nicht InputEnterHandler wegen Referenzeingabe !
1608 
1609         ScDocument* pDoc = aViewData.GetDocument();
1610         pDoc->MakeTable( nTab );
1611 
1612         // Update pending row heights before switching the sheet, so Reschedule from the progress bar
1613         // doesn't paint the new sheet with old heights
1614         aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
1615 
1616         SCTAB nTabCount = pDoc->GetTableCount();
1617         SCTAB nOldPos = nTab;
1618         while (!pDoc->IsVisible(nTab))              // naechste sichtbare suchen
1619         {
1620             sal_Bool bUp = (nTab>=nOldPos);
1621             if (bUp)
1622             {
1623                 ++nTab;
1624                 if (nTab>=nTabCount)
1625                 {
1626                     nTab = nOldPos;
1627                     bUp = sal_False;
1628                 }
1629             }
1630 
1631             if (!bUp)
1632             {
1633                 if (nTab != 0)
1634                     --nTab;
1635                 else
1636                 {
1637                     DBG_ERROR("keine sichtbare Tabelle");
1638                     pDoc->SetVisible( 0, sal_True );
1639                 }
1640             }
1641         }
1642 
1643         // #i71490# Deselect drawing objects before changing the sheet number in view data,
1644         // so the handling of notes still has the sheet selected on which the notes are.
1645         DrawDeselectAll();
1646 
1647         ScModule* pScMod = SC_MOD();
1648         sal_Bool bRefMode = pScMod->IsFormulaMode();
1649         if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
1650         {
1651             DoneBlockMode();
1652             pSelEngine->Reset();                // reset all flags, including locked modifiers
1653             aViewData.SetRefTabNo( nTab );
1654         }
1655 
1656         ScSplitPos eOldActive = aViewData.GetActivePart();      // before switching
1657         sal_Bool bFocus = pGridWin[eOldActive]->HasFocus();
1658 
1659         aViewData.SetTabNo( nTab );
1660         //  UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
1661         //  Fenster findet (wird aus SetCursor gerufen)
1662         UpdateShow();
1663         aViewData.ResetOldCursor();
1664         SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), sal_True );
1665 
1666         SfxBindings& rBindings = aViewData.GetBindings();
1667         ScMarkData& rMark = aViewData.GetMarkData();
1668 
1669         bool bAllSelected = true;
1670         for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
1671         {
1672             if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
1673             {
1674                 if (nTab == nSelTab)
1675                     // This tab is already in selection.  Keep the current
1676                     // selection.
1677                     bExtendSelection = true;
1678             }
1679             else
1680             {
1681                 bAllSelected = false;
1682                 if (bExtendSelection)
1683                     // We got what we need.  No need to stay in the loop.
1684                     break;
1685             }
1686         }
1687         if (bAllSelected && !bNew)
1688             // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
1689             // (not if called with bNew to update settings)
1690             bExtendSelection = false;
1691 
1692         if (bExtendSelection)
1693             rMark.SelectTable( nTab, sal_True );
1694         else
1695         {
1696             rMark.SelectOneTable( nTab );
1697             rBindings.Invalidate( FID_FILL_TAB );
1698             rBindings.Invalidate( FID_TAB_DESELECTALL );
1699         }
1700 
1701         bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
1702 
1703         // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
1704         RefreshZoom();
1705         UpdateVarZoom();
1706 
1707         if ( bRefMode )     // hide EditView if necessary (after aViewData.SetTabNo !)
1708         {
1709             for ( sal_uInt16 i=0; i<4; i++ )
1710                 if ( pGridWin[i] )
1711                     if ( pGridWin[i]->IsVisible() )
1712                         pGridWin[i]->UpdateEditViewPos();
1713         }
1714 
1715         TabChanged( bSameTabButMoved );                                     // DrawView
1716 
1717         aViewData.GetViewShell()->WindowChanged();          // falls das aktive Fenster anders ist
1718         if ( !bUnoRefDialog )
1719             aViewData.GetViewShell()->DisconnectAllClients();   // important for floating frames
1720         else
1721         {
1722             // hide / show inplace client
1723 
1724             ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
1725             if ( pClient && pClient->IsObjectInPlaceActive() )
1726             {
1727                 Rectangle aObjArea = pClient->GetObjArea();
1728                 if ( nTab == aViewData.GetRefTabNo() )
1729                 {
1730                     // move to its original position
1731 
1732                     SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
1733                     if ( pDrawObj )
1734                     {
1735                         Rectangle aRect = pDrawObj->GetLogicRect();
1736                         MapMode aMapMode( MAP_100TH_MM );
1737                         Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
1738                         aRect.SetSize( aOleSize );
1739                         aObjArea = aRect;
1740                     }
1741                 }
1742                 else
1743                 {
1744                     // move to an invisible position
1745 
1746                     aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
1747                 }
1748                 pClient->SetObjArea( aObjArea );
1749             }
1750         }
1751 
1752         if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
1753             ActiveGrabFocus();      // grab focus to the pane that's active now
1754 
1755             //  Fixierungen
1756 
1757         sal_Bool bResize = sal_False;
1758         if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1759             if (aViewData.UpdateFixX())
1760                 bResize = sal_True;
1761         if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1762             if (aViewData.UpdateFixY())
1763                 bResize = sal_True;
1764         if (bResize)
1765             RepeatResize();
1766         InvalidateSplit();
1767 
1768         // #163911# Update the visible range in each GridWin directly, don't wait for the repaint event.
1769         UpdateVisibleRange();
1770 
1771         if ( aViewData.IsPagebreakMode() )
1772             UpdatePageBreakData();              //! asynchron ??
1773 
1774         //  #53551# Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle kennen
1775         //  dafuer muss hier schon der MapMode stimmen
1776         for (sal_uInt16 i=0; i<4; i++)
1777             if (pGridWin[i])
1778                 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1779         SetNewVisArea();
1780 
1781         PaintGrid();
1782         PaintTop();
1783         PaintLeft();
1784         PaintExtras();
1785 
1786         DoResize( aBorderPos, aFrameSize );
1787         rBindings.Invalidate( SID_DELETE_PRINTAREA );   // Menue
1788         rBindings.Invalidate( FID_DEL_MANUALBREAKS );
1789         rBindings.Invalidate( FID_RESET_PRINTZOOM );
1790         rBindings.Invalidate( SID_STATUS_DOCPOS );      // Statusbar
1791         rBindings.Invalidate( SID_STATUS_PAGESTYLE );   // Statusbar
1792         rBindings.Invalidate( SID_CURRENTTAB );         // Navigator
1793         rBindings.Invalidate( SID_STYLE_FAMILY2 );  // Gestalter
1794         rBindings.Invalidate( SID_STYLE_FAMILY4 );  // Gestalter
1795         rBindings.Invalidate( SID_TABLES_COUNT );
1796 
1797         if(pScMod->IsRefDialogOpen())
1798         {
1799             sal_uInt16 nCurRefDlgId=pScMod->GetCurRefDlgId();
1800             SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
1801             SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
1802             if ( pChildWnd )
1803             {
1804                 IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
1805                 pRefDlg->ViewShellChanged(NULL);
1806             }
1807         }
1808     }
1809 }
1810 
1811 //
1812 //  Paint-Funktionen - nur fuer diese View
1813 //
1814 
1815 void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
1816 {
1817     DrawDeselectAll();
1818 
1819     if (pDrawView)
1820         DrawEnableAnim( sal_False );
1821 
1822     EditView* pSpellingView = aViewData.GetSpellingView();
1823 
1824     for (sal_uInt16 i=0; i<4; i++)
1825         if (pGridWin[i])
1826             if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
1827             {
1828                 ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1829                 ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1830                 SCCOL nScrX = aViewData.GetPosX( eHWhich );
1831                 SCROW nScrY = aViewData.GetPosY( eVWhich );
1832 
1833                 sal_Bool bPosVisible =
1834                      ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
1835                        nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
1836 
1837                 //  #102421# for the active part, create edit view even if outside the visible area,
1838                 //  so input isn't lost (and the edit view may be scrolled into the visible area)
1839 
1840                 //  #i26433# during spelling, the spelling view must be active
1841                 if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
1842                      ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
1843                 {
1844                     pGridWin[i]->HideCursor();
1845 
1846                     pGridWin[i]->DeleteCursorOverlay();
1847                     pGridWin[i]->DeleteAutoFillOverlay();
1848 
1849                     // flush OverlayManager before changing MapMode to text edit
1850                     pGridWin[i]->flushOverlayManager();
1851 
1852                     // MapMode must be set after HideCursor
1853                     pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
1854 
1855                     aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );
1856 
1857                     if ( !bPosVisible )
1858                     {
1859                         //  move the edit view area to the real (possibly negative) position,
1860                         //  or hide if completely above or left of the window
1861                         pGridWin[i]->UpdateEditViewPos();
1862                     }
1863                 }
1864             }
1865 
1866     if (aViewData.GetViewShell()->HasAccessibilityObjects())
1867         aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_ENTEREDITMODE));
1868 }
1869 
1870 void ScTabView::UpdateEditView()
1871 {
1872     ScSplitPos eActive = aViewData.GetActivePart();
1873     for (sal_uInt16 i=0; i<4; i++)
1874         if (aViewData.HasEditView( (ScSplitPos) i ))
1875         {
1876             EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
1877             aViewData.SetEditEngine( (ScSplitPos) i,
1878                 static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
1879                 pGridWin[i], GetViewData()->GetCurX(), GetViewData()->GetCurY() );
1880             if ( (ScSplitPos)i == eActive )
1881                 pEditView->ShowCursor( sal_False );
1882         }
1883 }
1884 
1885 void ScTabView::KillEditView( sal_Bool bNoPaint )
1886 {
1887     sal_uInt16 i;
1888     SCCOL nCol1 = aViewData.GetEditStartCol();
1889     SCROW nRow1 = aViewData.GetEditStartRow();
1890     SCCOL nCol2 = aViewData.GetEditEndCol();
1891     SCROW nRow2 = aViewData.GetEditEndRow();
1892     sal_Bool bPaint[4];
1893     sal_Bool bNotifyAcc(false);
1894 
1895     sal_Bool bExtended = nRow1 != nRow2;                    // Col wird sowieso bis zum Ende gezeichnet
1896     sal_Bool bAtCursor = nCol1 <= aViewData.GetCurX() &&
1897                      nCol2 >= aViewData.GetCurX() &&
1898                      nRow1 == aViewData.GetCurY();
1899     for (i=0; i<4; i++)
1900     {
1901         bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
1902         if (bPaint[i])
1903             bNotifyAcc = true;
1904     }
1905 
1906     // #108931#; notify accessibility before all things happen
1907     if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
1908         aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
1909 
1910     aViewData.ResetEditView();
1911     for (i=0; i<4; i++)
1912         if (pGridWin[i] && bPaint[i])
1913             if (pGridWin[i]->IsVisible())
1914             {
1915                 pGridWin[i]->ShowCursor();
1916 
1917                 pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
1918 
1919                 // #i73567# the cell still has to be repainted
1920                 if (bExtended || ( bAtCursor && !bNoPaint ))
1921                 {
1922                     pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
1923                     pGridWin[i]->UpdateSelectionOverlay();
1924                 }
1925             }
1926 
1927     if (pDrawView)
1928         DrawEnableAnim( sal_True );
1929 
1930         //  GrabFocus immer dann, wenn diese View aktiv ist und
1931         //  die Eingabezeile den Focus hat
1932 
1933     sal_Bool bGrabFocus = sal_False;
1934     if (aViewData.IsActive())
1935     {
1936         ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
1937         if ( pInputHdl )
1938         {
1939             ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
1940             if (pInputWin && pInputWin->IsInputActive())
1941                 bGrabFocus = sal_True;
1942         }
1943     }
1944 
1945     if (bGrabFocus)
1946     {
1947 //      So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
1948 //!     aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1949 //      deshalb erstmal so:
1950         GetActiveWin()->GrabFocus();
1951     }
1952 
1953     //  Cursor-Abfrage erst nach GrabFocus
1954 
1955     for (i=0; i<4; i++)
1956         if (pGridWin[i] && pGridWin[i]->IsVisible())
1957         {
1958             Cursor* pCur = pGridWin[i]->GetCursor();
1959             if (pCur && pCur->IsVisible())
1960                 pCur->Hide();
1961 
1962             if(bPaint[i])
1963             {
1964                 pGridWin[i]->UpdateCursorOverlay();
1965                 pGridWin[i]->UpdateAutoFillOverlay();
1966                 // pGridWin[i]->UpdateAllOverlays();
1967             }
1968         }
1969 }
1970 
1971 void ScTabView::UpdateFormulas()
1972 {
1973     if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
1974         return ;
1975 
1976     sal_uInt16 i;
1977     for (i=0; i<4; i++)
1978         if (pGridWin[i])
1979             if (pGridWin[i]->IsVisible())
1980                 pGridWin[i]->UpdateFormulas();
1981 
1982     if ( aViewData.IsPagebreakMode() )
1983         UpdatePageBreakData();              //! asynchron
1984 
1985     UpdateHeaderWidth();
1986 
1987     //  if in edit mode, adjust edit view area because widths/heights may have changed
1988     if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
1989         UpdateEditView();
1990 }
1991 
1992 //  PaintArea -Block neu zeichnen
1993 
1994 void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1995                             ScUpdateMode eMode )
1996 {
1997     sal_uInt16 i;
1998     SCCOL nCol1;
1999     SCROW nRow1;
2000     SCCOL nCol2;
2001     SCROW nRow2;
2002 
2003     PutInOrder( nStartCol, nEndCol );
2004     PutInOrder( nStartRow, nEndRow );
2005 
2006     for (i=0; i<4; i++)
2007         if (pGridWin[i])
2008             if (pGridWin[i]->IsVisible())
2009             {
2010                 ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
2011                 ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
2012                 sal_Bool bOut = sal_False;
2013 
2014                 nCol1 = nStartCol;
2015                 nRow1 = nStartRow;
2016                 nCol2 = nEndCol;
2017                 nRow2 = nEndRow;
2018 
2019                 SCCOL nScrX = aViewData.GetPosX( eHWhich );
2020                 SCROW nScrY = aViewData.GetPosY( eVWhich );
2021                 if (nCol1 < nScrX) nCol1 = nScrX;
2022                 if (nCol2 < nScrX)
2023                 {
2024                     if ( eMode == SC_UPDATE_ALL )   // #91240# for UPDATE_ALL, paint anyway
2025                         nCol2 = nScrX;              // (because of extending strings to the right)
2026                     else
2027                         bOut = sal_True;                // completely outside the window
2028                 }
2029                 if (nRow1 < nScrY) nRow1 = nScrY;
2030                 if (nRow2 < nScrY) bOut = sal_True;
2031 
2032                 SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
2033                 SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
2034                 if (nCol1 > nLastX) bOut = sal_True;
2035                 if (nCol2 > nLastX) nCol2 = nLastX;
2036                 if (nRow1 > nLastY) bOut = sal_True;
2037                 if (nRow2 > nLastY) nRow2 = nLastY;
2038 
2039                 if (!bOut)
2040                 {
2041                     if ( eMode == SC_UPDATE_CHANGED )
2042                         pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
2043                     else    // ALL oder MARKS
2044                     {
2045                         sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2046                         long nLayoutSign = bLayoutRTL ? -1 : 1;
2047 
2048                         Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
2049                         Point aEnd   = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
2050                         if ( eMode == SC_UPDATE_ALL )
2051                             aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
2052                         aEnd.X() -= nLayoutSign;
2053                         aEnd.Y() -= 1;
2054 
2055                         // #i85232# include area below cells (could be done in GetScrPos?)
2056                         if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
2057                             aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();
2058 
2059                         sal_Bool bShowChanges = sal_True;           //! ...
2060                         if (bShowChanges)
2061                         {
2062                             aStart.X() -= nLayoutSign;      // include change marks
2063                             aStart.Y() -= 1;
2064                         }
2065 
2066                         sal_Bool bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
2067                         if (bMarkClipped)
2068                         {
2069                             //  dazu muesste ScColumn::IsEmptyBlock optimiert werden
2070                             //  (auf Search() umstellen)
2071                             //!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
2072                             //!                     aViewData.GetTabNo(),
2073                             //!                     0, nRow1, nCol1-1, nRow2 ) )
2074                             {
2075                                 long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
2076                                 aStart.X() -= nMarkPixel * nLayoutSign;
2077                                 if (!bShowChanges)
2078                                     aStart.X() -= nLayoutSign;      // cell grid
2079                             }
2080                         }
2081 
2082                         pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
2083                     }
2084                 }
2085             }
2086 
2087     // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
2088     // with a wrong MapMode if editing in a cell (reference input).
2089     // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
2090     // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
2091     // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
2092     // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
2093     // is set (width or height changed).
2094 }
2095 
2096 void ScTabView::PaintRangeFinder( long nNumber )
2097 {
2098     ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
2099     if (pHdl)
2100     {
2101         ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
2102         if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
2103         {
2104             SCTAB nTab = aViewData.GetTabNo();
2105             sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
2106             for (sal_uInt16 i=0; i<nCount; i++)
2107                 if ( nNumber < 0 || nNumber == i )
2108                 {
2109                     ScRangeFindData* pData = pRangeFinder->GetObject(i);
2110                     if (pData)
2111                     {
2112                         ScRange aRef = pData->aRef;
2113                         aRef.Justify();                 // Justify fuer die Abfragen unten
2114 
2115                         if ( aRef.aStart == aRef.aEnd )     //! Tab ignorieren?
2116                             aViewData.GetDocument()->ExtendMerge(aRef);
2117 
2118                         if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
2119                         {
2120                             SCCOL nCol1 = aRef.aStart.Col();
2121                             SCROW nRow1 = aRef.aStart.Row();
2122                             SCCOL nCol2 = aRef.aEnd.Col();
2123                             SCROW nRow2 = aRef.aEnd.Row();
2124 
2125                             //  wegnehmen -> Repaint
2126                             //  SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende
2127 
2128                             sal_Bool bHiddenEdge = sal_False;
2129                             SCROW nTmp;
2130                             ScDocument* pDoc = aViewData.GetDocument();
2131                             SCCOL nLastCol = -1;
2132                             while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) )
2133                             {
2134                                 --nCol1;
2135                                 bHiddenEdge = sal_True;
2136                             }
2137                             while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) )
2138                             {
2139                                 ++nCol2;
2140                                 bHiddenEdge = sal_True;
2141                             }
2142                             nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
2143                             if (!ValidRow(nTmp))
2144                                 nTmp = 0;
2145                             if (nTmp < nRow1)
2146                             {
2147                                 nRow1 = nTmp;
2148                                 bHiddenEdge = sal_True;
2149                             }
2150                             nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
2151                             if (!ValidRow(nTmp))
2152                                 nTmp = MAXROW;
2153                             if (nTmp > nRow2)
2154                             {
2155                                 nRow2 = nTmp;
2156                                 bHiddenEdge = sal_True;
2157                             }
2158 
2159                             if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
2160                             {
2161                                 //  nur an den Raendern entlang
2162                                 PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
2163                                 PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
2164                                 PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
2165                                 PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
2166                             }
2167                             else    // alles am Stueck
2168                                 PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
2169                         }
2170                     }
2171                 }
2172         }
2173     }
2174 }
2175 
2176 //  fuer Chart-Daten-Markierung
2177 
2178 void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
2179 {
2180     if (!pHighlightRanges)
2181         pHighlightRanges = new ScHighlightRanges;
2182     pHighlightRanges->Insert( new ScHighlightEntry( rRange, rColor ) );
2183 
2184     SCTAB nTab = aViewData.GetTabNo();
2185     if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
2186         PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
2187                     rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
2188 }
2189 
2190 void ScTabView::ClearHighlightRanges()
2191 {
2192     if (pHighlightRanges)
2193     {
2194         ScHighlightRanges* pTemp = pHighlightRanges;
2195         pHighlightRanges = NULL;    // Repaint ohne Highlight
2196 
2197         SCTAB nTab = aViewData.GetTabNo();
2198         sal_uLong nCount = pTemp->Count();
2199         for (sal_uLong i=0; i<nCount; i++)
2200         {
2201             ScHighlightEntry* pEntry = pTemp->GetObject( i );
2202             if (pEntry)
2203             {
2204                 ScRange aRange = pEntry->aRef;
2205                 if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
2206                     PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
2207                                aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
2208             }
2209         }
2210         delete pTemp;
2211     }
2212 }
2213 
2214 void ScTabView::DoChartSelection(
2215     const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
2216 {
2217     ClearHighlightRanges();
2218 
2219     for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
2220     {
2221         Color aSelColor( rHilightRanges[i].PreferredColor );
2222         ScRangeList aRangeList;
2223         ScDocument* pDoc = aViewData.GetDocShell()->GetDocument();
2224         if( ScRangeStringConverter::GetRangeListFromString(
2225                 aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), ';' ))
2226         {
2227             for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
2228             {
2229                 if( rHilightRanges[i].Index == - 1 )
2230                     AddHighlightRange( *p, aSelColor );
2231                 else
2232                     AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
2233             }
2234         }
2235     }
2236 }
2237 
2238 //  DrawDragRect - Drag&Drop-Rechteck zeichnen (XOR)
2239 
2240 //UNUSED2008-05  void ScTabView::DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
2241 //UNUSED2008-05                                ScSplitPos ePos )
2242 //UNUSED2008-05  {
2243 //UNUSED2008-05      if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
2244 //UNUSED2008-05      {
2245 //UNUSED2008-05          for (sal_uInt16  i=0; i<4; i++)
2246 //UNUSED2008-05              if (pGridWin[i])
2247 //UNUSED2008-05                  if (pGridWin[i]->IsVisible())
2248 //UNUSED2008-05                      pGridWin[i]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
2249 //UNUSED2008-05      }
2250 //UNUSED2008-05      else
2251 //UNUSED2008-05          pGridWin[ePos]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
2252 //UNUSED2008-05  }
2253 //UNUSED2008-05
2254 //UNUSED2008-05  // PaintCell - einzelne Zelle neu zeichnen
2255 //UNUSED2008-05
2256 //UNUSED2008-05  void ScTabView::PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
2257 //UNUSED2008-05  {
2258 //UNUSED2008-05      if ( aViewData.GetTabNo() == nTab )
2259 //UNUSED2008-05      {
2260 //UNUSED2008-05          sal_uInt16 i;
2261 //UNUSED2008-05          for (i=0; i<4; i++)
2262 //UNUSED2008-05              if (pGridWin[i])
2263 //UNUSED2008-05                  if (pGridWin[i]->IsVisible())
2264 //UNUSED2008-05                      pGridWin[i]->Draw( nCol, nRow, nCol, nRow );
2265 //UNUSED2008-05      }
2266 //UNUSED2008-05  }
2267 //UNUSED2008-05
2268 //UNUSED2008-05  void ScTabView::PaintLeftRow( SCROW nRow )
2269 //UNUSED2008-05  {
2270 //UNUSED2008-05      PaintLeftArea( nRow, nRow );
2271 //UNUSED2008-05  }
2272 //UNUSED2008-05
2273 //UNUSED2008-05  void ScTabView::PaintTopCol( SCCOL nCol )
2274 //UNUSED2008-05  {
2275 //UNUSED2008-05      PaintTopArea( nCol, nCol );
2276 //UNUSED2008-05  }
2277 
2278 //  PaintGrid - Datenbereiche neu zeichnen
2279 
2280 void ScTabView::PaintGrid()
2281 {
2282     sal_uInt16 i;
2283     for (i=0; i<4; i++)
2284         if (pGridWin[i])
2285             if (pGridWin[i]->IsVisible())
2286                 pGridWin[i]->Invalidate();
2287 }
2288 
2289 //  PaintTop - obere Kontrollelemente neu zeichnen
2290 
2291 void ScTabView::PaintTop()
2292 {
2293     sal_uInt16 i;
2294     for (i=0; i<2; i++)
2295     {
2296         if (pColBar[i])
2297             pColBar[i]->Invalidate();
2298         if (pColOutline[i])
2299             pColOutline[i]->Invalidate();
2300     }
2301 }
2302 
2303 void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
2304 {
2305     sal_uInt16 i;
2306 
2307     for(i=0; i<4; i++)
2308     {
2309         if(pGridWin[i])
2310         {
2311             if(pGridWin[i]->IsVisible())
2312             {
2313                 pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
2314             }
2315         }
2316     }
2317 }
2318 
2319 void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
2320 {
2321         //  Pixel-Position der linken Kante
2322 
2323     if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
2324          nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
2325         aViewData.RecalcPixPos();
2326 
2327         //  Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
2328 
2329     if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
2330         if (aViewData.UpdateFixX())
2331             RepeatResize();
2332 
2333         //  zeichnen
2334 
2335     if (nStartCol>0)
2336         --nStartCol;                //! allgemeiner ?
2337 
2338     sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2339     long nLayoutSign = bLayoutRTL ? -1 : 1;
2340 
2341     for (sal_uInt16 i=0; i<2; i++)
2342     {
2343         ScHSplitPos eWhich = (ScHSplitPos) i;
2344         if (pColBar[eWhich])
2345         {
2346             Size aWinSize = pColBar[eWhich]->GetSizePixel();
2347             long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
2348             long nEndX;
2349             if (nEndCol >= MAXCOL)
2350                 nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
2351             else
2352                 nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
2353             pColBar[eWhich]->Invalidate(
2354                     Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
2355         }
2356         if (pColOutline[eWhich])
2357             pColOutline[eWhich]->Invalidate();
2358     }
2359 }
2360 
2361 
2362 //  PaintLeft - linke Kontrollelemente neu zeichnen
2363 
2364 void ScTabView::PaintLeft()
2365 {
2366     sal_uInt16 i;
2367     for (i=0; i<2; i++)
2368     {
2369         if (pRowBar[i])
2370             pRowBar[i]->Invalidate();
2371         if (pRowOutline[i])
2372             pRowOutline[i]->Invalidate();
2373     }
2374 }
2375 
2376 void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
2377 {
2378         //  Pixel-Position der oberen Kante
2379 
2380     if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
2381          nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
2382         aViewData.RecalcPixPos();
2383 
2384         //  Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
2385 
2386     if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
2387         if (aViewData.UpdateFixY())
2388             RepeatResize();
2389 
2390         //  zeichnen
2391 
2392     if (nStartRow>0)
2393         --nStartRow;
2394 
2395     for (sal_uInt16 i=0; i<2; i++)
2396     {
2397         ScVSplitPos eWhich = (ScVSplitPos) i;
2398         if (pRowBar[eWhich])
2399         {
2400             Size aWinSize = pRowBar[eWhich]->GetSizePixel();
2401             long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
2402             long nEndY;
2403             if (nEndRow >= MAXROW)
2404                 nEndY = aWinSize.Height()-1;
2405             else
2406                 nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
2407             pRowBar[eWhich]->Invalidate(
2408                     Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
2409         }
2410         if (pRowOutline[eWhich])
2411             pRowOutline[eWhich]->Invalidate();
2412     }
2413 }
2414 
2415 //  InvertBlockMark - Block invertieren
2416 
2417 void ScTabView::InvertBlockMark(SCCOL nStartX, SCROW nStartY,
2418                                 SCCOL nEndX, SCROW nEndY)
2419 {
2420     if ( !aViewData.IsActive() )
2421         return;                                 // invertiert wird nur auf aktiver View
2422 
2423     PutInOrder( nStartX, nEndX );
2424     PutInOrder( nStartY, nEndY );
2425 
2426     ScMarkData& rMark = aViewData.GetMarkData();
2427     ScDocShell* pDocSh = aViewData.GetDocShell();
2428     ScDocument* pDoc = pDocSh->GetDocument();
2429     SCTAB nTab = aViewData.GetTabNo();
2430 
2431     if ( pDocSh->GetLockCount() )
2432     {
2433         //  if paint is locked, avoid repeated inverting
2434         //  add repaint areas to paint lock data instead
2435         pDocSh->PostPaint( nStartX,nStartY,nTab, nEndX,nEndY,nTab, PAINT_GRID );
2436         return;
2437     }
2438 
2439     sal_Bool bSingle = rMark.IsMultiMarked();
2440     sal_Bool bMerge = pDoc->HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
2441                                     HASATTR_MERGED | HASATTR_OVERLAPPED );
2442 
2443     sal_uInt16 i;
2444     if ( bMerge || bSingle )
2445     {
2446         for (i=0; i<4; i++)
2447             if (pGridWin[i])
2448                 if (pGridWin[i]->IsVisible())
2449                     pGridWin[i]->InvertSimple( nStartX, nStartY, nEndX, nEndY,
2450                                                 bMerge, bBlockNeg );
2451     }
2452     else
2453     {
2454         for (i=0; i<4; i++)
2455             if (pGridWin[i])
2456                 if (pGridWin[i]->IsVisible())
2457                 {
2458                     ScSplitPos ePos = (ScSplitPos) i;
2459                     Point aStartPoint = aViewData.GetScrPos( nStartX, nStartY, ePos );
2460                     Point aEndPoint = aViewData.GetScrPos( nEndX+1, nEndY+1, ePos );
2461                     if ( pDoc->IsLayoutRTL( nTab ) )
2462                     {
2463                         long nTemp = aStartPoint.X();
2464                         aStartPoint.X() = aEndPoint.X() + 1;    // +1 - excluding start of nEndX+1
2465                         aEndPoint.X() = nTemp;
2466                     }
2467                     else
2468                         aEndPoint.X() -= 1;
2469                     aEndPoint.Y() -= 1;
2470                     if ( aEndPoint.X() >= aStartPoint.X() && aEndPoint.Y() >= aStartPoint.Y() )
2471                     {
2472                         MapMode aOld = pGridWin[ePos]->GetMapMode();
2473                         pGridWin[ePos]->SetMapMode(MAP_PIXEL);
2474                         pGridWin[ePos]->Invert( Rectangle(aStartPoint,aEndPoint), INVERT_HIGHLIGHT );
2475                         pGridWin[ePos]->SetMapMode(aOld);
2476                         pGridWin[ePos]->CheckInverted();
2477                     }
2478                 }
2479     }
2480 
2481         //
2482         //  wenn Controls betroffen, neu malen
2483         //
2484 
2485     sal_Bool bHide = sal_True;                  // wird Teil der Markierung aufgehoben ?
2486     if (rMark.IsMarked())
2487     {
2488         ScRange aMarkRange;
2489         rMark.GetMarkArea( aMarkRange );
2490         if ( aMarkRange.aStart.Col() <= nStartX && aMarkRange.aEnd.Col() >= nEndX &&
2491              aMarkRange.aStart.Row() <= nStartY && aMarkRange.aEnd.Row() >= nEndY )
2492         {
2493             bHide = sal_False;              // der ganze Bereich ist markiert
2494         }
2495     }
2496 }
2497 
2498 sal_Bool ScTabView::PaintExtras()
2499 {
2500     sal_Bool bRet = sal_False;
2501     ScDocument* pDoc = aViewData.GetDocument();
2502     SCTAB nTab = aViewData.GetTabNo();
2503     if (!pDoc->HasTable(nTab))                  // Tabelle geloescht ?
2504     {
2505         SCTAB nCount = pDoc->GetTableCount();
2506         aViewData.SetTabNo(nCount-1);
2507         bRet = sal_True;
2508     }
2509     pTabControl->UpdateStatus();                        // sal_True = active
2510     return bRet;
2511 }
2512 
2513 void ScTabView::RecalcPPT()
2514 {
2515     //  called after changes that require the PPT values to be recalculated
2516     //  (currently from detective operations)
2517 
2518     double nOldX = aViewData.GetPPTX();
2519     double nOldY = aViewData.GetPPTY();
2520 
2521     aViewData.RefreshZoom();                            // pre-calculate new PPT values
2522 
2523     sal_Bool bChangedX = ( aViewData.GetPPTX() != nOldX );
2524     sal_Bool bChangedY = ( aViewData.GetPPTY() != nOldY );
2525     if ( bChangedX || bChangedY )
2526     {
2527         //  call view SetZoom (including draw scale, split update etc)
2528         //  and paint only if values changed
2529 
2530         Fraction aZoomX = aViewData.GetZoomX();
2531         Fraction aZoomY = aViewData.GetZoomY();
2532         SetZoom( aZoomX, aZoomY, sal_False );
2533 
2534         PaintGrid();
2535         if (bChangedX)
2536             PaintTop();
2537         if (bChangedY)
2538             PaintLeft();
2539     }
2540 }
2541 
2542 void ScTabView::ActivateView( sal_Bool bActivate, sal_Bool bFirst )
2543 {
2544     if ( bActivate == aViewData.IsActive() && !bFirst )
2545     {
2546         //  keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
2547         //  auf ein anderes Dokument umgeschaltet wurde
2548         return;
2549     }
2550 
2551     // wird nur bei MDI-(De)Activate gerufen
2552     // aViewData.Activate hinten wegen Cursor-Show bei KillEditView
2553     //  Markierung nicht mehr loeschen - wenn an der ViewData Activate(sal_False) gesetzt ist,
2554     //  wird die Markierung nicht ausgegeben
2555 
2556     if (!bActivate)
2557     {
2558         ScModule* pScMod = SC_MOD();
2559         sal_Bool bRefMode = pScMod->IsFormulaMode();
2560 
2561             //  Referenzeingabe nicht abbrechen, um Referenzen auf
2562             //  andere Dokumente zuzulassen
2563 
2564         if (!bRefMode)
2565         {
2566             //pScMod->InputEnterHandler();
2567 
2568             //  #80843# pass view to GetInputHdl, this view may not be current anymore
2569             ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2570             if (pHdl)
2571                 pHdl->EnterHandler();
2572         }
2573     }
2574     pTabControl->ActivateView(bActivate);
2575     PaintExtras();
2576 
2577     aViewData.Activate(bActivate);
2578 
2579     PaintBlock(sal_False);                  // Repaint, Markierung je nach Active-Status
2580 
2581     if (!bActivate)
2582         HideAllCursors();               // Cursor
2583     else if (!bFirst)
2584         ShowAllCursors();
2585 
2586     //HMHif (pDrawView)
2587     //HMH   DrawShowMarkHdl(bActivate);     // Drawing-Markierung
2588 
2589     if (bActivate)
2590     {
2591         if ( bFirst )
2592         {
2593             ScSplitPos eWin = aViewData.GetActivePart();
2594             DBG_ASSERT( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
2595             if ( !pGridWin[eWin] )
2596             {
2597                 eWin = SC_SPLIT_BOTTOMLEFT;
2598                 if ( !pGridWin[eWin] )
2599                 {
2600                     short i;
2601                     for ( i=0; i<4; i++ )
2602                     {
2603                         if ( pGridWin[i] )
2604                         {
2605                             eWin = (ScSplitPos) i;
2606                             break;  // for
2607                         }
2608                     }
2609                     DBG_ASSERT( i<4, "und BUMM" );
2610                 }
2611                 aViewData.SetActivePart( eWin );
2612             }
2613         }
2614         //  hier nicht mehr selber GrabFocus rufen!
2615         //  Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
2616         //  Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)
2617 
2618         UpdateInputContext();
2619     }
2620     else
2621         pGridWin[aViewData.GetActivePart()]->ClickExtern();
2622 }
2623 
2624 void ScTabView::ActivatePart( ScSplitPos eWhich )
2625 {
2626     ScSplitPos eOld = aViewData.GetActivePart();
2627     if ( eOld != eWhich )
2628     {
2629         bInActivatePart = sal_True;
2630 
2631         sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
2632 
2633         //  #40565# the HasEditView call during SetCursor would fail otherwise
2634         if ( aViewData.HasEditView(eOld) && !bRefMode )
2635             UpdateInputLine();
2636 
2637         ScHSplitPos eOldH = WhichH(eOld);
2638         ScVSplitPos eOldV = WhichV(eOld);
2639         ScHSplitPos eNewH = WhichH(eWhich);
2640         ScVSplitPos eNewV = WhichV(eWhich);
2641         sal_Bool bTopCap  = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
2642         sal_Bool bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
2643 
2644         sal_Bool bFocus = pGridWin[eOld]->HasFocus();
2645         sal_Bool bCapture = pGridWin[eOld]->IsMouseCaptured();
2646         if (bCapture)
2647             pGridWin[eOld]->ReleaseMouse();
2648         pGridWin[eOld]->ClickExtern();
2649         pGridWin[eOld]->HideCursor();
2650         pGridWin[eWhich]->HideCursor();
2651         aViewData.SetActivePart( eWhich );
2652 
2653         ScTabViewShell* pShell = aViewData.GetViewShell();
2654         pShell->WindowChanged();
2655 
2656         pSelEngine->SetWindow(pGridWin[eWhich]);
2657         pSelEngine->SetWhich(eWhich);
2658         pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
2659 
2660         pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
2661 
2662         if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
2663         {
2664             //  Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
2665             //  (SelectionEngine ruft CaptureMouse beim SetWindow)
2666             //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
2667             pGridWin[eWhich]->ReleaseMouse();
2668             pGridWin[eWhich]->StartTracking();
2669         }
2670 
2671         if ( bTopCap && pColBar[eNewH] )
2672         {
2673             pColBar[eOldH]->SetIgnoreMove(sal_True);
2674             pColBar[eNewH]->SetIgnoreMove(sal_False);
2675             pHdrSelEng->SetWindow( pColBar[eNewH] );
2676             long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
2677             pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
2678             pColBar[eNewH]->CaptureMouse();
2679         }
2680         if ( bLeftCap && pRowBar[eNewV] )
2681         {
2682             pRowBar[eOldV]->SetIgnoreMove(sal_True);
2683             pRowBar[eNewV]->SetIgnoreMove(sal_False);
2684             pHdrSelEng->SetWindow( pRowBar[eNewV] );
2685             long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
2686             pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
2687             pRowBar[eNewV]->CaptureMouse();
2688         }
2689         aHdrFunc.SetWhich(eWhich);
2690 
2691         pGridWin[eOld]->ShowCursor();
2692         pGridWin[eWhich]->ShowCursor();
2693 
2694         SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
2695         sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
2696 
2697         //  #103823# don't switch ViewShell's active window during RefInput, because the focus
2698         //  might change, and subsequent SetReference calls wouldn't find the right EditView
2699         if ( !bRefMode && !bOleActive )
2700             aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
2701 
2702         if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
2703         {
2704             //  GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
2705             //  (z.B. wegen Suchen & Ersetzen)
2706 //!         aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
2707             pGridWin[eWhich]->GrabFocus();
2708         }
2709 
2710         bInActivatePart = sal_False;
2711     }
2712 }
2713 
2714 void ScTabView::HideListBox()
2715 {
2716     for (sal_uInt16 i=0; i<4; i++)
2717         if (pGridWin[i])
2718             pGridWin[i]->ClickExtern();
2719 }
2720 
2721 void ScTabView::UpdateInputContext()
2722 {
2723     ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2724     if (pWin)
2725         pWin->UpdateInputContext();
2726 }
2727 
2728 //  GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)
2729 
2730 long ScTabView::GetGridWidth( ScHSplitPos eWhich )
2731 {
2732     ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2733     if (pGridWin[eGridWhich])
2734         return pGridWin[eGridWhich]->GetSizePixel().Width();
2735     else
2736         return 0;
2737 }
2738 
2739 //  GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)
2740 
2741 long ScTabView::GetGridHeight( ScVSplitPos eWhich )
2742 {
2743     ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2744     if (pGridWin[eGridWhich])
2745         return pGridWin[eGridWhich]->GetSizePixel().Height();
2746     else
2747         return 0;
2748 }
2749 
2750 void ScTabView::UpdateInputLine()
2751 {
2752     SC_MOD()->InputEnterHandler();
2753 }
2754 
2755 void ScTabView::ZoomChanged()
2756 {
2757     ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2758     if (pHdl)
2759         pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
2760 
2761     UpdateFixPos();
2762 
2763     UpdateScrollBars();
2764 
2765     //  VisArea...
2766     // AW: Discussed with NN if there is a reason that new map mode was only set for one window,
2767     // but is not. Setting only on one window causes the first repaint to have the old mapMode
2768     // in three of four views, so the overlay will save the wrong content e.g. when zooming out.
2769     // Changing to setting map mode at all windows.
2770     sal_uInt32 a;
2771 
2772     for(a = 0L; a < 4L; a++)
2773     {
2774         if(pGridWin[a])
2775         {
2776             pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
2777         }
2778     }
2779 
2780     SetNewVisArea();
2781 
2782     /* the old code
2783     ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2784     if (pWin)
2785     {
2786         pWin->SetMapMode( pWin->GetDrawMapMode() ); // mit neuem Zoom
2787         SetNewVisArea();                            // benutzt den gesetzten MapMode
2788     } */
2789 
2790     InterpretVisible();     // #69343# have everything calculated before painting
2791 
2792     SfxBindings& rBindings = aViewData.GetBindings();
2793     rBindings.Invalidate( SID_ATTR_ZOOM );
2794     rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
2795 
2796     HideNoteMarker();
2797 
2798     // AW: To not change too much, use pWin here
2799     ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2800 
2801     if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
2802     {
2803         // flush OverlayManager before changing the MapMode
2804         pWin->flushOverlayManager();
2805 
2806         //  #93650# make sure the EditView's position and size are updated
2807         //  with the right (logic, not drawing) MapMode
2808         pWin->SetMapMode( aViewData.GetLogicMode() );
2809         UpdateEditView();
2810     }
2811 }
2812 
2813 void ScTabView::CheckNeedsRepaint()
2814 {
2815     sal_uInt16 i;
2816     for (i=0; i<4; i++)
2817         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
2818             pGridWin[i]->CheckNeedsRepaint();
2819 }
2820 
2821 
2822 
2823 
2824 
2825