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