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