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