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