LibreOffice Module sc (master)  1
tabview3.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <rangelst.hxx>
21 #include <scitems.hxx>
22 
23 #include <editeng/editview.hxx>
24 #include <svx/fmshell.hxx>
26 #include <svx/svdoole2.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/lokhelper.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <vcl/cursor.hxx>
31 #include <vcl/uitest/logger.hxx>
33 #include <sal/log.hxx>
34 
35 #include <IAnyRefDialog.hxx>
36 #include <tabview.hxx>
37 #include <tabvwsh.hxx>
38 #include <docsh.hxx>
39 #include <gridwin.hxx>
40 #include <olinewin.hxx>
41 #include <overlayobject.hxx>
42 #include <colrowba.hxx>
43 #include <tabcont.hxx>
44 #include <scmod.hxx>
45 #include <sc.hrc>
46 #include <viewutil.hxx>
47 #include <editutil.hxx>
48 #include <inputhdl.hxx>
49 #include <inputwin.hxx>
50 #include <validat.hxx>
51 #include <inputopt.hxx>
52 #include <rfindlst.hxx>
53 #include <hiranges.hxx>
54 #include <viewuno.hxx>
55 #include <dpobject.hxx>
56 #include <seltrans.hxx>
57 #include <fillinfo.hxx>
58 #include <rangeutl.hxx>
59 #include <client.hxx>
60 #include <tabprotection.hxx>
61 #include <markdata.hxx>
63 #include <comphelper/lok.hxx>
64 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
65 #include <output.hxx>
66 
67 #include <com/sun/star/chart2/data/HighlightedRange.hpp>
68 
69 namespace
70 {
71 
72 ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
73 {
74  ScAddress aResult( rRange.aStart );
75 
76  SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
77  SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
78  SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
79  if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
80  {
81  // row by row from first to last sheet
82  sal_Int32 nArea = nWidth * nHeight;
83  aResult.IncCol( static_cast< SCCOL >( nIndex % nWidth ) );
84  aResult.IncRow( static_cast< SCROW >( (nIndex % nArea) / nWidth ) );
85  aResult.IncTab( static_cast< SCTAB >( nIndex / nArea ) );
86  if( !rRange.In( aResult ) )
87  aResult = rRange.aStart;
88  }
89 
90  return ScRange( aResult );
91 }
92 
93 } // anonymous namespace
94 
95 using namespace com::sun::star;
96 
98 {
99  DBG_ASSERT(nTotalWindows == 0, "ScExtraEditViewManager dtor: some out window has not yet been removed!");
100 }
101 
102 inline void ScExtraEditViewManager::Add(SfxViewShell* pViewShell, ScSplitPos eWhich)
103 {
104  Apply<Adder>(pViewShell, eWhich);
105 }
106 
108 {
109  Apply<Remover>(pViewShell, eWhich);
110 }
111 
112 
113 template<ScExtraEditViewManager::ModifierTagType ModifierTag>
115 {
116  ScTabViewShell* pOtherViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
117  if (pOtherViewShell != nullptr && pOtherViewShell != mpThisViewShell)
118  {
119  mpOtherEditView = pOtherViewShell->GetViewData().GetEditView(eWhich);
120  if (mpOtherEditView != nullptr)
121  {
122  DBG_ASSERT(mpOtherEditView->GetEditEngine(), "Edit view has no valid engine.");
123  for (int i = 0; i < 4; ++i)
124  {
125  ScGridWindow* pWin = mpGridWin[i].get();
126  if (pWin != nullptr)
127  {
128  Modifier<ModifierTag>(pWin);
129  }
130  }
131  }
132  }
133 }
134 
135 template<ScExtraEditViewManager::ModifierTagType ModifierTag>
137 {
138  (void)this;
139  SAL_WARN("sc", "ScExtraEditViewManager::Modifier<ModifierTag>: non-specialized version should not be invoked.");
140 }
141 
142 template<>
143 void ScExtraEditViewManager::Modifier<ScExtraEditViewManager::Adder>(ScGridWindow* pWin)
144 {
145  if (mpOtherEditView->AddOtherViewWindow(pWin))
146  ++nTotalWindows;
147 }
148 
149 template<>
150 void ScExtraEditViewManager::Modifier<ScExtraEditViewManager::Remover>(ScGridWindow* pWin)
151 {
152  if (mpOtherEditView->RemoveOtherViewWindow(pWin))
153  --nTotalWindows;
154 }
155 
156 // --- public functions
157 
158 void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, bool bControl )
159 {
160  ScDocument* pDoc = aViewData.GetDocument();
161  SCTAB nTab = aViewData.GetTabNo();
162  pDoc->SkipOverlapped(nPosX, nPosY, nTab);
163 
164  bool bRefMode = SC_MOD()->IsFormulaMode();
165 
166  if ( bRefMode )
167  {
168  DoneRefMode();
169 
170  if (bControl)
171  SC_MOD()->AddRefEntry();
172 
173  InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
174  }
175  else
176  {
177  DoneBlockMode( bControl );
178  aViewData.ResetOldCursor();
179  SetCursor( nPosX, nPosY );
180  }
181 }
182 
183 void ScTabView::UpdateAutoFillMark(bool bFromPaste)
184 {
185  // single selection or cursor
186  ScRange aMarkRange;
187  bool bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
188 
189  for (sal_uInt16 i = 0; i < 4; i++)
190  {
191  if (pGridWin[i] && pGridWin[i]->IsVisible())
192  pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
193  }
194 
195  for (sal_uInt16 i = 0; i < 2; i++)
196  {
197  if (pColBar[i] && pColBar[i]->IsVisible())
198  pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
199  if (pRowBar[i] && pRowBar[i]->IsVisible())
200  pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
201  }
202 
203  // selection transfer object is checked together with AutoFill marks,
204  // because it has the same requirement of a single continuous block.
205  if (!bFromPaste)
206  CheckSelectionTransfer(); // update selection transfer object
207 }
208 
210 {
211  if (pGridWin[eWhich])
212  pGridWin[eWhich]->FakeButtonUp();
213 }
214 
216 {
217  for (VclPtr<ScGridWindow> & pWin : pGridWin)
218  {
219  if (pWin && pWin->IsVisible())
220  {
221  vcl::Cursor* pCur = pWin->GetCursor();
222  if (pCur && pCur->IsVisible())
223  pCur->Hide();
224  pWin->HideCursor();
225  }
226  }
227 }
228 
230 {
231  for (VclPtr<ScGridWindow> & pWin : pGridWin)
232  {
233  if (pWin && pWin->IsVisible())
234  {
235  pWin->ShowCursor();
236  pWin->CursorChanged();
237  }
238  }
239 }
240 
242 {
243  pGridWin[aViewData.GetActivePart()]->ShowCursor();
244  pGridWin[aViewData.GetActivePart()]->CursorChanged();
245 }
246 
248 {
249  SfxBindings& rBindings = aViewData.GetBindings();
250 
251  rBindings.Invalidate( SID_STYLE_APPLY );
252  rBindings.Invalidate( SID_STYLE_FAMILY2 );
253  // StarCalc knows only paragraph- or cell format templates
254 
255  rBindings.Invalidate( SID_ATTR_CHAR_FONT );
256  rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
257  rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
258 
259  rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
260  rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
261  rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
262  rBindings.Invalidate( SID_ULINE_VAL_NONE );
263  rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
264  rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
265  rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
266 
267  rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
268 
269  rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
270  rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
271  rBindings.Invalidate( SID_SET_SUB_SCRIPT );
272  rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
273  rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );
274 
275  rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
276  rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
277  rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
278  rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
279  rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT);
280 
281  rBindings.Invalidate( SID_ALIGNLEFT );
282  rBindings.Invalidate( SID_ALIGNRIGHT );
283  rBindings.Invalidate( SID_ALIGNBLOCK );
284  rBindings.Invalidate( SID_ALIGNCENTERHOR );
285 
286  rBindings.Invalidate( SID_ALIGNTOP );
287  rBindings.Invalidate( SID_ALIGNBOTTOM );
288  rBindings.Invalidate( SID_ALIGNCENTERVER );
289 
290  rBindings.Invalidate( SID_SCATTR_CELLPROTECTION );
291 
292  // stuff for sidebar panels
293  {
294  rBindings.Invalidate( SID_H_ALIGNCELL );
295  rBindings.Invalidate( SID_V_ALIGNCELL );
296  rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
297  rBindings.Invalidate( SID_FRAME_LINECOLOR );
298  rBindings.Invalidate( SID_FRAME_LINESTYLE );
299  rBindings.Invalidate( SID_ATTR_BORDER_OUTER );
300  rBindings.Invalidate( SID_ATTR_BORDER_INNER );
301  rBindings.Invalidate( SID_ATTR_BORDER_DIAG_TLBR );
302  rBindings.Invalidate( SID_ATTR_BORDER_DIAG_BLTR );
303  rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT );
304  }
305 
306  rBindings.Invalidate( SID_BACKGROUND_COLOR );
307 
308  rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
309  rBindings.Invalidate( SID_NUMBER_FORMAT );
310 
311  rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
312  rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
313  rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
314  rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
315 
316  // pseudo slots for Format menu
317  rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
318  rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
319  rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
320  rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
321  rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
322  rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
323  rBindings.Invalidate( SID_ALIGN_ANY_TOP );
324  rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
325  rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
326 
327  rBindings.Invalidate( SID_NUMBER_CURRENCY );
328  rBindings.Invalidate( SID_NUMBER_SCIENTIFIC );
329  rBindings.Invalidate( SID_NUMBER_DATE );
330  rBindings.Invalidate( SID_NUMBER_CURRENCY );
331  rBindings.Invalidate( SID_NUMBER_PERCENT );
332  rBindings.Invalidate( SID_NUMBER_TWODEC );
333  rBindings.Invalidate( SID_NUMBER_TIME );
334  rBindings.Invalidate( SID_NUMBER_STANDARD );
335  rBindings.Invalidate( SID_NUMBER_THOUSANDS );
336 }
337 
338 namespace {
339 
340 void collectUIInformation(const std::map<OUString, OUString>& aParameters)
341 {
342  EventDescription aDescription;
343  aDescription.aID = "grid_window";
344  aDescription.aAction = "SELECT";
345  aDescription.aParameters = aParameters;
346  aDescription.aParent = "MainWindow";
347  aDescription.aKeyWord = "ScGridWinUIObject";
348 
349  UITestLogger::getInstance().logEvent(aDescription);
350 }
351 
352 }
353 
354 // SetCursor - Cursor, set, draw, update InputWin
355 // or send reference
356 // Optimising breaks the functionality
357 
358 void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, bool bNew )
359 {
360  SCCOL nOldX = aViewData.GetCurX();
361  SCROW nOldY = aViewData.GetCurY();
362 
363  // DeactivateIP only for MarkListHasChanged
364 
365  // FIXME: this is to limit the number of rows handled in the Online
366  // to 1000; this will be removed again when the performance
367  // bottlenecks are sorted out
369  nPosY = std::min(nPosY, MAXTILEDROW);
370 
371  if ( nPosX != nOldX || nPosY != nOldY || bNew )
372  {
373  ScTabViewShell* pViewShell = aViewData.GetViewShell();
374  bool bRefMode = pViewShell && pViewShell->IsRefInputMode();
375  if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 or so
376  {
377  UpdateInputLine();
378  }
379 
380  HideAllCursors();
381 
382  aViewData.SetCurX( nPosX );
383  aViewData.SetCurY( nPosY );
384 
385  ShowAllCursors();
386 
387  CursorPosChanged();
388 
389  OUString aCurrAddress = ScAddress(nPosX,nPosY,0).GetColRowString();
390  collectUIInformation({{"CELL", aCurrAddress}});
391 
393  {
394  if (nPosX > aViewData.GetMaxTiledCol() - 10 || nPosY > aViewData.GetMaxTiledRow() - 25)
395  {
396  ScDocument* pDoc = aViewData.GetDocument();
397  ScDocShell* pDocSh = aViewData.GetDocShell();
398  ScModelObj* pModelObj = pDocSh ? comphelper::getUnoTunnelImplementation<ScModelObj>( pDocSh->GetModel() ) : nullptr;
399  Size aOldSize(0, 0);
400  if (pModelObj)
401  aOldSize = pModelObj->getDocumentSize();
402 
403  if (nPosX > aViewData.GetMaxTiledCol() - 10)
404  aViewData.SetMaxTiledCol(std::min<SCCOL>(std::max(nPosX, aViewData.GetMaxTiledCol()) + 10, pDoc->MaxCol()));
405 
406  if (nPosY > aViewData.GetMaxTiledRow() - 25)
407  aViewData.SetMaxTiledRow(std::min<SCROW>(std::max(nPosY, aViewData.GetMaxTiledRow()) + 25, MAXTILEDROW));
408 
409  Size aNewSize(0, 0);
410  if (pModelObj)
411  aNewSize = pModelObj->getDocumentSize();
412 
413  if (pDocSh)
414  {
415  // New area extended to the right of the sheet after last column
416  // including overlapping area with aNewRowArea
417  tools::Rectangle aNewColArea(aOldSize.getWidth(), 0, aNewSize.getWidth(), aNewSize.getHeight());
418  // New area extended to the bottom of the sheet after last row
419  // excluding overlapping area with aNewColArea
420  tools::Rectangle aNewRowArea(0, aOldSize.getHeight(), aOldSize.getWidth(), aNewSize.getHeight());
421 
422  // Only invalidate if spreadsheet extended to the right
423  if (aNewColArea.getWidth())
424  {
425  SfxLokHelper::notifyInvalidation(aViewData.GetViewShell(), aNewColArea.toString());
426  }
427 
428  // Only invalidate if spreadsheet extended to the bottom
429  if (aNewRowArea.getHeight())
430  {
431  SfxLokHelper::notifyInvalidation(aViewData.GetViewShell(), aNewRowArea.toString());
432  }
433 
434  // Provide size in the payload, so clients don't have to
435  // call lok::Document::getDocumentSize().
436  std::stringstream ss;
437  ss << aNewSize.Width() << ", " << aNewSize.Height();
438  OString sSize = ss.str().c_str();
439  ScModelObj* pModel = comphelper::getUnoTunnelImplementation<ScModelObj>(aViewData.GetViewShell()->GetCurrentDocument());
440  SfxLokHelper::notifyDocumentSizeChanged(aViewData.GetViewShell(), sSize, pModel, false);
441  }
442  }
443  }
444  }
445 }
446 
448 {
449  if (pViewFrm->HasChildWindow(WID_SIMPLE_REF))
450  {
451  SfxChildWindow* pChild = pViewFrm->GetChildWindow(WID_SIMPLE_REF);
452  if (pChild)
453  {
454  auto xDlgController = pChild->GetController();
455  if (xDlgController && xDlgController->getDialog()->get_visible())
456  return true;
457  }
458  }
459 
460  return false;
461 }
462 
464 {
465  if ( aViewData.IsActive() ) // only for active view
466  {
467  ScModule* pScMod = SC_MOD();
470  if ( pNew )
471  {
472  // create new selection
473 
474  if (pOld)
475  pOld->ForgetView();
476 
477  pScMod->SetSelectionTransfer( pNew.get() );
478 
479  // tdf#124975 changing the calc selection can trigger removal of the
480  // selection of an open ScSimpleRefDlg dialog, so don't inform the
481  // desktop clipboard of the changed selection if that dialog is open
482  if (!lcl_IsScSimpleRefDlgOpen(aViewData.GetViewShell()->GetViewFrame()))
483  pNew->CopyToSelection( GetActiveWin() ); // may delete pOld
484 
485  // Log the selection change
486  ScMarkData& rMark = aViewData.GetMarkData();
487  if (rMark.IsMarked())
488  {
489  ScRange aMarkRange;
490  rMark.GetMarkArea( aMarkRange );
491  OUString aStartAddress = aMarkRange.aStart.GetColRowString();
492  OUString aEndAddress = aMarkRange.aEnd.GetColRowString();
493  collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}});
494  }
495  }
496  }
497 }
498 
499 // update input row / menus
500 // CursorPosChanged calls SelectionChanged
501 // SelectionChanged calls CellContentChanged
502 
504 {
505  SfxBindings& rBindings = aViewData.GetBindings();
506 
507  rBindings.Invalidate( SID_ATTR_SIZE ); // -> show error message
508  rBindings.Invalidate( SID_THESAURUS );
509  rBindings.Invalidate( SID_HYPERLINK_GETLINK );
510  rBindings.Invalidate( SID_ROWCOL_SELCOUNT );
511 
512  InvalidateAttribs(); // attribut updates
513 
514  aViewData.GetViewShell()->UpdateInputHandler();
515 }
516 
517 void ScTabView::SetTabProtectionSymbol( SCTAB nTab, const bool bProtect )
518 {
519  pTabControl->SetProtectionSymbol( static_cast<sal_uInt16>(nTab)+1, bProtect);
520 }
521 
522 void ScTabView::SelectionChanged(bool bFromPaste)
523 {
524  SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
525  if (pViewFrame)
526  {
527  uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
528  if (xController.is())
529  {
530  ScTabViewObj* pImp = comphelper::getUnoTunnelImplementation<ScTabViewObj>( xController );
531  if (pImp)
532  pImp->SelectionChanged();
533  }
534  }
535 
536  UpdateAutoFillMark(bFromPaste); // also calls CheckSelectionTransfer
537 
538  SfxBindings& rBindings = aViewData.GetBindings();
539 
540  rBindings.Invalidate( SID_CURRENTCELL ); // -> Navigator
541  rBindings.Invalidate( SID_AUTO_FILTER ); // -> Menu
542  rBindings.Invalidate( FID_NOTE_VISIBLE );
543  rBindings.Invalidate( FID_SHOW_NOTE );
544  rBindings.Invalidate( FID_HIDE_NOTE );
545  rBindings.Invalidate( FID_SHOW_ALL_NOTES );
546  rBindings.Invalidate( FID_HIDE_ALL_NOTES );
547  rBindings.Invalidate( SID_TOGGLE_NOTES );
548  rBindings.Invalidate( SID_DELETE_NOTE );
549  rBindings.Invalidate( SID_ROWCOL_SELCOUNT );
550 
551  // functions than may need to be disabled
552 
553  rBindings.Invalidate( FID_INS_ROWBRK );
554  rBindings.Invalidate( FID_INS_COLBRK );
555  rBindings.Invalidate( FID_DEL_ROWBRK );
556  rBindings.Invalidate( FID_DEL_COLBRK );
557  rBindings.Invalidate( FID_MERGE_ON );
558  rBindings.Invalidate( FID_MERGE_OFF );
559  rBindings.Invalidate( FID_MERGE_TOGGLE );
560  rBindings.Invalidate( SID_AUTOFILTER_HIDE );
561  rBindings.Invalidate( SID_UNFILTER );
562  rBindings.Invalidate( SID_REIMPORT_DATA );
563  rBindings.Invalidate( SID_REFRESH_DBAREA );
564  rBindings.Invalidate( SID_OUTLINE_SHOW );
565  rBindings.Invalidate( SID_OUTLINE_HIDE );
566  rBindings.Invalidate( SID_OUTLINE_REMOVE );
567  rBindings.Invalidate( FID_FILL_TO_BOTTOM );
568  rBindings.Invalidate( FID_FILL_TO_RIGHT );
569  rBindings.Invalidate( FID_FILL_TO_TOP );
570  rBindings.Invalidate( FID_FILL_TO_LEFT );
571  rBindings.Invalidate( FID_FILL_SERIES );
572  rBindings.Invalidate( SID_SCENARIOS );
573  rBindings.Invalidate( SID_AUTOFORMAT );
574  rBindings.Invalidate( SID_OPENDLG_TABOP );
575  rBindings.Invalidate( SID_DATA_SELECT );
576 
577  rBindings.Invalidate( SID_CUT );
578  rBindings.Invalidate( SID_COPY );
579  rBindings.Invalidate( SID_PASTE );
580  rBindings.Invalidate( SID_PASTE_SPECIAL );
581  rBindings.Invalidate( SID_PASTE_UNFORMATTED );
582 
583  rBindings.Invalidate( FID_INS_ROW );
584  rBindings.Invalidate( FID_INS_COLUMN );
585  rBindings.Invalidate( FID_INS_ROWS_BEFORE );
586  rBindings.Invalidate( FID_INS_COLUMNS_BEFORE );
587  rBindings.Invalidate( FID_INS_ROWS_AFTER );
588  rBindings.Invalidate( FID_INS_COLUMNS_AFTER );
589  rBindings.Invalidate( FID_INS_CELL );
590  rBindings.Invalidate( FID_INS_CELLSDOWN );
591  rBindings.Invalidate( FID_INS_CELLSRIGHT );
592 
593  rBindings.Invalidate( FID_CHG_COMMENT );
594 
595  // only due to protect cell:
596 
597  rBindings.Invalidate( SID_CELL_FORMAT_RESET );
598  rBindings.Invalidate( SID_DELETE );
599  rBindings.Invalidate( SID_DELETE_CONTENTS );
600  rBindings.Invalidate( FID_DELETE_CELL );
601  rBindings.Invalidate( FID_CELL_FORMAT );
602  rBindings.Invalidate( SID_ENABLE_HYPHENATION );
603  rBindings.Invalidate( SID_INSERT_POSTIT );
604  rBindings.Invalidate( SID_CHARMAP );
605  rBindings.Invalidate( SID_OPENDLG_FUNCTION );
606  rBindings.Invalidate( FID_VALIDATION );
607  rBindings.Invalidate( SID_EXTERNAL_SOURCE );
608  rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
609  rBindings.Invalidate( SID_SORT_ASCENDING );
610  rBindings.Invalidate( SID_SORT_DESCENDING );
611  rBindings.Invalidate( SID_SELECT_UNPROTECTED_CELLS );
612 
613  if (aViewData.GetViewShell()->HasAccessibilityObjects())
614  aViewData.GetViewShell()->BroadcastAccessibility(SfxHint(SfxHintId::ScAccCursorChanged));
615 
616  CellContentChanged();
617 }
618 
620 {
621  bool bRefMode = SC_MOD()->IsFormulaMode();
622  if ( !bRefMode ) // check that RefMode works when switching sheets
623  aViewData.GetDocShell()->Broadcast( SfxHint( SfxHintId::ScKillEditView ) );
624 
625  // Broadcast, so that other Views of the document also switch
626 
627  ScDocument* pDoc = aViewData.GetDocument();
628  bool bDP = nullptr != pDoc->GetDPAtCursor(
629  aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
630  aViewData.GetViewShell()->SetPivotShell(bDP);
631 
632  // UpdateInputHandler now in CellContentChanged
633 
634  SelectionChanged();
635 
636  aViewData.SetTabStartCol( SC_TABSTART_NONE );
637 }
638 
639 namespace {
640 
641 Point calcHintWindowPosition(
642  const Point& rCellPos, const Size& rCellSize, const Size& rFrameWndSize, const Size& rHintWndSize)
643 {
644  const long nMargin = 20;
645 
646  long nMLeft = rCellPos.X();
647  long nMRight = rFrameWndSize.Width() - rCellPos.X() - rCellSize.Width();
648  long nMTop = rCellPos.Y();
649  long nMBottom = rFrameWndSize.Height() - rCellPos.Y() - rCellSize.Height();
650 
651  // First, see if we can fit the entire hint window in the visible region.
652 
653  if (nMRight - nMargin >= rHintWndSize.Width())
654  {
655  // Right margin is wide enough.
656  if (rFrameWndSize.Height() >= rHintWndSize.Height())
657  {
658  // The frame has enough height. Take it.
659  Point aPos = rCellPos;
660  aPos.AdjustX(rCellSize.Width() + nMargin );
661  if (aPos.Y() + rHintWndSize.Height() > rFrameWndSize.Height())
662  {
663  // Push the hint window up a bit to make it fit.
664  aPos.setY( rFrameWndSize.Height() - rHintWndSize.Height() );
665  }
666  return aPos;
667  }
668  }
669 
670  if (nMBottom - nMargin >= rHintWndSize.Height())
671  {
672  // Bottom margin is high enough.
673  if (rFrameWndSize.Width() >= rHintWndSize.Width())
674  {
675  // The frame has enough width. Take it.
676  Point aPos = rCellPos;
677  aPos.AdjustY(rCellSize.Height() + nMargin );
678  if (aPos.X() + rHintWndSize.Width() > rFrameWndSize.Width())
679  {
680  // Move the hint window to the left to make it fit.
681  aPos.setX( rFrameWndSize.Width() - rHintWndSize.Width() );
682  }
683  return aPos;
684  }
685  }
686 
687  if (nMLeft - nMargin >= rHintWndSize.Width())
688  {
689  // Left margin is wide enough.
690  if (rFrameWndSize.Height() >= rHintWndSize.Height())
691  {
692  // The frame is high enough. Take it.
693  Point aPos = rCellPos;
694  aPos.AdjustX( -(rHintWndSize.Width() + nMargin) );
695  if (aPos.Y() + rHintWndSize.Height() > rFrameWndSize.Height())
696  {
697  // Push the hint window up a bit to make it fit.
698  aPos.setY( rFrameWndSize.Height() - rHintWndSize.Height() );
699  }
700  return aPos;
701  }
702  }
703 
704  if (nMTop - nMargin >= rHintWndSize.Height())
705  {
706  // Top margin is high enough.
707  if (rFrameWndSize.Width() >= rHintWndSize.Width())
708  {
709  // The frame is wide enough. Take it.
710  Point aPos = rCellPos;
711  aPos.AdjustY( -(rHintWndSize.Height() + nMargin) );
712  if (aPos.X() + rHintWndSize.Width() > rFrameWndSize.Width())
713  {
714  // Move the hint window to the left to make it fit.
715  aPos.setX( rFrameWndSize.Width() - rHintWndSize.Width() );
716  }
717  return aPos;
718  }
719  }
720 
721  // The popup doesn't fit in any direction in its entirety. Do our best.
722 
723  if (nMRight - nMargin >= rHintWndSize.Width())
724  {
725  // Right margin is good enough.
726  Point aPos = rCellPos;
727  aPos.AdjustX(nMargin + rCellSize.Width() );
728  aPos.setY( 0 );
729  return aPos;
730  }
731 
732  if (nMBottom - nMargin >= rHintWndSize.Height())
733  {
734  // Bottom margin is good enough.
735  Point aPos = rCellPos;
736  aPos.AdjustY(nMargin + rCellSize.Height() );
737  aPos.setX( 0 );
738  return aPos;
739  }
740 
741  if (nMLeft - nMargin >= rHintWndSize.Width())
742  {
743  // Left margin is good enough.
744  Point aPos = rCellPos;
745  aPos.AdjustX( -(rHintWndSize.Width() + nMargin) );
746  aPos.setY( 0 );
747  return aPos;
748  }
749 
750  if (nMTop - nMargin >= rHintWndSize.Height())
751  {
752  // Top margin is good enough.
753  Point aPos = rCellPos;
754  aPos.AdjustY( -(rHintWndSize.Height() + nMargin) );
755  aPos.setX( 0 );
756  return aPos;
757  }
758 
759  // None of the above. Hopeless. At least try not to cover the current
760  // cell.
761  Point aPos = rCellPos;
762  aPos.AdjustX(rCellSize.Width() );
763  return aPos;
764 }
765 
766 }
767 
769 {
770  // show input help window and list drop-down button for validity
771 
772  mxInputHintOO.reset();
773 
774  bool bListValButton = false;
775  ScAddress aListValPos;
776 
777  ScDocument* pDoc = aViewData.GetDocument();
778  const SfxUInt32Item* pItem = pDoc->GetAttr( aViewData.GetCurX(),
779  aViewData.GetCurY(),
780  aViewData.GetTabNo(),
781  ATTR_VALIDDATA );
782  if ( pItem->GetValue() )
783  {
784  const ScValidationData* pData = pDoc->GetValidationEntry( pItem->GetValue() );
785  OSL_ENSURE(pData,"ValidationData not found");
786  OUString aTitle, aMessage;
787 
788  if ( pData && pData->GetInput( aTitle, aMessage ) && !aMessage.isEmpty() )
789  {
790  ScSplitPos eWhich = aViewData.GetActivePart();
791  ScGridWindow* pWin = pGridWin[eWhich].get();
792  SCCOL nCol = aViewData.GetCurX();
793  SCROW nRow = aViewData.GetCurY();
794  Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
795  Size aWinSize = pWin->GetOutputSizePixel();
796  // cursor visible?
797  if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
798  nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
799  aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
800  {
801  const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
802  Color aCommentColor = rColorCfg.GetColorValue(svtools::CALCNOTESBACKGROUND).nColor;
803  // create HintWindow, determines its size by itself
804  ScOverlayHint* pOverlay = new ScOverlayHint(aTitle, aMessage, aCommentColor, pFrameWin->GetFont());
805 
806  mxInputHintOO.reset(new sdr::overlay::OverlayObjectList);
807  mxInputHintOO->append(std::unique_ptr<sdr::overlay::OverlayObject>(pOverlay));
808 
809  Size aHintWndSize = pOverlay->GetSizePixel();
810  long nCellSizeX = 0;
811  long nCellSizeY = 0;
812  aViewData.GetMergeSizePixel(nCol, nRow, nCellSizeX, nCellSizeY);
813 
814  Point aHintPos = calcHintWindowPosition(
815  aPos, Size(nCellSizeX,nCellSizeY), aWinSize, aHintWndSize);
816 
817  pOverlay->SetPos(pWin->PixelToLogic(aHintPos, pWin->GetDrawMapMode()), pWin->GetDrawMapMode());
818  for (VclPtr<ScGridWindow> & pWindow : pGridWin)
819  {
820  if (!pWindow)
821  continue;
822  if (!pWindow->IsVisible())
823  continue;
824  rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = pWindow->getOverlayManager();
825  if (!xOverlayManager.is())
826  continue;
827  if (pWindow == pWin)
828  {
829  xOverlayManager->add(*pOverlay);
830  }
831  else
832  {
833  //tdf#92530 if the help tip doesn't fit into its allocated area in a split window
834  //scenario, then because here we place it into the other split windows as well the
835  //missing portions will be displayed in the other split windows to form an apparent
836  //single tip, albeit "under" the split lines
837  Point aOtherPos(pWindow->ScreenToOutputPixel(pWin->OutputToScreenPixel(aHintPos)));
838  std::unique_ptr<ScOverlayHint> pOtherOverlay(new ScOverlayHint(aTitle, aMessage, aCommentColor, pFrameWin->GetFont()));
839  Point aFooPos(pWindow->PixelToLogic(aOtherPos, pWindow->GetDrawMapMode()));
840  pOtherOverlay->SetPos(aFooPos, pWindow->GetDrawMapMode());
841  xOverlayManager->add(*pOtherOverlay);
842  mxInputHintOO->append(std::move(pOtherOverlay));
843  }
844  }
845  }
846  }
847 
848  // list drop-down button
849  if ( pData && pData->HasSelectionList() )
850  {
851  aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
852  bListValButton = true;
853  }
854  }
855 
856  for (VclPtr<ScGridWindow> const & pWin : pGridWin)
857  {
858  if (pWin && pWin->IsVisible())
859  pWin->UpdateListValPos(bListValButton, aListValPos);
860  }
861 }
862 
863 bool ScTabView::HasHintWindow() const { return mxInputHintOO != nullptr; }
864 
866 {
867  mxInputHintOO.reset();
868 }
869 
870 // find window that should not be over the cursor
872 {
874 
875  // search & replace
876  if (pViewFrm->HasChildWindow(SID_SEARCH_DLG))
877  {
878  SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
879  if (pChild)
880  {
881  auto xDlgController = pChild->GetController();
882  if (xDlgController && xDlgController->getDialog()->get_visible())
883  return xDlgController->getDialog();
884  }
885  }
886 
887  // apply changes
888  if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
889  {
890  SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
891  if (pChild)
892  {
893  auto xDlgController = pChild->GetController();
894  if (xDlgController && xDlgController->getDialog()->get_visible())
895  return xDlgController->getDialog();
896  }
897  }
898 
899  return nullptr;
900 }
901 
902  // adjust screen with respect to cursor position
903 
905  const ScSplitPos* pWhich )
906 {
907  // now switch active part here
908 
909  ScSplitPos eActive = aViewData.GetActivePart();
910  ScHSplitPos eActiveX = WhichH(eActive);
911  ScVSplitPos eActiveY = WhichV(eActive);
912  bool bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
913  bool bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
914  if (bHFix && eActiveX == SC_SPLIT_LEFT && nCurX >= aViewData.GetFixPosX())
915  {
916  ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
917  eActiveX = SC_SPLIT_RIGHT;
918  }
919  if (bVFix && eActiveY == SC_SPLIT_TOP && nCurY >= aViewData.GetFixPosY())
920  {
921  ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
922  eActiveY = SC_SPLIT_BOTTOM;
923  }
924 
925  // actual align
926 
927  if ( eMode != SC_FOLLOW_NONE )
928  {
929  ScSplitPos eAlign;
930  if (pWhich)
931  eAlign = *pWhich;
932  else
933  eAlign = aViewData.GetActivePart();
934  ScHSplitPos eAlignX = WhichH(eAlign);
935  ScVSplitPos eAlignY = WhichV(eAlign);
936 
937  SCCOL nDeltaX = aViewData.GetPosX(eAlignX);
938  SCROW nDeltaY = aViewData.GetPosY(eAlignY);
939  SCCOL nSizeX = aViewData.VisibleCellsX(eAlignX);
940  SCROW nSizeY = aViewData.VisibleCellsY(eAlignY);
941 
942  long nCellSizeX;
943  long nCellSizeY;
944  if ( nCurX >= 0 && nCurY >= 0 )
945  aViewData.GetMergeSizePixel( nCurX, nCurY, nCellSizeX, nCellSizeY );
946  else
947  nCellSizeX = nCellSizeY = 0;
948  Size aScrSize = aViewData.GetScrSize();
949  long nSpaceX = ( aScrSize.Width() - nCellSizeX ) / 2;
950  long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
951  // nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
952 
953  bool bForceNew = false; // force new calculation of JUMP position (vertical only)
954 
955  // VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
956 
957  // when for instance a search dialog is open, don't put the cursor behind the dialog
958  // if possible, put the row with the cursor above or below the dialog
960 
961  if ( eMode == SC_FOLLOW_JUMP )
962  {
963  weld::Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
964  if (pCare)
965  {
966  bool bLimit = false;
967  tools::Rectangle aDlgPixel;
968  Size aWinSize;
969  vcl::Window* pWin = GetActiveWin();
970  weld::Window* pFrame = pWin ? pWin->GetFrameWeld() : nullptr;
971  int x, y, width, height;
972  if (pFrame && pCare->get_extents_relative_to(*pFrame, x, y, width, height))
973  {
974  aDlgPixel = tools::Rectangle(Point(x, y), Size(width, height));
975  aWinSize = pWin->GetOutputSizePixel();
976  // dos the dialog cover the GridWin?
977  if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
978  {
979  if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
980  nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
981  bLimit = true; // scroll anyway
982  else
983  {
984  // cursor is on the screen
985  Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
986  long nCSX, nCSY;
987  aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
988  tools::Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
989  if ( aCursor.IsOver( aDlgPixel ) )
990  bLimit = true; // cell is covered by the dialog
991  }
992  }
993  }
994 
995  if (bLimit)
996  {
997  bool bBottom = false;
998  long nTopSpace = aDlgPixel.Top();
999  long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
1000  if ( nBotSpace > 0 && nBotSpace > nTopSpace )
1001  {
1002  long nDlgBot = aDlgPixel.Bottom();
1003  SCCOL nWPosX;
1004  SCROW nWPosY;
1005  aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
1006  ++nWPosY; // below the last affected cell
1007 
1008  SCROW nDiff = nWPosY - nDeltaY;
1009  if ( nCurY >= nDiff ) // position can not be negative
1010  {
1011  nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
1012  bBottom = true;
1013  bForceNew = true;
1014  }
1015  }
1016  if ( !bBottom && nTopSpace > 0 )
1017  {
1018  nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
1019  bForceNew = true;
1020  }
1021  }
1022  }
1023  }
1024 
1025  SCCOL nNewDeltaX = nDeltaX;
1026  SCROW nNewDeltaY = nDeltaY;
1027  bool bDoLine = false;
1028 
1029  switch (eMode)
1030  {
1031  case SC_FOLLOW_JUMP:
1032  if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
1033  {
1034  nNewDeltaX = nCurX - aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<sal_uInt16>(nSpaceX) );
1035  if (nNewDeltaX < 0)
1036  nNewDeltaX = 0;
1037  nSizeX = aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
1038  }
1039  if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
1040  {
1041  nNewDeltaY = nCurY - aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<sal_uInt16>(nSpaceY) );
1042  if (nNewDeltaY < 0)
1043  nNewDeltaY = 0;
1044  nSizeY = aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
1045  }
1046  bDoLine = true;
1047  break;
1048 
1049  case SC_FOLLOW_LINE:
1050  bDoLine = true;
1051  break;
1052 
1053  case SC_FOLLOW_FIX:
1054  if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
1055  {
1056  nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
1057  if (nNewDeltaX < 0)
1058  nNewDeltaX = 0;
1059  nSizeX = aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
1060  }
1061  if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
1062  {
1063  nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
1064  if (nNewDeltaY < 0)
1065  nNewDeltaY = 0;
1066  nSizeY = aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
1067  }
1068 
1069  // like old version of SC_FOLLOW_JUMP:
1070 
1071  if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
1072  {
1073  nNewDeltaX = nCurX - (nSizeX / 2);
1074  if (nNewDeltaX < 0)
1075  nNewDeltaX = 0;
1076  nSizeX = aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
1077  }
1078  if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
1079  {
1080  nNewDeltaY = nCurY - (nSizeY / 2);
1081  if (nNewDeltaY < 0)
1082  nNewDeltaY = 0;
1083  nSizeY = aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
1084  }
1085 
1086  bDoLine = true;
1087  break;
1088 
1089  case SC_FOLLOW_NONE:
1090  break;
1091  default:
1092  OSL_FAIL("Wrong cursor mode");
1093  break;
1094  }
1095 
1096  ScDocument* pDoc = aViewData.GetDocument();
1097  if (bDoLine)
1098  {
1099  while ( nCurX >= nNewDeltaX+nSizeX )
1100  {
1101  nNewDeltaX = nCurX-nSizeX+1;
1102  SCTAB nTab = aViewData.GetTabNo();
1103  while ( nNewDeltaX < pDoc->MaxCol() && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
1104  ++nNewDeltaX;
1105  nSizeX = aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
1106  }
1107  while ( nCurY >= nNewDeltaY+nSizeY )
1108  {
1109  nNewDeltaY = nCurY-nSizeY+1;
1110  SCTAB nTab = aViewData.GetTabNo();
1111  while ( nNewDeltaY < pDoc->MaxRow() && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
1112  ++nNewDeltaY;
1113  nSizeY = aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
1114  }
1115  if ( nCurX < nNewDeltaX )
1116  nNewDeltaX = nCurX;
1117  if ( nCurY < nNewDeltaY )
1118  nNewDeltaY = nCurY;
1119  }
1120 
1121  if ( nNewDeltaX != nDeltaX )
1122  nSizeX = aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
1123  if (nNewDeltaX+nSizeX-1 > pDoc->MaxCol())
1124  nNewDeltaX = pDoc->MaxCol()-nSizeX+1;
1125  if (nNewDeltaX < 0)
1126  nNewDeltaX = 0;
1127 
1128  if ( nNewDeltaY != nDeltaY )
1129  nSizeY = aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
1130  if (nNewDeltaY+nSizeY-1 > pDoc->MaxRow())
1131  nNewDeltaY = pDoc->MaxRow()-nSizeY+1;
1132  if (nNewDeltaY < 0)
1133  nNewDeltaY = 0;
1134 
1135  if ( nNewDeltaX != nDeltaX )
1136  ScrollX( nNewDeltaX - nDeltaX, eAlignX );
1137  if ( nNewDeltaY != nDeltaY )
1138  ScrollY( nNewDeltaY - nDeltaY, eAlignY );
1139  }
1140 
1141  // switch active part again
1142 
1143  if (bHFix)
1144  if (eActiveX == SC_SPLIT_RIGHT && nCurX < aViewData.GetFixPosX())
1145  {
1146  ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
1147  eActiveX = SC_SPLIT_LEFT;
1148  }
1149  if (bVFix)
1150  if (eActiveY == SC_SPLIT_BOTTOM && nCurY < aViewData.GetFixPosY())
1151  {
1152  ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
1153  }
1154 }
1155 
1157 {
1158  bool bRet = false;
1159 
1160  // #i3875# *Hack*
1161  bool bMod1Locked = (aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1) != 0;
1162  aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );
1163 
1164  if ( pSelEngine )
1165  {
1166  bMoveIsShift = rMEvt.IsShift();
1167  bRet = pSelEngine->SelMouseButtonDown( rMEvt );
1168  bMoveIsShift = false;
1169  }
1170 
1171  aViewData.SetSelCtrlMouseClick( false ); // #i3875# *Hack*
1172 
1173  return bRet;
1174 }
1175 
1176  // MoveCursor - with adjustment of the view section
1177 
1179  bool bShift, bool bControl, bool bKeepOld, bool bKeepSel )
1180 {
1181  if (!bKeepOld)
1182  aViewData.ResetOldCursor();
1183 
1184  ScDocument* pDoc = aViewData.GetDocument();
1185  // #i123629#
1186  if( aViewData.GetViewShell()->GetForceFocusOnCurCell() )
1187  aViewData.GetViewShell()->SetForceFocusOnCurCell( !pDoc->ValidColRow(nCurX, nCurY) );
1188 
1189  if (nCurX < 0) nCurX = 0;
1190  if (nCurY < 0) nCurY = 0;
1191  if (nCurX > pDoc->MaxCol()) nCurX = pDoc->MaxCol();
1192  if (nCurY > pDoc->MaxRow()) nCurY = pDoc->MaxRow();
1193 
1194  // FIXME: this is to limit the number of rows handled in the Online
1195  // to 1000; this will be removed again when the performance
1196  // bottlenecks are sorted out
1198  nCurY = std::min(nCurY, MAXTILEDROW);
1199 
1200  HideAllCursors();
1201 
1202  // switch of active now in AlignToCursor
1203 
1204  AlignToCursor( nCurX, nCurY, eMode );
1205 
1206  if (bKeepSel)
1207  {
1208  SetCursor( nCurX, nCurY ); // keep selection
1209 
1210  // If the cursor is in existing selection, it's a cursor movement by
1211  // ENTER or TAB. If not, then it's a new selection during ADD
1212  // selection mode.
1213 
1214  const ScMarkData& rMark = aViewData.GetMarkData();
1215  ScRangeList aSelList;
1216  rMark.FillRangeListWithMarks(&aSelList, false);
1217  if (!aSelList.In(ScRange(nCurX, nCurY, aViewData.GetTabNo())))
1218  // Cursor not in existing selection. Start a new selection.
1219  DoneBlockMode(true);
1220  }
1221  else
1222  {
1223  if (!bShift)
1224  {
1225  // Remove all marked data on cursor movement unless the Shift is locked.
1226  ScMarkData& rMark = aViewData.GetMarkData();
1227  bool bMarked = rMark.IsMarked() || rMark.IsMultiMarked();
1228  if (bMarked)
1229  {
1230  rMark.ResetMark();
1231  DoneBlockMode();
1232  InitOwnBlockMode();
1233  MarkDataChanged();
1234  }
1235  }
1236 
1237  bool bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
1238  bMoveIsShift = bShift;
1239  pSelEngine->CursorPosChanging( bShift, bControl );
1240  bMoveIsShift = false;
1241  aFunctionSet.SetCursorAtCell( nCurX, nCurY, false );
1242 
1243  // If the cursor has not been moved, the SelectionChanged for canceling the
1244  // selection has to happen here individually:
1245  if (bSame)
1246  SelectionChanged();
1247  }
1248 
1249  ShowAllCursors();
1250  TestHintWindow();
1251 }
1252 
1254  bool bShift, bool bKeepSel )
1255 {
1256  ScDocument* pDoc = aViewData.GetDocument();
1257  SCTAB nTab = aViewData.GetTabNo();
1258 
1259  bool bSkipProtected = false, bSkipUnprotected = false;
1260  ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
1261  if ( pProtect && pProtect->isProtected() )
1262  {
1263  bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
1264  bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
1265  }
1266 
1267  if ( bSkipProtected && bSkipUnprotected )
1268  return;
1269 
1270  SCCOL nOldX;
1271  SCROW nOldY;
1272  SCCOL nCurX;
1273  SCROW nCurY;
1274  if ( aViewData.IsRefMode() )
1275  {
1276  nOldX = aViewData.GetRefEndX();
1277  nOldY = aViewData.GetRefEndY();
1278  nCurX = nOldX + nMovX;
1279  nCurY = nOldY + nMovY;
1280  }
1281  else
1282  {
1283  nOldX = aViewData.GetCurX();
1284  nOldY = aViewData.GetCurY();
1285  nCurX = (nMovX != 0) ? nOldX+nMovX : aViewData.GetOldCurX();
1286  nCurY = (nMovY != 0) ? nOldY+nMovY : aViewData.GetOldCurY();
1287  }
1288 
1289  if (nMovX < 0 && nOldX == 0)
1290  { // trying to go left from 1st column
1291  if (nMovY == 0) // done, because no vertical move is requested
1292  return;
1293  }
1294  if (nMovY < 0 && nOldY == 0)
1295  { // trying to go up from 1st row
1296  if (nMovX == 0) // done, because no horizontal move is requested
1297  return;
1298  }
1299 
1300  aViewData.ResetOldCursor();
1301 
1302  if (nMovX != 0 && pDoc->ValidColRow(nCurX,nCurY))
1303  SkipCursorHorizontal(nCurX, nCurY, nOldX, nMovX);
1304 
1305  if (nMovY != 0 && pDoc->ValidColRow(nCurX,nCurY))
1306  SkipCursorVertical(nCurX, nCurY, nOldY, nMovY);
1307 
1308  MoveCursorAbs( nCurX, nCurY, eMode, bShift, false, true, bKeepSel );
1309 }
1310 
1311 void ScTabView::MoveCursorPage( SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1312 {
1313  SCCOL nPageX;
1314  SCROW nPageY;
1315  GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
1316  MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
1317 }
1318 
1319 void ScTabView::MoveCursorArea( SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1320 {
1321  SCCOL nNewX;
1322  SCROW nNewY;
1323  GetAreaMoveEndPosition(nMovX, nMovY, eMode, nNewX, nNewY, eMode);
1324  MoveCursorRel(nNewX, nNewY, eMode, bShift, bKeepSel);
1325 }
1326 
1327 void ScTabView::MoveCursorEnd( SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1328 {
1329  ScDocument* pDoc = aViewData.GetDocument();
1330  SCTAB nTab = aViewData.GetTabNo();
1331 
1332  SCCOL nCurX;
1333  SCROW nCurY;
1334  aViewData.GetMoveCursor( nCurX,nCurY );
1335  SCCOL nNewX = nCurX;
1336  SCROW nNewY = nCurY;
1337 
1338  SCCOL nUsedX = 0;
1339  SCROW nUsedY = 0;
1340  if ( nMovX > 0 || nMovY > 0 )
1341  pDoc->GetPrintArea( nTab, nUsedX, nUsedY ); // get end
1342 
1343  if (nMovX<0)
1344  nNewX=0;
1345  else if (nMovX>0)
1346  nNewX=nUsedX; // last used range
1347 
1348  if (nMovY<0)
1349  nNewY=0;
1350  else if (nMovY>0)
1351  nNewY=nUsedY;
1352 
1353  aViewData.ResetOldCursor();
1354  MoveCursorRel( nNewX-nCurX, nNewY-nCurY, eMode, bShift, bKeepSel );
1355 }
1356 
1357 void ScTabView::MoveCursorScreen( SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift )
1358 {
1359  ScDocument* pDoc = aViewData.GetDocument();
1360  SCTAB nTab = aViewData.GetTabNo();
1361 
1362  SCCOL nCurX;
1363  SCROW nCurY;
1364  aViewData.GetMoveCursor( nCurX,nCurY );
1365  SCCOL nNewX = nCurX;
1366  SCROW nNewY = nCurY;
1367 
1368  ScSplitPos eWhich = aViewData.GetActivePart();
1369  SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
1370  SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );
1371 
1372  SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
1373  if (nAddX != 0)
1374  --nAddX;
1375  SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
1376  if (nAddY != 0)
1377  --nAddY;
1378 
1379  if (nMovX<0)
1380  nNewX=nPosX;
1381  else if (nMovX>0)
1382  nNewX=nPosX+nAddX;
1383 
1384  if (nMovY<0)
1385  nNewY=nPosY;
1386  else if (nMovY>0)
1387  nNewY=nPosY+nAddY;
1388 
1389  aViewData.SetOldCursor( nNewX,nNewY );
1390  pDoc->SkipOverlapped(nNewX, nNewY, nTab);
1391  MoveCursorAbs( nNewX, nNewY, eMode, bShift, false, true );
1392 }
1393 
1394 void ScTabView::MoveCursorEnter( bool bShift ) // bShift -> up/down
1395 {
1396  const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
1397  if (!rOpt.GetMoveSelection())
1398  {
1399  aViewData.UpdateInputHandler(true);
1400  return;
1401  }
1402 
1403  SCCOL nMoveX = 0;
1404  SCROW nMoveY = 0;
1405  switch (static_cast<ScDirection>(rOpt.GetMoveDir()))
1406  {
1407  case DIR_BOTTOM:
1408  nMoveY = bShift ? -1 : 1;
1409  break;
1410  case DIR_RIGHT:
1411  nMoveX = bShift ? -1 : 1;
1412  break;
1413  case DIR_TOP:
1414  nMoveY = bShift ? 1 : -1;
1415  break;
1416  case DIR_LEFT:
1417  nMoveX = bShift ? 1 : -1;
1418  break;
1419  }
1420 
1421  SCCOL nCurX;
1422  SCROW nCurY;
1423  aViewData.GetMoveCursor( nCurX,nCurY );
1424  SCCOL nNewX = nCurX;
1425  SCROW nNewY = nCurY;
1426  SCTAB nTab = aViewData.GetTabNo();
1427 
1428  ScMarkData& rMark = aViewData.GetMarkData();
1429  ScDocument* pDoc = aViewData.GetDocument();
1430 
1431  if (rMark.IsMarked() || rMark.IsMultiMarked())
1432  {
1433  pDoc->GetNextPos( nNewX, nNewY, nTab, nMoveX, nMoveY, true, false, rMark );
1434 
1435  MoveCursorRel( nNewX - nCurX, nNewY - nCurY, SC_FOLLOW_LINE, false, true );
1436 
1437  // update input line even if cursor was not moved
1438  if ( nNewX == nCurX && nNewY == nCurY )
1439  aViewData.UpdateInputHandler(true);
1440  }
1441  else
1442  {
1443  // After Tab and Enter back to the starting column again.
1444  const SCCOL nTabStartCol = ((nMoveY != 0 && !nMoveX) ? aViewData.GetTabStartCol() : SC_TABSTART_NONE);
1445  pDoc->GetNextPos( nNewX, nNewY, nTab, nMoveX, nMoveY, false, true, rMark, nTabStartCol );
1446 
1447  MoveCursorRel( nNewX - nCurX, nNewY - nCurY, SC_FOLLOW_LINE, false);
1448  }
1449 }
1450 
1451 bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
1452 {
1453  const vcl::KeyCode& rKCode = rKeyEvent.GetKeyCode();
1454 
1455  enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
1456  rKCode.IsMod1() ?
1457  (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
1458  (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
1459 
1460  bool bSel = rKCode.IsShift();
1461  sal_uInt16 nCode = rKCode.GetCode();
1462 
1463  // CURSOR keys
1464  SCCOL nDX = 0;
1465  SCROW nDY = 0;
1466  switch( nCode )
1467  {
1468  case KEY_LEFT: nDX = -1; break;
1469  case KEY_RIGHT: nDX = 1; break;
1470  case KEY_UP: nDY = -1; break;
1471  case KEY_DOWN: nDY = 1; break;
1472  }
1473  if( nDX != 0 || nDY != 0 )
1474  {
1475  switch( eModifier )
1476  {
1477  case MOD_NONE: MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel ); break;
1478  case MOD_CTRL: MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel ); break;
1479  default:
1480  {
1481  // added to avoid warnings
1482  }
1483  }
1484  // always true to suppress changes of col/row size (ALT+CURSOR)
1485  return true;
1486  }
1487 
1488  // PAGEUP/PAGEDOWN
1489  if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
1490  {
1491  nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
1492  switch( eModifier )
1493  {
1494  case MOD_NONE: MoveCursorPage( 0, static_cast<SCCOLROW>(nDX), SC_FOLLOW_FIX, bSel ); break;
1495  case MOD_ALT: MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel ); break;
1496  case MOD_CTRL: SelectNextTab( nDX, false ); break;
1497  default:
1498  {
1499  // added to avoid warnings
1500  }
1501  }
1502  return true;
1503  }
1504 
1505  // HOME/END
1506  if( (nCode == KEY_HOME) || (nCode == KEY_END) )
1507  {
1508  nDX = (nCode == KEY_HOME) ? -1 : 1;
1510  switch( eModifier )
1511  {
1512  case MOD_NONE: MoveCursorEnd( nDX, 0, eMode, bSel ); break;
1513  case MOD_CTRL: MoveCursorEnd( nDX, static_cast<SCCOLROW>(nDX), eMode, bSel ); break;
1514  default:
1515  {
1516  // added to avoid warnings
1517  }
1518  }
1519  return true;
1520  }
1521 
1522  return false;
1523 }
1524 
1525  // next/previous unprotected cell
1526 void ScTabView::FindNextUnprot( bool bShift, bool bInSelection )
1527 {
1528  short nMove = bShift ? -1 : 1;
1529 
1530  ScMarkData& rMark = aViewData.GetMarkData();
1531  bool bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
1532 
1533  SCCOL nCurX;
1534  SCROW nCurY;
1535  aViewData.GetMoveCursor( nCurX,nCurY );
1536  SCCOL nNewX = nCurX;
1537  SCROW nNewY = nCurY;
1538  SCTAB nTab = aViewData.GetTabNo();
1539 
1540  ScDocument* pDoc = aViewData.GetDocument();
1541  pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked, true, rMark );
1542 
1543  SCCOL nTabCol = aViewData.GetTabStartCol();
1544  if ( nTabCol == SC_TABSTART_NONE )
1545  nTabCol = nCurX; // back to this column after Enter
1546 
1547  MoveCursorRel( nNewX-nCurX, nNewY-nCurY, SC_FOLLOW_LINE, false, true );
1548 
1549  // TabCol is reset in MoveCursorRel...
1550  aViewData.SetTabStartCol( nTabCol );
1551 }
1552 
1554 {
1555  SCCOL nStartCol;
1556  SCCOL nEndCol;
1557 
1558  ScMarkData& rMark = aViewData.GetMarkData();
1559  if (rMark.IsMarked())
1560  {
1561  ScRange aMarkRange;
1562  rMark.GetMarkArea( aMarkRange );
1563  nStartCol = aMarkRange.aStart.Col();
1564  nEndCol = aMarkRange.aEnd.Col();
1565  }
1566  else
1567  {
1568  SCROW nDummy;
1569  aViewData.GetMoveCursor( nStartCol, nDummy );
1570  nEndCol=nStartCol;
1571  }
1572 
1573  SCTAB nTab = aViewData.GetTabNo();
1574  ScDocument* pDoc = aViewData.GetDocument();
1575  DoneBlockMode();
1576  InitBlockMode( nStartCol,0, nTab );
1577  MarkCursor( nEndCol, pDoc->MaxRow(), nTab );
1578  SelectionChanged();
1579 }
1580 
1582 {
1583  SCROW nStartRow;
1584  SCROW nEndRow;
1585 
1586  ScMarkData& rMark = aViewData.GetMarkData();
1587  if (rMark.IsMarked())
1588  {
1589  ScRange aMarkRange;
1590  rMark.GetMarkArea( aMarkRange );
1591  nStartRow = aMarkRange.aStart.Row();
1592  nEndRow = aMarkRange.aEnd.Row();
1593  }
1594  else
1595  {
1596  SCCOL nDummy;
1597  aViewData.GetMoveCursor( nDummy, nStartRow );
1598  nEndRow=nStartRow;
1599  }
1600 
1601  SCTAB nTab = aViewData.GetTabNo();
1602  ScDocument* pDoc = aViewData.GetDocument();
1603  DoneBlockMode();
1604  InitBlockMode( 0,nStartRow, nTab );
1605  MarkCursor( pDoc->MaxCol(), nEndRow, nTab );
1606  SelectionChanged();
1607 }
1608 
1609 
1610 void ScTabView::MarkColumns(SCCOL nCol, sal_Int16 nModifier)
1611 {
1612  ScDocument* pDoc = aViewData.GetDocument();
1613  SCCOL nStartCol = nCol;
1614  SCTAB nTab = aViewData.GetTabNo();
1615 
1616  if ((nModifier & KEY_SHIFT) == KEY_SHIFT)
1617  bMoveIsShift = true;
1618 
1619  DoneBlockMode( nModifier != 0 );
1620  InitBlockMode( nStartCol, 0, nTab, true, true);
1621  MarkCursor( nCol, pDoc->MaxRow(), nTab );
1622  bMoveIsShift = false;
1623  SetCursor( nCol, 0 );
1624  SelectionChanged();
1625 }
1626 
1627 void ScTabView::MarkRows(SCROW nRow, sal_Int16 nModifier)
1628 {
1629  ScDocument* pDoc = aViewData.GetDocument();
1630  SCROW nStartRow = nRow;
1631  SCTAB nTab = aViewData.GetTabNo();
1632 
1633  if ((nModifier & KEY_SHIFT) == KEY_SHIFT)
1634  bMoveIsShift = true;
1635 
1636  DoneBlockMode( nModifier != 0 );
1637  InitBlockMode( 0, nStartRow, nTab, true, false, true );
1638  MarkCursor( pDoc->MaxCol(), nRow, nTab );
1639  bMoveIsShift = false;
1640  SetCursor( 0, nRow );
1641  SelectionChanged();
1642 }
1643 
1644 void ScTabView::MarkDataArea( bool bIncludeCursor )
1645 {
1646  ScDocument* pDoc = aViewData.GetDocument();
1647  SCTAB nTab = aViewData.GetTabNo();
1648  SCCOL nStartCol = aViewData.GetCurX();
1649  SCROW nStartRow = aViewData.GetCurY();
1650  SCCOL nEndCol = nStartCol;
1651  SCROW nEndRow = nStartRow;
1652 
1653  pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );
1654 
1655  HideAllCursors();
1656  DoneBlockMode();
1657  InitBlockMode( nStartCol, nStartRow, nTab );
1658  MarkCursor( nEndCol, nEndRow, nTab );
1659  ShowAllCursors();
1660 
1661  SelectionChanged();
1662 }
1663 
1665 {
1666  ScDocument* pDoc = aViewData.GetDocument();
1667  ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
1668  ScRange aMatrix;
1669  if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
1670  {
1671  MarkRange( aMatrix, false ); // cursor is already within the range
1672  }
1673 }
1674 
1675 void ScTabView::MarkRange( const ScRange& rRange, bool bSetCursor, bool bContinue )
1676 {
1677  ScDocument* pDoc = aViewData.GetDocument();
1678  SCTAB nTab = rRange.aStart.Tab();
1679  SetTabNo( nTab );
1680 
1681  HideAllCursors();
1682  DoneBlockMode( bContinue ); // bContinue==true -> clear old mark
1683  if (bSetCursor) // if Cursor is set, also always align
1684  {
1685  SCCOL nAlignX = rRange.aStart.Col();
1686  SCROW nAlignY = rRange.aStart.Row();
1687  bool bCol = ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == pDoc->MaxCol() ) && !aViewData.GetDocument()->IsInVBAMode();
1688  bool bRow = ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == pDoc->MaxRow() );
1689  if ( bCol )
1690  nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
1691  if ( bRow )
1692  nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
1693  AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
1694  }
1695  InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
1696  MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
1697  if (bSetCursor)
1698  {
1699  SCCOL nPosX = rRange.aStart.Col();
1700  SCROW nPosY = rRange.aStart.Row();
1701  pDoc->SkipOverlapped(nPosX, nPosY, nTab);
1702 
1703  aViewData.ResetOldCursor();
1704  SetCursor( nPosX, nPosY );
1705  }
1706  ShowAllCursors();
1707 
1708  SelectionChanged();
1709 }
1710 
1712 {
1713  ScMarkData& rMark = aViewData.GetMarkData();
1714  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1715  {
1716  SCCOL nCurX;
1717  SCROW nCurY;
1718  aViewData.GetMoveCursor( nCurX,nCurY );
1719  MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, false, false );
1720 
1721  SelectionChanged();
1722  }
1723 }
1724 
1726 {
1727  DoneBlockMode();
1728  InitOwnBlockMode();
1729  aViewData.GetMarkData() = rNew;
1730 
1731  MarkDataChanged();
1732 }
1733 
1735 {
1736  // has to be called after making direct changes to mark data (not via MarkCursor etc)
1737 
1738  UpdateSelectionOverlay();
1739 }
1740 
1741 void ScTabView::SelectNextTab( short nDir, bool bExtendSelection )
1742 {
1743  if (!nDir)
1744  return;
1745  OSL_ENSURE( nDir==-1 || nDir==1, "SelectNextTab: invalid value");
1746 
1747  ScDocument* pDoc = aViewData.GetDocument();
1748  SCTAB nTab = aViewData.GetTabNo();
1749  if (nDir<0)
1750  {
1751  if (!nTab)
1752  return;
1753  --nTab;
1754  while (!pDoc->IsVisible(nTab))
1755  {
1756  if (!nTab)
1757  return;
1758  --nTab;
1759  }
1760  }
1761  else
1762  {
1763  SCTAB nCount = pDoc->GetTableCount();
1764  ++nTab;
1765  if (nTab >= nCount)
1766  return;
1767  while (!pDoc->IsVisible(nTab))
1768  {
1769  ++nTab;
1770  if (nTab >= nCount)
1771  return;
1772  }
1773  }
1774 
1775  SetTabNo( nTab, false, bExtendSelection );
1776  PaintExtras();
1777 }
1778 
1779 void ScTabView::SelectTabPage( const sal_uInt16 nTab )
1780 {
1781  pTabControl->SwitchToPageId( nTab );
1782 }
1783 
1784 // SetTabNo - set the displayed sheet
1785 
1786 void ScTabView::SetTabNo( SCTAB nTab, bool bNew, bool bExtendSelection, bool bSameTabButMoved )
1787 {
1788  if ( !ValidTab(nTab) )
1789  {
1790  OSL_FAIL("SetTabNo: invalid sheet");
1791  return;
1792  }
1793 
1794  if ( nTab != aViewData.GetTabNo() || bNew )
1795  {
1796  // FormShell would like to be informed before the switch
1797  FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
1798  if (pFormSh)
1799  {
1800  bool bAllowed = pFormSh->PrepareClose();
1801  if (!bAllowed)
1802  {
1805 
1806  return; // FormShell says that it can not be switched
1807  }
1808  }
1809 
1810  // not InputEnterHandler due to reference input
1811 
1812  ScDocument* pDoc = aViewData.GetDocument();
1813 
1814  pDoc->MakeTable( nTab );
1815 
1816  // Update pending row heights before switching the sheet, so Reschedule from the progress bar
1817  // doesn't paint the new sheet with old heights
1818  aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
1819 
1820  SCTAB nTabCount = pDoc->GetTableCount();
1821  SCTAB nOldPos = nTab;
1822  while (!pDoc->IsVisible(nTab)) // search for next visible
1823  {
1824  bool bUp = (nTab>=nOldPos);
1825  if (bUp)
1826  {
1827  ++nTab;
1828  if (nTab>=nTabCount)
1829  {
1830  nTab = nOldPos;
1831  bUp = false;
1832  }
1833  }
1834 
1835  if (!bUp)
1836  {
1837  if (nTab != 0)
1838  --nTab;
1839  else
1840  {
1841  OSL_FAIL("no visible sheets");
1842  pDoc->SetVisible( 0, true );
1843  }
1844  }
1845  }
1846 
1847  // #i71490# Deselect drawing objects before changing the sheet number in view data,
1848  // so the handling of notes still has the sheet selected on which the notes are.
1849  DrawDeselectAll();
1850 
1851  ScModule* pScMod = SC_MOD();
1852  bool bRefMode = pScMod->IsFormulaMode();
1853  if ( !bRefMode ) // query, so that RefMode works when switching sheet
1854  {
1855  DoneBlockMode();
1856  pSelEngine->Reset(); // reset all flags, including locked modifiers
1857  aViewData.SetRefTabNo( nTab );
1858  }
1859 
1860  ScSplitPos eOldActive = aViewData.GetActivePart(); // before switching
1861  bool bFocus = pGridWin[eOldActive] && pGridWin[eOldActive]->HasFocus();
1862 
1863  aViewData.SetTabNo( nTab );
1864  // UpdateShow before SetCursor, so that UpdateAutoFillMark finds the correct
1865  // window (is called from SetCursor)
1866  UpdateShow();
1867 
1868  SfxBindings& rBindings = aViewData.GetBindings();
1869  ScMarkData& rMark = aViewData.GetMarkData();
1870 
1871  bool bAllSelected = true;
1872  for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
1873  {
1874  if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
1875  {
1876  if (nTab == nSelTab)
1877  // This tab is already in selection. Keep the current
1878  // selection.
1879  bExtendSelection = true;
1880  }
1881  else
1882  {
1883  bAllSelected = false;
1884  if (bExtendSelection)
1885  // We got what we need. No need to stay in the loop.
1886  break;
1887  }
1888  }
1889  if (bAllSelected && !bNew)
1890  // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
1891  // (not if called with bNew to update settings)
1892  bExtendSelection = false;
1893 
1894  if (bExtendSelection)
1895  rMark.SelectTable( nTab, true );
1896  else
1897  {
1898  rMark.SelectOneTable( nTab );
1899  rBindings.Invalidate( FID_FILL_TAB );
1900  rBindings.Invalidate( FID_TAB_DESELECTALL );
1901  }
1902 
1903  bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
1904 
1905  // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
1906  RefreshZoom();
1907  UpdateVarZoom();
1908 
1909  if ( bRefMode ) // hide EditView if necessary (after aViewData.SetTabNo !)
1910  {
1911  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1912  {
1913  if (pWin && pWin->IsVisible())
1914  pWin->UpdateEditViewPos();
1915  }
1916  }
1917 
1918  TabChanged(bSameTabButMoved); // DrawView
1919  collectUIInformation({{"TABLE", OUString::number(nTab)}});
1920  UpdateVisibleRange();
1921 
1922  aViewData.GetViewShell()->WindowChanged(); // if the active window has changed
1923  aViewData.ResetOldCursor();
1924  SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), true );
1925 
1926  if ( !bUnoRefDialog )
1927  aViewData.GetViewShell()->DisconnectAllClients(); // important for floating frames
1928  else
1929  {
1930  // hide / show inplace client
1931  ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
1932  if ( pClient && pClient->IsObjectInPlaceActive() )
1933  {
1934  tools::Rectangle aObjArea = pClient->GetObjArea();
1935  if ( nTab == aViewData.GetRefTabNo() )
1936  {
1937  // move to its original position
1938 
1939  SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
1940  if ( pDrawObj )
1941  {
1942  tools::Rectangle aRect = pDrawObj->GetLogicRect();
1943  MapMode aMapMode( MapUnit::Map100thMM );
1944  Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
1945  aRect.SetSize( aOleSize );
1946  aObjArea = aRect;
1947  }
1948  }
1949  else
1950  {
1951  // move to an invisible position
1952 
1953  aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
1954  }
1955  pClient->SetObjArea( aObjArea );
1956  }
1957  }
1958 
1959  if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
1960  ActiveGrabFocus(); // grab focus to the pane that's active now
1961 
1962  // freeze
1963 
1964  bool bResize = false;
1965  if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1966  if (aViewData.UpdateFixX())
1967  bResize = true;
1968  if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1969  if (aViewData.UpdateFixY())
1970  bResize = true;
1971  if (bResize)
1972  RepeatResize();
1973  InvalidateSplit();
1974 
1975  if ( aViewData.IsPagebreakMode() )
1976  UpdatePageBreakData();
1977 
1978  // Form Layer must know the visible area of the new sheet
1979  // that is why MapMode must already be correct here
1980  for (VclPtr<ScGridWindow> & pWin : pGridWin)
1981  {
1982  if (pWin)
1983  pWin->SetMapMode(pWin->GetDrawMapMode());
1984  }
1985  SetNewVisArea();
1986 
1987  PaintGrid();
1988  PaintTop();
1989  PaintLeft();
1990  PaintExtras();
1991 
1992  DoResize( aBorderPos, aFrameSize );
1993  rBindings.Invalidate( SID_DELETE_PRINTAREA ); // Menu
1994  rBindings.Invalidate( FID_DEL_MANUALBREAKS );
1995  rBindings.Invalidate( FID_RESET_PRINTZOOM );
1996  rBindings.Invalidate( SID_STATUS_DOCPOS ); // Status bar
1997  rBindings.Invalidate( SID_ROWCOL_SELCOUNT ); // Status bar
1998  rBindings.Invalidate( SID_STATUS_PAGESTYLE ); // Status bar
1999  rBindings.Invalidate( SID_CURRENTTAB ); // Navigator
2000  rBindings.Invalidate( SID_STYLE_FAMILY2 ); // Designer
2001  rBindings.Invalidate( SID_STYLE_FAMILY4 ); // Designer
2002  rBindings.Invalidate( SID_TABLES_COUNT );
2003 
2004  if (pScMod->IsRefDialogOpen())
2005  {
2006  sal_uInt16 nCurRefDlgId=pScMod->GetCurRefDlgId();
2007  SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
2008  SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
2009  if (pChildWnd)
2010  {
2011  if (pChildWnd->GetController())
2012  {
2013  IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
2014  if (pRefDlg)
2015  pRefDlg->ViewShellChanged();
2016  }
2017  }
2018  }
2019 
2020  OnLibreOfficeKitTabChanged();
2021  }
2022 }
2023 
2025 {
2026  aExtraEditViewManager.Add(pViewShell, eWhich);
2027 }
2028 
2030 {
2031  aExtraEditViewManager.Remove(pViewShell, eWhich);
2032 }
2033 
2035 {
2037  {
2038  ScTabViewShell* pThisViewShell = aViewData.GetViewShell();
2039  SCTAB nThisTabNo = pThisViewShell->GetViewData().GetTabNo();
2040  auto lTabSwitch = [pThisViewShell, nThisTabNo] (ScTabViewShell* pOtherViewShell)
2041  {
2042  ScViewData& rOtherViewData = pOtherViewShell->GetViewData();
2043  SCTAB nOtherTabNo = rOtherViewData.GetTabNo();
2044  if (nThisTabNo == nOtherTabNo)
2045  {
2046  for (int i = 0; i < 4; ++i)
2047  {
2048  if (rOtherViewData.HasEditView(ScSplitPos(i)))
2049  {
2050  pThisViewShell->AddWindowToForeignEditView(pOtherViewShell, ScSplitPos(i));
2051  }
2052  }
2053  }
2054  else
2055  {
2056  for (int i = 0; i < 4; ++i)
2057  {
2058  if (rOtherViewData.HasEditView(ScSplitPos(i)))
2059  {
2060  pThisViewShell->RemoveWindowFromForeignEditView(pOtherViewShell, ScSplitPos(i));
2061  }
2062  }
2063  }
2064  };
2065 
2066  SfxLokHelper::forEachOtherView(pThisViewShell, lTabSwitch);
2067 
2068  pThisViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_HEADER, "all");
2069 
2070  if (pThisViewShell->GetInputHandler())
2071  pThisViewShell->GetInputHandler()->UpdateLokReferenceMarks();
2072  }
2073 }
2074 
2075 // paint functions - only for this View
2076 
2078 {
2079  DrawDeselectAll();
2080 
2081  if (pDrawView)
2082  DrawEnableAnim( false );
2083 
2084  EditView* pSpellingView = aViewData.GetSpellingView();
2085 
2086  for (sal_uInt16 i = 0; i < 4; i++)
2087  {
2088  if (pGridWin[i] && pGridWin[i]->IsVisible() && !aViewData.HasEditView(ScSplitPos(i)))
2089  {
2090  ScHSplitPos eHWhich = WhichH( static_cast<ScSplitPos>(i) );
2091  ScVSplitPos eVWhich = WhichV( static_cast<ScSplitPos>(i) );
2092  SCCOL nScrX = aViewData.GetPosX( eHWhich );
2093  SCROW nScrY = aViewData.GetPosY( eVWhich );
2094 
2095  bool bPosVisible =
2096  ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
2097  nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
2098 
2099  // for the active part, create edit view even if outside the visible area,
2100  // so input isn't lost (and the edit view may be scrolled into the visible area)
2101 
2102  // #i26433# during spelling, the spelling view must be active
2103  if ( bPosVisible || aViewData.GetActivePart() == static_cast<ScSplitPos>(i) ||
2104  ( pSpellingView && aViewData.GetEditView(static_cast<ScSplitPos>(i)) == pSpellingView ) )
2105  {
2106  pGridWin[i]->HideCursor();
2107 
2108  pGridWin[i]->DeleteCursorOverlay();
2109  pGridWin[i]->DeleteAutoFillOverlay();
2110  pGridWin[i]->DeleteCopySourceOverlay();
2111 
2112  // flush OverlayManager before changing MapMode to text edit
2113  pGridWin[i]->flushOverlayManager();
2114 
2115  // MapMode must be set after HideCursor
2116  pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
2117 
2118  aViewData.SetEditEngine( static_cast<ScSplitPos>(i), pEngine, pGridWin[i], nCol, nRow );
2119 
2120  if ( !bPosVisible )
2121  {
2122  // move the edit view area to the real (possibly negative) position,
2123  // or hide if completely above or left of the window
2124  pGridWin[i]->UpdateEditViewPos();
2125  }
2126  }
2127  }
2128  }
2129 
2130  if (aViewData.GetViewShell()->HasAccessibilityObjects())
2131  aViewData.GetViewShell()->BroadcastAccessibility(SfxHint(SfxHintId::ScAccEnterEditMode));
2132 }
2133 
2135 {
2136  ScSplitPos eActive = aViewData.GetActivePart();
2137  for (sal_uInt16 i = 0; i < 4; i++)
2138  {
2139  ScSplitPos eCurrent = ScSplitPos(i);
2140  if (aViewData.HasEditView(eCurrent))
2141  {
2142  EditView* pEditView = aViewData.GetEditView(eCurrent);
2143 
2144  long nRefTabNo = GetViewData().GetRefTabNo();
2145  long nX = GetViewData().GetCurXForTab(nRefTabNo);
2146  long nY = GetViewData().GetCurYForTab(nRefTabNo);
2147 
2148  aViewData.SetEditEngine(eCurrent,
2149  static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
2150  pGridWin[i], nX, nY );
2151  if (eCurrent == eActive)
2152  pEditView->ShowCursor( false );
2153  }
2154  }
2155 }
2156 
2157 void ScTabView::KillEditView( bool bNoPaint )
2158 {
2159  SCCOL nCol1 = aViewData.GetEditStartCol();
2160  SCROW nRow1 = aViewData.GetEditStartRow();
2161  SCCOL nCol2 = aViewData.GetEditEndCol();
2162  SCROW nRow2 = aViewData.GetEditEndRow();
2163  bool bPaint[4];
2164  bool bNotifyAcc = false;
2165  tools::Rectangle aRectangle[4];
2166 
2167  bool bExtended = nRow1 != nRow2; // column is painted to the end anyway
2168 
2169  bool bAtCursor = nCol1 <= aViewData.GetCurX() &&
2170  nCol2 >= aViewData.GetCurX() &&
2171  nRow1 == aViewData.GetCurY();
2172  for (sal_uInt16 i = 0; i < 4; i++)
2173  {
2174  bPaint[i] = aViewData.HasEditView( static_cast<ScSplitPos>(i) );
2175  if (bPaint[i])
2176  {
2177  bNotifyAcc = true;
2178 
2179  EditView* pView = aViewData.GetEditView( static_cast<ScSplitPos>(i) );
2180  aRectangle[i] = pView->GetInvalidateRect();
2181  }
2182  }
2183 
2184  // notify accessibility before all things happen
2185  if (bNotifyAcc && aViewData.GetViewShell()->HasAccessibilityObjects())
2186  aViewData.GetViewShell()->BroadcastAccessibility(SfxHint(SfxHintId::ScAccLeaveEditMode));
2187 
2188  aViewData.ResetEditView();
2189  for (sal_uInt16 i = 0; i < 4; i++)
2190  {
2191  if (pGridWin[i] && bPaint[i] && pGridWin[i]->IsVisible())
2192  {
2193  pGridWin[i]->ShowCursor();
2194 
2195  pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
2196 
2198  {
2199  const tools::Rectangle& rInvRect = aRectangle[i];
2200  pGridWin[i]->Invalidate(rInvRect);
2201 
2202  // invalidate other views
2203  auto lInvalidateWindows =
2204  [&rInvRect] (ScTabView* pTabView)
2205  {
2206  for (VclPtr<ScGridWindow> const & pWin: pTabView->pGridWin)
2207  {
2208  if (pWin)
2209  pWin->Invalidate(rInvRect);
2210  }
2211  };
2212 
2213  SfxLokHelper::forEachOtherView(GetViewData().GetViewShell(), lInvalidateWindows);
2214  }
2215  // #i73567# the cell still has to be repainted
2216  else if (bExtended || ( bAtCursor && !bNoPaint ))
2217  {
2218  pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, ScUpdateMode::All );
2219  pGridWin[i]->UpdateSelectionOverlay();
2220  }
2221  }
2222  }
2223 
2224  if (pDrawView)
2225  DrawEnableAnim( true );
2226 
2227  // GrabFocus always when this View is active and
2228  // when the input row has the focus
2229 
2230  bool bGrabFocus = false;
2231  if (aViewData.IsActive())
2232  {
2233  ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
2234  if ( pInputHdl )
2235  {
2236  ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
2237  if (pInputWin && pInputWin->IsInputActive())
2238  bGrabFocus = true;
2239  }
2240  }
2241 
2242  if (bGrabFocus)
2243  {
2244 // should be done like this, so that Sfx notice it, but it does not work:
2246 // therefore first like this:
2247  GetActiveWin()->GrabFocus();
2248  }
2249 
2250  // cursor query only after GrabFocus
2251 
2252  for (sal_uInt16 i = 0; i < 4; i++)
2253  {
2254  if (pGridWin[i] && pGridWin[i]->IsVisible())
2255  {
2256  vcl::Cursor* pCur = pGridWin[i]->GetCursor();
2257  if (pCur && pCur->IsVisible())
2258  pCur->Hide();
2259 
2260  if (bPaint[i])
2261  {
2262  pGridWin[i]->UpdateCursorOverlay();
2263  pGridWin[i]->UpdateAutoFillOverlay();
2264  }
2265  }
2266  }
2267 }
2268 
2269 void ScTabView::UpdateFormulas(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow)
2270 {
2271  if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
2272  return;
2273 
2274  for (sal_uInt16 i = 0; i < 4; i++)
2275  {
2276  if (pGridWin[i] && pGridWin[i]->IsVisible())
2277  pGridWin[i]->UpdateFormulas(nStartCol, nStartRow, nEndCol, nEndRow);
2278  }
2279 
2280  if ( aViewData.IsPagebreakMode() )
2281  UpdatePageBreakData();
2282 
2283  UpdateHeaderWidth();
2284 
2285  // if in edit mode, adjust edit view area because widths/heights may have changed
2286  if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
2287  UpdateEditView();
2288 }
2289 
2290 // PaintArea - repaint block
2291 
2292 void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
2293  ScUpdateMode eMode )
2294 {
2295  SCCOL nCol1;
2296  SCROW nRow1;
2297  SCCOL nCol2;
2298  SCROW nRow2;
2299  bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
2300  ScDocument* pDoc = aViewData.GetDocument();
2301 
2302  PutInOrder( nStartCol, nEndCol );
2303  PutInOrder( nStartRow, nEndRow );
2304 
2305  for (size_t i = 0; i < 4; ++i)
2306  {
2307  if (!pGridWin[i] || !pGridWin[i]->IsVisible())
2308  continue;
2309 
2310  ScHSplitPos eHWhich = WhichH( static_cast<ScSplitPos>(i) );
2311  ScVSplitPos eVWhich = WhichV( static_cast<ScSplitPos>(i) );
2312  bool bOut = false;
2313 
2314  nCol1 = nStartCol;
2315  nRow1 = nStartRow;
2316  nCol2 = nEndCol;
2317  nRow2 = nEndRow;
2318 
2319  SCCOL nLastX = 0;
2320  SCROW nLastY = 0;
2321 
2322  if (bIsTiledRendering)
2323  {
2324  nLastX = aViewData.GetMaxTiledCol();
2325  nLastY = aViewData.GetMaxTiledRow();
2326  }
2327  else
2328  {
2329 
2330  SCCOL nScrX = aViewData.GetPosX( eHWhich );
2331  SCROW nScrY = aViewData.GetPosY( eVWhich );
2332 
2333  if (nCol1 < nScrX)
2334  nCol1 = nScrX;
2335  if (nCol2 < nScrX)
2336  {
2337  if ( eMode == ScUpdateMode::All ) // for UPDATE_ALL, paint anyway
2338  nCol2 = nScrX; // (because of extending strings to the right)
2339  else
2340  bOut = true; // completely outside the window
2341  }
2342  if (nRow1 < nScrY)
2343  nRow1 = nScrY;
2344  if (nRow2 < nScrY)
2345  bOut = true;
2346 
2347  nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
2348  nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
2349  }
2350 
2351  if (nCol1 > nLastX)
2352  bOut = true;
2353  if (nCol2 > nLastX)
2354  nCol2 = nLastX;
2355  if (nRow1 > nLastY)
2356  bOut = true;
2357  if (nRow2 > nLastY)
2358  nRow2 = nLastY;
2359 
2360  if (bOut)
2361  continue;
2362 
2363  bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2364  long nLayoutSign = bLayoutRTL ? -1 : 1;
2365 
2366  Point aStart = aViewData.GetScrPos( nCol1, nRow1, static_cast<ScSplitPos>(i) );
2367  Point aEnd = aViewData.GetScrPos( nCol2+1, nRow2+1, static_cast<ScSplitPos>(i) );
2368  if ( eMode == ScUpdateMode::All )
2369  {
2370  if (bIsTiledRendering)
2371  {
2372  // When a cell content is deleted we have no clue about
2373  // the width of the embedded text.
2374  // Anyway, clients will ask only for tiles that overlaps
2375  // the visible area.
2376  // Remember that wsd expects int and that aEnd.X() is
2377  // in pixels and will be converted in twips, before performing
2378  // the lok callback, so we need to avoid that an overflow occurs.
2379  aEnd.setX( bLayoutRTL ? 0 : std::numeric_limits<int>::max() / 1000 );
2380  }
2381  else
2382  {
2383  aEnd.setX( bLayoutRTL ? 0 : pGridWin[i]->GetOutputSizePixel().Width() );
2384  }
2385  }
2386  aEnd.AdjustX( -nLayoutSign );
2387  aEnd.AdjustY( -1 );
2388 
2389  // #i85232# include area below cells (could be done in GetScrPos?)
2390  if ( eMode == ScUpdateMode::All && nRow2 >= pDoc->MaxRow() && !bIsTiledRendering )
2391  aEnd.setY( pGridWin[i]->GetOutputSizePixel().Height() );
2392 
2393  aStart.AdjustX( -nLayoutSign ); // include change marks
2394  aStart.AdjustY( -1 );
2395 
2396  bool bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
2397  if (bMarkClipped)
2398  {
2399  // ScColumn::IsEmptyBlock has to be optimized for this
2400  // (switch to Search() )
2404  long nMarkPixel = static_cast<long>( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
2405  aStart.AdjustX( -(nMarkPixel * nLayoutSign) );
2406  }
2407 
2408  pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( tools::Rectangle( aStart,aEnd ) ) );
2409  }
2410 
2411  // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
2412  // with a wrong MapMode if editing in a cell (reference input).
2413  // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
2414  // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
2415  // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
2416  // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PaintPartFlags::Left/PaintPartFlags::Top
2417  // is set (width or height changed).
2418 }
2419 
2421 {
2422  ScRange aRef = pData->aRef;
2423  aRef.PutInOrder(); // PutInOrder for the queries below
2424 
2425  if ( aRef.aStart == aRef.aEnd )
2426  aViewData.GetDocument()->ExtendMerge(aRef);
2427 
2428  if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
2429  {
2430  SCCOL nCol1 = aRef.aStart.Col();
2431  SCROW nRow1 = aRef.aStart.Row();
2432  SCCOL nCol2 = aRef.aEnd.Col();
2433  SCROW nRow2 = aRef.aEnd.Row();
2434 
2435  // remove -> repaint
2436  // ScUpdateMode::Marks: Invalidate, nothing until end of row
2437 
2438  bool bHiddenEdge = false;
2439  SCROW nTmp;
2440  ScDocument* pDoc = aViewData.GetDocument();
2441  while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab) )
2442  {
2443  --nCol1;
2444  bHiddenEdge = true;
2445  }
2446  while ( nCol2 < pDoc->MaxCol() && pDoc->ColHidden(nCol2, nTab) )
2447  {
2448  ++nCol2;
2449  bHiddenEdge = true;
2450  }
2451  nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
2452  if (!pDoc->ValidRow(nTmp))
2453  nTmp = 0;
2454  if (nTmp < nRow1)
2455  {
2456  nRow1 = nTmp;
2457  bHiddenEdge = true;
2458  }
2459  nTmp = pDoc->FirstVisibleRow(nRow2, pDoc->MaxRow(), nTab);
2460  if (!pDoc->ValidRow(nTmp))
2461  nTmp = pDoc->MaxRow();
2462  if (nTmp > nRow2)
2463  {
2464  nRow2 = nTmp;
2465  bHiddenEdge = true;
2466  }
2467 
2468  if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
2469  {
2470  // only along the edges
2471  PaintArea( nCol1, nRow1, nCol2, nRow1, ScUpdateMode::Marks );
2472  PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, ScUpdateMode::Marks );
2473  PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, ScUpdateMode::Marks );
2474  PaintArea( nCol1, nRow2, nCol2, nRow2, ScUpdateMode::Marks );
2475  }
2476  else // all in one
2477  PaintArea( nCol1, nRow1, nCol2, nRow2, ScUpdateMode::Marks );
2478  }
2479 }
2480 
2481 void ScTabView::PaintRangeFinder( long nNumber )
2482 {
2483  ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
2484  if (pHdl)
2485  {
2486  ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
2487  if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
2488  {
2489  SCTAB nTab = aViewData.GetTabNo();
2490  sal_uInt16 nCount = static_cast<sal_uInt16>(pRangeFinder->Count());
2491 
2492  if (nNumber < 0)
2493  {
2494  for (sal_uInt16 i=0; i<nCount; i++)
2495  PaintRangeFinderEntry(&pRangeFinder->GetObject(i),nTab);
2496  }
2497  else
2498  {
2499  sal_uInt16 idx = nNumber;
2500  if (idx < nCount)
2501  PaintRangeFinderEntry(&pRangeFinder->GetObject(idx),nTab);
2502  }
2503  }
2504  }
2505 }
2506 
2507 // for chart data selection
2508 
2509 void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
2510 {
2511  maHighlightRanges.emplace_back( rRange, rColor );
2512 
2513  SCTAB nTab = aViewData.GetTabNo();
2514  if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
2515  PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
2516  rRange.aEnd.Col(), rRange.aEnd.Row(), ScUpdateMode::Marks );
2517 }
2518 
2520 {
2521  SCTAB nTab = aViewData.GetTabNo();
2522  for (ScHighlightEntry const & rEntry : maHighlightRanges)
2523  {
2524  ScRange aRange = rEntry.aRef;
2525  if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
2526  PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
2527  aRange.aEnd.Col(), aRange.aEnd.Row(), ScUpdateMode::Marks );
2528  }
2529 
2530  maHighlightRanges.clear();
2531 }
2532 
2534  const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
2535 {
2536  ClearHighlightRanges();
2538  size_t nSize = 0;
2539  size_t nIndex = 0;
2540  std::vector<ReferenceMark> aReferenceMarks( nSize );
2541 
2542  for (chart2::data::HighlightedRange const & rHighlightedRange : rHilightRanges)
2543  {
2544  Color aSelColor(rHighlightedRange.PreferredColor);
2545  ScRangeList aRangeList;
2546  ScDocument& rDoc = aViewData.GetDocShell()->GetDocument();
2548  aRangeList, rHighlightedRange.RangeRepresentation, &rDoc, rDoc.GetAddressConvention(), sep ))
2549  {
2550  size_t nListSize = aRangeList.size();
2551  nSize += nListSize;
2552  aReferenceMarks.resize(nSize);
2553 
2554  for ( size_t j = 0; j < nListSize; ++j )
2555  {
2556  ScRange& p = aRangeList[j];
2557  ScRange aTargetRange;
2558  if( rHighlightedRange.Index == - 1 )
2559  {
2560  aTargetRange = p;
2561  AddHighlightRange( aTargetRange, aSelColor );
2562  }
2563  else
2564  {
2565  aTargetRange = lcl_getSubRangeByIndex( p, rHighlightedRange.Index );
2566  AddHighlightRange( aTargetRange, aSelColor );
2567  }
2568 
2569  if ( comphelper::LibreOfficeKit::isActive() && aViewData.GetViewShell() )
2570  {
2571  aTargetRange.PutInOrder();
2572 
2573  long nX1 = aTargetRange.aStart.Col();
2574  long nX2 = aTargetRange.aEnd.Col();
2575  long nY1 = aTargetRange.aStart.Row();
2576  long nY2 = aTargetRange.aEnd.Row();
2577  long nTab = aTargetRange.aStart.Tab();
2578 
2579  aReferenceMarks[nIndex++] = ScInputHandler::GetReferenceMark( aViewData, aViewData.GetDocShell(),
2580  nX1, nX2, nY1, nY2,
2581  nTab, aSelColor );
2582  }
2583  }
2584  }
2585  }
2586 
2587  if ( comphelper::LibreOfficeKit::isActive() && aViewData.GetViewShell() )
2588  ScInputHandler::SendReferenceMarks( aViewData.GetViewShell(), aReferenceMarks );
2589 }
2590 
2591 void ScTabView::DoDPFieldPopup(OUString const & rPivotTableName, sal_Int32 nDimensionIndex, Point aPoint, Size aSize)
2592 {
2593  ScDocument& rDocument = aViewData.GetDocShell()->GetDocument();
2594  ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
2595 
2596  if (!pWin)
2597  return;
2598 
2599  ScDPCollection* pDPCollection = rDocument.GetDPCollection();
2600  ScDPObject* pDPObject = pDPCollection->GetByName(rPivotTableName);
2601  if (!pDPObject)
2602  return;
2603 
2604  pDPObject->BuildAllDimensionMembers();
2605 
2606  Point aScreenPoint = pWin->OutputToScreenPixel(pWin->LogicToPixel(aPoint));
2607  Size aScreenSize = pWin->LogicToPixel(aSize);
2608 
2609  pWin->DPLaunchFieldPopupMenu(aScreenPoint, aScreenSize, nDimensionIndex, pDPObject);
2610 }
2611 
2612 // PaintGrid - repaint data range
2613 
2615 {
2616  for (sal_uInt16 i = 0; i < 4; i++)
2617  {
2618  if (pGridWin[i] && pGridWin[i]->IsVisible())
2619  pGridWin[i]->Invalidate();
2620  }
2621 }
2622 
2623 // PaintTop - repaint top control elements
2624 
2626 {
2627  for (sal_uInt16 i = 0; i < 2; i++)
2628  {
2629  if (pColBar[i])
2630  pColBar[i]->Invalidate();
2631  if (pColOutline[i])
2632  pColOutline[i]->Invalidate();
2633  }
2634 }
2635 
2637 {
2638  for (sal_uInt16 i = 0; i < 4; i++)
2639  {
2640  if(pGridWin[i] && pGridWin[i]->IsVisible())
2641  pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
2642  }
2643 }
2644 
2645 void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
2646 {
2647  // pixel position of the left edge
2648 
2649  if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
2650  nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
2651  aViewData.RecalcPixPos();
2652 
2653  // adjust freeze (UpdateFixX resets HSplitPos)
2654 
2655  if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
2656  if (aViewData.UpdateFixX())
2657  RepeatResize();
2658 
2659  // paint
2660 
2661  if (nStartCol>0)
2662  --nStartCol;
2663 
2664  ScDocument* pDoc = aViewData.GetDocument();
2665  bool bLayoutRTL = pDoc->IsLayoutRTL( aViewData.GetTabNo() );
2666  long nLayoutSign = bLayoutRTL ? -1 : 1;
2667 
2668  for (sal_uInt16 i = 0; i < 2; i++)
2669  {
2670  ScHSplitPos eWhich = ScHSplitPos(i);
2671  if (pColBar[eWhich])
2672  {
2673  Size aWinSize = pColBar[eWhich]->GetSizePixel();
2674  long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
2675  long nEndX;
2676  if (nEndCol >= pDoc->MaxCol())
2677  nEndX = nStartX + (bLayoutRTL ? 0 : ( aWinSize.Width()-1 ));
2678  else
2679  nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
2680  pColBar[eWhich]->Invalidate(
2681  tools::Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
2682  }
2683  if (pColOutline[eWhich])
2684  pColOutline[eWhich]->Invalidate();
2685  }
2686 }
2687 
2688 // PaintLeft - repaint left control elements
2689 
2691 {
2692  for (sal_uInt16 i = 0; i < 2; i++)
2693  {
2694  if (pRowBar[i])
2695  pRowBar[i]->Invalidate();
2696  if (pRowOutline[i])
2697  pRowOutline[i]->Invalidate();
2698  }
2699 }
2700 
2701 void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
2702 {
2703  // pixel position of the upper edge
2704 
2705  if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
2706  nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
2707  aViewData.RecalcPixPos();
2708 
2709  // adjust freeze (UpdateFixY reset VSplitPos)
2710 
2711  if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
2712  if (aViewData.UpdateFixY())
2713  RepeatResize();
2714 
2715  // paint
2716 
2717  if (nStartRow>0)
2718  --nStartRow;
2719 
2720  ScDocument* pDoc = aViewData.GetDocument();
2721  for (sal_uInt16 i = 0; i < 2; i++)
2722  {
2723  ScVSplitPos eWhich = ScVSplitPos(i);
2724  if (pRowBar[eWhich])
2725  {
2726  Size aWinSize = pRowBar[eWhich]->GetSizePixel();
2727  long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
2728  long nEndY;
2729  if (nEndRow >= pDoc->MaxRow())
2730  nEndY = nStartY + aWinSize.Height() - 1;
2731  else
2732  nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
2733  pRowBar[eWhich]->Invalidate(
2734  tools::Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
2735  }
2736  if (pRowOutline[eWhich])
2737  pRowOutline[eWhich]->Invalidate();
2738  }
2739 }
2740 
2742 {
2743  bool bRet = false;
2744  ScDocument* pDoc = aViewData.GetDocument();
2745  SCTAB nTab = aViewData.GetTabNo();
2746  if (!pDoc->HasTable(nTab)) // sheet is deleted?
2747  {
2748  SCTAB nCount = pDoc->GetTableCount();
2749  aViewData.SetTabNo(nCount-1);
2750  bRet = true;
2751  }
2752  pTabControl->UpdateStatus(); // true = active
2753  return bRet;
2754 }
2755 
2757 {
2758  // called after changes that require the PPT values to be recalculated
2759  // (currently from detective operations)
2760 
2761  double nOldX = aViewData.GetPPTX();
2762  double nOldY = aViewData.GetPPTY();
2763 
2764  aViewData.RefreshZoom(); // pre-calculate new PPT values
2765 
2766  bool bChangedX = ( aViewData.GetPPTX() != nOldX );
2767  bool bChangedY = ( aViewData.GetPPTY() != nOldY );
2768  if ( bChangedX || bChangedY )
2769  {
2770  // call view SetZoom (including draw scale, split update etc)
2771  // and paint only if values changed
2772 
2773  Fraction aZoomX = aViewData.GetZoomX();
2774  Fraction aZoomY = aViewData.GetZoomY();
2775  SetZoom( aZoomX, aZoomY, false );
2776 
2777  PaintGrid();
2778  if (bChangedX)
2779  PaintTop();
2780  if (bChangedY)
2781  PaintLeft();
2782  }
2783 }
2784 
2785 void ScTabView::ActivateView( bool bActivate, bool bFirst )
2786 {
2787  if ( bActivate == aViewData.IsActive() && !bFirst )
2788  {
2789  // no assertion anymore - occurs when previously in Drag&Drop switching over
2790  // to another document
2791  return;
2792  }
2793 
2794  // is only called for MDI-(De)Activate
2795  // aViewData.Activate behind due to cursor show for KillEditView
2796  // don't delete selection - if Activate(false) is set in ViewData,
2797  // then the selection is not displayed
2798 
2799  if (!bActivate)
2800  {
2801  ScModule* pScMod = SC_MOD();
2802  bool bRefMode = pScMod->IsFormulaMode();
2803 
2804  // don't cancel reference input, to allow reference
2805  // to other document
2806 
2807  if (!bRefMode)
2808  {
2809  // pass view to GetInputHdl, this view may not be current anymore
2810  ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2811  if (pHdl)
2812  pHdl->EnterHandler();
2813  }
2814  }
2815 
2816  PaintExtras();
2817 
2818  aViewData.Activate(bActivate);
2819 
2820  PaintBlock(false); // repaint, selection after active status
2821 
2822  if (!bActivate)
2823  HideAllCursors(); // Cursor
2824  else if (!bFirst)
2825  ShowAllCursors();
2826 
2827  if (bActivate)
2828  {
2829  if ( bFirst )
2830  {
2831  ScSplitPos eWin = aViewData.GetActivePart();
2832  OSL_ENSURE( pGridWin[eWin], "Corrupted document, not all SplitPos in GridWin" );
2833  if ( !pGridWin[eWin] )
2834  {
2835  eWin = SC_SPLIT_BOTTOMLEFT;
2836  if ( !pGridWin[eWin] )
2837  {
2838  short i;
2839  for ( i=0; i<4; i++ )
2840  {
2841  if ( pGridWin[i] )
2842  {
2843  eWin = static_cast<ScSplitPos>(i);
2844  break; // for
2845  }
2846  }
2847  OSL_ENSURE( i<4, "and BOOM" );
2848  }
2849  aViewData.SetActivePart( eWin );
2850  }
2851  }
2852  // do not call GrabFocus from here!
2853  // if the document is processed, then Sfx calls GrabFocus in the window of the shell.
2854  // if it is a mail body for instance, then it can't get the focus
2855  UpdateInputContext();
2856  }
2857  else
2858  pGridWin[aViewData.GetActivePart()]->ClickExtern();
2859 }
2860 
2862 {
2863  ScSplitPos eOld = aViewData.GetActivePart();
2864  if ( eOld != eWhich )
2865  {
2866  bInActivatePart = true;
2867 
2868  bool bRefMode = SC_MOD()->IsFormulaMode();
2869 
2870  // the HasEditView call during SetCursor would fail otherwise
2871  if ( aViewData.HasEditView(eOld) && !bRefMode )
2872  UpdateInputLine();
2873 
2874  ScHSplitPos eOldH = WhichH(eOld);
2875  ScVSplitPos eOldV = WhichV(eOld);
2876  ScHSplitPos eNewH = WhichH(eWhich);
2877  ScVSplitPos eNewV = WhichV(eWhich);
2878  bool bTopCap = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
2879  bool bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
2880 
2881  bool bFocus = pGridWin[eOld]->HasFocus();
2882  bool bCapture = pGridWin[eOld]->IsMouseCaptured();
2883  if (bCapture)
2884  pGridWin[eOld]->ReleaseMouse();
2885  pGridWin[eOld]->ClickExtern();
2886  pGridWin[eOld]->HideCursor();
2887  pGridWin[eWhich]->HideCursor();
2888  aViewData.SetActivePart( eWhich );
2889 
2890  ScTabViewShell* pShell = aViewData.GetViewShell();
2891  pShell->WindowChanged();
2892 
2893  pSelEngine->SetWindow(pGridWin[eWhich]);
2894  pSelEngine->SetWhich(eWhich);
2895  pSelEngine->SetVisibleArea( tools::Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
2896 
2897  pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
2898 
2899  if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
2900  {
2901  // tracking instead of CaptureMouse, so it can be cancelled cleanly
2902  // (SelectionEngine calls CaptureMouse for SetWindow)
2904  pGridWin[eWhich]->ReleaseMouse();
2905  pGridWin[eWhich]->StartTracking();
2906  }
2907 
2908  if ( bTopCap && pColBar[eNewH] )
2909  {
2910  pColBar[eOldH]->SetIgnoreMove(true);
2911  pColBar[eNewH]->SetIgnoreMove(false);
2912  pHdrSelEng->SetWindow( pColBar[eNewH] );
2913  long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
2914  pHdrSelEng->SetVisibleArea( tools::Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
2915  pColBar[eNewH]->CaptureMouse();
2916  }
2917  if ( bLeftCap && pRowBar[eNewV] )
2918  {
2919  pRowBar[eOldV]->SetIgnoreMove(true);
2920  pRowBar[eNewV]->SetIgnoreMove(false);
2921  pHdrSelEng->SetWindow( pRowBar[eNewV] );
2922  long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
2923  pHdrSelEng->SetVisibleArea( tools::Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
2924  pRowBar[eNewV]->CaptureMouse();
2925  }
2926  aHdrFunc.SetWhich(eWhich);
2927 
2928  pGridWin[eOld]->ShowCursor();
2929  pGridWin[eWhich]->ShowCursor();
2930 
2931  SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
2932  bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
2933 
2934  // don't switch ViewShell's active window during RefInput, because the focus
2935  // might change, and subsequent SetReference calls wouldn't find the right EditView
2936  if ( !bRefMode && !bOleActive )
2937  aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
2938 
2939  if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
2940  {
2941  // GrabFocus only if previously the other GridWindow had the focus
2942  // (for instance due to search and replace)
2943  pGridWin[eWhich]->GrabFocus();
2944  }
2945 
2946  bInActivatePart = false;
2947  }
2948 }
2949 
2951 {
2952  for (VclPtr<ScGridWindow> & pWin : pGridWin)
2953  {
2954  if (pWin)
2955  pWin->ClickExtern();
2956  }
2957 }
2958 
2960 {
2961  ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
2962  if (pWin)
2963  pWin->UpdateInputContext();
2964 
2965  if (pTabControl)
2966  pTabControl->UpdateInputContext();
2967 }
2968 
2969 // GetGridWidth - width of an output range (for ViewData)
2970 
2972 {
2973  ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2974  if (pGridWin[eGridWhich])
2975  return pGridWin[eGridWhich]->GetSizePixel().Width();
2976  else
2977  return 0;
2978 }
2979 
2980 // GetGridHeight - height of an output range (for ViewData)
2981 
2983 {
2984  ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2985  if (pGridWin[eGridWhich])
2986  return pGridWin[eGridWhich]->GetSizePixel().Height();
2987  else
2988  return 0;
2989 }
2990 
2992 {
2993  SC_MOD()->InputEnterHandler();
2994 }
2995 
2997 {
2998  ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2999  if (pHdl)
3000  pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
3001 
3002  UpdateFixPos();
3003 
3004  UpdateScrollBars();
3005 
3006  // VisArea...
3007  // AW: Discussed with NN if there is a reason that new map mode was only set for one window,
3008  // but is not. Setting only on one window causes the first repaint to have the old mapMode
3009  // in three of four views, so the overlay will save the wrong content e.g. when zooming out.
3010  // Changing to setting map mode at all windows.
3011 
3012  for (sal_uInt32 i = 0; i < 4; i++)
3013  {
3014  if (pGridWin[i])
3015  pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
3016  }
3017 
3018  SetNewVisArea();
3019 
3020  InterpretVisible(); // have everything calculated before painting
3021 
3022  SfxBindings& rBindings = aViewData.GetBindings();
3023  rBindings.Invalidate( SID_ATTR_ZOOM );
3024  rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
3025 
3026  HideNoteMarker();
3027 
3028  // To not change too much, use pWin here
3029  ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
3030 
3031  if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
3032  {
3033  // flush OverlayManager before changing the MapMode
3034  pWin->flushOverlayManager();
3035 
3036  // make sure the EditView's position and size are updated
3037  // with the right (logic, not drawing) MapMode
3038  pWin->SetMapMode( aViewData.GetLogicMode() );
3039  UpdateEditView();
3040  }
3041 }
3042 
3044 {
3045  for (sal_uInt16 i = 0; i < 4; i++)
3046  {
3047  if (pGridWin[i] && pGridWin[i]->IsVisible())
3048  pGridWin[i]->CheckNeedsRepaint();
3049  }
3050 }
3051 
3053 {
3054  for (VclPtr<ScGridWindow> & pWin : pGridWin)
3055  {
3056  if (pWin && pWin->IsVisible() && pWin->NeedsRepaint())
3057  return true;
3058  }
3059  return false;
3060 }
3061 
3062 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::shared_ptr< SfxDialogController > & GetController()
void FindNextUnprot(bool bShift, bool bInSelection)
Definition: tabview3.cxx:1526
SC_DLLPUBLIC bool GetPrintArea(SCTAB nTab, SCCOL &rEndCol, SCROW &rEndRow, bool bNotes=true) const
Definition: documen2.cxx:573
static bool lcl_IsScSimpleRefDlgOpen(SfxViewFrame *pViewFrm)
Definition: tabview3.cxx:447
void TestHintWindow()
Definition: tabview3.cxx:768
SfxViewFrame * GetViewFrame() const
long Width() const
void SetPos(const Point &rPoint)
SC_DLLPUBLIC ScDPObject * GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: documen3.cxx:358
virtual bool get_extents_relative_to(Widget &rRelative, int &x, int &y, int &width, int &height)=0
void DoChartSelection(const css::uno::Sequence< css::chart2::data::HighlightedRange > &rHilightRanges)
Definition: tabview3.cxx:2533
void MarkDataArea(bool bIncludeCursor=true)
Definition: tabview3.cxx:1644
OUString GetColRowString() const
Create a human-readable string representation of the cell address.
Definition: address.cxx:2492
static weld::Window * lcl_GetCareWin(SfxViewFrame *pViewFrm)
Definition: tabview3.cxx:871
bool GetMoveSelection() const
Definition: inputopt.hxx:50
ScAddress aStart
Definition: address.hxx:500
static void notifyDocumentSizeChanged(SfxViewShell const *pThisView, const OString &rPayload, vcl::ITiledRenderable *pDoc, bool bInvalidateAll=true)
long GetHeight() const
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
SfxChildWindow * GetChildWindow(sal_uInt16)
ScVSplitPos WhichV(ScSplitPos ePos)
Definition: viewdata.hxx:714
constexpr sal_uInt16 KEY_MOD1
void RemoveWindowFromForeignEditView(SfxViewShell *pViewShell, ScSplitPos eWhich)
Definition: tabview3.cxx:2029
void flushOverlayManager()
Definition: gridwin.cxx:6752
bool SetObjArea(const tools::Rectangle &)
MapMode GetDrawMapMode(bool bForce=false)
MapMode for the drawinglayer objects.
Definition: gridwin3.cxx:246
SCROW Row() const
Definition: address.hxx:262
ScVSplitPos
Definition: viewdata.hxx:47
std::unique_ptr< ContentProperties > pData
void SetTabProtectionSymbol(SCTAB nTab, const bool bProtect)
Definition: tabview3.cxx:517
void UpdateInputContext()
Definition: tabview3.cxx:2959
bool IsObjectInPlaceActive() const
long Height() const
void CursorPosChanged()
Definition: tabview3.cxx:619
bool PaintExtras()
Definition: tabview3.cxx:2741
void MarkRange(const ScRange &rRange, bool bSetCursor=true, bool bContinue=false)
Definition: tabview3.cxx:1675
sheet protection state container
void ResetMark()
Definition: markdata.cxx:85
void PaintRangeFinder(long nNumber)
Definition: tabview3.cxx:2481
ScHSplitPos WhichH(ScSplitPos ePos)
Definition: viewdata.hxx:708
void ShowCursor(bool bGotoCursor=true, bool bForceVisCursor=true, bool bActivate=false)
SC_DLLPUBLIC ScDPCollection * GetDPCollection()
Definition: documen3.cxx:346
ScFollowMode
Screen behavior related to cursor movements.
Definition: viewdata.hxx:53
CALCNOTESBACKGROUND
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:387
void Remove(SfxViewShell *pViewShell, ScSplitPos eWhich)
Definition: tabview3.cxx:107
bool IsShift() const
bool IsOver(const tools::Rectangle &rRect) const
const sal_uInt8 SC_CLIPMARK_SIZE
Definition: fillinfo.hxx:52
bool HasEditView(ScSplitPos eWhich) const
Definition: viewdata.hxx:569
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
sal_uInt16 GetCode() const
SC_DLLPUBLIC SCROW FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4478
void PaintGrid()
Definition: tabview3.cxx:2614
void Unmark()
Definition: tabview3.cxx:1711
ScAddress aEnd
Definition: address.hxx:501
SC_DLLPUBLIC SCROW LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:4486
static void UpdateInputLine()
Definition: tabview3.cxx:2991
void RemoveHintWindow()
Definition: tabview3.cxx:865
bool NeedsRepaint()
Definition: tabview3.cxx:3052
Size GetOrigObjSize(MapMode const *pTargetMapMode=nullptr) const
void AddHighlightRange(const ScRange &rRange, const Color &rColor)
Definition: tabview3.cxx:2509
bool HasSelectionList() const
Returns true, if the validation cell will show a selection list.
Definition: validat.cxx:672
css::uno::Reference< css::frame::XModel > GetModel() const
void Invalidate(sal_uInt16 nId)
static void forEachOtherView(ViewShellType *pThisViewShell, FunctionType f)
float x
SC_DLLPUBLIC void SetCursor(SCCOL nPosX, SCROW nPosY, bool bNew=false)
Definition: tabview3.cxx:358
SC_DLLPUBLIC void SetVisible(SCTAB nTab, bool bVisible)
Definition: document.cxx:901
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:475
void SetMapMode()
void PaintRangeFinderEntry(const ScRangeFindData *pData, SCTAB nTab)
Update marks for a selected Range.
Definition: tabview3.cxx:2420
constexpr sal_uInt16 KEY_UP
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4164
ScSplitPos
Definition: viewdata.hxx:45
SC_DLLPUBLIC void MoveCursorAbs(SCCOL nCurX, SCROW nCurY, ScFollowMode eMode, bool bShift, bool bControl, bool bKeepOld=false, bool bKeepSel=false)
Definition: tabview3.cxx:1178
constexpr sal_uInt16 KEY_END
void GetMarkArea(ScRange &rRange) const
Definition: markdata.cxx:112
SC_DLLPUBLIC const ScValidationData * GetValidationEntry(sal_uLong nIndex) const
Definition: documen4.cxx:871
static UITestLogger & getInstance()
void KillEditView(bool bNoPaint)
Definition: tabview3.cxx:2157
weld::Window * GetFrameWeld() const
void MoveCursorScreen(SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift)
Definition: tabview3.cxx:1357
void UpdateAutoFillMark(bool bFromPaste=false)
Definition: tabview3.cxx:183
void logEvent(const EventDescription &rDescription)
sal_uInt16 sal_Unicode
long Right() const
Reference< XController > xController
void PaintLeft()
Definition: tabview3.cxx:2690
static void notifyInvalidation(SfxViewShell const *pThisView, const OString &rPayload)
bool isOptionEnabled(Option eOption) const
void PaintLeftArea(SCROW nStartRow, SCROW nEndRow)
Definition: tabview3.cxx:2701
long GetGridWidth(ScHSplitPos eWhich)
Definition: tabview3.cxx:2971
bool IsFormulaMode()
Definition: scmod.cxx:1621
void MoveCursorEnd(SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel=false)
Definition: tabview3.cxx:1327
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:873
void UpdateInputContext()
Definition: gridwin.cxx:3373
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:314
long GetGridHeight(ScVSplitPos eWhich)
Definition: tabview3.cxx:2982
bool In(const ScRange &) const
Definition: rangelst.cxx:1089
bool IsMultiMarked() const
Definition: markdata.hxx:83
void MarkDataChanged()
Definition: tabview3.cxx:1734
void OnLibreOfficeKitTabChanged()
Definition: tabview3.cxx:2034
SfxFrame & GetFrame() const
int nCount
constexpr sal_uInt16 KEY_PAGEUP
ScInputWindow * GetInputWindow()
Definition: inputhdl.hxx:260
void libreOfficeKitViewCallback(int nType, const char *pPayload) const override
void Modifier(ScGridWindow *pWin)
Definition: tabview3.cxx:136
bool SelMouseButtonDown(const MouseEvent &rMEvt)
Definition: tabview3.cxx:1156
void UpdateFormulas(SCCOL nStartCol=-1, SCROW nStartRow=-1, SCCOL nEndCol=-1, SCROW nEndRow=-1)
Definition: tabview3.cxx:2269
void UpdateEditView()
Definition: tabview3.cxx:2134
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:191
Mode eMode
SCTAB Tab() const
Definition: address.hxx:271
SC_DLLPUBLIC void GetNextPos(SCCOL &rCol, SCROW &rRow, SCTAB nTab, SCCOL nMovX, SCROW nMovY, bool bMarked, bool bUnprotected, const ScMarkData &rMark, SCCOL nTabStartCol=SC_TABSTART_NONE) const
Definition: document.cxx:6097
void ActivatePart(ScSplitPos eWhich)
Definition: tabview3.cxx:2861
bool IsInputActive()
Definition: inputwin.cxx:644
void RecalcPPT()
Definition: tabview3.cxx:2756
long Top() const
void ClearHighlightRanges()
Definition: tabview3.cxx:2519
static sal_Unicode GetNativeSymbolChar(OpCode eOp)
void ActivateView(bool bActivate, bool bFirst)
Definition: tabview3.cxx:2785
sal_uInt16 nCode
ScViewData & GetViewData()
Definition: tabview.hxx:332
void PaintTop()
Definition: tabview3.cxx:2625
void CheckNeedsRepaint()
Definition: tabview3.cxx:3043
void SelectionChanged(bool bFromPaste=false)
Definition: tabview3.cxx:522
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4717
bool HasHintWindow() const
Definition: tabview3.cxx:863
static ScSelectionTransferObj * CreateFromView(ScTabView *pSource)
Definition: seltrans.cxx:69
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:954
float y
ocSep
static ReferenceMark GetReferenceMark(ScViewData &rViewData, ScDocShell *pDocSh, long nX1, long nX2, long nY1, long nY2, long nTab, const Color &rColor)
Definition: inputhdl.cxx:431
void PaintArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScUpdateMode eMode=ScUpdateMode::All)
Definition: tabview3.cxx:2292
void UpdateLokReferenceMarks()
Definition: inputhdl.cxx:481
void SelectTabPage(const sal_uInt16 nTab)
Definition: tabview3.cxx:1779
constexpr sal_uInt16 KEY_DOWN
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALIDDATA(153)
ScDPObject * GetByName(const OUString &rName) const
Definition: dpobject.cxx:3692
SC_DLLPUBLIC void GetDataArea(SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bIncludeOld, bool bOnlyDown) const
Return the smallest area containing at least all contiguous cells having data.
Definition: document.cxx:1096
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:872
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4448
sal_uInt16 GetCurRefDlgId() const
Definition: scmod.hxx:232
bool IsMarked() const
Definition: markdata.hxx:82
void SetWindow(vcl::Window *pViewPort)
#define DBG_ASSERT(sCon, aError)
int i
void WindowChanged()
Definition: tabvwsh2.cxx:53
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:172
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:406
sal_Int16 SCCOL
Definition: types.hxx:22
constexpr sal_uInt16 KEY_HOME
void CreateAnchorHandles(SdrHdlList &rHdl, const ScAddress &rAddress)
Definition: tabview3.cxx:2636
EditEngine * GetEditEngine() const
void SetPos(const Point &rPos, const MapMode &rMode)
Definition: hintwin.cxx:162
#define SC_MOD()
Definition: scmod.hxx:253
void SetSize(const Size &rSize)
void FakeButtonUp(ScSplitPos eWhich)
Definition: tabview3.cxx:209
void EnterHandler(ScEnterMode nBlockMode=ScEnterMode::NORMAL)
Definition: inputhdl.cxx:2901
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
SC_DLLPUBLIC void SetTabNo(SCTAB nTab, bool bNew=false, bool bExtendSelection=false, bool bSameTabButMoved=false)
Definition: tabview3.cxx:1786
size_t size() const
Definition: rangelst.hxx:90
void SelectOneTable(SCTAB nTab)
Definition: markdata.cxx:189
long Bottom() const
constexpr sal_uInt16 KEY_PAGEDOWN
static bool GetRangeListFromString(ScRangeList &rRangeList, const OUString &rRangeListStr, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
Definition: rangeutl.cxx:528
virtual void ViewShellChanged()=0
Size GetOutputSizePixel() const
PaintArea
bool In(const ScAddress &) const
is Address& in Range?
Definition: address.hxx:733
void MakeEditView(ScEditEngineDefaulter *pEngine, SCCOL nCol, SCROW nRow)
Definition: tabview3.cxx:2077
void DoDPFieldPopup(OUString const &rPivotTableName, sal_Int32 nDimensionIndex, Point aPoint, Size aSize)
Definition: tabview3.cxx:2591
void GrabFocus()
SfxViewShell * GetViewShell() const
virtual bool isProtected() const override
void InvalidateAttribs()
Definition: tabview3.cxx:247
const long LONG_MAX
SCCOL Col() const
Definition: address.hxx:267
ScSelectionTransferObj * GetSelectionTransfer() const
Definition: scmod.hxx:155
void Apply(SfxViewShell *pViewShell, ScSplitPos eWhich)
Definition: tabview3.cxx:114
const sal_uInt16 idx[]
constexpr sal_uInt16 KEY_RIGHT
void Add(SfxViewShell *pViewShell, ScSplitPos eWhich)
Definition: tabview3.cxx:102
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
void ClickCursor(SCCOL nPosX, SCROW nPosY, bool bControl)
Definition: tabview3.cxx:158
SdrOle2Obj * GetDrawObj()
Definition: client.cxx:50
sal_uLong Count() const
Definition: rfindlst.hxx:51
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: document.hxx:877
void SetEditEngine(EditEngine *pEditEngine)
ScHSplitPos
Definition: viewdata.hxx:46
void SkipOverlapped(SCCOL &rCol, SCROW &rRow, SCTAB nTab) const
Definition: document.cxx:5724
ScRange aRef
Definition: rfindlst.hxx:31
void MarkRows()
Definition: tabview3.cxx:1581
sal_Int32 SCROW
Definition: types.hxx:18
const vcl::KeyCode & GetKeyCode() const
SfxViewShell * GetViewShell() const
SC_DLLPUBLIC void PutInOrder()
Definition: address.cxx:1577
void SelectionChanged()
Definition: viewuno.cxx:1644
void MoveCursorEnter(bool bShift)
Definition: tabview3.cxx:1394
bool HasChildWindow(sal_uInt16)
bool IsShift() const
SfxInPlaceClient * GetIPClient() const
bool ValidRow(SCROW nRow) const
Definition: document.hxx:876
void HideAllCursors()
Definition: tabview3.cxx:215
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
ScUpdateMode
Definition: viewutil.hxx:39
void MoveCursorPage(SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel=false)
Definition: tabview3.cxx:1311
void CheckSelectionTransfer()
Definition: tabview3.cxx:463
void AddWindowToForeignEditView(SfxViewShell *pViewShell, ScSplitPos eWhich)
Definition: tabview3.cxx:2024
void MoveCursorArea(SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel=false)
Definition: tabview3.cxx:1319
css::uno::Reference< css::frame::XController > GetController() const
void MoveCursorRel(SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel=false)
Definition: tabview3.cxx:1253
bool GetInput(OUString &rTitle, OUString &rMsg) const
Definition: validat.hxx:108
const tools::Rectangle & GetObjArea() const
bool PrepareClose(bool bUI=true)
static void SendReferenceMarks(const SfxViewShell *pViewShell, const std::vector< ReferenceMark > &rReferenceMarks)
Definition: inputhdl.cxx:268
bool IsMod1() const
sal_uInt16 GetMoveDir() const
Definition: inputopt.hxx:48
void * p
void ZoomChanged()
Definition: tabview3.cxx:2996
const SCROW MAXTILEDROW
Definition: address.hxx:76
long Left() const
void AlignToCursor(SCCOL nCurX, SCROW nCurY, ScFollowMode eMode, const ScSplitPos *pWhich=nullptr)
Definition: tabview3.cxx:904
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:994
SC_DLLPUBLIC ScTableProtection * GetTabProtection(SCTAB nTab) const
Definition: documen3.cxx:1880
bool IsVisible() const
void HideListBox()
Definition: tabview3.cxx:2950
void ShowCursor()
Definition: tabview3.cxx:241
void SetSelectionTransfer(ScSelectionTransferObj *pNew)
Definition: scmod.cxx:650
void SelectNextTab(short nDir, bool bExtendSelection)
Definition: tabview3.cxx:1741
sal_uInt32 GetValue() const
ScRangeFindData & GetObject(sal_uLong nIndex)
Definition: rfindlst.hxx:54
Size GetSizePixel() const
Definition: hintwin.cxx:155
SC_DLLPUBLIC bool IsVisible(SCTAB nTab) const
Definition: document.cxx:908
#define SAL_WARN(area, stream)
void DPLaunchFieldPopupMenu(const Point &rScrPos, const Size &rScrSize, const ScAddress &rPos, ScDPObject *pDPObj)
Definition: gridwin2.cxx:436
SC_DLLPUBLIC bool GetMatrixFormulaRange(const ScAddress &rCellPos, ScRange &rMatrix)
Definition: document.cxx:5431
const SCCOL SC_TABSTART_NONE
Definition: address.hxx:89
bool IsRefInputMode() const
Definition: tabvwsha.cxx:579
constexpr sal_uInt16 KEY_LEFT
Point OutputToScreenPixel(const Point &rPos) const
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:168
tools::Rectangle GetInvalidateRect() const
long getHeight() const
const OUString & GetDocName() const
Definition: rfindlst.hxx:58
bool GetTableSelect(SCTAB nTab) const
Definition: markdata.cxx:184
bool IsRefDialogOpen()
Definition: scmod.cxx:1605
std::map< OUString, OUString > aParameters
void PaintTopArea(SCCOL nStartCol, SCCOL nEndCol)
Definition: tabview3.cxx:2645
constexpr sal_uInt16 KEY_SHIFT
void BuildAllDimensionMembers()
Definition: dpobject.cxx:960
ScRangeFindList * GetRangeFindList()
Definition: inputhdl.hxx:249
void MarkColumns()
Definition: tabview3.cxx:1553
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4123
long getWidth() const
const ScInputHandler * GetInputHandler() const
Definition: tabvwsh.hxx:233
void MarkMatrixFormula()
Definition: tabview3.cxx:1664
SC_DLLPUBLIC void CellContentChanged()
Definition: tabview3.cxx:503
bool ValidTab(SCTAB nTab)
Definition: address.hxx:105
void GetEditView(ScSplitPos eWhich, EditView *&rViewPtr, SCCOL &rCol, SCROW &rRow)
Definition: viewdata.cxx:2225
sal_Int16 SCTAB
Definition: types.hxx:23
virtual Size getDocumentSize() override
Definition: docuno.cxx:650
bool MoveCursorKeyInput(const KeyEvent &rKeyEvent)
Definition: tabview3.cxx:1451
void ShowAllCursors()
Definition: tabview3.cxx:229
void SetRefScale(const Fraction &rX, const Fraction &rY)
Definition: inputhdl.cxx:825
bool IsMod1() const
virtual const tools::Rectangle & GetLogicRect() const override
void SetMarkData(const ScMarkData &rNew)
Definition: tabview3.cxx:1725
bool IsMod2() const
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo