LibreOffice Module sc (master)  1
viewdata.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 <scitems.hxx>
21 #include <editeng/eeitem.hxx>
22 #include <o3tl/safeint.hxx>
23 #include <sfx2/lokhelper.hxx>
24 #include <sfx2/viewfrm.hxx>
25 #include <editeng/adjustitem.hxx>
26 #include <editeng/brushitem.hxx>
27 #include <svtools/colorcfg.hxx>
28 #include <editeng/editview.hxx>
29 #include <editeng/editstat.hxx>
30 #include <editeng/outliner.hxx>
31 #include <editeng/unolingu.hxx>
32 #include <editeng/justifyitem.hxx>
33 
34 #include <vcl/svapp.hxx>
35 #include <rtl/math.hxx>
36 #include <sal/log.hxx>
37 
38 #include <viewdata.hxx>
39 #include <docoptio.hxx>
40 #include <scmod.hxx>
41 #include <global.hxx>
42 #include <document.hxx>
43 #include <drwlayer.hxx>
44 #include <attrib.hxx>
45 #include <tabview.hxx>
46 #include <tabvwsh.hxx>
47 #include <docsh.hxx>
48 #include <patattr.hxx>
49 #include <editutil.hxx>
50 #include <scextopt.hxx>
51 #include <miscuno.hxx>
52 #include <unonames.hxx>
53 #include <inputopt.hxx>
54 #include <viewutil.hxx>
55 #include <markdata.hxx>
57 #include <gridwin.hxx>
58 #include <comphelper/flagguard.hxx>
59 #include <comphelper/lok.hxx>
61 #include <comphelper/string.hxx>
62 
63 #include <vcl/uitest/logger.hxx>
65 
66 #include <com/sun/star/container/XNameContainer.hpp>
67 #include <com/sun/star/document/NamedPropertyValues.hpp>
68 
69 using namespace com::sun::star;
70 
71 #define SC_GROWY_SMALL_EXTRA 100
72 #define SC_GROWY_BIG_EXTRA 200
73 
74 #define TAG_TABBARWIDTH "tw:"
75 
76 namespace {
77 
78 void lcl_LOKRemoveWindow(ScTabViewShell* pTabViewShell, ScSplitPos eWhich)
79 {
81  {
82  auto lRemoveWindows =
83  [pTabViewShell, eWhich] (ScTabViewShell* pOtherViewShell)
84  { pOtherViewShell->RemoveWindowFromForeignEditView(pTabViewShell, eWhich); };
85 
86  SfxLokHelper::forEachOtherView(pTabViewShell, lRemoveWindows);
87  }
88 }
89 
90 } // anonymous namespace
91 
92 namespace {
93 
94 void collectUIInformation(const std::map<OUString, OUString>& aParameters, const OUString& rAction)
95 {
96  EventDescription aDescription;
97  aDescription.aID = "grid_window";
98  aDescription.aAction = rAction;
99  aDescription.aParameters = aParameters;
100  aDescription.aParent = "MainWindow";
101  aDescription.aKeyWord = "ScGridWinUIObject";
102 
103  UITestLogger::getInstance().logEvent(aDescription);
104 }
105 }
106 
108 
109 bool ScPositionHelper::Comp::operator() (const value_type& rValue1, const value_type& rValue2) const
110 {
111  if (rValue1.first == null || rValue2.first == null)
112  {
113  return rValue1.second < rValue2.second;
114  }
115  else
116  {
117  return rValue1.first < rValue2.first;
118  }
119 }
120 
122  : MAX_INDEX(bColumn ? (pDoc ? pDoc->MaxCol() : -1) : MAXTILEDROW)
123 {
124  mData.insert(std::make_pair(-1, 0));
125 }
126 
127 void ScPositionHelper::setDocument(ScDocument *pDoc, bool bColumn)
128 {
129  MAX_INDEX = bColumn ? pDoc->MaxCol() : MAXTILEDROW;
130 }
131 
132 void ScPositionHelper::insert(index_type nIndex, long nPos)
133 {
134  if (nIndex < 0) return;
135  SAL_INFO("sc.lok.poshelper", "ScPositionHelper::insert: nIndex: "
136  << nIndex << ", nPos: " << nPos << ", size: " << mData.size());
137  value_type aValue = std::make_pair(nIndex, nPos);
138  mData.erase(aValue);
139  mData.insert(aValue);
140  SAL_INFO("sc.lok.poshelper",
141  "ScPositionHelper::insert: after insert: size: " << mData.size());
142 }
143 
145 {
146  if (nIndex < 0)
147  return;
148  SAL_INFO("sc.lok.poshelper", "ScPositionHelper::remove: nIndex: " << nIndex
149  << ", size: " << mData.size());
150  auto it = mData.find(std::make_pair(nIndex, 0));
151  if (it == mData.end()) return;
152  mData.erase(it);
153  SAL_INFO("sc.lok.poshelper",
154  "ScPositionHelper::remove: after erase: size: " << mData.size());
155 }
156 
158 {
159  SAL_INFO("sc.lok.poshelper", "ScPositionHelper::invalidate: nIndex: " << nIndex);
160  if (nIndex < 0)
161  {
162  mData.clear();
163  mData.insert(std::make_pair(-1, 0));
164  }
165  else
166  {
167  auto it = mData.lower_bound(std::make_pair(nIndex, 0));
168  mData.erase(it, mData.end());
169  }
170 }
171 
173 {
174  SAL_INFO("sc.lok.poshelper", "ScPositionHelper::invalidate: nPos: " << nPos);
175  if (nPos <= 0)
176  {
177  mData.clear();
178  mData.insert(std::make_pair(-1, 0));
179  }
180  else
181  {
182  auto it = mData.lower_bound(std::make_pair(null, nPos));
183  mData.erase(it, mData.end());
184  }
185 }
186 
189 {
190  SAL_INFO("sc.lok.poshelper",
191  "ScPositionHelper::getNearest: nIndex: " << nIndex << ", size: " << mData.size());
192  auto posUB = mData.upper_bound(std::make_pair(nIndex, 0));
193  if (posUB == mData.begin())
194  {
195  return *posUB;
196  }
197 
198  auto posLB = std::prev(posUB);
199  // coverity[copy_paste_error : FALSE] - posUB is correct
200  if (posUB == mData.end())
201  {
202  return *posLB;
203  }
204 
205  long nDiffUB = posUB->first - nIndex;
206  long nDiffLB = posLB->first - nIndex;
207  if (nDiffUB < -nDiffLB)
208  {
209  return *posUB;
210  }
211  else
212  {
213  return *posLB;
214  }
215 }
216 
219 {
220  SAL_INFO("sc.lok.poshelper",
221  "ScPositionHelper::getNearest: nPos: " << nPos << ", size: " << mData.size());
222  auto posUB = mData.upper_bound(std::make_pair(null, nPos));
223 
224  if (posUB == mData.begin())
225  {
226  return *posUB;
227  }
228 
229  auto posLB = std::prev(posUB);
230  // coverity[copy_paste_error : FALSE] - posUB is correct
231  if (posUB == mData.end())
232  {
233  return *posLB;
234  }
235 
236  long nDiffUB = posUB->second - nPos;
237  long nDiffLB = posLB->second - nPos;
238 
239  if (nDiffUB < -nDiffLB)
240  {
241  return *posUB;
242  }
243  else
244  {
245  return *posLB;
246  }
247 }
248 
250 {
251  auto it = mData.find(std::make_pair(nIndex, 0));
252  if (it == mData.end()) return -1;
253  return it->second;
254 }
255 
256 long ScPositionHelper::computePosition(index_type nIndex, const std::function<long (index_type)>& getSizePx)
257 {
258  assert(MAX_INDEX > 0);
259  if (nIndex < 0) nIndex = 0;
260  if (nIndex > MAX_INDEX) nIndex = MAX_INDEX;
261 
262  const auto& rNearest = getNearestByIndex(nIndex);
263  index_type nStartIndex = rNearest.first;
264  long nTotalPixels = rNearest.second;
265 
266  if (nStartIndex < nIndex)
267  {
268  for (index_type nIdx = nStartIndex + 1; nIdx <= nIndex; ++nIdx)
269  {
270  nTotalPixels += getSizePx(nIdx);
271  }
272  }
273  else
274  {
275  for (index_type nIdx = nStartIndex; nIdx > nIndex; --nIdx)
276  {
277  nTotalPixels -= getSizePx(nIdx);
278  }
279  }
280  return nTotalPixels;
281 }
282 
283 ScBoundsProvider::ScBoundsProvider(const ScViewData &rView, SCTAB nT, bool bColHeader)
284  : pDoc(rView.GetDocument())
285  , nTab(nT)
286  , bColumnHeader(bColHeader)
287  , MAX_INDEX(bColHeader ? pDoc->MaxCol() : MAXTILEDROW)
288  , mfPPTX(rView.GetPPTX())
289  , mfPPTY(rView.GetPPTY())
290  , nFirstIndex(-1)
291  , nSecondIndex(-1)
292  , nFirstPositionPx(-1)
293  , nSecondPositionPx(-1)
294 {}
295 
296 void ScBoundsProvider::GetStartIndexAndPosition(SCCOL& nIndex, long& nPosition) const
297 {
299  nIndex = nFirstIndex;
300  nPosition = nFirstPositionPx;
301 }
302 
303 void ScBoundsProvider::GetEndIndexAndPosition(SCCOL& nIndex, long& nPosition) const
304 {
306  nIndex = nSecondIndex;
307  nPosition = nSecondPositionPx;
308 }
309 
310 void ScBoundsProvider::GetStartIndexAndPosition(SCROW& nIndex, long& nPosition) const
311 {
313  nIndex = nFirstIndex;
314  nPosition = nFirstPositionPx;
315 }
316 
317 void ScBoundsProvider::GetEndIndexAndPosition(SCROW& nIndex, long& nPosition) const
318 {
320  nIndex = nSecondIndex;
321  nPosition = nSecondPositionPx;
322 }
323 
325 {
326  const sal_uInt16 nSize = bColumnHeader ? pDoc->GetColWidth(nIndex, nTab) : pDoc->GetRowHeight(nIndex, nTab);
327  return ScViewData::ToPixel(nSize, bColumnHeader ? mfPPTX : mfPPTY);
328 }
329 
330 void ScBoundsProvider::GetIndexAndPos(index_type nNearestIndex, long nNearestPosition,
331  long nBound, index_type& nFoundIndex, long& nPosition,
332  bool bTowards, long nDiff)
333 {
334  if (nDiff > 0) // nBound < nNearestPosition
335  GeIndexBackwards(nNearestIndex, nNearestPosition, nBound,
336  nFoundIndex, nPosition, bTowards);
337  else
338  GetIndexTowards(nNearestIndex, nNearestPosition, nBound,
339  nFoundIndex, nPosition, bTowards);
340 }
341 
343  value_type aFirstNearest, value_type aSecondNearest,
344  long nFirstBound, long nSecondBound)
345 {
346  SAL_INFO("sc.lok.header", "BoundsProvider: nFirstBound: " << nFirstBound
347  << ", nSecondBound: " << nSecondBound);
348 
349  long nFirstDiff = aFirstNearest.second - nFirstBound;
350  long nSecondDiff = aSecondNearest.second - nSecondBound;
351  SAL_INFO("sc.lok.header", "BoundsProvider: rTopNearest: index: " << aFirstNearest.first
352  << ", pos: " << aFirstNearest.second << ", diff: " << nFirstDiff);
353  SAL_INFO("sc.lok.header", "BoundsProvider: rBottomNearest: index: " << aSecondNearest.first
354  << ", pos: " << aSecondNearest.second << ", diff: " << nSecondDiff);
355 
356  bool bReverse = (std::abs(nFirstDiff) >= std::abs(nSecondDiff));
357 
358  if(bReverse)
359  {
360  std::swap(aFirstNearest, aSecondNearest);
361  std::swap(nFirstBound, nSecondBound);
362  std::swap(nFirstDiff, nSecondDiff);
363  }
364 
365  index_type nNearestIndex = aFirstNearest.first;
366  long nNearestPosition = aFirstNearest.second;
367  SAL_INFO("sc.lok.header", "BoundsProvider: nearest to first bound: nNearestIndex: "
368  << nNearestIndex << ", nNearestPosition: " << nNearestPosition);
369 
370  GetIndexAndPos(nNearestIndex, nNearestPosition, nFirstBound,
371  nFirstIndex, nFirstPositionPx, !bReverse, nFirstDiff);
372  SAL_INFO("sc.lok.header", "BoundsProvider: nFirstIndex: " << nFirstIndex
373  << ", nFirstPositionPx: " << nFirstPositionPx);
374 
375  if (std::abs(nSecondDiff) < std::abs(nSecondBound - nFirstPositionPx))
376  {
377  nNearestIndex = aSecondNearest.first;
378  nNearestPosition = aSecondNearest.second;
379  }
380  else
381  {
382  nNearestPosition = nFirstPositionPx;
383  nNearestIndex = nFirstIndex;
384  nSecondDiff = !bReverse ? -1 : 1;
385  }
386  SAL_INFO("sc.lok.header", "BoundsProvider: nearest to second bound: nNearestIndex: "
387  << nNearestIndex << ", nNearestPosition: " << nNearestPosition
388  << ", diff: " << nSecondDiff);
389 
390  GetIndexAndPos(nNearestIndex, nNearestPosition, nSecondBound,
391  nSecondIndex, nSecondPositionPx, bReverse, nSecondDiff);
392  SAL_INFO("sc.lok.header", "BoundsProvider: nSecondIndex: " << nSecondIndex
393  << ", nSecondPositionPx: " << nSecondPositionPx);
394 
395  if (bReverse)
396  {
397  std::swap(nFirstIndex, nSecondIndex);
399  }
400 }
401 
403 {
404  const index_type nNewFirstIndex =
405  std::max(static_cast<index_type>(-1),
406  static_cast<index_type>(nFirstIndex - nOffset));
407  for (index_type nIndex = nFirstIndex; nIndex > nNewFirstIndex; --nIndex)
408  {
409  const long nSizePx = GetSize(nIndex);
410  nFirstPositionPx -= nSizePx;
411  }
412  nFirstIndex = nNewFirstIndex;
413  SAL_INFO("sc.lok.header", "BoundsProvider: added offset: nFirstIndex: " << nFirstIndex
414  << ", nFirstPositionPx: " << nFirstPositionPx);
415 }
416 
418 {
419  const index_type nNewSecondIndex = std::min(MAX_INDEX, static_cast<index_type>(nSecondIndex + nOffset));
420  for (index_type nIndex = nSecondIndex + 1; nIndex <= nNewSecondIndex; ++nIndex)
421  {
422  const long nSizePx = GetSize(nIndex);
423  nSecondPositionPx += nSizePx;
424  }
425  nSecondIndex = nNewSecondIndex;
426  SAL_INFO("sc.lok.header", "BoundsProvider: added offset: nSecondIndex: " << nSecondIndex
427  << ", nSecondPositionPx: " << nSecondPositionPx);
428 }
429 
431  index_type nNearestIndex, long nNearestPosition,
432  long nBound, index_type& nFoundIndex, long& nPosition, bool bTowards)
433 {
434  nFoundIndex = -1;
435  for (index_type nIndex = nNearestIndex; nIndex >= 0; --nIndex)
436  {
437  if (nBound >= nNearestPosition)
438  {
439  nFoundIndex = nIndex; // last index whose nPosition is less than nBound
440  nPosition = nNearestPosition;
441  break;
442  }
443 
444  const long nSizePx = GetSize(nIndex);
445  nNearestPosition -= nSizePx;
446  }
447  if (!bTowards && nFoundIndex != -1)
448  {
449  nFoundIndex += 1;
450  nPosition += GetSize(nFoundIndex);
451  }
452 }
453 
455  index_type nNearestIndex, long nNearestPosition,
456  long nBound, index_type& nFoundIndex, long& nPosition, bool bTowards)
457 {
458  nFoundIndex = -2;
459  for (index_type nIndex = nNearestIndex + 1; nIndex <= MAX_INDEX; ++nIndex)
460  {
461  const long nSizePx = GetSize(nIndex);
462  nNearestPosition += nSizePx;
463 
464  if (nNearestPosition > nBound)
465  {
466  nFoundIndex = nIndex; // first index whose nPosition is greater than nBound
467  nPosition = nNearestPosition;
468  break;
469  }
470  }
471  if (nFoundIndex == -2)
472  {
473  nFoundIndex = MAX_INDEX;
474  nPosition = nNearestPosition;
475  }
476  else if (bTowards)
477  {
478  nPosition -= GetSize(nFoundIndex);
479  nFoundIndex -= 1;
480  }
481 }
482 
484  eZoomType( SvxZoomType::PERCENT ),
485  aZoomX( 1,1 ),
486  aZoomY( 1,1 ),
487  aPageZoomX( 3,5 ), // Page-Default: 60%
488  aPageZoomY( 3,5 ),
489  nHSplitPos( 0 ),
490  nVSplitPos( 0 ),
491  eHSplitMode( SC_SPLIT_NONE ),
492  eVSplitMode( SC_SPLIT_NONE ),
493  eWhichActive( SC_SPLIT_BOTTOMLEFT ),
494  nFixPosX( 0 ),
495  nFixPosY( 0 ),
496  nCurX( 0 ),
497  nCurY( 0 ),
498  nOldCurX( 0 ),
499  nOldCurY( 0 ),
500  aWidthHelper(pDoc, true),
501  aHeightHelper(pDoc, false),
502  nMaxTiledCol( 20 ),
503  nMaxTiledRow( 50 ),
504  bShowGrid( true ),
505  mbOldCursorValid( false )
506 {
507  nPosX[0]=nPosX[1]=0;
508  nPosY[0]=nPosY[1]=0;
509  nTPosX[0]=nTPosX[1]=0;
510  nTPosY[0]=nTPosY[1]=0;
511  nMPosX[0]=nMPosX[1]=0;
512  nMPosY[0]=nMPosY[1]=0;
513  nPixPosX[0]=nPixPosX[1]=0;
514  nPixPosY[0]=nPixPosY[1]=0;
515 }
516 
518 {
519  aWidthHelper.setDocument(pDoc, true);
520  aHeightHelper.setDocument(pDoc, false);
521 }
522 
523 void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings, const ScViewData& rViewData, SCTAB nTab) const
524 {
525  rSettings.realloc(SC_TABLE_VIEWSETTINGS_COUNT);
526  beans::PropertyValue* pSettings = rSettings.getArray();
527 
528  ScSplitMode eExHSplitMode = eHSplitMode;
529  ScSplitMode eExVSplitMode = eVSplitMode;
530  SCCOL nExFixPosX = nFixPosX;
531  SCROW nExFixPosY = nFixPosY;
532  long nExHSplitPos = nHSplitPos;
533  long nExVSplitPos = nVSplitPos;
534 
536  {
537  rViewData.OverrideWithLOKFreeze(eExHSplitMode, eExVSplitMode,
538  nExFixPosX, nExFixPosY,
539  nExHSplitPos, nExVSplitPos, nTab);
540  }
541 
542  pSettings[SC_CURSOR_X].Name = SC_CURSORPOSITIONX;
543  pSettings[SC_CURSOR_X].Value <<= sal_Int32(nCurX);
544  pSettings[SC_CURSOR_Y].Name = SC_CURSORPOSITIONY;
545  pSettings[SC_CURSOR_Y].Value <<= sal_Int32(nCurY);
547  pSettings[SC_HORIZONTAL_SPLIT_MODE].Value <<= sal_Int16(eExHSplitMode);
549  pSettings[SC_VERTICAL_SPLIT_MODE].Value <<= sal_Int16(eExVSplitMode);
551  if (eExHSplitMode == SC_SPLIT_FIX)
552  pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nExFixPosX);
553  else
554  pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nExHSplitPos);
556  if (eExVSplitMode == SC_SPLIT_FIX)
557  pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nExFixPosY);
558  else
559  pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nExVSplitPos);
560  // Prevent writing odd settings that would make crash versions that
561  // don't apply SanitizeWhichActive() when reading the settings.
562  // See tdf#117093
563  const ScSplitPos eActiveSplitRange = SanitizeWhichActive();
564  // And point out to give us a chance to inspect weird things (if anyone
565  // remembers what s/he did).
566  assert(eWhichActive == eActiveSplitRange);
567  pSettings[SC_ACTIVE_SPLIT_RANGE].Name = SC_ACTIVESPLITRANGE;
568  pSettings[SC_ACTIVE_SPLIT_RANGE].Value <<= sal_Int16(eActiveSplitRange);
569  pSettings[SC_POSITION_LEFT].Name = SC_POSITIONLEFT;
570  pSettings[SC_POSITION_LEFT].Value <<= sal_Int32(nPosX[SC_SPLIT_LEFT]);
571  pSettings[SC_POSITION_RIGHT].Name = SC_POSITIONRIGHT;
572  pSettings[SC_POSITION_RIGHT].Value <<= sal_Int32(nPosX[SC_SPLIT_RIGHT]);
573  pSettings[SC_POSITION_TOP].Name = SC_POSITIONTOP;
574  pSettings[SC_POSITION_TOP].Value <<= sal_Int32(nPosY[SC_SPLIT_TOP]);
575  pSettings[SC_POSITION_BOTTOM].Name = SC_POSITIONBOTTOM;
576  pSettings[SC_POSITION_BOTTOM].Value <<= sal_Int32(nPosY[SC_SPLIT_BOTTOM]);
577 
578  sal_Int32 nZoomValue = long(aZoomY * 100);
579  sal_Int32 nPageZoomValue = long(aPageZoomY * 100);
580  pSettings[SC_TABLE_ZOOM_TYPE].Name = SC_ZOOMTYPE;
581  pSettings[SC_TABLE_ZOOM_TYPE].Value <<= sal_Int16(eZoomType);
582  pSettings[SC_TABLE_ZOOM_VALUE].Name = SC_ZOOMVALUE;
583  pSettings[SC_TABLE_ZOOM_VALUE].Value <<= nZoomValue;
585  pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
586 
587  pSettings[SC_TABLE_SHOWGRID].Name = SC_UNO_SHOWGRID;
588  pSettings[SC_TABLE_SHOWGRID].Value <<= bShowGrid;
589 
590  // Common SdrModel processing
591  rViewData.GetDocument()->GetDrawLayer()->WriteUserDataSequence(rSettings);
592 }
593 
594 void ScViewDataTable::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& aSettings, ScViewData& rViewData, SCTAB nTab, bool& rHasZoom )
595 {
596  rHasZoom = false;
597 
598  sal_Int32 nTemp32(0);
599  sal_Int16 nTemp16(0);
600  sal_Int32 nTempPosV(0);
601  sal_Int32 nTempPosH(0);
602  sal_Int32 nTempPosVTw(0);
603  sal_Int32 nTempPosHTw(0);
604  bool bHasVSplitInTwips = false;
605  bool bHasHSplitInTwips = false;
606  for (const auto& rSetting : aSettings)
607  {
608  OUString sName(rSetting.Name);
609  if (sName == SC_CURSORPOSITIONX)
610  {
611  rSetting.Value >>= nTemp32;
612  nCurX = rViewData.GetDocument()->SanitizeCol( static_cast<SCCOL>(nTemp32));
613  }
614  else if (sName == SC_CURSORPOSITIONY)
615  {
616  rSetting.Value >>= nTemp32;
617  nCurY = rViewData.GetDocument()->SanitizeRow( static_cast<SCROW>(nTemp32));
618  }
619  else if (sName == SC_HORIZONTALSPLITMODE)
620  {
621  if ((rSetting.Value >>= nTemp16) && nTemp16 <= ScSplitMode::SC_SPLIT_MODE_MAX_ENUM)
622  eHSplitMode = static_cast<ScSplitMode>(nTemp16);
623  }
624  else if (sName == SC_VERTICALSPLITMODE)
625  {
626  if ((rSetting.Value >>= nTemp16) && nTemp16 <= ScSplitMode::SC_SPLIT_MODE_MAX_ENUM)
627  eVSplitMode = static_cast<ScSplitMode>(nTemp16);
628  }
629  else if (sName == SC_HORIZONTALSPLITPOSITION)
630  {
631  rSetting.Value >>= nTempPosH;
632  bHasHSplitInTwips = false;
633  }
634  else if (sName == SC_VERTICALSPLITPOSITION)
635  {
636  rSetting.Value >>= nTempPosV;
637  bHasVSplitInTwips = false;
638  }
639  else if (sName == SC_HORIZONTALSPLITPOSITION_TWIPS)
640  {
641  rSetting.Value >>= nTempPosHTw;
642  bHasHSplitInTwips = true;
643  }
644  else if (sName == SC_VERTICALSPLITPOSITION_TWIPS)
645  {
646  rSetting.Value >>= nTempPosVTw;
647  bHasVSplitInTwips = true;
648  }
649  else if (sName == SC_ACTIVESPLITRANGE)
650  {
651  if ((rSetting.Value >>= nTemp16) && nTemp16 <= ScSplitPos::SC_SPLIT_POS_MAX_ENUM)
652  eWhichActive = static_cast<ScSplitPos>(nTemp16);
653  }
654  else if (sName == SC_POSITIONLEFT)
655  {
656  rSetting.Value >>= nTemp32;
657  nPosX[SC_SPLIT_LEFT] = rViewData.GetDocument()->SanitizeCol( static_cast<SCCOL>(nTemp32));
658  }
659  else if (sName == SC_POSITIONRIGHT)
660  {
661  rSetting.Value >>= nTemp32;
662  nPosX[SC_SPLIT_RIGHT] = rViewData.GetDocument()->SanitizeCol( static_cast<SCCOL>(nTemp32));
663  }
664  else if (sName == SC_POSITIONTOP)
665  {
666  rSetting.Value >>= nTemp32;
667  nPosY[SC_SPLIT_TOP] = rViewData.GetDocument()->SanitizeRow( static_cast<SCROW>(nTemp32));
668  }
669  else if (sName == SC_POSITIONBOTTOM)
670  {
671  rSetting.Value >>= nTemp32;
672  nPosY[SC_SPLIT_BOTTOM] = rViewData.GetDocument()->SanitizeRow( static_cast<SCROW>(nTemp32));
673  }
674  else if (sName == SC_ZOOMTYPE)
675  {
676  rSetting.Value >>= nTemp16;
677  eZoomType = SvxZoomType(nTemp16);
678  rHasZoom = true; // set if there is any zoom information
679  }
680  else if (sName == SC_ZOOMVALUE)
681  {
682  rSetting.Value >>= nTemp32;
683  Fraction aZoom(nTemp32, 100);
684  aZoomX = aZoomY = aZoom;
685  rHasZoom = true;
686  }
687  else if (sName == SC_PAGEVIEWZOOMVALUE)
688  {
689  rSetting.Value >>= nTemp32;
690  Fraction aZoom(nTemp32, 100);
691  aPageZoomX = aPageZoomY = aZoom;
692  rHasZoom = true;
693  }
694  else if (sName == SC_UNO_SHOWGRID)
695  {
696  rSetting.Value >>= bShowGrid;
697  }
698  else if (sName == SC_TABLESELECTED)
699  {
700  bool bSelected = false;
701  rSetting.Value >>= bSelected;
702  rViewData.GetMarkData().SelectTable( nTab, bSelected );
703  }
704  else if (sName == SC_UNONAME_TABCOLOR)
705  {
706  // There are documents out there that have their tab color defined as a view setting.
707  Color aColor = COL_AUTO;
708  rSetting.Value >>= aColor;
709  if (aColor != COL_AUTO)
710  {
711  ScDocument* pDoc = rViewData.GetDocument();
712  pDoc->SetTabBgColor(nTab, aColor);
713  }
714  }
715  // Fallback to common SdrModel processing
716  else rViewData.GetDocument()->GetDrawLayer()->ReadUserDataSequenceValue(&rSetting);
717  }
718 
719  if (eHSplitMode == SC_SPLIT_FIX)
720  nFixPosX = rViewData.GetDocument()->SanitizeCol( static_cast<SCCOL>( bHasHSplitInTwips ? nTempPosHTw : nTempPosH ));
721  else
722  nHSplitPos = bHasHSplitInTwips ? static_cast< long >( nTempPosHTw * rViewData.GetPPTX() ) : nTempPosH;
723 
724  if (eVSplitMode == SC_SPLIT_FIX)
725  nFixPosY = rViewData.GetDocument()->SanitizeRow( static_cast<SCROW>( bHasVSplitInTwips ? nTempPosVTw : nTempPosV ));
726  else
727  nVSplitPos = bHasVSplitInTwips ? static_cast< long >( nTempPosVTw * rViewData.GetPPTY() ) : nTempPosV;
728 
730 }
731 
733 {
736  {
737  SAL_WARN("sc.ui","ScViewDataTable::SanitizeWhichActive - bad eWhichActive " << eWhichActive);
738  // The default always initialized grid window is SC_SPLIT_BOTTOMLEFT.
739  return SC_SPLIT_BOTTOMLEFT;
740  }
741  return eWhichActive;
742 }
743 
745 
747  nPPTX(0.0),
748  nPPTY(0.0),
749  mpMarkData(pDocSh?
750  new ScMarkData(pDocSh->GetDocument().GetSheetLimits()) :
752  ),
753  pDocShell ( pDocSh ),
754  pDoc ( nullptr ),
755  pView ( pViewSh ),
756  pViewShell ( pViewSh ),
757  pOptions ( new ScViewOptions ),
758  pSpellingView ( nullptr ),
759  aLogicMode ( MapUnit::Map100thMM ),
760  eDefZoomType( SvxZoomType::PERCENT ),
761  aDefZoomX ( 1,1 ),
762  aDefZoomY ( 1,1 ),
763  aDefPageZoomX( 3,5 ),
764  aDefPageZoomY( 3,5 ),
765  eRefType ( SC_REFTYPE_NONE ),
766  nTabNo ( 0 ),
767  nRefTabNo ( 0 ),
768  nRefStartX(0),
769  nRefStartY(0),
770  nRefStartZ(0),
771  nRefEndX(0),
772  nRefEndY(0),
773  nRefEndZ(0),
774  nFillStartX(0),
775  nFillStartY(0),
776  nFillEndX(0),
777  nFillEndY(0),
778  nPasteFlags ( ScPasteFlags::NONE ),
779  eEditActivePart( SC_SPLIT_BOTTOMLEFT ),
780  nFillMode ( ScFillMode::NONE ),
781  eEditAdjust ( SvxAdjust::Left ),
782  bActive ( true ), // how to initialize?
783  bIsRefMode ( false ),
784  bDelMarkValid( false ),
785  bPagebreak ( false ),
786  bSelCtrlMouseClick( false ),
787  bMoveArea ( false ),
788  bGrowing (false),
789  m_nLOKPageUpDownOffset( 0 )
790 {
791  mpMarkData->SelectOneTable(0); // Sync with nTabNo
792 
793  SetGridMode ( true );
794  SetSyntaxMode ( false );
795  SetHeaderMode ( true );
796  SetTabMode ( true );
797  SetVScrollMode ( true );
798  SetHScrollMode ( true );
799  SetOutlineMode ( true );
800 
802  static_cast<long>( ScGlobal::nStdRowHeight * PIXEL_PER_TWIPS * OLE_STD_CELLS_Y ) );
803  maTabData.emplace_back( new ScViewDataTable(nullptr) );
804  pThisTab = maTabData[nTabNo].get();
805  for (sal_uInt16 j=0; j<4; j++)
806  {
807  pEditView[j] = nullptr;
808  bEditActive[j] = false;
809  }
810 
812  nEditEndRow = nEditRow = 0;
814 
815  if (pDocShell)
816  {
817  pDoc = &pDocShell->GetDocument();
819  }
820 
821  // don't show hidden tables
822  if (pDoc && !pDoc->IsVisible(nTabNo))
823  {
824  while ( !pDoc->IsVisible(nTabNo) && pDoc->HasTable(nTabNo+1) )
825  {
826  ++nTabNo;
827  maTabData.emplace_back(nullptr);
828  }
829  maTabData[nTabNo].reset( new ScViewDataTable(nullptr) );
830  pThisTab = maTabData[nTabNo].get();
831  }
832 
833  if (pDoc)
834  {
835  SCTAB nTableCount = pDoc->GetTableCount();
836  EnsureTabDataSize(nTableCount);
837 
838  for ( auto & xTabData : maTabData )
839  {
840  if (xTabData)
841  xTabData->InitData( pDoc );
842  }
843  }
844 
845  CalcPPT();
846 }
847 
849 {
850  pDoc = pDocument;
852  for ( auto & xTabData : maTabData )
853  {
854  if (xTabData)
855  xTabData->InitData( pDocument );
856  }
857 }
858 
860 {
861  if (pDoc)
862  return pDoc;
863  else if (pDocShell)
864  return &pDocShell->GetDocument();
865 
866  OSL_FAIL("no document on ViewData");
867  return nullptr;
868 }
869 
870 ScViewData::~ScViewData() COVERITY_NOEXCEPT_FALSE
871 {
872  KillEditView();
873  pOptions.reset();
874 }
875 
877 {
878  assert(0 <= nTabNo && o3tl::make_unsigned(nTabNo) < maTabData.size());
879  pThisTab = maTabData[nTabNo].get();
880  while (!pThisTab)
881  {
882  if (nTabNo > 0)
883  pThisTab = maTabData[--nTabNo].get();
884  else
885  {
886  maTabData[0].reset(new ScViewDataTable(pDoc));
887  pThisTab = maTabData[0].get();
888  }
889  }
890 }
891 
893 {
894  if( nTab >= static_cast<SCTAB>(maTabData.size()))
895  maTabData.resize(nTab+1);
896  else
897  maTabData.insert( maTabData.begin() + nTab, nullptr );
898  CreateTabData( nTab );
899 
901  mpMarkData->InsertTab( nTab );
902 
903  collectUIInformation({{}}, "InsertTab");
904 }
905 
906 void ScViewData::InsertTabs( SCTAB nTab, SCTAB nNewSheets )
907 {
908  if (nTab >= static_cast<SCTAB>(maTabData.size()))
909  maTabData.resize(nTab+nNewSheets);
910  else
911  {
912  // insert nNewSheets new tables at position nTab
913  auto prevSize = maTabData.size();
914  maTabData.resize(prevSize + nNewSheets);
915  std::move_backward(maTabData.begin() + nTab, maTabData.begin() + prevSize, maTabData.end());
916  }
917  for (SCTAB i = nTab; i < nTab + nNewSheets; ++i)
918  {
919  CreateTabData( i );
920  mpMarkData->InsertTab( i );
921  }
923 }
924 
926 {
927  assert(nTab < static_cast<SCTAB>(maTabData.size()));
928  maTabData.erase(maTabData.begin() + nTab);
929 
930  if (o3tl::make_unsigned(nTabNo) >= maTabData.size())
931  {
933  nTabNo = maTabData.size() - 1;
934  }
936  mpMarkData->DeleteTab( nTab );
937 }
938 
939 void ScViewData::DeleteTabs( SCTAB nTab, SCTAB nSheets )
940 {
941  for (SCTAB i = 0; i < nSheets; ++i)
942  {
943  mpMarkData->DeleteTab( nTab + i );
944  }
945  maTabData.erase(maTabData.begin() + nTab, maTabData.begin()+ nTab+nSheets);
946  if (o3tl::make_unsigned(nTabNo) >= maTabData.size())
947  {
949  nTabNo = maTabData.size() - 1;
950  }
952 }
953 
954 void ScViewData::CopyTab( SCTAB nSrcTab, SCTAB nDestTab )
955 {
956  if (nDestTab==SC_TAB_APPEND)
957  nDestTab = pDoc->GetTableCount() - 1; // something had to have been copied
958 
959  if (nDestTab > MAXTAB)
960  {
961  OSL_FAIL("too many sheets");
962  return;
963  }
964 
965  if (nSrcTab >= static_cast<SCTAB>(maTabData.size()))
966  OSL_FAIL("pTabData out of bounds, FIX IT");
967 
968  EnsureTabDataSize(nDestTab + 1);
969 
970  if ( maTabData[nSrcTab] )
971  maTabData.emplace(maTabData.begin() + nDestTab, new ScViewDataTable( *maTabData[nSrcTab] ));
972  else
973  maTabData.insert(maTabData.begin() + nDestTab, nullptr);
974 
976  mpMarkData->InsertTab( nDestTab );
977 }
978 
979 void ScViewData::MoveTab( SCTAB nSrcTab, SCTAB nDestTab )
980 {
981  if (nDestTab==SC_TAB_APPEND)
982  nDestTab = pDoc->GetTableCount() - 1;
983  std::unique_ptr<ScViewDataTable> pTab;
984  if (nSrcTab < static_cast<SCTAB>(maTabData.size()))
985  {
986  pTab = std::move(maTabData[nSrcTab]);
987  maTabData.erase( maTabData.begin() + nSrcTab );
988  }
989 
990  if (nDestTab < static_cast<SCTAB>(maTabData.size()))
991  maTabData.insert( maTabData.begin() + nDestTab, std::move(pTab) );
992  else
993  {
994  EnsureTabDataSize(nDestTab + 1);
995  maTabData[nDestTab] = std::move(pTab);
996  }
997 
999  mpMarkData->DeleteTab( nSrcTab );
1000  mpMarkData->InsertTab( nDestTab ); // adapted if needed
1001 }
1002 
1003 void ScViewData::CreateTabData( std::vector< SCTAB >& rvTabs )
1004 {
1005  for ( const auto& rTab : rvTabs )
1006  CreateTabData(rTab);
1007 }
1008 
1009 void ScViewData::SetZoomType( SvxZoomType eNew, std::vector< SCTAB >& tabs )
1010 {
1011  bool bAll = tabs.empty();
1012 
1013  if ( !bAll ) // create associated table data
1014  CreateTabData( tabs );
1015 
1016  if ( bAll )
1017  {
1018  for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabData.size()); ++i )
1019  {
1020  if ( maTabData[i] )
1021  maTabData[i]->eZoomType = eNew;
1022  }
1023  eDefZoomType = eNew;
1024  }
1025  else
1026  {
1027  for ( const SCTAB& i : tabs )
1028  {
1029  if ( i < static_cast<SCTAB>(maTabData.size()) && maTabData[i] )
1030  maTabData[i]->eZoomType = eNew;
1031  }
1032  }
1033 }
1034 
1035 void ScViewData::SetZoomType( SvxZoomType eNew, bool bAll )
1036 {
1037  std::vector< SCTAB > vTabs; // Empty for all tabs
1038  if ( !bAll ) // get selected tabs
1039  {
1040  ScMarkData::iterator itr = mpMarkData->begin(), itrEnd = mpMarkData->end();
1041  vTabs.insert(vTabs.begin(), itr, itrEnd);
1042  }
1043  SetZoomType( eNew, vTabs );
1044 }
1045 
1046 void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& tabs )
1047 {
1048  bool bAll = tabs.empty();
1049  if ( !bAll ) // create associated table data
1050  CreateTabData( tabs );
1051 
1052  // sanity check - we shouldn't need something this low / big
1053  SAL_WARN_IF(rNewX < Fraction(1, 100) || rNewX > Fraction(100, 1), "sc.viewdata",
1054  "fraction rNewX not sensible: " << static_cast<double>(rNewX));
1055  SAL_WARN_IF(rNewY < Fraction(1, 100) || rNewY > Fraction(100, 1), "sc.viewdata",
1056  "fraction rNewY not sensible: " << static_cast<double>(rNewY));
1057 
1058  if ( bAll )
1059  {
1060  for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabData.size()); ++i )
1061  {
1062  if ( maTabData[i] )
1063  {
1064  if ( bPagebreak )
1065  {
1066  maTabData[i]->aPageZoomX = rNewX;
1067  maTabData[i]->aPageZoomY = rNewY;
1068  }
1069  else
1070  {
1071  maTabData[i]->aZoomX = rNewX;
1072  maTabData[i]->aZoomY = rNewY;
1073  }
1074  }
1075  }
1076  if ( bPagebreak )
1077  {
1078  aDefPageZoomX = rNewX;
1079  aDefPageZoomY = rNewY;
1080  }
1081  else
1082  {
1083  aDefZoomX = rNewX;
1084  aDefZoomY = rNewY;
1085  }
1086  }
1087  else
1088  {
1089  for ( const SCTAB& i : tabs )
1090  {
1091  if ( i < static_cast<SCTAB>(maTabData.size()) && maTabData[i] )
1092  {
1093  if ( bPagebreak )
1094  {
1095  maTabData[i]->aPageZoomX = rNewX;
1096  maTabData[i]->aPageZoomY = rNewY;
1097  }
1098  else
1099  {
1100  maTabData[i]->aZoomX = rNewX;
1101  maTabData[i]->aZoomY = rNewY;
1102  }
1103  }
1104  }
1105  }
1106  RefreshZoom();
1107 }
1108 
1109 void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, bool bAll )
1110 {
1111  std::vector< SCTAB > vTabs;
1112  if ( !bAll ) // get selected tabs
1113  {
1114  ScMarkData::iterator itr = mpMarkData->begin(), itrEnd = mpMarkData->end();
1115  vTabs.insert(vTabs.begin(), itr, itrEnd);
1116  }
1117  SetZoom( rNewX, rNewY, vTabs );
1118 }
1119 
1120 void ScViewData::SetShowGrid( bool bShow )
1121 {
1123  maTabData[nTabNo]->bShowGrid = bShow;
1124 }
1125 
1127 {
1128  // recalculate zoom-dependent values (only for current sheet)
1129 
1130  CalcPPT();
1131  RecalcPixPos();
1132  aScenButSize = Size(0,0);
1135 }
1136 
1138 {
1139  bPagebreak = bSet;
1140 
1141  RefreshZoom();
1142 }
1143 
1145 {
1146  ScMarkType eMarkType = SC_MARK_NONE;
1147 
1148  if ( rNewMark.IsMarked() || rNewMark.IsMultiMarked() )
1149  {
1150  if ( rNewMark.IsMultiMarked() )
1151  rNewMark.MarkToSimple();
1152 
1153  if ( rNewMark.IsMarked() && !rNewMark.IsMultiMarked() )
1154  {
1155  rNewMark.GetMarkArea( rRange );
1156  if (ScViewUtil::HasFiltered( rRange, GetDocument()))
1157  eMarkType = SC_MARK_SIMPLE_FILTERED;
1158  else
1159  eMarkType = SC_MARK_SIMPLE;
1160  }
1161  else
1162  eMarkType = SC_MARK_MULTI;
1163  }
1164  if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
1165  {
1166  if (eMarkType == SC_MARK_NONE)
1167  eMarkType = SC_MARK_SIMPLE;
1168  rRange = ScRange( GetCurX(), GetCurY(), GetTabNo() );
1169  }
1170  return eMarkType;
1171 }
1172 
1173 ScMarkType ScViewData::GetSimpleArea( SCCOL& rStartCol, SCROW& rStartRow, SCTAB& rStartTab,
1174  SCCOL& rEndCol, SCROW& rEndRow, SCTAB& rEndTab ) const
1175 {
1176  // parameter bMergeMark is no longer needed: The view's selection is never modified
1177  // (a local copy is used), and a multi selection that adds to a single range can always
1178  // be treated like a single selection (GetSimpleArea isn't used in selection
1179  // handling itself)
1180 
1181  ScRange aRange;
1182  ScMarkData aNewMark(*mpMarkData); // use a local copy for MarkToSimple
1183  ScMarkType eMarkType = GetSimpleArea( aRange, aNewMark);
1184  aRange.GetVars( rStartCol, rStartRow, rStartTab, rEndCol, rEndRow, rEndTab);
1185  return eMarkType;
1186 }
1187 
1189 {
1190  // parameter bMergeMark is no longer needed, see above
1191 
1192  ScMarkData aNewMark(*mpMarkData); // use a local copy for MarkToSimple
1193  return GetSimpleArea( rRange, aNewMark);
1194 }
1195 
1197 {
1198  // parameter bMergeMark is no longer needed, see GetSimpleArea
1199 
1200  ScMarkData aNewMark(*mpMarkData); // use a local copy for MarkToSimple
1201 
1202  bool bMulti = aNewMark.IsMultiMarked();
1203  if (bMulti)
1204  {
1205  aNewMark.MarkToSimple();
1206  bMulti = aNewMark.IsMultiMarked();
1207  }
1208  if (bMulti)
1209  {
1210  rRange = new ScRangeList;
1211  aNewMark.FillRangeListWithMarks( rRange.get(), false );
1212  }
1213  else
1214  {
1215  ScRange aSimple;
1216  GetSimpleArea(aSimple);
1217  rRange = new ScRangeList(aSimple);
1218  }
1219 }
1220 
1222 {
1223  SCCOL nStartCol;
1224  SCROW nStartRow;
1225  SCTAB nStartTab;
1226  SCCOL nEndCol;
1227  SCROW nEndRow;
1228  SCTAB nEndTab;
1229  if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1230  if (nStartRow==0 && nEndRow==pDoc->MaxRow())
1231  return true;
1232 
1233  return false;
1234 }
1235 
1237 {
1238  SCCOL nStartCol;
1239  SCROW nStartRow;
1240  SCTAB nStartTab;
1241  SCCOL nEndCol;
1242  SCROW nEndRow;
1243  SCTAB nEndTab;
1244  if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1245  if (nStartCol==0 && nEndCol==pDoc->MaxCol())
1246  return true;
1247 
1248  return false;
1249 }
1250 
1252 {
1253  // Test for "real" multi selection, calling MarkToSimple on a local copy,
1254  // and taking filtered in simple area marks into account.
1255 
1256  ScRange aDummy;
1257  ScMarkType eType = GetSimpleArea(aDummy);
1258  return (eType & SC_MARK_SIMPLE) != SC_MARK_SIMPLE;
1259 }
1260 
1262 {
1263  ScRange aSelRange( ScAddress::UNINITIALIZED );
1264  ScMarkType eMarkType = GetSimpleArea( aSelRange);
1265  return eMarkType != SC_MARK_MULTI && SelectionFillDOOM( aSelRange);
1266 }
1267 
1268 // static
1270 {
1271  // Assume that more than 23 full columns (23M cells) will not be
1272  // successful... Even with only 10 bytes per cell that would already be
1273  // 230MB, formula cells would be 100 bytes and more per cell.
1274  // rows * columns > 23m => rows > 23m / columns
1275  // to not overflow in case number of available columns or rows would be
1276  // arbitrarily increased.
1277  // We could refine this and take some actual cell size into account,
1278  // evaluate available memory and what not, but...
1279  const sal_Int32 kMax = 23 * 1024 * 1024; // current MAXROWCOUNT is 1024*1024=1048576
1280  return (rRange.aEnd.Row() - rRange.aStart.Row() + 1) > (kMax / (rRange.aEnd.Col() - rRange.aStart.Col() + 1));
1281 }
1282 
1283 void ScViewData::SetFillMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
1284 {
1286  nFillStartX = nStartCol;
1287  nFillStartY = nStartRow;
1288  nFillEndX = nEndCol;
1289  nFillEndY = nEndRow;
1290 }
1291 
1292 void ScViewData::SetDragMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1293  ScFillMode nMode )
1294 {
1295  nFillMode = nMode;
1296  nFillStartX = nStartCol;
1297  nFillStartY = nStartRow;
1298  nFillEndX = nEndCol;
1299  nFillEndY = nEndRow;
1300 }
1301 
1303 {
1305 }
1306 
1307 void ScViewData::GetFillData( SCCOL& rStartCol, SCROW& rStartRow,
1308  SCCOL& rEndCol, SCROW& rEndRow )
1309 {
1310  rStartCol = nFillStartX;
1311  rStartRow = nFillStartY;
1312  rEndCol = nFillEndX;
1313  rEndRow = nFillEndY;
1314 }
1315 
1317 {
1319  return pThisTab->nOldCurX;
1320  else
1321  return pThisTab->nCurX;
1322 }
1323 
1325 {
1327  return pThisTab->nOldCurY;
1328  else
1329  return pThisTab->nCurY;
1330 }
1331 
1333 {
1334  pThisTab->nOldCurX = nNewX;
1335  pThisTab->nOldCurY = nNewY;
1336  pThisTab->mbOldCursorValid = true;
1337 }
1338 
1340 {
1341  pThisTab->mbOldCursorValid = false;
1342 }
1343 
1344 SCCOL ScViewData::GetPosX( ScHSplitPos eWhich, SCTAB nForTab ) const
1345 {
1347  return 0;
1348 
1349  if (nForTab == -1)
1350  return pThisTab->nPosX[eWhich];
1351 
1352  if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
1353  return -1;
1354 
1355  return maTabData[nForTab]->nPosX[eWhich];
1356 }
1357 
1358 SCROW ScViewData::GetPosY( ScVSplitPos eWhich, SCTAB nForTab ) const
1359 {
1361  return 0;
1362 
1363  if (nForTab == -1)
1364  return pThisTab->nPosY[eWhich];
1365 
1366  if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
1367  return -1;
1368 
1369  return maTabData[nForTab]->nPosY[eWhich];
1370 }
1371 
1373 {
1374  if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
1375  return -1;
1376 
1377  return maTabData[nTabIndex]->nCurX;
1378 }
1379 
1381 {
1382  if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
1383  return -1;
1384 
1385  return maTabData[nTabIndex]->nCurY;
1386 }
1387 
1388 void ScViewData::SetCurXForTab( SCCOL nNewCurX, SCTAB nTabIndex )
1389 {
1390  if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
1391  return;
1392 
1393  maTabData[nTabIndex]->nCurX = nNewCurX;
1394 }
1395 
1396 void ScViewData::SetCurYForTab( SCCOL nNewCurY, SCTAB nTabIndex )
1397 {
1398  if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
1399  return;
1400 
1401  maTabData[nTabIndex]->nCurY = nNewCurY;
1402 }
1403 
1405 {
1406  if (nNewMaxCol < 0)
1407  nNewMaxCol = 0;
1408  if (nNewMaxCol > pDoc->MaxCol())
1409  nNewMaxCol = pDoc->MaxCol();
1410 
1411  const SCTAB nTab = GetTabNo();
1412  auto GetColWidthPx = [this, nTab](SCCOL nCol) {
1413  const sal_uInt16 nSize = this->pDoc->GetColWidth(nCol, nTab);
1414  const long nSizePx = ScViewData::ToPixel(nSize, nPPTX);
1415  return nSizePx;
1416  };
1417 
1418  long nTotalPixels = GetLOKWidthHelper().computePosition(nNewMaxCol, GetColWidthPx);
1419 
1420  SAL_INFO("sc.lok.docsize", "ScViewData::SetMaxTiledCol: nNewMaxCol: "
1421  << nNewMaxCol << ", nTotalPixels: " << nTotalPixels);
1422 
1424  GetLOKWidthHelper().insert(nNewMaxCol, nTotalPixels);
1425 
1426  pThisTab->nMaxTiledCol = nNewMaxCol;
1427 }
1428 
1430 {
1431  if (nNewMaxRow < 0)
1432  nNewMaxRow = 0;
1433  if (nNewMaxRow > MAXTILEDROW)
1434  nNewMaxRow = MAXTILEDROW;
1435 
1436  const SCTAB nTab = GetTabNo();
1437  auto GetRowHeightPx = [this, nTab](SCROW nRow) {
1438  const sal_uInt16 nSize = this->pDoc->GetRowHeight(nRow, nTab);
1439  const long nSizePx = ScViewData::ToPixel(nSize, nPPTY);
1440  return nSizePx;
1441  };
1442 
1443  long nTotalPixels = GetLOKHeightHelper().computePosition(nNewMaxRow, GetRowHeightPx);
1444 
1445  SAL_INFO("sc.lok.docsize", "ScViewData::SetMaxTiledRow: nNewMaxRow: "
1446  << nNewMaxRow << ", nTotalPixels: " << nTotalPixels);
1447 
1449  GetLOKHeightHelper().insert(nNewMaxRow, nTotalPixels);
1450 
1451  pThisTab->nMaxTiledRow = nNewMaxRow;
1452 }
1453 
1455  vcl::Window* pWin, const ScPatternAttr* pPattern,
1456  bool bForceToTop, bool bInPrintTwips )
1457 {
1458  Point aCellTopLeft = bInPrintTwips ?
1459  GetPrintTwipsPos(nPosX, nPosY) : GetScrPos(nPosX, nPosY, eWhich, true);
1460  return ScEditUtil( pDoc, nPosX, nPosY, nTabNo, aCellTopLeft,
1461  pWin, nPPTX, nPPTY, GetZoomX(), GetZoomY(), bInPrintTwips ).
1462  GetEditArea( pPattern, bForceToTop );
1463 }
1464 
1466  ScEditEngineDefaulter* pNewEngine,
1467  vcl::Window* pWin, SCCOL nNewX, SCROW nNewY )
1468 {
1469  bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
1470  ScHSplitPos eHWhich = WhichH(eWhich);
1471  ScVSplitPos eVWhich = WhichV(eWhich);
1472  bool bLOKActive = comphelper::LibreOfficeKit::isActive();
1473  bool bLOKPrintTwips = bLOKActive && comphelper::LibreOfficeKit::isCompatFlagSet(
1474  comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
1475 
1476  bool bWasThere = false;
1477  if (pEditView[eWhich])
1478  {
1479  // if the view is already there don't call anything that changes the cursor position
1480  if (bEditActive[eWhich])
1481  {
1482  bWasThere = true;
1483  }
1484  else
1485  {
1486  lcl_LOKRemoveWindow(GetViewShell(), eWhich);
1487  pEditView[eWhich]->SetEditEngine(pNewEngine);
1488  }
1489 
1490  if (pEditView[eWhich]->GetWindow() != pWin)
1491  {
1492  lcl_LOKRemoveWindow(GetViewShell(), eWhich);
1493  pEditView[eWhich]->SetWindow(pWin);
1494  OSL_FAIL("EditView Window has changed");
1495  }
1496  }
1497  else
1498  {
1499  pEditView[eWhich].reset(new EditView( pNewEngine, pWin ));
1500 
1501  if (bLOKActive)
1502  {
1503  // We can broadcast the view-cursor message in print-twips for all views.
1504  pEditView[eWhich]->SetBroadcastLOKViewCursor(bLOKPrintTwips);
1505  pEditView[eWhich]->RegisterViewShell(pViewShell);
1506  }
1507  }
1508 
1509  // add windows from other views
1510  if (!bWasThere && bLOKActive)
1511  {
1512  ScTabViewShell* pThisViewShell = GetViewShell();
1513  SCTAB nThisTabNo = GetTabNo();
1514  auto lAddWindows =
1515  [pThisViewShell, nThisTabNo, eWhich] (ScTabViewShell* pOtherViewShell)
1516  {
1517  ScViewData& rOtherViewData = pOtherViewShell->GetViewData();
1518  SCTAB nOtherTabNo = rOtherViewData.GetTabNo();
1519  if (nThisTabNo == nOtherTabNo)
1520  pOtherViewShell->AddWindowToForeignEditView(pThisViewShell, eWhich);
1521  };
1522 
1523  SfxLokHelper::forEachOtherView(pThisViewShell, lAddWindows);
1524  }
1525 
1526  // if view is gone then during IdleFormat sometimes a cursor is drawn
1527 
1528  EEControlBits nEC = pNewEngine->GetControlWord();
1529  pNewEngine->SetControlWord(nEC & ~EEControlBits::DOIDLEFORMAT);
1530 
1531  EVControlBits nVC = pEditView[eWhich]->GetControlWord();
1532  pEditView[eWhich]->SetControlWord(nVC & ~EVControlBits::AUTOSCROLL);
1533 
1534  bEditActive[eWhich] = true;
1535 
1536  const ScPatternAttr* pPattern = pDoc->GetPattern( nNewX, nNewY, nTabNo );
1537  SvxCellHorJustify eJust = pPattern->GetItem( ATTR_HOR_JUSTIFY ).GetValue();
1538 
1539  bool bBreak = ( eJust == SvxCellHorJustify::Block ) ||
1540  pPattern->GetItem(ATTR_LINEBREAK).GetValue();
1541 
1542  bool bAsianVertical = pNewEngine->IsVertical(); // set by InputHandler
1543 
1544  tools::Rectangle aPixRect = ScEditUtil( pDoc, nNewX,nNewY,nTabNo, GetScrPos(nNewX,nNewY,eWhich),
1545  pWin, nPPTX,nPPTY,GetZoomX(),GetZoomY() ).
1546  GetEditArea( pPattern, true );
1547 
1548  tools::Rectangle aPTwipsRect;
1549  if (bLOKPrintTwips)
1550  {
1551  aPTwipsRect = ScEditUtil(pDoc, nNewX, nNewY, nTabNo, GetPrintTwipsPos(nNewX, nNewY),
1552  pWin, nPPTX, nPPTY, GetZoomX(), GetZoomY(), true /* bInPrintTwips */).
1553  GetEditArea(pPattern, true);
1554  }
1555 
1556  // when right-aligned, leave space for the cursor
1557  // in vertical mode, editing is always right-aligned
1558  if ( GetEditAdjust() == SvxAdjust::Right || bAsianVertical )
1559  {
1560  aPixRect.AdjustRight(1 );
1561  if (bLOKPrintTwips)
1562  aPTwipsRect.AdjustRight(TWIPS_PER_PIXEL);
1563  }
1564 
1565  if (bLOKPrintTwips)
1566  {
1567  if (!pEditView[eWhich]->HasLOKSpecialPositioning())
1568  pEditView[eWhich]->InitLOKSpecialPositioning(MapUnit::MapTwip, aPTwipsRect, Point());
1569  else
1570  pEditView[eWhich]->SetLOKSpecialOutputArea(aPTwipsRect);
1571  }
1572 
1573  tools::Rectangle aOutputArea = pWin->PixelToLogic( aPixRect, GetLogicMode() );
1574  pEditView[eWhich]->SetOutputArea( aOutputArea );
1575 
1576  if ( bActive && eWhich == GetActivePart() )
1577  {
1578  // keep the part that has the active edit view available after
1579  // switching sheets or reference input on a different part
1580  eEditActivePart = eWhich;
1581 
1582  // modify members nEditCol etc. only if also extending for needed area
1583  nEditCol = nNewX;
1584  nEditRow = nNewY;
1585  const ScMergeAttr* pMergeAttr = &pPattern->GetItem(ATTR_MERGE);
1587  if (pMergeAttr->GetColMerge() > 1)
1588  nEditEndCol += pMergeAttr->GetColMerge() - 1;
1590  if (pMergeAttr->GetRowMerge() > 1)
1591  nEditEndRow += pMergeAttr->GetRowMerge() - 1;
1593 
1594  // For growing use only the alignment value from the attribute, numbers
1595  // (existing or started) with default alignment extend to the right.
1596  bool bGrowCentered = ( eJust == SvxCellHorJustify::Center );
1597  bool bGrowToLeft = ( eJust == SvxCellHorJustify::Right ); // visual left
1598  if ( bAsianVertical )
1599  bGrowCentered = bGrowToLeft = false; // keep old behavior for asian mode
1600 
1601  long nSizeXPix, nSizeXPTwips = 0;
1602 
1603  const long nGridWidthPx = pView->GetGridWidth(eHWhich);
1604  const long nGridHeightPx = pView->GetGridHeight(eVWhich);
1605  long nGridWidthTwips = 0, nGridHeightTwips = 0;
1606  if (bLOKPrintTwips)
1607  {
1608  Size aGridSize(nGridWidthPx, nGridHeightPx);
1609  const MapMode& rWinMapMode = GetLogicMode();
1610  aGridSize = OutputDevice::LogicToLogic(
1611  pWin->PixelToLogic(aGridSize, rWinMapMode),
1612  rWinMapMode, MapMode(MapUnit::MapTwip));
1613  nGridWidthTwips = aGridSize.Width();
1614  nGridHeightTwips = aGridSize.Height();
1615  }
1616 
1617  if (bBreak && !bAsianVertical)
1618  {
1619  nSizeXPix = aPixRect.GetWidth(); // papersize -> no horizontal scrolling
1620  if (bLOKPrintTwips)
1621  nSizeXPTwips = aPTwipsRect.GetWidth();
1622  }
1623  else
1624  {
1625  OSL_ENSURE(pView,"no View for EditView");
1626 
1627  if ( bGrowCentered )
1628  {
1629  // growing into both directions until one edge is reached
1631  long nLeft = aPixRect.Left();
1632  long nRight = nGridWidthPx - aPixRect.Right();
1633  nSizeXPix = aPixRect.GetWidth() + 2 * std::min( nLeft, nRight );
1634  if (bLOKPrintTwips)
1635  {
1636  long nLeftPTwips = aPTwipsRect.Left();
1637  long nRightPTwips = nGridWidthTwips - aPTwipsRect.Right();
1638  nSizeXPTwips = aPTwipsRect.GetWidth() + 2 * std::min(nLeftPTwips, nRightPTwips);
1639  }
1640  }
1641  else if ( bGrowToLeft )
1642  {
1643  nSizeXPix = aPixRect.Right(); // space that's available in the window when growing to the left
1644  if (bLOKPrintTwips)
1645  nSizeXPTwips = aPTwipsRect.Right();
1646  }
1647  else
1648  {
1649  nSizeXPix = nGridWidthPx - aPixRect.Left();
1650  if (bLOKPrintTwips)
1651  nSizeXPTwips = nGridWidthTwips - aPTwipsRect.Left();
1652  }
1653 
1654  if ( nSizeXPix <= 0 )
1655  {
1656  nSizeXPix = aPixRect.GetWidth(); // editing outside to the right of the window -> keep cell width
1657  if (bLOKPrintTwips)
1658  nSizeXPTwips = aPTwipsRect.GetWidth();
1659  }
1660  }
1661  OSL_ENSURE(pView,"no View for EditView");
1662  long nSizeYPix = nGridHeightPx - aPixRect.Top();
1663  long nSizeYPTwips = bLOKPrintTwips ? (nGridHeightTwips - aPTwipsRect.Top()) : 0;
1664 
1665  if ( nSizeYPix <= 0 )
1666  {
1667  nSizeYPix = aPixRect.GetHeight(); // editing outside below the window -> keep cell height
1668  if (bLOKPrintTwips)
1669  nSizeYPTwips = aPTwipsRect.GetHeight();
1670  }
1671 
1672  Size aPaperSize = pView->GetActiveWin()->PixelToLogic( Size( nSizeXPix, nSizeYPix ), GetLogicMode() );
1673  Size aPaperSizePTwips(nSizeXPTwips, nSizeYPTwips);
1674  if ( bBreak && !bAsianVertical && SC_MOD()->GetInputOptions().GetTextWysiwyg() )
1675  {
1676  // if text is formatted for printer, use the exact same paper width
1677  // (and same line breaks) as for output.
1678 
1679  Fraction aFract(1,1);
1680  tools::Rectangle aUtilRect = ScEditUtil( pDoc,nNewX,nNewY,nTabNo, Point(0,0), pWin,
1681  HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, false );
1682  aPaperSize.setWidth( aUtilRect.GetWidth() );
1683  if (bLOKPrintTwips)
1684  aPaperSizePTwips.setWidth(OutputDevice::LogicToLogic(
1685  aUtilRect.GetWidth(), MapUnit::Map100thMM, MapUnit::MapTwip));
1686  }
1687 
1688  pNewEngine->SetPaperSize( aPaperSize );
1689  if (bLOKPrintTwips)
1690  pNewEngine->SetLOKSpecialPaperSize(aPaperSizePTwips);
1691 
1692  // sichtbarer Ausschnitt
1693  Size aPaper = pNewEngine->GetPaperSize();
1694  tools::Rectangle aVis = pEditView[eWhich]->GetVisArea();
1695  tools::Rectangle aVisPTwips;
1696  if (bLOKPrintTwips)
1697  aVisPTwips = pEditView[eWhich]->GetLOKSpecialVisArea();
1698 
1699  long nDiff = aVis.Right() - aVis.Left();
1700  long nDiffPTwips = bLOKPrintTwips ? (aVisPTwips.Right() - aVisPTwips.Left()) : 0;
1701  if ( GetEditAdjust() == SvxAdjust::Right )
1702  {
1703  aVis.SetRight( aPaper.Width() - 1 );
1704  if (bLOKPrintTwips)
1705  aVisPTwips.SetRight( aPaperSizePTwips.Width() - 1 );
1706  bMoveArea = !bLayoutRTL;
1707  }
1708  else if ( GetEditAdjust() == SvxAdjust::Center )
1709  {
1710  aVis.SetRight( ( aPaper.Width() - 1 + nDiff ) / 2 );
1711  if (bLOKPrintTwips)
1712  aVisPTwips.SetRight( ( aPaperSizePTwips.Width() - 1 + nDiffPTwips ) / 2 );
1713  bMoveArea = true; // always
1714  }
1715  else
1716  {
1717  aVis.SetRight( nDiff );
1718  if (bLOKPrintTwips)
1719  aVisPTwips.SetRight(nDiffPTwips);
1720  bMoveArea = bLayoutRTL;
1721  }
1722  aVis.SetLeft( aVis.Right() - nDiff );
1723  if (bLOKPrintTwips)
1724  aVisPTwips.SetLeft(aVisPTwips.Right() - nDiffPTwips);
1725  // #i49561# Important note:
1726  // The set offset of the visible area of the EditView for centered and
1727  // right alignment in horizontal layout is consider by instances of
1728  // class <ScEditObjectViewForwarder> in its methods <LogicToPixel(..)>
1729  // and <PixelToLogic(..)>. This is needed for the correct visibility
1730  // of paragraphs in edit mode at the accessibility API.
1731  pEditView[eWhich]->SetVisArea(aVis);
1732  if (bLOKPrintTwips)
1733  pEditView[eWhich]->SetLOKSpecialVisArea(aVisPTwips);
1734  // UpdateMode has been disabled in ScInputHandler::StartTable
1735  // must be enabled before EditGrowY (GetTextHeight)
1736  pNewEngine->SetUpdateMode( true );
1737 
1738  pNewEngine->SetStatusEventHdl( LINK( this, ScViewData, EditEngineHdl ) );
1739 
1740  EditGrowY( true ); // adjust to existing text content
1741  EditGrowX();
1742 
1743  Point aDocPos = pEditView[eWhich]->GetWindowPosTopLeft(0);
1744  if (aDocPos.Y() < aOutputArea.Top())
1745  pEditView[eWhich]->Scroll( 0, aOutputArea.Top() - aDocPos.Y() );
1746  }
1747 
1748  // here bEditActive needs to be set already
1749  // (due to Map-Mode during Paint)
1750  if (!bWasThere)
1751  pNewEngine->InsertView(pEditView[eWhich].get());
1752 
1753  // background color of the cell
1754  Color aBackCol = pPattern->GetItem(ATTR_BACKGROUND).GetColor();
1755 
1756  ScModule* pScMod = SC_MOD();
1757  if ( aBackCol.GetTransparency() > 0 )
1758  {
1759  aBackCol = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
1760  }
1761  pEditView[eWhich]->SetBackgroundColor( aBackCol );
1762 
1763  pEditView[eWhich]->Invalidate(); // needed?
1764  // needed, if position changed
1765 }
1766 
1767 IMPL_LINK( ScViewData, EditEngineHdl, EditStatus&, rStatus, void )
1768 {
1769  EditStatusFlags nStatus = rStatus.GetStatusWord();
1770  if (nStatus & (EditStatusFlags::HSCROLL | EditStatusFlags::TextHeightChanged | EditStatusFlags::TEXTWIDTHCHANGED | EditStatusFlags::CURSOROUT))
1771  {
1772  EditGrowY();
1773  EditGrowX();
1774 
1775  if (nStatus & EditStatusFlags::CURSOROUT)
1776  {
1777  ScSplitPos eWhich = GetActivePart();
1778  if (pEditView[eWhich])
1779  pEditView[eWhich]->ShowCursor(false);
1780  }
1781  }
1782 }
1783 
1785 {
1786  // It is insane to call EditGrowX while the output area is already growing.
1787  // That could occur because of the call to SetDefaultItem later.
1788  // We end up with wrong start/end edit columns and the changes
1789  // to the output area performed by the inner call to this method are
1790  // useless since they are discarded by the outer call.
1791  if (bGrowing)
1792  return;
1793 
1794  comphelper::FlagRestorationGuard aFlagGuard(bGrowing, true);
1795 
1796  bool bLOKActive = comphelper::LibreOfficeKit::isActive();
1797  bool bLOKPrintTwips = bLOKActive && comphelper::LibreOfficeKit::isCompatFlagSet(
1798  comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
1799 
1800  ScDocument* pLocalDoc = GetDocument();
1801 
1802  ScSplitPos eWhich = GetActivePart();
1803  ScHSplitPos eHWhich = WhichH(eWhich);
1804  EditView* pCurView = pEditView[eWhich].get();
1805 
1806  if ( !pCurView || !bEditActive[eWhich])
1807  return;
1808 
1809  bool bLayoutRTL = pLocalDoc->IsLayoutRTL( nTabNo );
1810 
1811  ScEditEngineDefaulter* pEngine =
1812  static_cast<ScEditEngineDefaulter*>( pCurView->GetEditEngine() );
1813  vcl::Window* pWin = pCurView->GetWindow();
1814 
1815  // Get the left- and right-most column positions.
1816  SCCOL nLeft = GetPosX(eHWhich);
1817  SCCOL nRight = nLeft + VisibleCellsX(eHWhich);
1818 
1819  Size aSize = pEngine->GetPaperSize();
1820  Size aSizePTwips;
1821  if (bLOKPrintTwips)
1822  aSizePTwips = pEngine->GetLOKSpecialPaperSize();
1823 
1824  tools::Rectangle aArea = pCurView->GetOutputArea();
1825  tools::Rectangle aAreaPTwips;
1826  if (bLOKPrintTwips)
1827  aAreaPTwips = pCurView->GetLOKSpecialOutputArea();
1828 
1829  long nOldRight = aArea.Right();
1830 
1831  // Margin is already included in the original width.
1832  long nTextWidth = pEngine->CalcTextWidth();
1833 
1834  bool bChanged = false;
1835  bool bAsianVertical = pEngine->IsVertical();
1836 
1837  // get bGrow... variables the same way as in SetEditEngine
1838  const ScPatternAttr* pPattern = pLocalDoc->GetPattern( nEditCol, nEditRow, nTabNo );
1839  SvxCellHorJustify eJust = pPattern->GetItem( ATTR_HOR_JUSTIFY ).GetValue();
1840  bool bGrowCentered = ( eJust == SvxCellHorJustify::Center );
1841  bool bGrowToLeft = ( eJust == SvxCellHorJustify::Right ); // visual left
1842  bool bGrowBackwards = bGrowToLeft; // logical left
1843  if ( bLayoutRTL )
1844  bGrowBackwards = !bGrowBackwards; // invert on RTL sheet
1845  if ( bAsianVertical )
1846  bGrowCentered = bGrowToLeft = bGrowBackwards = false; // keep old behavior for asian mode
1847 
1848  bool bUnevenGrow = false;
1849  if ( bGrowCentered )
1850  {
1851  while (aArea.GetWidth() + 0 < nTextWidth && ( nEditStartCol > nLeft || nEditEndCol < nRight ) )
1852  {
1853  long nLogicLeft = 0;
1854  long nLogicLeftPTwips = 0;
1855  if ( nEditStartCol > nLeft )
1856  {
1857  --nEditStartCol;
1858  long nColWidth = pLocalDoc->GetColWidth( nEditStartCol, nTabNo );
1859  long nLeftPix = ToPixel( nColWidth, nPPTX );
1860  nLogicLeft = pWin->PixelToLogic(Size(nLeftPix,0)).Width();
1861  if (bLOKPrintTwips)
1862  nLogicLeftPTwips = nColWidth;
1863  }
1864  long nLogicRight = 0;
1865  long nLogicRightPTwips = 0;
1866  if ( nEditEndCol < nRight )
1867  {
1868  ++nEditEndCol;
1869  long nColWidth = pLocalDoc->GetColWidth( nEditEndCol, nTabNo );
1870  long nRightPix = ToPixel( nColWidth, nPPTX );
1871  nLogicRight = pWin->PixelToLogic(Size(nRightPix,0)).Width();
1872  if (bLOKPrintTwips)
1873  nLogicRightPTwips = nColWidth;
1874  }
1875 
1876  aArea.AdjustLeft( -(bLayoutRTL ? nLogicRight : nLogicLeft) );
1877  aArea.AdjustRight(bLayoutRTL ? nLogicLeft : nLogicRight );
1878  if (bLOKPrintTwips)
1879  {
1880  aAreaPTwips.AdjustLeft( -(bLayoutRTL ? nLogicRightPTwips : nLogicLeftPTwips) );
1881  aAreaPTwips.AdjustRight(bLayoutRTL ? nLogicLeftPTwips : nLogicRightPTwips );
1882  }
1883 
1884  if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1885  {
1886  long nCenter = ( aArea.Left() + aArea.Right() ) / 2;
1887  long nHalf = aSize.Width() / 2;
1888  aArea.SetLeft( nCenter - nHalf + 1 );
1889  aArea.SetRight( nCenter + aSize.Width() - nHalf - 1 );
1890 
1891  if (bLOKPrintTwips)
1892  {
1893  long nCenterPTwips = ( aAreaPTwips.Left() + aAreaPTwips.Right() ) / 2;
1894  long nHalfPTwips = aSizePTwips.Width() / 2;
1895  aAreaPTwips.SetLeft( nCenterPTwips - nHalfPTwips + 1 );
1896  aAreaPTwips.SetRight( nCenterPTwips + aSizePTwips.Width() - nHalfPTwips - 1 );
1897  }
1898  }
1899 
1900  bChanged = true;
1901  if ( nLogicLeft != nLogicRight )
1902  bUnevenGrow = true;
1903  }
1904  }
1905  else if ( bGrowBackwards )
1906  {
1907  while (aArea.GetWidth() + 0 < nTextWidth && nEditStartCol > nLeft)
1908  {
1909  --nEditStartCol;
1910  long nColWidth = pLocalDoc->GetColWidth( nEditStartCol, nTabNo );
1911  long nPix = ToPixel( nColWidth, nPPTX );
1912  long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
1913  long& nLogicWidthPTwips = nColWidth;
1914 
1915  if ( !bLayoutRTL )
1916  {
1917  aArea.AdjustLeft( -nLogicWidth );
1918  if (bLOKPrintTwips)
1919  aAreaPTwips.AdjustLeft( -nLogicWidthPTwips );
1920  }
1921  else
1922  {
1923  aArea.AdjustRight(nLogicWidth );
1924  if (bLOKPrintTwips)
1925  aAreaPTwips.AdjustRight(nLogicWidthPTwips);
1926  }
1927 
1928  if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1929  {
1930  if ( !bLayoutRTL )
1931  {
1932  aArea.SetLeft( aArea.Right() - aSize.Width() + 1 );
1933  if (bLOKPrintTwips)
1934  aAreaPTwips.SetLeft( aAreaPTwips.Right() - aSizePTwips.Width() + 1 );
1935  }
1936  else
1937  {
1938  aArea.SetRight( aArea.Left() + aSize.Width() - 1 );
1939  if (bLOKPrintTwips)
1940  aAreaPTwips.SetRight( aAreaPTwips.Left() + aSizePTwips.Width() - 1 );
1941  }
1942  }
1943 
1944  bChanged = true;
1945  }
1946  }
1947  else
1948  {
1949  while (aArea.GetWidth() + 0 < nTextWidth && nEditEndCol < nRight)
1950  {
1951  ++nEditEndCol;
1952  long nColWidth = pLocalDoc->GetColWidth( nEditEndCol, nTabNo );
1953  long nPix = ToPixel( nColWidth, nPPTX );
1954  long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
1955  long& nLogicWidthPTwips = nColWidth;
1956  if ( bLayoutRTL )
1957  {
1958  aArea.AdjustLeft( -nLogicWidth );
1959  if (bLOKPrintTwips)
1960  aAreaPTwips.AdjustLeft( -nLogicWidthPTwips );
1961  }
1962  else
1963  {
1964  aArea.AdjustRight(nLogicWidth );
1965  if (bLOKPrintTwips)
1966  aAreaPTwips.AdjustRight(nLogicWidthPTwips);
1967  }
1968 
1969  if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1970  {
1971  if ( bLayoutRTL )
1972  {
1973  aArea.SetLeft( aArea.Right() - aSize.Width() + 1 );
1974  if (bLOKPrintTwips)
1975  aAreaPTwips.SetLeft( aAreaPTwips.Right() - aSizePTwips.Width() + 1 );
1976  }
1977  else
1978  {
1979  aArea.SetRight( aArea.Left() + aSize.Width() - 1 );
1980  if (bLOKPrintTwips)
1981  aAreaPTwips.SetRight( aAreaPTwips.Left() + aSizePTwips.Width() - 1 );
1982  }
1983  }
1984 
1985  bChanged = true;
1986  }
1987  }
1988 
1989  if (bChanged)
1990  {
1991  if ( bMoveArea || bGrowCentered || bGrowBackwards || bLayoutRTL )
1992  {
1993  tools::Rectangle aVis = pCurView->GetVisArea();
1994  tools::Rectangle aVisPTwips;
1995  if (bLOKPrintTwips)
1996  aVisPTwips = pCurView->GetLOKSpecialVisArea();
1997 
1998  if ( bGrowCentered )
1999  {
2000  // switch to center-aligned (undo?) and reset VisArea to center
2001 
2002  pEngine->SetDefaultItem( SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST ) );
2003 
2004  long nCenter = aSize.Width() / 2;
2005  long nVisSize = aArea.GetWidth();
2006  aVis.SetLeft( nCenter - nVisSize / 2 );
2007  aVis.SetRight( aVis.Left() + nVisSize - 1 );
2008 
2009  if (bLOKPrintTwips)
2010  {
2011  long nCenterPTwips = aSizePTwips.Width() / 2;
2012  long nVisSizePTwips = aAreaPTwips.GetWidth();
2013  aVisPTwips.SetLeft( nCenterPTwips - nVisSizePTwips / 2 );
2014  aVisPTwips.SetRight( aVisPTwips.Left() + nVisSizePTwips - 1 );
2015  }
2016  }
2017  else if ( bGrowToLeft )
2018  {
2019  // switch to right-aligned (undo?) and reset VisArea to the right
2020 
2021  pEngine->SetDefaultItem( SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ) );
2022 
2023  aVis.SetRight( aSize.Width() - 1 );
2024  aVis.SetLeft( aSize.Width() - aArea.GetWidth() ); // with the new, increased area
2025 
2026  if (bLOKPrintTwips)
2027  {
2028  aVisPTwips.SetRight( aSizePTwips.Width() - 1 );
2029  aVisPTwips.SetLeft( aSizePTwips.Width() - aAreaPTwips.GetWidth() ); // with the new, increased area
2030  }
2031  }
2032  else
2033  {
2034  // switch to left-aligned (undo?) and reset VisArea to the left
2035 
2036  pEngine->SetDefaultItem( SvxAdjustItem( SvxAdjust::Left, EE_PARA_JUST ) );
2037 
2038  long nMove = aVis.Left();
2039  aVis.SetLeft( 0 );
2040  aVis.AdjustRight( -nMove );
2041 
2042  if (bLOKPrintTwips)
2043  {
2044  long nMovePTwips = aVisPTwips.Left();
2045  aVisPTwips.SetLeft( 0 );
2046  aVisPTwips.AdjustRight( -nMovePTwips );
2047  }
2048  }
2049 
2050  pCurView->SetVisArea( aVis );
2051  if (bLOKPrintTwips)
2052  pCurView->SetLOKSpecialVisArea( aVisPTwips );
2053 
2054  bMoveArea = false;
2055  }
2056 
2057  if (bLOKPrintTwips)
2058  pCurView->SetLOKSpecialOutputArea(aAreaPTwips);
2059 
2060  pCurView->SetOutputArea(aArea);
2061 
2062  // In vertical mode, the whole text is moved to the next cell (right-aligned),
2063  // so everything must be repainted. Otherwise, paint only the new area.
2064  // If growing in centered alignment, if the cells left and right have different sizes,
2065  // the whole text will move, and may not even obscure all of the original display.
2066  if ( bUnevenGrow )
2067  {
2068  aArea.SetLeft( pWin->PixelToLogic( Point(0,0) ).X() );
2069  aArea.SetRight( pWin->PixelToLogic( aScrSize ).Width() );
2070  }
2071  else if ( !bAsianVertical && !bGrowToLeft && !bGrowCentered )
2072  aArea.SetLeft( nOldRight );
2073  pWin->Invalidate(aArea);
2074 
2075  // invalidate other views
2076  pCurView->InvalidateOtherViewWindows(aArea);
2077  }
2078 }
2079 
2080 void ScViewData::EditGrowY( bool bInitial )
2081 {
2082  if (bGrowing)
2083  return;
2084 
2085  comphelper::FlagRestorationGuard aFlagGuard(bGrowing, true);
2086 
2087  bool bLOKActive = comphelper::LibreOfficeKit::isActive();
2088  bool bLOKPrintTwips = bLOKActive && comphelper::LibreOfficeKit::isCompatFlagSet(
2089  comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs);
2090 
2091  ScSplitPos eWhich = GetActivePart();
2092  ScVSplitPos eVWhich = WhichV(eWhich);
2093  EditView* pCurView = pEditView[eWhich].get();
2094 
2095  if ( !pCurView || !bEditActive[eWhich])
2096  return;
2097 
2098  EVControlBits nControl = pEditView[eWhich]->GetControlWord();
2099  if ( nControl & EVControlBits::AUTOSCROLL )
2100  {
2101  // if end of screen had already been reached and scrolling enabled,
2102  // don't further try to grow the edit area
2103 
2104  pCurView->SetOutputArea( pCurView->GetOutputArea() ); // re-align to pixels
2105  return;
2106  }
2107 
2108  EditEngine* pEngine = pCurView->GetEditEngine();
2109  vcl::Window* pWin = pCurView->GetWindow();
2110 
2111  SCROW nBottom = GetPosY(eVWhich) + VisibleCellsY(eVWhich);
2112 
2113  Size aSize = pEngine->GetPaperSize();
2114  Size aSizePTwips;
2115  tools::Rectangle aArea = pCurView->GetOutputArea();
2116  tools::Rectangle aAreaPTwips;
2117 
2118  if (bLOKPrintTwips)
2119  {
2120  aSizePTwips = pEngine->GetLOKSpecialPaperSize();
2121  aAreaPTwips = pCurView->GetLOKSpecialOutputArea();
2122  }
2123 
2124  long nOldBottom = aArea.Bottom();
2125  long nTextHeight = pEngine->GetTextHeight();
2126 
2127  // When editing a formula in a cell with optimal height, allow a larger portion
2128  // to be clipped before extending to following rows, to avoid obscuring cells for
2129  // reference input (next row is likely to be useful in formulas).
2130  long nAllowedExtra = SC_GROWY_SMALL_EXTRA;
2132  pEngine->GetParagraphCount() <= 1 )
2133  {
2134  // If the (only) paragraph starts with a '=', it's a formula.
2135  // If this is the initial call and the text is empty, allow the larger value, too,
2136  // because this occurs in the normal progress of editing a formula.
2137  // Subsequent calls with empty text might involve changed attributes (including
2138  // font height), so they are treated like normal text.
2139  OUString aText = pEngine->GetText( 0 );
2140  if ( ( aText.isEmpty() && bInitial ) || aText.startsWith("=") )
2141  nAllowedExtra = SC_GROWY_BIG_EXTRA;
2142  }
2143 
2144  bool bChanged = false;
2145  bool bMaxReached = false;
2146  while (aArea.GetHeight() + nAllowedExtra < nTextHeight && nEditEndRow < nBottom && !bMaxReached)
2147  {
2148  ++nEditEndRow;
2149  ScDocument* pLocalDoc = GetDocument();
2150  long nRowHeight = pLocalDoc->GetRowHeight( nEditEndRow, nTabNo );
2151  long nPix = ToPixel( nRowHeight, nPPTY );
2152  aArea.AdjustBottom(pWin->PixelToLogic(Size(0,nPix)).Height() );
2153  if (bLOKPrintTwips)
2154  aAreaPTwips.AdjustBottom(nRowHeight);
2155 
2156  if ( aArea.Bottom() > aArea.Top() + aSize.Height() - 1 )
2157  {
2158  aArea.SetBottom( aArea.Top() + aSize.Height() - 1 );
2159  if (bLOKPrintTwips)
2160  aAreaPTwips.SetBottom( aAreaPTwips.Top() + aSizePTwips.Height() - 1 );
2161  bMaxReached = true; // don't occupy more cells beyond paper size
2162  }
2163 
2164  bChanged = true;
2165  nAllowedExtra = SC_GROWY_SMALL_EXTRA; // larger value is only for first row
2166  }
2167 
2168  if (bChanged)
2169  {
2170  if (bLOKPrintTwips)
2171  pCurView->SetLOKSpecialOutputArea(aAreaPTwips);
2172 
2173  pCurView->SetOutputArea(aArea);
2174 
2175  if (nEditEndRow >= nBottom || bMaxReached)
2176  {
2177  if (!(nControl & EVControlBits::AUTOSCROLL))
2178  pCurView->SetControlWord( nControl | EVControlBits::AUTOSCROLL );
2179  }
2180 
2181  aArea.SetTop( nOldBottom );
2182  pWin->Invalidate(aArea);
2183 
2184  // invalidate other views
2185  pCurView->InvalidateOtherViewWindows(aArea);
2186  }
2187 }
2188 
2190 {
2191  EditEngine* pEngine = nullptr;
2192  for (sal_uInt16 i=0; i<4; i++)
2193  if (pEditView[i])
2194  {
2195  if (bEditActive[i])
2196  {
2197  lcl_LOKRemoveWindow(GetViewShell(), static_cast<ScSplitPos>(i));
2198  pEngine = pEditView[i]->GetEditEngine();
2199  pEngine->RemoveView(pEditView[i].get());
2200  pEditView[i]->SetOutputArea( tools::Rectangle() );
2201  }
2202  bEditActive[i] = false;
2203  }
2204 
2205  if (pEngine)
2207 }
2208 
2210 {
2211  EditEngine* pEngine = nullptr;
2212  for (sal_uInt16 i=0; i<4; i++)
2213  if (pEditView[i])
2214  {
2215  if (bEditActive[i])
2216  {
2217  pEngine = pEditView[i]->GetEditEngine();
2218  if (pEngine)
2219  pEngine->RemoveView(pEditView[i].get());
2220  }
2221  pEditView[i].reset();
2222  }
2223 }
2224 
2225 void ScViewData::GetEditView( ScSplitPos eWhich, EditView*& rViewPtr, SCCOL& rCol, SCROW& rRow )
2226 {
2227  rViewPtr = pEditView[eWhich].get();
2228  rCol = nEditCol;
2229  rRow = nEditRow;
2230 }
2231 
2233 {
2234  EnsureTabDataSize(nNewTab + 1);
2235 
2236  if (!maTabData[nNewTab])
2237  {
2238  maTabData[nNewTab].reset( new ScViewDataTable(pDoc) );
2239 
2240  maTabData[nNewTab]->eZoomType = eDefZoomType;
2241  maTabData[nNewTab]->aZoomX = aDefZoomX;
2242  maTabData[nNewTab]->aZoomY = aDefZoomY;
2243  maTabData[nNewTab]->aPageZoomX = aDefPageZoomX;
2244  maTabData[nNewTab]->aPageZoomY = aDefPageZoomY;
2245  }
2246 }
2247 
2249 {
2250  for (const auto& rTab : *mpMarkData)
2251  CreateTabData(rTab);
2252 }
2253 
2255 {
2256  if (nSize > maTabData.size())
2257  maTabData.resize(nSize);
2258 }
2259 
2261 {
2262  if (!ValidTab(nNewTab))
2263  {
2264  OSL_FAIL("wrong sheet number");
2265  return;
2266  }
2267 
2268  nTabNo = nNewTab;
2270  pThisTab = maTabData[nTabNo].get();
2271 
2272  CalcPPT(); // for common column width correction
2273  RecalcPixPos();
2274 }
2275 
2277 {
2278  if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
2279  {
2280  return nullptr;
2281  }
2282  return &(maTabData[nTabIndex]->aWidthHelper);
2283 }
2284 
2286 {
2287  if (!ValidTab(nTabIndex) || (nTabIndex >= static_cast<SCTAB>(maTabData.size())))
2288  {
2289  return nullptr;
2290  }
2291  return &(maTabData[nTabIndex]->aHeightHelper);
2292 }
2293 
2295 {
2296  pThisTab->eWhichActive = eNewActive;
2297 
2298  // Let's hope we find the culprit for tdf#117093
2299  // Don't sanitize the real value (yet?) because this function might be
2300  // called before setting the then corresponding split modes. For which in
2301  // fact then the order should be changed.
2302  assert(eNewActive == pThisTab->SanitizeWhichActive());
2303 }
2304 
2305 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScHSplitPos eWhich ) const
2306 {
2307  OSL_ENSURE( eWhich==SC_SPLIT_LEFT || eWhich==SC_SPLIT_RIGHT, "wrong position" );
2309  return GetScrPos( nWhereX, nWhereY, ePos );
2310 }
2311 
2312 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const
2313 {
2314  OSL_ENSURE( eWhich==SC_SPLIT_TOP || eWhich==SC_SPLIT_BOTTOM, "wrong position" );
2316  return GetScrPos( nWhereX, nWhereY, ePos );
2317 }
2318 
2320  bool bAllowNeg, SCTAB nForTab ) const
2321 {
2322  ScHSplitPos eWhichX = SC_SPLIT_LEFT;
2323  ScVSplitPos eWhichY = SC_SPLIT_BOTTOM;
2324  switch( eWhich )
2325  {
2326  case SC_SPLIT_TOPLEFT:
2327  eWhichX = SC_SPLIT_LEFT;
2328  eWhichY = SC_SPLIT_TOP;
2329  break;
2330  case SC_SPLIT_TOPRIGHT:
2331  eWhichX = SC_SPLIT_RIGHT;
2332  eWhichY = SC_SPLIT_TOP;
2333  break;
2334  case SC_SPLIT_BOTTOMLEFT:
2335  eWhichX = SC_SPLIT_LEFT;
2336  eWhichY = SC_SPLIT_BOTTOM;
2337  break;
2338  case SC_SPLIT_BOTTOMRIGHT:
2339  eWhichX = SC_SPLIT_RIGHT;
2340  eWhichY = SC_SPLIT_BOTTOM;
2341  break;
2342  }
2343 
2344  if (nForTab == -1)
2345  nForTab = nTabNo;
2346  bool bForCurTab = (nForTab == nTabNo);
2347  if (!bForCurTab && (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size()))))
2348  {
2349  SAL_WARN("sc.viewdata", "ScViewData::GetScrPos : invalid nForTab = " << nForTab);
2350  nForTab = nTabNo;
2351  bForCurTab = true;
2352  }
2353 
2354  ScViewDataTable* pViewTable = bForCurTab ? pThisTab : maTabData[nForTab].get();
2355 
2356  if (pView)
2357  {
2358  const_cast<ScViewData*>(this)->aScrSize.setWidth( pView->GetGridWidth(eWhichX) );
2359  const_cast<ScViewData*>(this)->aScrSize.setHeight( pView->GetGridHeight(eWhichY) );
2360  }
2361 
2362  sal_uLong nTSize;
2363  bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
2364 
2365 
2366  SCCOL nPosX = GetPosX(eWhichX, nForTab);
2367  long nScrPosX = 0;
2368 
2369  if (bAllowNeg || nWhereX >= nPosX)
2370  {
2371  SCROW nStartPosX = nPosX;
2372  if (bIsTiledRendering)
2373  {
2374  OSL_ENSURE(nPosX == 0, "Unsupported case.");
2375  const auto& rNearest = pViewTable->aWidthHelper.getNearestByIndex(nWhereX - 1);
2376  nStartPosX = rNearest.first + 1;
2377  nScrPosX = rNearest.second;
2378  }
2379 
2380  if (nWhereX >= nStartPosX)
2381  {
2382  for (SCCOL nX = nStartPosX; nX < nWhereX && (bAllowNeg || bIsTiledRendering || nScrPosX <= aScrSize.Width()); nX++)
2383  {
2384  if ( nX > pDoc->MaxCol() )
2385  nScrPosX = 0x7FFFFFFF;
2386  else
2387  {
2388  nTSize = pDoc->GetColWidth( nX, nForTab );
2389  if (nTSize)
2390  {
2391  long nSizeXPix = ToPixel( nTSize, nPPTX );
2392  nScrPosX += nSizeXPix;
2393  }
2394  }
2395  }
2396  }
2397  else
2398  {
2399  for (SCCOL nX = nStartPosX; nX > nWhereX;)
2400  {
2401  --nX;
2402  nTSize = pDoc->GetColWidth( nX, nForTab );
2403  if (nTSize)
2404  {
2405  long nSizeXPix = ToPixel( nTSize, nPPTX );
2406  nScrPosX -= nSizeXPix;
2407  }
2408  }
2409  }
2410 
2411  }
2412 
2413 
2414  SCROW nPosY = GetPosY(eWhichY, nForTab);
2415  long nScrPosY = 0;
2416 
2417  if (bAllowNeg || nWhereY >= nPosY)
2418  {
2419  SCROW nStartPosY = nPosY;
2420  if (bIsTiledRendering)
2421  {
2422  OSL_ENSURE(nPosY == 0, "Unsupported case.");
2423  const auto& rNearest = pViewTable->aHeightHelper.getNearestByIndex(nWhereY - 1);
2424  nStartPosY = rNearest.first + 1;
2425  nScrPosY = rNearest.second;
2426  }
2427 
2428  if (nWhereY >= nStartPosY)
2429  {
2430  if (bAllowNeg || bIsTiledRendering || nScrPosY <= aScrSize.Height())
2431  {
2432  if ( nWhereY-1 > pDoc->MaxRow() )
2433  nScrPosY = 0x7FFFFFFF;
2434  else if (bAllowNeg || bIsTiledRendering)
2435  {
2436  sal_uLong nSizeYPix = pDoc->GetScaledRowHeight( nStartPosY, nWhereY-1, nForTab, nPPTY );
2437  nScrPosY += nSizeYPix;
2438  }
2439  else
2440  {
2441  sal_uLong nMaxHeight = aScrSize.getHeight() - nScrPosY;
2442  sal_uLong nSizeYPix = pDoc->GetScaledRowHeight( nStartPosY, nWhereY-1, nForTab, nPPTY, &nMaxHeight );
2443  nScrPosY += nSizeYPix;
2444  }
2445  }
2446  }
2447  else
2448  {
2449  for (SCROW nY = nStartPosY; nY > nWhereY;)
2450  {
2451  --nY;
2452  nTSize = pDoc->GetRowHeight( nY, nForTab );
2453  if (nTSize)
2454  {
2455  long nSizeYPix = ToPixel( nTSize, nPPTY );
2456  nScrPosY -= nSizeYPix;
2457  }
2458  }
2459  }
2460  }
2461 
2462  if ( pDoc->IsLayoutRTL( nForTab ) )
2463  {
2464  // mirror horizontal position
2465  nScrPosX = aScrSize.Width() - 1 - nScrPosX;
2466  }
2467 
2468  return Point( nScrPosX, nScrPosY );
2469 }
2470 
2472 {
2473  // hidden ones are given 0 sizes by these by default.
2474  // TODO: rewrite this to loop over spans (matters for jumbosheets).
2475  long nPosX = nCol ? pDoc->GetColWidth(0, nCol - 1, nTabNo) : 0;
2476  // This is now fast as it loops over spans.
2477  long nPosY = nRow ? pDoc->GetRowHeight(0, nRow - 1, nTabNo) : 0;
2478  // TODO: adjust for RTL layout case.
2479 
2480  return Point(nPosX, nPosY);
2481 }
2482 
2483 Point ScViewData::GetPrintTwipsPosFromTileTwips(const Point& rTileTwipsPos) const
2484 {
2485  const long nPixelX = static_cast<long>(rTileTwipsPos.X() * nPPTX);
2486  const long nPixelY = static_cast<long>(rTileTwipsPos.Y() * nPPTY);
2487  SCCOL nCol = 0;
2488  SCROW nRow = 0;
2489 
2490  // The following call (with bTestMerge = false) will not modify any members.
2491  const_cast<ScViewData*>(this)->GetPosFromPixel(nPixelX, nPixelY, SC_SPLIT_TOPLEFT, nCol, nRow, false /* bTestMerge */);
2492  const Point aPixCellPos = GetScrPos(nCol, nRow, SC_SPLIT_TOPLEFT, true /* bAllowNeg */);
2493  const Point aTileTwipsCellPos(aPixCellPos.X() / nPPTX, aPixCellPos.Y() / nPPTY);
2494  const Point aPrintTwipsCellPos = GetPrintTwipsPos(nCol, nRow);
2495  return aPrintTwipsCellPos + (rTileTwipsPos - aTileTwipsCellPos);
2496 }
2497 
2498 OString ScViewData::describeCellCursorAt(SCCOL nX, SCROW nY, bool bPixelAligned) const
2499 {
2500  const bool bPosSizeInPixels = bPixelAligned;
2501  Point aCellPos = bPosSizeInPixels ? GetScrPos( nX, nY, SC_SPLIT_BOTTOMRIGHT, true ) :
2502  GetPrintTwipsPos(nX, nY);
2503 
2504  long nSizeX;
2505  long nSizeY;
2506  if (bPosSizeInPixels)
2507  GetMergeSizePixel( nX, nY, nSizeX, nSizeY );
2508  else
2509  GetMergeSizePrintTwips(nX, nY, nSizeX, nSizeY);
2510 
2511  std::stringstream ss;
2512  if (bPosSizeInPixels)
2513  {
2514  double fPPTX = GetPPTX();
2515  double fPPTY = GetPPTY();
2516 
2517  // make it a slim cell cursor, but not empty
2518  if (nSizeX == 0)
2519  nSizeX = 1;
2520 
2521  if (nSizeY == 0)
2522  nSizeY = 1;
2523 
2524  long nPosXTw = rtl::math::round(aCellPos.getX() / fPPTX);
2525  long nPosYTw = rtl::math::round(aCellPos.getY() / fPPTY);
2526  // look at Rectangle( const Point& rLT, const Size& rSize ) for the '- 1'
2527  long nSizeXTw = rtl::math::round(nSizeX / fPPTX) - 1;
2528  long nSizeYTw = rtl::math::round(nSizeY / fPPTY) - 1;
2529 
2530  ss << nPosXTw << ", " << nPosYTw << ", " << nSizeXTw << ", " << nSizeYTw << ", "
2531  << nX << ", " << nY;
2532  }
2533  else
2534  {
2535  // look at Rectangle( const Point& rLT, const Size& rSize ) for the decrement.
2536  if (nSizeX)
2537  --nSizeX;
2538  if (nSizeY)
2539  --nSizeY;
2540  ss << aCellPos.getX() << ", " << aCellPos.getY()
2541  << ", " << nSizeX << ", " << nSizeY << ", "
2542  << nX << ", " << nY;
2543  }
2544 
2545  return ss.str().c_str();
2546 }
2547 
2548 // Number of cells on a screen
2549 SCCOL ScViewData::CellsAtX( SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX, sal_uInt16 nScrSizeX ) const
2550 {
2551  OSL_ENSURE( nDir==1 || nDir==-1, "wrong CellsAt call" );
2552 
2553  if (pView)
2554  const_cast<ScViewData*>(this)->aScrSize.setWidth( pView->GetGridWidth(eWhichX) );
2555 
2556  SCCOL nX;
2557  sal_uInt16 nScrPosX = 0;
2558  if (nScrSizeX == SC_SIZE_NONE) nScrSizeX = static_cast<sal_uInt16>(aScrSize.Width());
2559 
2560  if (nDir==1)
2561  nX = nPosX; // forwards
2562  else
2563  nX = nPosX-1; // backwards
2564 
2565  bool bOut = false;
2566  for ( ; nScrPosX<=nScrSizeX && !bOut; nX = sal::static_int_cast<SCCOL>(nX + nDir) )
2567  {
2568  SCCOL nColNo = nX;
2569  if ( nColNo < 0 || nColNo > pDoc->MaxCol() )
2570  bOut = true;
2571  else
2572  {
2573  sal_uInt16 nTSize = pDoc->GetColWidth( nColNo, nTabNo );
2574  if (nTSize)
2575  {
2576  long nSizeXPix = ToPixel( nTSize, nPPTX );
2577  nScrPosX = sal::static_int_cast<sal_uInt16>( nScrPosX + static_cast<sal_uInt16>(nSizeXPix) );
2578  }
2579  }
2580  }
2581 
2582  if (nDir==1)
2583  nX = sal::static_int_cast<SCCOL>( nX - nPosX );
2584  else
2585  nX = (nPosX-1)-nX;
2586 
2587  if (nX>0) --nX;
2588  return nX;
2589 }
2590 
2591 SCROW ScViewData::CellsAtY( SCROW nPosY, SCROW nDir, ScVSplitPos eWhichY, sal_uInt16 nScrSizeY ) const
2592 {
2593  OSL_ENSURE( nDir==1 || nDir==-1, "wrong CellsAt call" );
2594 
2595  if (pView)
2596  const_cast<ScViewData*>(this)->aScrSize.setHeight( pView->GetGridHeight(eWhichY) );
2597 
2598  if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = static_cast<sal_uInt16>(aScrSize.Height());
2599 
2600  SCROW nY;
2601 
2602  if (nDir==1)
2603  {
2604  // forward
2605  nY = nPosY;
2606  long nScrPosY = 0;
2607  AddPixelsWhile( nScrPosY, nScrSizeY, nY, pDoc->MaxRow(), nPPTY, pDoc, nTabNo);
2608  // Original loop ended on last evaluated +1 or if that was MaxRow even on MaxRow+2.
2609  nY += (nY == pDoc->MaxRow() ? 2 : 1);
2610  nY -= nPosY;
2611  }
2612  else
2613  {
2614  // backward
2615  nY = nPosY-1;
2616  long nScrPosY = 0;
2617  AddPixelsWhileBackward( nScrPosY, nScrSizeY, nY, 0, nPPTY, pDoc, nTabNo);
2618  // Original loop ended on last evaluated -1 or if that was 0 even on -2.
2619  nY -= (nY == 0 ? 2 : 1);
2620  nY = (nPosY-1)-nY;
2621  }
2622 
2623  if (nY>0) --nY;
2624  return nY;
2625 }
2626 
2628 {
2629  return CellsAtX( GetPosX( eWhichX ), 1, eWhichX );
2630 }
2631 
2633 {
2634  return CellsAtY( GetPosY( eWhichY ), 1, eWhichY );
2635 }
2636 
2638 {
2639  return CellsAtX( GetPosX( eWhichX ), -1, eWhichX );
2640 }
2641 
2643 {
2644  return CellsAtY( GetPosY( eWhichY ), -1, eWhichY );
2645 }
2646 
2647 bool ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix ) const
2648 {
2649  const ScMergeAttr* pMerge = pDoc->GetAttr( nX,nY,nTabNo, ATTR_MERGE );
2650  if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 )
2651  {
2652  long nOutWidth = 0;
2653  long nOutHeight = 0;
2654  SCCOL nCountX = pMerge->GetColMerge();
2655  for (SCCOL i=0; i<nCountX; i++)
2656  nOutWidth += ToPixel( pDoc->GetColWidth(nX+i,nTabNo), nPPTX );
2657  SCROW nCountY = pMerge->GetRowMerge();
2658 
2659  for (SCROW nRow = nY; nRow <= nY+nCountY-1; ++nRow)
2660  {
2661  SCROW nLastRow = nRow;
2662  if (pDoc->RowHidden(nRow, nTabNo, nullptr, &nLastRow))
2663  {
2664  nRow = nLastRow;
2665  continue;
2666  }
2667 
2668  sal_uInt16 nHeight = pDoc->GetRowHeight(nRow, nTabNo);
2669  nOutHeight += ToPixel(nHeight, nPPTY);
2670  }
2671 
2672  rSizeXPix = nOutWidth;
2673  rSizeYPix = nOutHeight;
2674  return true;
2675  }
2676  else
2677  {
2678  rSizeXPix = ToPixel( pDoc->GetColWidth( nX, nTabNo ), nPPTX );
2679  rSizeYPix = ToPixel( pDoc->GetRowHeight( nY, nTabNo ), nPPTY );
2680  return false;
2681  }
2682 }
2683 
2684 bool ScViewData::GetMergeSizePrintTwips(SCCOL nX, SCROW nY, long& rSizeXTwips, long& rSizeYTwips) const
2685 {
2686  const ScMergeAttr* pMerge = pDoc->GetAttr(nX, nY, nTabNo, ATTR_MERGE);
2687  SCCOL nCountX = pMerge->GetColMerge();
2688  if (!nCountX)
2689  nCountX = 1;
2690  rSizeXTwips = pDoc->GetColWidth(nX, nX + nCountX - 1, nTabNo);
2691 
2692  SCROW nCountY = pMerge->GetRowMerge();
2693  if (!nCountY)
2694  nCountY = 1;
2695  rSizeYTwips = pDoc->GetRowHeight(nY, nY + nCountY - 1, nTabNo);
2696 
2697  return (nCountX > 1 || nCountY > 1);
2698 }
2699 
2700 void ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
2701  SCCOL& rPosX, SCROW& rPosY,
2702  bool bTestMerge, bool bRepair, SCTAB nForTab )
2703 {
2704  // special handling of 0 is now in ScViewFunctionSet::SetCursorAtPoint
2705 
2706  if (nForTab == -1)
2707  nForTab = nTabNo;
2708  bool bForCurTab = (nForTab == nTabNo);
2709  if (!bForCurTab && (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size()))))
2710  {
2711  SAL_WARN("sc.viewdata", "ScViewData::GetPosFromPixel : invalid nForTab = " << nForTab);
2712  nForTab = nTabNo;
2713  bForCurTab = true;
2714  }
2715 
2716  ScHSplitPos eHWhich = WhichH(eWhich);
2717  ScVSplitPos eVWhich = WhichV(eWhich);
2718 
2719  if ( pDoc->IsLayoutRTL( nForTab ) )
2720  {
2721  // mirror horizontal position
2722  if (pView)
2723  aScrSize.setWidth( pView->GetGridWidth(eHWhich) );
2724  nClickX = aScrSize.Width() - 1 - nClickX;
2725  }
2726 
2727  SCCOL nStartPosX = GetPosX(eHWhich, nForTab);
2728  SCROW nStartPosY = GetPosY(eVWhich, nForTab);
2729  rPosX = nStartPosX;
2730  rPosY = nStartPosY;
2731  long nScrX = 0;
2732  long nScrY = 0;
2733 
2734  if (nClickX > 0)
2735  {
2736  while ( rPosX<=pDoc->MaxCol() && nClickX >= nScrX )
2737  {
2738  nScrX += ToPixel( pDoc->GetColWidth( rPosX, nForTab ), nPPTX );
2739  ++rPosX;
2740  }
2741  --rPosX;
2742  }
2743  else
2744  {
2745  while ( rPosX>0 && nClickX < nScrX )
2746  {
2747  --rPosX;
2748  nScrX -= ToPixel( pDoc->GetColWidth( rPosX, nForTab ), nPPTX );
2749  }
2750  }
2751 
2752  if (nClickY > 0)
2753  AddPixelsWhile( nScrY, nClickY, rPosY, pDoc->MaxRow(), nPPTY, pDoc, nForTab );
2754  else
2755  {
2756  /* TODO: could need some "SubPixelsWhileBackward" method */
2757  while ( rPosY>0 && nClickY < nScrY )
2758  {
2759  --rPosY;
2760  nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nForTab ), nPPTY );
2761  }
2762  }
2763 
2764  // cells too big?
2765  if ( rPosX == nStartPosX && nClickX > 0 )
2766  {
2767  if (pView)
2768  aScrSize.setWidth( pView->GetGridWidth(eHWhich) );
2769  if ( nClickX > aScrSize.Width() )
2770  ++rPosX;
2771  }
2772  if ( rPosY == nStartPosY && nClickY > 0 )
2773  {
2774  if (pView)
2775  aScrSize.setHeight( pView->GetGridHeight(eVWhich) );
2776  if ( nClickY > aScrSize.Height() )
2777  ++rPosY;
2778  }
2779 
2780  if (rPosX<0) rPosX=0;
2781  if (rPosX>pDoc->MaxCol()) rPosX=pDoc->MaxCol();
2782  if (rPosY<0) rPosY=0;
2783  if (rPosY>pDoc->MaxRow()) rPosY=pDoc->MaxRow();
2784 
2785  if (bTestMerge && bForCurTab)
2786  {
2787  // public method to adapt position
2788  SCCOL nOrigX = rPosX;
2789  SCROW nOrigY = rPosY;
2790  pDoc->SkipOverlapped(rPosX, rPosY, nTabNo);
2791  bool bHOver = (nOrigX != rPosX);
2792  bool bVOver = (nOrigY != rPosY);
2793 
2794  if ( bRepair && ( bHOver || bVOver ) )
2795  {
2796  const ScMergeAttr* pMerge = pDoc->GetAttr( rPosX, rPosY, nTabNo, ATTR_MERGE );
2797  if ( ( bHOver && pMerge->GetColMerge() <= 1 ) ||
2798  ( bVOver && pMerge->GetRowMerge() <= 1 ) )
2799  {
2800  OSL_FAIL("merge error found");
2801 
2802  pDoc->RemoveFlagsTab( 0,0, pDoc->MaxCol(),pDoc->MaxRow(), nTabNo, ScMF::Hor | ScMF::Ver );
2803  SCCOL nEndCol = pDoc->MaxCol();
2804  SCROW nEndRow = pDoc->MaxRow();
2805  pDoc->ExtendMerge( 0,0, nEndCol,nEndRow, nTabNo, true );
2806  if (pDocShell)
2807  pDocShell->PostPaint( ScRange(0,0,nTabNo,pDoc->MaxCol(),pDoc->MaxRow(),nTabNo), PaintPartFlags::Grid );
2808  }
2809  }
2810  }
2811 }
2812 
2813 void ScViewData::GetMouseQuadrant( const Point& rClickPos, ScSplitPos eWhich,
2814  SCCOL nPosX, SCROW nPosY, bool& rLeft, bool& rTop )
2815 {
2816  bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
2817  long nLayoutSign = bLayoutRTL ? -1 : 1;
2818 
2819  Point aCellStart = GetScrPos( nPosX, nPosY, eWhich, true );
2820  long nSizeX;
2821  long nSizeY;
2822  GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
2823  rLeft = ( rClickPos.X() - aCellStart.X() ) * nLayoutSign <= nSizeX / 2;
2824  rTop = rClickPos.Y() - aCellStart.Y() <= nSizeY / 2;
2825 }
2826 
2827 void ScViewData::SetPosX( ScHSplitPos eWhich, SCCOL nNewPosX )
2828 {
2829  // in the tiled rendering case, nPosX [the leftmost visible column] must be 0
2830  bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
2831  if (nNewPosX != 0 && !bIsTiledRendering)
2832  {
2833  SCCOL nOldPosX = pThisTab->nPosX[eWhich];
2834  long nTPosX = pThisTab->nTPosX[eWhich];
2835  long nPixPosX = pThisTab->nPixPosX[eWhich];
2836  SCCOL i;
2837  if ( nNewPosX > nOldPosX )
2838  for ( i=nOldPosX; i<nNewPosX; i++ )
2839  {
2840  long nThis = pDoc->GetColWidth( i,nTabNo );
2841  nTPosX -= nThis;
2842  nPixPosX -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
2843  }
2844  else
2845  for ( i=nNewPosX; i<nOldPosX; i++ )
2846  {
2847  long nThis = pDoc->GetColWidth( i,nTabNo );
2848  nTPosX += nThis;
2849  nPixPosX += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
2850  }
2851 
2852  pThisTab->nPosX[eWhich] = nNewPosX;
2853  pThisTab->nTPosX[eWhich] = nTPosX;
2854  pThisTab->nMPosX[eWhich] = static_cast<long>(nTPosX * HMM_PER_TWIPS);
2855  pThisTab->nPixPosX[eWhich] = nPixPosX;
2856  }
2857  else
2858  {
2859  pThisTab->nPixPosX[eWhich] =
2860  pThisTab->nTPosX[eWhich] =
2861  pThisTab->nMPosX[eWhich] =
2862  pThisTab->nPosX[eWhich] = 0;
2863  }
2864 }
2865 
2866 void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY )
2867 {
2868  // in the tiled rendering case, nPosY [the topmost visible row] must be 0
2869  bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
2870  if (nNewPosY != 0 && !bIsTiledRendering)
2871  {
2872  SCROW nOldPosY = pThisTab->nPosY[eWhich];
2873  long nTPosY = pThisTab->nTPosY[eWhich];
2874  long nPixPosY = pThisTab->nPixPosY[eWhich];
2875  SCROW i, nHeightEndRow;
2876  if ( nNewPosY > nOldPosY )
2877  for ( i=nOldPosY; i<nNewPosY; i++ )
2878  {
2879  long nThis = pDoc->GetRowHeight( i, nTabNo, nullptr, &nHeightEndRow );
2880  SCROW nRows = std::min( nNewPosY, nHeightEndRow + 1) - i;
2881  i = nHeightEndRow;
2882  nTPosY -= nThis * nRows;
2883  nPixPosY -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
2884  }
2885  else
2886  for ( i=nNewPosY; i<nOldPosY; i++ )
2887  {
2888  long nThis = pDoc->GetRowHeight( i, nTabNo, nullptr, &nHeightEndRow );
2889  SCROW nRows = std::min( nOldPosY, nHeightEndRow + 1) - i;
2890  i = nHeightEndRow;
2891  nTPosY += nThis * nRows;
2892  nPixPosY += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
2893  }
2894 
2895  pThisTab->nPosY[eWhich] = nNewPosY;
2896  pThisTab->nTPosY[eWhich] = nTPosY;
2897  pThisTab->nMPosY[eWhich] = static_cast<long>(nTPosY * HMM_PER_TWIPS);
2898  pThisTab->nPixPosY[eWhich] = nPixPosY;
2899  }
2900  else
2901  {
2902  pThisTab->nPixPosY[eWhich] =
2903  pThisTab->nTPosY[eWhich] =
2904  pThisTab->nMPosY[eWhich] =
2905  pThisTab->nPosY[eWhich] = 0;
2906  }
2907 }
2908 
2909 void ScViewData::RecalcPixPos() // after zoom changes
2910 {
2911  for (sal_uInt16 eWhich=0; eWhich<2; eWhich++)
2912  {
2913  long nPixPosX = 0;
2914  SCCOL nPosX = pThisTab->nPosX[eWhich];
2915  for (SCCOL i=0; i<nPosX; i++)
2916  nPixPosX -= ToPixel(pDoc->GetColWidth(i,nTabNo), nPPTX);
2917  pThisTab->nPixPosX[eWhich] = nPixPosX;
2918 
2919  long nPixPosY = 0;
2920  SCROW nPosY = pThisTab->nPosY[eWhich];
2921  for (SCROW j=0; j<nPosY; j++)
2922  nPixPosY -= ToPixel(pDoc->GetRowHeight(j,nTabNo), nPPTY);
2923  pThisTab->nPixPosY[eWhich] = nPixPosY;
2924  }
2925 }
2926 
2928 {
2930  pThisTab->nMPosY[WhichV(eWhich)] ) );
2931  return aLogicMode;
2932 }
2933 
2935 {
2936  aLogicMode.SetOrigin( Point() );
2937  return aLogicMode;
2938 }
2939 
2940 void ScViewData::SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2941 {
2942  SCCOL nCol;
2943  SCROW nRow;
2944  sal_uInt16 nTSize;
2945  long nSizePix;
2946  long nScrPosX = 0;
2947  long nScrPosY = 0;
2948 
2950  SetPosX( SC_SPLIT_LEFT, nCol1 );
2951  SetPosY( SC_SPLIT_BOTTOM, nRow1 );
2952 
2953  for (nCol=nCol1; nCol<=nCol2; nCol++)
2954  {
2955  nTSize = pDoc->GetColWidth( nCol, nTabNo );
2956  if (nTSize)
2957  {
2958  nSizePix = ToPixel( nTSize, nPPTX );
2959  nScrPosX += static_cast<sal_uInt16>(nSizePix);
2960  }
2961  }
2962 
2963  for (nRow=nRow1; nRow<=nRow2; nRow++)
2964  {
2965  nTSize = pDoc->GetRowHeight( nRow, nTabNo );
2966  if (nTSize)
2967  {
2968  nSizePix = ToPixel( nTSize, nPPTY );
2969  nScrPosY += static_cast<sal_uInt16>(nSizePix);
2970  }
2971  }
2972 
2973  aScrSize = Size( nScrPosX, nScrPosY );
2974 }
2975 
2976 void ScViewData::SetScreenPos( const Point& rVisAreaStart )
2977 {
2978  long nSize;
2979  long nTwips;
2980  long nAdd;
2981  bool bEnd;
2982 
2983  nSize = 0;
2984  nTwips = static_cast<long>(rVisAreaStart.X() / HMM_PER_TWIPS);
2985  if ( pDoc->IsLayoutRTL( nTabNo ) )
2986  nTwips = -nTwips;
2987  SCCOL nX1 = 0;
2988  bEnd = false;
2989  while (!bEnd)
2990  {
2991  nAdd = static_cast<long>(pDoc->GetColWidth(nX1,nTabNo));
2992  if (nSize+nAdd <= nTwips+1 && nX1<pDoc->MaxCol())
2993  {
2994  nSize += nAdd;
2995  ++nX1;
2996  }
2997  else
2998  bEnd = true;
2999  }
3000 
3001  nSize = 0;
3002  nTwips = static_cast<long>(rVisAreaStart.Y() / HMM_PER_TWIPS);
3003  SCROW nY1 = 0;
3004  bEnd = false;
3005  while (!bEnd)
3006  {
3007  nAdd = static_cast<long>(pDoc->GetRowHeight(nY1,nTabNo));
3008  if (nSize+nAdd <= nTwips+1 && nY1<pDoc->MaxRow())
3009  {
3010  nSize += nAdd;
3011  ++nY1;
3012  }
3013  else
3014  bEnd = true;
3015  }
3016 
3018  SetPosX( SC_SPLIT_LEFT, nX1 );
3019  SetPosY( SC_SPLIT_BOTTOM, nY1 );
3020 
3021  SetCurX( nX1 );
3022  SetCurY( nY1 );
3023 }
3024 
3026 {
3027  SetScreenPos( rVisArea.TopLeft() );
3028 
3029  // here without GetOutputFactor(), since it's for the output into a Metafile
3030 
3031  aScrSize = rVisArea.GetSize();
3032  aScrSize.setWidth( static_cast<long>( aScrSize.Width() * ScGlobal::nScreenPPTX / HMM_PER_TWIPS ) );
3033  aScrSize.setHeight( static_cast<long>( aScrSize.Height() * ScGlobal::nScreenPPTY / HMM_PER_TWIPS ) );
3034 }
3035 
3037 {
3038  return pDocShell->GetDocFunc();
3039 }
3040 
3042 {
3043  assert(pViewShell && "GetBindings() without ViewShell");
3044  return pViewShell->GetViewFrame()->GetBindings();
3045 }
3046 
3048 {
3049  assert(pViewShell && "GetDispatcher() without ViewShell");
3050  return *pViewShell->GetViewFrame()->GetDispatcher();
3051 }
3052 
3054 {
3055  return *mpMarkData;
3056 }
3057 
3059 {
3060  return *mpMarkData;
3061 }
3062 
3064 {
3065  assert(pViewShell && "GetDialogParent() without ViewShell");
3066  return pViewShell->GetDialogParent();
3067 }
3068 
3070 {
3071  assert(pView && "GetActiveWin() without View");
3072  return pView->GetActiveWin();
3073 }
3074 
3076 {
3077  assert(pView && "GetActiveWin() without View");
3078  return pView->GetActiveWin();
3079 }
3080 
3082 {
3083  assert(pView && "GetScDrawView() without View");
3084  return pView->GetScDrawView();
3085 }
3086 
3088 {
3089  assert(pView && "IsMinimized() without View");
3090  return pView->IsMinimized();
3091 }
3092 
3093 void ScViewData::UpdateScreenZoom( const Fraction& rNewX, const Fraction& rNewY )
3094 {
3095  Fraction aOldX = GetZoomX();
3096  Fraction aOldY = GetZoomY();
3097 
3098  SetZoom( rNewX, rNewY, false );
3099 
3100  Fraction aWidth = GetZoomX();
3101  aWidth *= Fraction( aScrSize.Width(),1 );
3102  aWidth /= aOldX;
3103 
3104  Fraction aHeight = GetZoomY();
3105  aHeight *= Fraction( aScrSize.Height(),1 );
3106  aHeight /= aOldY;
3107 
3108  aScrSize.setWidth( static_cast<long>(aWidth) );
3109  aScrSize.setHeight( static_cast<long>(aHeight) );
3110 }
3111 
3113 {
3114  double nOldPPTX = nPPTX;
3115  double nOldPPTY = nPPTY;
3116  nPPTX = ScGlobal::nScreenPPTX * static_cast<double>(GetZoomX());
3117  if (pDocShell)
3118  nPPTX = nPPTX / pDocShell->GetOutputFactor(); // Factor is printer to screen
3119  nPPTY = ScGlobal::nScreenPPTY * static_cast<double>(GetZoomY());
3120 
3121  // if detective objects are present,
3122  // try to adjust horizontal scale so the most common column width has minimal rounding errors,
3123  // to avoid differences between cell and drawing layer output
3124 
3125  if ( pDoc && pDoc->HasDetectiveObjects(nTabNo) )
3126  {
3127  SCCOL nEndCol = 0;
3128  SCROW nDummy = 0;
3129  pDoc->GetTableArea( nTabNo, nEndCol, nDummy );
3130  if (nEndCol<20)
3131  nEndCol = 20; // same end position as when determining draw scale
3132 
3133  sal_uInt16 nTwips = pDoc->GetCommonWidth( nEndCol, nTabNo );
3134  if ( nTwips )
3135  {
3136  double fOriginal = nTwips * nPPTX;
3137  if ( fOriginal < static_cast<double>(nEndCol) )
3138  {
3139  // if one column is smaller than the column count,
3140  // rounding errors are likely to add up to a whole column.
3141 
3142  double fRounded = ::rtl::math::approxFloor( fOriginal + 0.5 );
3143  if ( fRounded > 0.0 )
3144  {
3145  double fScale = fRounded / fOriginal + 1E-6;
3146  if ( fScale >= 0.9 && fScale <= 1.1 )
3147  nPPTX *= fScale;
3148  }
3149  }
3150  }
3151  }
3152 
3153  if (nPPTX != nOldPPTX)
3155  if (nPPTY != nOldPPTY)
3157 }
3158 
3159 #define SC_OLD_TABSEP '/'
3160 #define SC_NEW_TABSEP '+'
3161 
3162 void ScViewData::WriteUserData(OUString& rData)
3163 {
3164  // nZoom (until 364v) or nZoom/nPageZoom/bPageMode (from 364w)
3165  // nTab
3166  // Tab control width
3167  // per sheet:
3168  // CursorX/CursorY/HSplitMode/VSplitMode/HSplitPos/VSplitPos/SplitActive/
3169  // PosX[left]/PosX[right]/PosY[top]/PosY[bottom]
3170  // when rows bigger than 8192, "+" instead of "/"
3171 
3172  sal_uInt16 nZoom = static_cast<sal_uInt16>(long(pThisTab->aZoomY * 100));
3173  rData = OUString::number( nZoom ) + "/";
3174  nZoom = static_cast<sal_uInt16>(long(pThisTab->aPageZoomY * 100));
3175  rData += OUString::number( nZoom ) + "/";
3176  if (bPagebreak)
3177  rData += "1";
3178  else
3179  rData += "0";
3180 
3181  rData += ";" + OUString::number( nTabNo ) + ";" TAG_TABBARWIDTH +
3182  OUString::number( pView->GetTabBarWidth() );
3183 
3184  SCTAB nTabCount = pDoc->GetTableCount();
3185  for (SCTAB i=0; i<nTabCount; i++)
3186  {
3187  rData += ";"; // Numbering must not get mixed up under any circumstances
3188  if (i < static_cast<SCTAB>(maTabData.size()) && maTabData[i])
3189  {
3190  OUString cTabSep(SC_OLD_TABSEP); // like 3.1
3191  if ( maTabData[i]->nCurY > MAXROW_30 ||
3192  maTabData[i]->nPosY[0] > MAXROW_30 || maTabData[i]->nPosY[1] > MAXROW_30 ||
3193  ( maTabData[i]->eVSplitMode == SC_SPLIT_FIX &&
3194  maTabData[i]->nFixPosY > MAXROW_30 ) )
3195  {
3196  cTabSep = OUStringChar(SC_NEW_TABSEP); // in order to not kill a 3.1-version
3197  }
3198 
3199  rData += OUString::number( maTabData[i]->nCurX ) + cTabSep +
3200  OUString::number( maTabData[i]->nCurY ) + cTabSep +
3201  OUString::number( maTabData[i]->eHSplitMode ) + cTabSep +
3202  OUString::number( maTabData[i]->eVSplitMode ) + cTabSep;
3203  if ( maTabData[i]->eHSplitMode == SC_SPLIT_FIX )
3204  rData += OUString::number( maTabData[i]->nFixPosX );
3205  else
3206  rData += OUString::number( maTabData[i]->nHSplitPos );
3207  rData += cTabSep;
3208  if ( maTabData[i]->eVSplitMode == SC_SPLIT_FIX )
3209  rData += OUString::number( maTabData[i]->nFixPosY );
3210  else
3211  rData += OUString::number( maTabData[i]->nVSplitPos );
3212  rData += cTabSep +
3213  OUString::number( maTabData[i]->eWhichActive ) + cTabSep +
3214  OUString::number( maTabData[i]->nPosX[0] ) + cTabSep +
3215  OUString::number( maTabData[i]->nPosX[1] ) + cTabSep +
3216  OUString::number( maTabData[i]->nPosY[0] ) + cTabSep +
3217  OUString::number( maTabData[i]->nPosY[1] );
3218  }
3219  }
3220 }
3221 
3222 void ScViewData::ReadUserData(const OUString& rData)
3223 {
3224  if (rData.isEmpty()) // empty string on "reload"
3225  return; // then exit without assertion
3226 
3227  if ( comphelper::string::getTokenCount(rData, ';') <= 2 )
3228  {
3229  // when reload, in page preview, the preview UserData may have been left intact.
3230  // we don't want the zoom from the page preview here.
3231  OSL_FAIL("ReadUserData: This is not my data");
3232  return;
3233  }
3234 
3235  Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY; // evaluate (all sheets?)
3236 
3237  sal_Int32 nMainIdx {0};
3238  sal_Int32 nIdx {0};
3239 
3240  OUString aZoomStr = rData.getToken(0, ';', nMainIdx); // Zoom/PageZoom/Mode
3241  sal_uInt16 nNormZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.getToken(0, '/', nIdx).toInt32());
3242  if ( nNormZoom >= MINZOOM && nNormZoom <= MAXZOOM )
3243  aZoomX = aZoomY = Fraction( nNormZoom, 100 ); // "normal" zoom (always)
3244  sal_uInt16 nPageZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.getToken(0, '/', nIdx).toInt32());
3245  if ( nPageZoom >= MINZOOM && nPageZoom <= MAXZOOM )
3246  aPageZoomX = aPageZoomY = Fraction( nPageZoom, 100 ); // Pagebreak zoom, if set
3247  sal_Unicode cMode = aZoomStr.getToken(0, '/', nIdx)[0]; // 0 or "0"/"1"
3248  SetPagebreakMode( cMode == '1' );
3249  // SetPagebreakMode must always be called due to CalcPPT / RecalcPixPos()
3250 
3251  // sheet may have become invalid (for instance last version):
3252  SCTAB nNewTab = static_cast<SCTAB>(rData.getToken(0, ';', nMainIdx).toUInt32());
3253  if (pDoc->HasTable( nNewTab ))
3254  SetTabNo(nNewTab);
3255 
3256  // if available, get tab bar width:
3257  const sal_Int32 nMainIdxRef {nMainIdx};
3258  OUString aTabOpt = rData.getToken(0, ';', nMainIdx);
3259 
3260  OUString aRest;
3261  if (aTabOpt.startsWith(TAG_TABBARWIDTH, &aRest))
3262  {
3263  pView->SetTabBarWidth(aRest.toInt32());
3264  }
3265  else
3266  {
3267  // Tab bar width not specified, token to be processed again
3268  nMainIdx = nMainIdxRef;
3269  }
3270 
3271  // per sheet
3272  SCTAB nPos = 0;
3273  while ( nMainIdx>0 )
3274  {
3275  aTabOpt = rData.getToken(0, ';', nMainIdx);
3276  EnsureTabDataSize(nPos + 1);
3277  if (!maTabData[nPos])
3278  maTabData[nPos].reset( new ScViewDataTable(pDoc) );
3279 
3280  sal_Unicode cTabSep = 0;
3282  cTabSep = SC_OLD_TABSEP;
3283  else if (comphelper::string::getTokenCount(aTabOpt, SC_NEW_TABSEP) >= 11)
3284  cTabSep = SC_NEW_TABSEP;
3285  // '+' is only allowed, if we can deal with rows > 8192
3286 
3287  if (cTabSep)
3288  {
3289  nIdx = 0;
3290  maTabData[nPos]->nCurX = pDoc->SanitizeCol( static_cast<SCCOL>(aTabOpt.getToken(0, cTabSep, nIdx).toInt32()));
3291  maTabData[nPos]->nCurY = pDoc->SanitizeRow( aTabOpt.getToken(0, cTabSep, nIdx).toInt32());
3292  maTabData[nPos]->eHSplitMode = static_cast<ScSplitMode>(aTabOpt.getToken(0, cTabSep, nIdx).toInt32());
3293  maTabData[nPos]->eVSplitMode = static_cast<ScSplitMode>(aTabOpt.getToken(0, cTabSep, nIdx).toInt32());
3294 
3295  sal_Int32 nTmp{ aTabOpt.getToken(0, cTabSep, nIdx).toInt32() };
3296  if ( maTabData[nPos]->eHSplitMode == SC_SPLIT_FIX )
3297  {
3298  maTabData[nPos]->nFixPosX = pDoc->SanitizeCol( static_cast<SCCOL>(nTmp));
3299  UpdateFixX(nPos);
3300  }
3301  else
3302  maTabData[nPos]->nHSplitPos = nTmp;
3303 
3304  nTmp = aTabOpt.getToken(0, cTabSep, nIdx).toInt32();
3305  if ( maTabData[nPos]->eVSplitMode == SC_SPLIT_FIX )
3306  {
3307  maTabData[nPos]->nFixPosY = pDoc->SanitizeRow(nTmp);
3308  UpdateFixY(nPos);
3309  }
3310  else
3311  maTabData[nPos]->nVSplitPos = nTmp;
3312 
3313  maTabData[nPos]->eWhichActive = static_cast<ScSplitPos>(aTabOpt.getToken(0, cTabSep, nIdx).toInt32());
3314  maTabData[nPos]->nPosX[0] = pDoc->SanitizeCol( static_cast<SCCOL>(aTabOpt.getToken(0, cTabSep, nIdx).toInt32()));
3315  maTabData[nPos]->nPosX[1] = pDoc->SanitizeCol( static_cast<SCCOL>(aTabOpt.getToken(0, cTabSep, nIdx).toInt32()));
3316  maTabData[nPos]->nPosY[0] = pDoc->SanitizeRow( aTabOpt.getToken(0, cTabSep, nIdx).toInt32());
3317  maTabData[nPos]->nPosY[1] = pDoc->SanitizeRow( aTabOpt.getToken(0, cTabSep, nIdx).toInt32());
3318 
3319  maTabData[nPos]->eWhichActive = maTabData[nPos]->SanitizeWhichActive();
3320  }
3321  ++nPos;
3322  }
3323 
3324  RecalcPixPos();
3325 }
3326 
3328 {
3329  // *** Fill extended document data for export filters ***
3330 
3331  // document settings
3332  ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
3333 
3334  // displayed sheet
3335  rDocSett.mnDisplTab = GetTabNo();
3336 
3337  // width of the tabbar, relative to frame window width
3339  if( rDocSett.mfTabBarWidth < 0.0 )
3341 
3342  bool bLOKActive = comphelper::LibreOfficeKit::isActive();
3343 
3344  // sheet settings
3345  for( SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabData.size()); ++nTab )
3346  {
3347  if( const ScViewDataTable* pViewTab = maTabData[ nTab ].get() )
3348  {
3349  ScExtTabSettings& rTabSett = rDocOpt.GetOrCreateTabSettings( nTab );
3350 
3351  // split mode
3352  ScSplitMode eExHSplit = pViewTab->eHSplitMode;
3353  ScSplitMode eExVSplit = pViewTab->eVSplitMode;
3354  SCCOL nExFixPosX = pViewTab->nFixPosX;
3355  SCROW nExFixPosY = pViewTab->nFixPosY;
3356  long nExHSplitPos = pViewTab->nHSplitPos;
3357  long nExVSplitPos = pViewTab->nVSplitPos;
3358 
3359  if (bLOKActive)
3360  {
3361  OverrideWithLOKFreeze(eExHSplit, eExVSplit,
3362  nExFixPosX, nExFixPosY,
3363  nExHSplitPos, nExVSplitPos, nTab);
3364  }
3365 
3366  bool bHSplit = eExHSplit != SC_SPLIT_NONE;
3367  bool bVSplit = eExVSplit != SC_SPLIT_NONE;
3368  bool bRealSplit = (eExHSplit == SC_SPLIT_NORMAL) || (eExVSplit == SC_SPLIT_NORMAL);
3369  bool bFrozen = (eExHSplit == SC_SPLIT_FIX) || (eExVSplit == SC_SPLIT_FIX);
3370  OSL_ENSURE( !bRealSplit || !bFrozen, "ScViewData::WriteExtOptions - split and freeze in same sheet" );
3371  rTabSett.mbFrozenPanes = !bRealSplit && bFrozen;
3372 
3373  // split and freeze position
3374  rTabSett.maSplitPos = Point( 0, 0 );
3375  rTabSett.maFreezePos.Set( 0, 0, nTab );
3376  if( bRealSplit )
3377  {
3378  Point& rSplitPos = rTabSett.maSplitPos;
3379  rSplitPos = Point( bHSplit ? nExHSplitPos : 0, bVSplit ? nExVSplitPos : 0 );
3380  rSplitPos = Application::GetDefaultDevice()->PixelToLogic( rSplitPos, MapMode( MapUnit::MapTwip ) );
3381  if( pDocShell )
3382  rSplitPos.setX( static_cast<long>(static_cast<double>(rSplitPos.X()) / pDocShell->GetOutputFactor()) );
3383  }
3384  else if( bFrozen )
3385  {
3386  if( bHSplit ) rTabSett.maFreezePos.SetCol( nExFixPosX );
3387  if( bVSplit ) rTabSett.maFreezePos.SetRow( nExFixPosY );
3388  }
3389 
3390  // first visible cell in top-left and additional panes
3391  rTabSett.maFirstVis.Set( pViewTab->nPosX[ SC_SPLIT_LEFT ], pViewTab->nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ], nTab );
3392  rTabSett.maSecondVis.Set( pViewTab->nPosX[ SC_SPLIT_RIGHT ], pViewTab->nPosY[ SC_SPLIT_BOTTOM ], nTab );
3393 
3394  // active pane
3395  switch( pViewTab->eWhichActive )
3396  {
3397  // no horizontal split -> always use left panes
3398  // no vertical split -> always use top panes
3399  case SC_SPLIT_TOPLEFT:
3400  rTabSett.meActivePane = SCEXT_PANE_TOPLEFT;
3401  break;
3402  case SC_SPLIT_TOPRIGHT:
3403  rTabSett.meActivePane = bHSplit ? SCEXT_PANE_TOPRIGHT : SCEXT_PANE_TOPLEFT;
3404  break;
3405  case SC_SPLIT_BOTTOMLEFT:
3406  rTabSett.meActivePane = bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT;
3407  break;
3408  case SC_SPLIT_BOTTOMRIGHT:
3409  rTabSett.meActivePane = bHSplit ?
3412  break;
3413  }
3414 
3415  // cursor position
3416  rTabSett.maCursor.Set( pViewTab->nCurX, pViewTab->nCurY, nTab );
3417 
3418  // sheet selection and selected ranges
3419  const ScMarkData& rMarkData = GetMarkData();
3420  rTabSett.mbSelected = rMarkData.GetTableSelect( nTab );
3421  rMarkData.FillRangeListWithMarks( &rTabSett.maSelection, true );
3422 
3423  // grid color
3424  rTabSett.maGridColor = COL_AUTO;
3425  if( pOptions )
3426  {
3427  const Color& rGridColor = pOptions->GetGridColor();
3428  if( rGridColor != SC_STD_GRIDCOLOR )
3429  rTabSett.maGridColor = rGridColor;
3430  }
3431  rTabSett.mbShowGrid = pViewTab->bShowGrid;
3432 
3433  // view mode and zoom
3434  rTabSett.mbPageMode = bPagebreak;
3435  rTabSett.mnNormalZoom = static_cast< long >( pViewTab->aZoomY * Fraction( 100.0 ) );
3436  rTabSett.mnPageZoom = static_cast< long >( pViewTab->aPageZoomY * Fraction( 100.0 ) );
3437  }
3438  }
3439 }
3440 
3442 {
3443  // *** Get extended document data from import filters ***
3444 
3445  if( !rDocOpt.IsChanged() ) return;
3446 
3447  // document settings
3448  const ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
3449 
3450  // displayed sheet
3451  SetTabNo( rDocSett.mnDisplTab );
3452 
3453  /* Width of the tabbar, relative to frame window width. We do not have the
3454  correct width of the frame window here -> store in ScTabView, which sets
3455  the size in the next resize. */
3457 
3458  // sheet settings
3459  SCTAB nLastTab = rDocOpt.GetLastTab();
3460  if (static_cast<SCTAB>(maTabData.size()) <= nLastTab)
3461  maTabData.resize(nLastTab+1);
3462 
3463  for( SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabData.size()); ++nTab )
3464  {
3465  if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nTab ) )
3466  {
3467  if( !maTabData[ nTab ] )
3468  maTabData[ nTab ].reset( new ScViewDataTable(pDoc) );
3469 
3470  const ScExtTabSettings& rTabSett = *pTabSett;
3471  ScViewDataTable& rViewTab = *maTabData[ nTab ];
3472 
3473  // split mode initialization
3474  bool bFrozen = rTabSett.mbFrozenPanes;
3475  bool bHSplit = bFrozen ? (rTabSett.maFreezePos.Col() > 0) : (rTabSett.maSplitPos.X() > 0);
3476  bool bVSplit = bFrozen ? (rTabSett.maFreezePos.Row() > 0) : (rTabSett.maSplitPos.Y() > 0);
3477 
3478  // first visible cell of top-left pane and additional panes
3479  if (rTabSett.maFirstVis.IsValid())
3480  {
3481  rViewTab.nPosX[ SC_SPLIT_LEFT ] = rTabSett.maFirstVis.Col();
3482  rViewTab.nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ] = rTabSett.maFirstVis.Row();
3483  }
3484 
3485  if (rTabSett.maSecondVis.IsValid())
3486  {
3487  if (bHSplit)
3488  rViewTab.nPosX[ SC_SPLIT_RIGHT ] = rTabSett.maSecondVis.Col();
3489  if (bVSplit)
3490  rViewTab.nPosY[ SC_SPLIT_BOTTOM ] = rTabSett.maSecondVis.Row();
3491  }
3492 
3493  // split mode, split and freeze position
3494  rViewTab.eHSplitMode = rViewTab.eVSplitMode = SC_SPLIT_NONE;
3495  rViewTab.nHSplitPos = rViewTab.nVSplitPos = 0;
3496  rViewTab.nFixPosX = 0;
3497  rViewTab.nFixPosY = 0;
3498  if( bFrozen )
3499  {
3500  if( bHSplit )
3501  {
3502  rViewTab.eHSplitMode = SC_SPLIT_FIX;
3503  rViewTab.nFixPosX = rTabSett.maFreezePos.Col();
3504  UpdateFixX( nTab );
3505  }
3506  if( bVSplit )
3507  {
3508  rViewTab.eVSplitMode = SC_SPLIT_FIX;
3509  rViewTab.nFixPosY = rTabSett.maFreezePos.Row();
3510  UpdateFixY( nTab );
3511  }
3512  }
3513  else
3514  {
3516  rTabSett.maSplitPos, MapMode( MapUnit::MapTwip ) );
3517  // the test for use of printer metrics for text formatting here
3518  // effectively results in the nFactor = 1.0 regardless of the Option setting.
3519  if( pDocShell && SC_MOD()->GetInputOptions().GetTextWysiwyg())
3520  {
3521  double nFactor = pDocShell->GetOutputFactor();
3522  aPixel.setX( static_cast<long>( aPixel.X() * nFactor + 0.5 ) );
3523  }
3524 
3525  bHSplit = bHSplit && aPixel.X() > 0;
3526  bVSplit = bVSplit && aPixel.Y() > 0;
3527  if( bHSplit )
3528  {
3529  rViewTab.eHSplitMode = SC_SPLIT_NORMAL;
3530  rViewTab.nHSplitPos = aPixel.X();
3531  }
3532  if( bVSplit )
3533  {
3534  rViewTab.eVSplitMode = SC_SPLIT_NORMAL;
3535  rViewTab.nVSplitPos = aPixel.Y();
3536  }
3537  }
3538 
3539  // active pane
3541  switch( rTabSett.meActivePane )
3542  {
3543  // no horizontal split -> always use left panes
3544  // no vertical split -> always use *bottom* panes
3545  case SCEXT_PANE_TOPLEFT:
3546  ePos = bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
3547  break;
3548  case SCEXT_PANE_TOPRIGHT:
3549  ePos = bHSplit ?
3550  (bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT) :
3551  (bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT);
3552  break;
3553  case SCEXT_PANE_BOTTOMLEFT:
3554  ePos = SC_SPLIT_BOTTOMLEFT;
3555  break;
3557  ePos = bHSplit ? SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_BOTTOMLEFT;
3558  break;
3559  }
3560  rViewTab.eWhichActive = ePos;
3561 
3562  // cursor position
3563  const ScAddress& rCursor = rTabSett.maCursor;
3564  if( rCursor.IsValid() )
3565  {
3566  rViewTab.nCurX = rCursor.Col();
3567  rViewTab.nCurY = rCursor.Row();
3568  }
3569 
3570  // sheet selection and selected ranges
3571  ScMarkData& rMarkData = GetMarkData();
3572  rMarkData.SelectTable( nTab, rTabSett.mbSelected );
3573 
3574  // zoom for each sheet
3575  if( rTabSett.mnNormalZoom )
3576  rViewTab.aZoomX = rViewTab.aZoomY = Fraction( rTabSett.mnNormalZoom, 100 );
3577  if( rTabSett.mnPageZoom )
3578  rViewTab.aPageZoomX = rViewTab.aPageZoomY = Fraction( rTabSett.mnPageZoom, 100 );
3579 
3580  rViewTab.bShowGrid = rTabSett.mbShowGrid;
3581 
3582  // get some settings from displayed Excel sheet, set at Calc document
3583  if( nTab == GetTabNo() )
3584  {
3585  // grid color -- #i47435# set automatic grid color explicitly
3586  if( pOptions )
3587  {
3588  Color aGridColor( rTabSett.maGridColor );
3589  if( aGridColor == COL_AUTO )
3590  aGridColor = SC_STD_GRIDCOLOR;
3591  pOptions->SetGridColor( aGridColor, EMPTY_OUSTRING );
3592  }
3593 
3594  // view mode and default zoom (for new sheets) from current sheet
3595  if( rTabSett.mnNormalZoom )
3596  aDefZoomX = aDefZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
3597  if( rTabSett.mnPageZoom )
3598  aDefPageZoomX = aDefPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
3599  /* #i46820# set pagebreak mode via SetPagebreakMode(), this will
3600  update map modes that are needed to draw text correctly. */
3601  SetPagebreakMode( rTabSett.mbPageMode );
3602  }
3603  }
3604  }
3605 
3608 
3609  // RecalcPixPos or so - also nMPos - also for ReadUserData ??!?!
3610 }
3611 
3612 void ScViewData::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings) const
3613 {
3614  rSettings.realloc(SC_VIEWSETTINGS_COUNT);
3615  // + 1, because we have to put the view id in the sequence
3616  beans::PropertyValue* pSettings = rSettings.getArray();
3617 
3618  sal_uInt16 nViewID(pViewShell->GetViewFrame()->GetCurViewId());
3619  pSettings[SC_VIEW_ID].Name = SC_VIEWID;
3620  pSettings[SC_VIEW_ID].Value <<= SC_VIEW + OUString::number(nViewID);
3621 
3622  uno::Reference<container::XNameContainer> xNameContainer =
3623  document::NamedPropertyValues::create( comphelper::getProcessComponentContext() );
3624  for (SCTAB nTab=0; nTab<static_cast<SCTAB>(maTabData.size()); nTab++)
3625  {
3626  if (maTabData[nTab])
3627  {
3628  uno::Sequence <beans::PropertyValue> aTableViewSettings;
3629  maTabData[nTab]->WriteUserDataSequence(aTableViewSettings, *this, nTab);
3630  OUString sTabName;
3631  GetDocument()->GetName( nTab, sTabName );
3632  try
3633  {
3634  xNameContainer->insertByName(sTabName, uno::Any(aTableViewSettings));
3635  }
3636  //#101739#; two tables with the same name are possible
3637  catch ( container::ElementExistException& )
3638  {
3639  OSL_FAIL("seems there are two tables with the same name");
3640  }
3641  catch ( uno::RuntimeException& )
3642  {
3643  OSL_FAIL("something went wrong");
3644  }
3645  }
3646  }
3647  pSettings[SC_TABLE_VIEWSETTINGS].Name = SC_TABLES;
3648  pSettings[SC_TABLE_VIEWSETTINGS].Value <<= xNameContainer;
3649 
3650  OUString sName;
3651  GetDocument()->GetName( nTabNo, sName );
3652  pSettings[SC_ACTIVE_TABLE].Name = SC_ACTIVETABLE;
3653  pSettings[SC_ACTIVE_TABLE].Value <<= sName;
3655  pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Value <<= sal_Int32(pView->GetTabBarWidth());
3656  sal_Int32 nZoomValue = long(pThisTab->aZoomY * 100);
3657  sal_Int32 nPageZoomValue = long(pThisTab->aPageZoomY * 100);
3658  pSettings[SC_ZOOM_TYPE].Name = SC_ZOOMTYPE;
3659  pSettings[SC_ZOOM_TYPE].Value <<= sal_Int16(pThisTab->eZoomType);
3660  pSettings[SC_ZOOM_VALUE].Name = SC_ZOOMVALUE;
3661  pSettings[SC_ZOOM_VALUE].Value <<= nZoomValue;
3663  pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
3665  pSettings[SC_PAGE_BREAK_PREVIEW].Value <<= bPagebreak;
3666 
3667  if (pOptions)
3668  {
3669  pSettings[SC_SHOWZERO].Name = SC_UNO_SHOWZERO;
3670  pSettings[SC_SHOWZERO].Value <<= pOptions->GetOption( VOPT_NULLVALS );
3671  pSettings[SC_SHOWNOTES].Name = SC_UNO_SHOWNOTES;
3672  pSettings[SC_SHOWNOTES].Value <<= pOptions->GetOption( VOPT_NOTES );
3673  pSettings[SC_SHOWGRID].Name = SC_UNO_SHOWGRID;
3674  pSettings[SC_SHOWGRID].Value <<= pOptions->GetOption( VOPT_GRID );
3675  pSettings[SC_GRIDCOLOR].Name = SC_UNO_GRIDCOLOR;
3676  OUString aColorName;
3677  Color aColor = pOptions->GetGridColor(&aColorName);
3678  pSettings[SC_GRIDCOLOR].Value <<= aColor;
3679  pSettings[SC_SHOWPAGEBR].Name = SC_UNO_SHOWPAGEBR;
3680  pSettings[SC_SHOWPAGEBR].Value <<= pOptions->GetOption( VOPT_PAGEBREAKS );
3681  pSettings[SC_COLROWHDR].Name = SC_UNO_COLROWHDR;
3682  pSettings[SC_COLROWHDR].Value <<= pOptions->GetOption( VOPT_HEADER );
3683  pSettings[SC_SHEETTABS].Name = SC_UNO_SHEETTABS;
3684  pSettings[SC_SHEETTABS].Value <<= pOptions->GetOption( VOPT_TABCONTROLS );
3685  pSettings[SC_OUTLSYMB].Name = SC_UNO_OUTLSYMB;
3686  pSettings[SC_OUTLSYMB].Value <<= pOptions->GetOption( VOPT_OUTLINER );
3687  pSettings[SC_VALUE_HIGHLIGHTING].Name = SC_UNO_VALUEHIGH;
3688  pSettings[SC_VALUE_HIGHLIGHTING].Value <<= pOptions->GetOption( VOPT_SYNTAX );
3689 
3690  const ScGridOptions& aGridOpt = pOptions->GetGridOptions();
3691  pSettings[SC_SNAPTORASTER].Name = SC_UNO_SNAPTORASTER;
3692  pSettings[SC_SNAPTORASTER].Value <<= aGridOpt.GetUseGridSnap();
3693  pSettings[SC_RASTERVIS].Name = SC_UNO_RASTERVIS;
3694  pSettings[SC_RASTERVIS].Value <<= aGridOpt.GetGridVisible();
3695  pSettings[SC_RASTERRESX].Name = SC_UNO_RASTERRESX;
3696  pSettings[SC_RASTERRESX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFieldDrawX() );
3697  pSettings[SC_RASTERRESY].Name = SC_UNO_RASTERRESY;
3698  pSettings[SC_RASTERRESY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFieldDrawY() );
3699  pSettings[SC_RASTERSUBX].Name = SC_UNO_RASTERSUBX;
3700  pSettings[SC_RASTERSUBX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFieldDivisionX() );
3701  pSettings[SC_RASTERSUBY].Name = SC_UNO_RASTERSUBY;
3702  pSettings[SC_RASTERSUBY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFieldDivisionY() );
3703  pSettings[SC_RASTERSYNC].Name = SC_UNO_RASTERSYNC;
3704  pSettings[SC_RASTERSYNC].Value <<= aGridOpt.GetSynchronize();
3705  }
3706 
3707  // Common SdrModel processing
3709 }
3710 
3711 void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& rSettings)
3712 {
3713  std::vector<bool> aHasZoomVect( GetDocument()->GetTableCount(), false );
3714 
3715  sal_Int32 nTemp32(0);
3716  sal_Int16 nTemp16(0);
3717  bool bPageMode(false);
3718 
3719  EnsureTabDataSize(GetDocument()->GetTableCount());
3720 
3721  for (const auto& rSetting : rSettings)
3722  {
3723  // SC_VIEWID has to parse and use by mba
3724  OUString sName(rSetting.Name);
3725  if (sName == SC_TABLES)
3726  {
3727  uno::Reference<container::XNameContainer> xNameContainer;
3728  if ((rSetting.Value >>= xNameContainer) && xNameContainer->hasElements())
3729  {
3730  const uno::Sequence< OUString > aNames(xNameContainer->getElementNames());
3731  for (const OUString& sTabName : aNames)
3732  {
3733  SCTAB nTab(0);
3734  if (GetDocument()->GetTable(sTabName, nTab))
3735  {
3736  uno::Any aAny = xNameContainer->getByName(sTabName);
3737  uno::Sequence<beans::PropertyValue> aTabSettings;
3738  if (aAny >>= aTabSettings)
3739  {
3740  EnsureTabDataSize(nTab + 1);
3741  if (!maTabData[nTab])
3742  maTabData[nTab].reset( new ScViewDataTable(pDoc) );
3743 
3744  bool bHasZoom = false;
3745  maTabData[nTab]->ReadUserDataSequence(aTabSettings, *this, nTab, bHasZoom);
3746  aHasZoomVect[nTab] = bHasZoom;
3747  }
3748  }
3749  }
3750  }
3751  }
3752  else if (sName == SC_ACTIVETABLE)
3753  {
3754  OUString sTabName;
3755  if(rSetting.Value >>= sTabName)
3756  {
3757  SCTAB nTab(0);
3758  if (GetDocument()->GetTable(sTabName, nTab))
3759  nTabNo = nTab;
3760  }
3761  }
3762  else if (sName == SC_HORIZONTALSCROLLBARWIDTH)
3763  {
3764  if (rSetting.Value >>= nTemp32)
3765  pView->SetTabBarWidth(nTemp32);
3766  }
3767  else if (sName == SC_RELHORIZONTALTABBARWIDTH)
3768  {
3769  double fWidth = 0.0;
3770  if (rSetting.Value >>= fWidth)
3771  pView->SetPendingRelTabBarWidth( fWidth );
3772  }
3773  else if (sName == SC_ZOOMTYPE)
3774  {
3775  if (rSetting.Value >>= nTemp16)
3776  eDefZoomType = SvxZoomType(nTemp16);
3777  }
3778  else if (sName == SC_ZOOMVALUE)
3779  {
3780  if (rSetting.Value >>= nTemp32)
3781  {
3782  Fraction aZoom(nTemp32, 100);
3783  aDefZoomX = aDefZoomY = aZoom;
3784  }
3785  }
3786  else if (sName == SC_PAGEVIEWZOOMVALUE)
3787  {
3788  if (rSetting.Value >>= nTemp32)
3789  {
3790  Fraction aZoom(nTemp32, 100);
3791  aDefPageZoomX = aDefPageZoomY = aZoom;
3792  }
3793  }
3794  else if (sName == SC_SHOWPAGEBREAKPREVIEW)
3795  bPageMode = ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value );
3796  else if ( sName == SC_UNO_SHOWZERO )
3797  pOptions->SetOption(VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3798  else if ( sName == SC_UNO_SHOWNOTES )
3799  pOptions->SetOption(VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3800  else if ( sName == SC_UNO_SHOWGRID )
3801  pOptions->SetOption(VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3802  else if ( sName == SC_UNO_GRIDCOLOR )
3803  {
3804  Color aColor;
3805  if (rSetting.Value >>= aColor)
3806  {
3807  // #i47435# set automatic grid color explicitly
3808  if( aColor == COL_AUTO )
3809  aColor = SC_STD_GRIDCOLOR;
3810  pOptions->SetGridColor(aColor, OUString());
3811  }
3812  }
3813  else if ( sName == SC_UNO_SHOWPAGEBR )
3814  pOptions->SetOption(VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3815  else if ( sName == SC_UNO_COLROWHDR )
3816  pOptions->SetOption(VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3817  else if ( sName == SC_UNO_SHEETTABS )
3818  pOptions->SetOption(VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3819  else if ( sName == SC_UNO_OUTLSYMB )
3820  pOptions->SetOption(VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3821  else if ( sName == SC_UNO_SHOWOBJ )
3822  {
3823  // #i80528# placeholders not supported anymore
3824  if ( rSetting.Value >>= nTemp16 )
3825  pOptions->SetObjMode( VOBJ_TYPE_OLE, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
3826  }
3827  else if ( sName == SC_UNO_SHOWCHARTS )
3828  {
3829  // #i80528# placeholders not supported anymore
3830  if ( rSetting.Value >>= nTemp16 )
3831  pOptions->SetObjMode( VOBJ_TYPE_CHART, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
3832  }
3833  else if ( sName == SC_UNO_SHOWDRAW )
3834  {
3835  // #i80528# placeholders not supported anymore
3836  if ( rSetting.Value >>= nTemp16 )
3837  pOptions->SetObjMode( VOBJ_TYPE_DRAW, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
3838  }
3839  else if ( sName.compareToAscii( SC_UNO_VALUEHIGH ) == 0 )
3840  pOptions->SetOption( VOPT_SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3841  else
3842  {
3843  ScGridOptions aGridOpt(pOptions->GetGridOptions());
3844  if ( sName == SC_UNO_SNAPTORASTER )
3845  aGridOpt.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3846  else if ( sName == SC_UNO_RASTERVIS )
3847  aGridOpt.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3848  else if ( sName == SC_UNO_RASTERRESX )
3849  aGridOpt.SetFieldDrawX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSetting.Value ) ) );
3850  else if ( sName == SC_UNO_RASTERRESY )
3851  aGridOpt.SetFieldDrawY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSetting.Value ) ) );
3852  else if ( sName == SC_UNO_RASTERSUBX )
3853  aGridOpt.SetFieldDivisionX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSetting.Value ) ) );
3854  else if ( sName == SC_UNO_RASTERSUBY )
3855  aGridOpt.SetFieldDivisionY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSetting.Value ) ) );
3856  else if ( sName == SC_UNO_RASTERSYNC )
3857  aGridOpt.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( rSetting.Value ) );
3858  // Fallback to common SdrModel processing
3859  else GetDocument()->GetDrawLayer()->ReadUserDataSequenceValue(&rSetting);
3860 
3861  pOptions->SetGridOptions(aGridOpt);
3862  }
3863  }
3864 
3865  // copy default zoom to sheets where a different one wasn't specified
3866  for (SCTAB nZoomTab=0; nZoomTab< static_cast<SCTAB>(maTabData.size()); ++nZoomTab)
3867  if (maTabData[nZoomTab] && ( nZoomTab >= static_cast<SCTAB>(aHasZoomVect.size()) || !aHasZoomVect[nZoomTab] ))
3868  {
3869  maTabData[nZoomTab]->eZoomType = eDefZoomType;
3870  maTabData[nZoomTab]->aZoomX = aDefZoomX;
3871  maTabData[nZoomTab]->aZoomY = aDefZoomY;
3872  maTabData[nZoomTab]->aPageZoomX = aDefPageZoomX;
3873  maTabData[nZoomTab]->aPageZoomY = aDefPageZoomY;
3874  }
3875 
3876  if (rSettings.hasElements())
3877  SetPagebreakMode( bPageMode );
3878 
3879  // #i47426# write view options to document, needed e.g. for Excel export
3881 
3884 }
3885 
3887 {
3888  // if visibility of horizontal ScrollBar is changed, TabBar may have to be resized...
3889  bool bHScrollChanged = ( rOpt.GetOption(VOPT_HSCROLL) != pOptions->GetOption(VOPT_HSCROLL) );
3890 
3891  // if graphics are turned on or off, animation has to be started or stopped
3892  // graphics are controlled by VOBJ_TYPE_OLE
3893  bool bGraphicsChanged = ( pOptions->GetObjMode(VOBJ_TYPE_OLE) !=
3894  rOpt.GetObjMode(VOBJ_TYPE_OLE) );
3895 
3896  *pOptions = rOpt;
3897  OSL_ENSURE( pView, "No View" );
3898 
3899  if( pView )
3900  {
3901  pView->ViewOptionsHasChanged( bHScrollChanged, bGraphicsChanged );
3902  }
3903 }
3904 
3906 {
3907  OSL_ENSURE( pView, "GetMousePosPixel() without View" );
3908  return pView->GetMousePosPixel();
3909 }
3910 
3912 {
3913  if (pViewShell)
3914  pViewShell->UpdateInputHandler( bForce );
3915 }
3916 
3917 bool ScViewData::IsOle() const
3918 {
3919  return pDocShell && pDocShell->IsOle();
3920 }
3921 
3922 bool ScViewData::UpdateFixX( SCTAB nTab ) // true = value changed
3923 {
3924  if (!ValidTab(nTab)) // Default
3925  nTab=nTabNo; // current table
3926 
3927  if (!pView || maTabData[nTab]->eHSplitMode != SC_SPLIT_FIX)
3928  return false;
3929 
3930  ScDocument* pLocalDoc = GetDocument();
3931  if (!pLocalDoc->HasTable(nTab)) // if called from reload, the sheet may not exist
3932  return false;
3933 
3934  SCCOL nFix = maTabData[nTab]->nFixPosX;
3935  long nNewPos = 0;
3936  for (SCCOL nX=maTabData[nTab]->nPosX[SC_SPLIT_LEFT]; nX<nFix; nX++)
3937  {
3938  sal_uInt16 nTSize = pLocalDoc->GetColWidth( nX, nTab );
3939  if (nTSize)
3940  {
3941  long nPix = ToPixel( nTSize, nPPTX );
3942  nNewPos += nPix;
3943  }
3944  }
3945  nNewPos += pView->GetGridOffset().X();
3946  if (nNewPos != maTabData[nTab]->nHSplitPos)
3947  {
3948  maTabData[nTab]->nHSplitPos = nNewPos;
3949  if (nTab == nTabNo)
3950  RecalcPixPos(); // should not be needed
3951  return true;
3952  }
3953 
3954  return false;
3955 }
3956 
3957 bool ScViewData::UpdateFixY( SCTAB nTab ) // true = value changed
3958 {
3959  if (!ValidTab(nTab)) // Default
3960  nTab=nTabNo; // current table
3961 
3962  if (!pView || maTabData[nTab]->eVSplitMode != SC_SPLIT_FIX)
3963  return false;
3964 
3965  ScDocument* pLocalDoc = GetDocument();
3966  if (!pLocalDoc->HasTable(nTab)) // if called from reload, the sheet may not exist
3967  return false;
3968 
3969  SCROW nFix = maTabData[nTab]->nFixPosY;
3970  long nNewPos = 0;
3971  for (SCROW nY=maTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++)
3972  {
3973  sal_uInt16 nTSize = pLocalDoc->GetRowHeight( nY, nTab );
3974  if (nTSize)
3975  {
3976  long nPix = ToPixel( nTSize, nPPTY );
3977  nNewPos += nPix;
3978  }
3979  }
3980  nNewPos += pView->GetGridOffset().Y();
3981  if (nNewPos != maTabData[nTab]->nVSplitPos)
3982  {
3983  maTabData[nTab]->nVSplitPos = nNewPos;
3984  if (nTab == nTabNo)
3985  RecalcPixPos(); // should not be needed
3986  return true;
3987  }
3988 
3989  return false;
3990 }
3991 
3993 {
3994  ScDocument* pLocalDoc = GetDocument();
3995  bool bOnlineSpell = pLocalDoc->GetDocOptions().IsAutoSpell();
3996 
3997  EEControlBits nCntrl = rOutl.GetControlWord();
3998  nCntrl |= EEControlBits::MARKNONURLFIELDS;
3999  nCntrl &= ~EEControlBits::MARKURLFIELDS; // URLs not shaded for output
4000  nCntrl |= EEControlBits::AUTOCORRECT;
4001  if( bOnlineSpell )
4002  nCntrl |= EEControlBits::ONLINESPELLING;
4003  else
4004  nCntrl &= ~EEControlBits::ONLINESPELLING;
4005  rOutl.SetControlWord(nCntrl);
4006 
4007  rOutl.SetCalcFieldValueHdl( LINK( SC_MOD(), ScModule, CalcFieldValueHdl ) );
4008 
4009  // don't call GetSpellChecker if online spelling isn't enabled.
4010  // The language for AutoCorrect etc. is taken from the pool defaults
4011  // (set in ScDocument::UpdateDrawLanguages)
4012 
4013  if ( bOnlineSpell )
4014  {
4015  css::uno::Reference<css::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
4016  rOutl.SetSpeller( xXSpellChecker1 );
4017  }
4018 
4020  pLocalDoc->GetEditTextDirection( nTabNo ) );
4021 }
4022 
4024 {
4025  return ScAddress( GetCurX(), GetCurY(), GetTabNo() );
4026 }
4027 
4028 void ScViewData::SetRefStart( SCCOL nNewX, SCROW nNewY, SCTAB nNewZ )
4029 {
4030  nRefStartX = nNewX; nRefStartY = nNewY; nRefStartZ = nNewZ;
4031 }
4032 
4033 void ScViewData::SetRefEnd( SCCOL nNewX, SCROW nNewY, SCTAB nNewZ )
4034 {
4035  nRefEndX = nNewX; nRefEndY = nNewY; nRefEndZ = nNewZ;
4036 }
4037 
4038 void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY,
4039  SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo )
4040 {
4041  SCROW nRow = rPosY;
4042  while (rScrY <= nEndPixels && nRow <= nEndRow)
4043  {
4044  SCROW nHeightEndRow;
4045  sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, nullptr, &nHeightEndRow);
4046  if (nHeightEndRow > nEndRow)
4047  nHeightEndRow = nEndRow;
4048  if (!nHeight)
4049  nRow = nHeightEndRow + 1;
4050  else
4051  {
4052  SCROW nRows = nHeightEndRow - nRow + 1;
4053  sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
4054  sal_Int64 nAdd = nPixel * nRows;
4055  if (nAdd + rScrY > nEndPixels)
4056  {
4057  sal_Int64 nDiff = rScrY + nAdd - nEndPixels;
4058  nRows -= static_cast<SCROW>(nDiff / nPixel);
4059  nAdd = nPixel * nRows;
4060  // We're looking for a value that satisfies loop condition.
4061  if (nAdd + rScrY <= nEndPixels)
4062  {
4063  ++nRows;
4064  nAdd += nPixel;
4065  }
4066  }
4067  rScrY += static_cast<long>(nAdd);
4068  nRow += nRows;
4069  }
4070  }
4071  if (nRow > rPosY)
4072  --nRow;
4073  rPosY = nRow;
4074 }
4075 
4076 void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
4077  SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc,
4078  SCTAB nTabNo )
4079 {
4080  SCROW nRow = rPosY;
4081  while (rScrY <= nEndPixels && nRow >= nStartRow)
4082  {
4083  SCROW nHeightStartRow;
4084  sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, nullptr);
4085  if (nHeightStartRow < nStartRow)
4086  nHeightStartRow = nStartRow;
4087  if (!nHeight)
4088  nRow = nHeightStartRow - 1;
4089  else
4090  {
4091  SCROW nRows = nRow - nHeightStartRow + 1;
4092  sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
4093  sal_Int64 nAdd = nPixel * nRows;
4094  if (nAdd + rScrY > nEndPixels)
4095  {
4096  sal_Int64 nDiff = nAdd + rScrY - nEndPixels;
4097  nRows -= static_cast<SCROW>(nDiff / nPixel);
4098  nAdd = nPixel * nRows;
4099  // We're looking for a value that satisfies loop condition.
4100  if (nAdd + rScrY <= nEndPixels)
4101  {
4102  ++nRows;
4103  nAdd += nPixel;
4104  }
4105  }
4106  rScrY += static_cast<long>(nAdd);
4107  nRow -= nRows;
4108  }
4109  }
4110  if (nRow < rPosY)
4111  ++nRow;
4112  rPosY = nRow;
4113 }
4114 
4116 {
4117  SCCOLROW nFreezeIndex = bIsCol ? pDoc->GetLOKFreezeCol(nTabNo) : pDoc->GetLOKFreezeRow(nTabNo);
4118  return nFreezeIndex >= 0 ? nFreezeIndex : 0;
4119 }
4120 
4121 bool ScViewData::SetLOKSheetFreezeIndex(const SCCOLROW nFreezeIndex, bool bIsCol, SCTAB nForTab)
4122 {
4123  if (nForTab == -1)
4124  {
4125  nForTab = nTabNo;
4126  }
4127  else if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
4128  {
4129  SAL_WARN("sc.viewdata", "ScViewData::SetLOKSheetFreezeIndex : invalid nForTab = " << nForTab);
4130  return false;
4131  }
4132 
4133  return bIsCol ?
4134  pDoc->SetLOKFreezeCol(static_cast<SCCOL>(nFreezeIndex), nForTab) :
4135  pDoc->SetLOKFreezeRow(static_cast<SCROW>(nFreezeIndex), nForTab);
4136 }
4137 
4139 {
4140  SCTAB nMaxTab = static_cast<SCTAB>(maTabData.size()) - 1;
4141  for (SCTAB nTab = 0; nTab <= nMaxTab; ++nTab)
4143 }
4144 
4146 {
4147  if (!ValidTab(nForTab) || (nForTab >= static_cast<SCTAB>(maTabData.size())))
4148  {
4149  SAL_WARN("sc.viewdata", "ScViewData::DeriveLOKFreezeIfNeeded : invalid nForTab = " << nForTab);
4150  return;
4151  }
4152 
4153  ScViewDataTable* pViewTable = maTabData[nForTab].get();
4154  if (!pViewTable)
4155  return;
4156 
4157  bool bConvertToFreezeX = false;
4158  bool bConvertToFreezeY = false;
4159  SCCOL nFreezeCol = pDoc->GetLOKFreezeCol(nForTab);
4160  SCROW nFreezeRow = pDoc->GetLOKFreezeRow(nForTab);
4161 
4162  if (nFreezeCol == -1)
4163  {
4164  ScSplitMode eSplitMode = pViewTable->eHSplitMode;
4165  if (eSplitMode == SC_SPLIT_FIX)
4166  nFreezeCol = pViewTable->nFixPosX;
4167  else if (eSplitMode == SC_SPLIT_NORMAL)
4168  bConvertToFreezeX = true;
4169  else
4170  nFreezeCol = 0;
4171  }
4172 
4173  if (nFreezeRow == -1)
4174  {
4175  ScSplitMode eSplitMode = pViewTable->eVSplitMode;
4176  if (eSplitMode == SC_SPLIT_FIX)
4177  nFreezeRow = pViewTable->nFixPosY;
4178  else if (eSplitMode == SC_SPLIT_NORMAL)
4179  bConvertToFreezeY = true;
4180  else
4181  nFreezeRow = 0;
4182  }
4183 
4184  if (bConvertToFreezeX || bConvertToFreezeY)
4185  {
4186  SCCOL nCol;
4187  SCROW nRow;
4188  GetPosFromPixel(bConvertToFreezeX ? pViewTable->nHSplitPos : 0,
4189  bConvertToFreezeY ? pViewTable->nVSplitPos : 0,
4190  SC_SPLIT_BOTTOMLEFT, nCol, nRow,
4191  false /* bTestMerge */, false /* bRepair */,
4192  nForTab);
4193  if (bConvertToFreezeX)
4194  nFreezeCol = nCol;
4195  if (bConvertToFreezeY)
4196  nFreezeRow = nRow;
4197  }
4198 
4199  pDoc->SetLOKFreezeCol(nFreezeCol, nForTab);
4200  pDoc->SetLOKFreezeRow(nFreezeRow, nForTab);
4201 }
4202 
4203 void ScViewData::OverrideWithLOKFreeze(ScSplitMode& eExHSplitMode, ScSplitMode& eExVSplitMode,
4204  SCCOL& nExFixPosX, SCROW& nExFixPosY,
4205  long& nExHSplitPos, long& nExVSplitPos, SCTAB nForTab) const
4206 {
4207  SCCOL nFreezeCol = pDoc->GetLOKFreezeCol(nForTab);
4208  SCROW nFreezeRow = pDoc->GetLOKFreezeRow(nForTab);
4209 
4210  bool bConvertToScrPosX = false;
4211  bool bConvertToScrPosY = false;
4212 
4213  if (nFreezeCol >= 0)
4214  {
4215  if (eExHSplitMode == SC_SPLIT_NONE)
4216  eExHSplitMode = SC_SPLIT_FIX;
4217 
4218  if (eExHSplitMode == SC_SPLIT_FIX)
4219  nExFixPosX = nFreezeCol;
4220  else
4221  bConvertToScrPosX = true;
4222  }
4223 
4224  if (nFreezeRow >= 0)
4225  {
4226  if (eExVSplitMode == SC_SPLIT_NONE)
4227  eExVSplitMode = SC_SPLIT_FIX;
4228 
4229  if (eExVSplitMode == SC_SPLIT_FIX)
4230  nExFixPosY = nFreezeRow;
4231  else
4232  bConvertToScrPosY = true;
4233  }
4234 
4235  if (bConvertToScrPosX || bConvertToScrPosY)
4236  {
4237  Point aExSplitPos = GetScrPos(nFreezeCol, nFreezeRow, SC_SPLIT_BOTTOMLEFT, true, nForTab);
4238  if (bConvertToScrPosX)
4239  nExHSplitPos = aExSplitPos.X();
4240  if (bConvertToScrPosY)
4241  nExVSplitPos = aExSplitPos.Y();
4242  }
4243 }
4244 
4245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetGridMode(bool bNewMode)
Definition: viewdata.hxx:541
#define MAXZOOM
Definition: global.hxx:76
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3053
tools::Rectangle GetEditArea(const ScPatternAttr *pPattern, bool bForceToTop)
Definition: editutil.cxx:285
Point TopLeft() const
#define SC_HORIZONTAL_SPLIT_MODE
SfxViewFrame * GetViewFrame() const
Fraction aZoomY
Definition: viewdata.hxx:213
long Width() const
void DeriveLOKFreezeIfNeeded(SCTAB nForTab)
Definition: viewdata.cxx:4145
tools::Rectangle GetLOKSpecialOutputArea() const
#define SC_UNO_COLROWHDR
Definition: unonames.hxx:535
#define SC_TABLE_SHOWGRID
void SetOutlineMode(bool bNewMode)
Definition: viewdata.hxx:553
sal_uInt32 GetFieldDivisionY() const
#define SC_POSITIONLEFT
constexpr double nPPTY
#define SC_TABLE_VIEWSETTINGS
void SetControlWord(EVControlBits nWord)
#define SC_UNO_SHOWCHARTS
Definition: unonames.hxx:542
SCCOL GetColMerge() const
Definition: attrib.hxx:69
SvxCellHorJustify
OUString GetText(LineEnd eEnd=LINEEND_LF) const
ScExtPanePos meActivePane
Active (focused) pane.
Definition: scextopt.hxx:57
long GetWidth() const
#define OLE_STD_CELLS_Y
Definition: global.hxx:115
void KillEditView()
Definition: viewdata.cxx:2209
EEControlBits GetControlWord() const
SCCOL GetOldCurX() const
Definition: viewdata.cxx:1316
#define SC_SHEETTABS
SCCOL SanitizeCol(SCCOL nCol) const
Definition: document.hxx:884
void MarkToSimple()
Definition: markdata.cxx:237
SvxZoomType eDefZoomType
Definition: viewdata.hxx:292
#define SC_CURSORPOSITIONX
index_type nSecondIndex
Definition: viewdata.hxx:166
ScAddress aStart
Definition: address.hxx:500
#define SC_HORIZONTAL_SPLIT_POSITION
long GetHeight() const
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
void SetTabBarWidth(long nNewWidth)
Sets an absolute tab bar width (in pixels).
Definition: tabview.cxx:850
#define SC_ZOOMTYPE
void SetCurX(SCCOL nNewCurX)
Definition: viewdata.hxx:431
Bottom, or bottom-left pane.
Definition: scextopt.hxx:43
ScDocShell * pDocShell
Definition: viewdata.hxx:279
ScVSplitPos WhichV(ScSplitPos ePos)
Definition: viewdata.hxx:714
#define EMPTY_OUSTRING
Definition: global.hxx:214
const SCROW MAXROW_30
Definition: address.hxx:91
#define SC_VERTICAL_SPLIT_POSITION
long nMPosY[2]
Definition: viewdata.hxx:220
#define SC_UNO_RASTERSYNC
Definition: unonames.hxx:559
void ReadExtOptions(const ScExtDocOptions &rOpt)
Definition: viewdata.cxx:3441
SAL_DLLPRIVATE void EnsureTabDataSize(size_t nSize)
Definition: viewdata.cxx:2254
#define SC_RASTERSUBY
SCROW Row() const
Definition: address.hxx:262
ScVSplitPos
Definition: viewdata.hxx:47
void GetEndIndexAndPosition(SCCOL &nIndex, long &nPosition) const
Definition: viewdata.cxx:303
SCCOL MaxCol() const
Definition: viewdata.hxx:396
#define SC_ACTIVETABLE
EditView * RemoveView(EditView *pEditView)
void SetUpdateMode(bool bUpdate, bool bRestoring=false)
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
const Fraction & GetZoomX() const
Definition: viewdata.hxx:459
#define SC_RELHORIZONTALTABBARWIDTH
ScPositionHelper aHeightHelper
Definition: viewdata.hxx:239
SAL_DLLPRIVATE void CalcPPT()
Definition: viewdata.cxx:3112
void EnlargeEndBy(long nOffset)
Definition: viewdata.cxx:417
Fraction aDefPageZoomX
Definition: viewdata.hxx:295
#define SC_UNO_RASTERRESX
Definition: unonames.hxx:555
long Height() const
void SetScreenPos(const Point &rVisAreaStart)
Definition: viewdata.cxx:2976
Size aScenButSize
Definition: viewdata.hxx:287
ScAddress maCursor
The cursor position (column/row only).
Definition: scextopt.hxx:52
ScViewDataTable(ScDocument *pDoc=nullptr)
Definition: viewdata.cxx:483
#define SC_UNO_VALUEHIGH
Definition: unonames.hxx:551
bool IsChanged() const
Definition: scextopt.cxx:160
SC_DLLPUBLIC void SetTabBgColor(SCTAB nTab, const Color &rColor)
Definition: documen3.cxx:436
Fraction aDefPageZoomY
Definition: viewdata.hxx:296
SCCOL GetCurXForTab(SCTAB nTabIndex) const
Definition: viewdata.cxx:1372
void SetHeaderMode(bool bNewMode)
Definition: viewdata.hxx:545
void invalidateByPosition(long nPos)
Definition: viewdata.cxx:172
Point GetPrintTwipsPos(SCCOL nCol, SCROW nRow) const
returns the position (top-left corner) of the requested cell in print twips coordinates.
Definition: viewdata.cxx:2471
SfxDispatcher * GetDispatcher()
::std::vector< std::unique_ptr< ScViewDataTable > > maTabData
Definition: viewdata.hxx:276
long AdjustLeft(long nHorzMoveDelta)
#define SC_HORIZONTALSCROLLBARWIDTH
#define TWIPS_PER_PIXEL
Definition: global.hxx:88
void InsertTabs(SCTAB nTab, SCTAB nNewSheets)
Definition: viewdata.cxx:906
static bool SelectionFillDOOM(const ScRange &rRange)
Determine DOOM condition, i.e. from selected range.
Definition: viewdata.cxx:1269
void RefreshZoom()
Definition: viewdata.cxx:1126
SCROW GetLOKFreezeRow(SCTAB nTab) const
#define OLE_STD_CELLS_X
Definition: global.hxx:114
#define SC_CURSOR_Y
void SetActivePart(ScSplitPos eNewActive)
Definition: viewdata.cxx:2294
sal_uInt8 GetTransparency() const
sal_uIntPtr sal_uLong
Fraction aPageZoomY
Definition: viewdata.hxx:215
ScAddress maSecondVis
Top-left visible cell in add. panes (column/row only).
Definition: scextopt.hxx:54
sal_uInt32 GetFieldDrawX() const
SCROW GetCurY() const
Definition: viewdata.hxx:402
void EnlargeStartBy(long nOffset)
Definition: viewdata.cxx:402
svtools::ColorConfig & GetColorConfig()
Definition: scmod.cxx:820
ScHSplitPos WhichH(ScSplitPos ePos)
Definition: viewdata.hxx:708
ScDocFunc & GetDocFunc() const
Definition: viewdata.cxx:3036
void SetSpeller(css::uno::Reference< css::linguistic2::XSpellChecker1 > const &xSpeller)
#define SC_PAGE_VIEW_ZOOM_VALUE
const bool bColumnHeader
Definition: viewdata.hxx:160
SCCOL nPosX[2]
X position of the top left cell of the visible area.
Definition: viewdata.hxx:241
SCCOLROW GetLOKSheetFreezeIndex(bool bIsCol) const
Definition: viewdata.cxx:4115
void DeriveLOKFreezeAllSheets()
Definition: viewdata.cxx:4138
double GetOutputFactor() const
Definition: docsh.hxx:352
bool IsMinimized() const
Definition: tabview.hxx:342
void OverrideWithLOKFreeze(ScSplitMode &eExHSplitMode, ScSplitMode &eExVSplitMode, SCCOL &nExFixPosX, SCROW &nExFixPosY, long &nExHSplitPos, long &nExVSplitPos, SCTAB nForTab) const
Definition: viewdata.cxx:4203
ScViewData(ScDocShell *pDocSh, ScTabViewShell *pViewSh)
Definition: viewdata.cxx:746
#define SC_TABLE_VIEWSETTINGS_COUNT
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:387
SvxAdjust GetEditAdjust() const
Definition: viewdata.hxx:501
long nMPosX[2]
Definition: viewdata.hxx:219
double GetPPTX() const
Definition: viewdata.hxx:468
SCCOL nTabStartCol
Definition: viewdata.hxx:317
const ScExtDocSettings & GetDocSettings() const
Definition: scextopt.cxx:170
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
static bool HasFiltered(const ScRange &rRange, const ScDocument *pDoc)
Definition: viewutil.cxx:272
void ViewOptionsHasChanged(bool bHScrollChanged, bool bGraphicsChanged)
Definition: tabview5.cxx:444
#define SC_SHOWZERO
bool SimpleRowMarked()
Definition: viewdata.cxx:1236
ScAddress aEnd
Definition: address.hxx:501
Extended options held by an ScDocument containing additional settings for filters.
Definition: scextopt.hxx:77
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:398
std::unique_ptr< EditView > pEditView[4]
Definition: viewdata.hxx:283
void EditGrowY(bool bInitial=false)
Extend the output area for the edit engine view in a vertical direction as needed.
Definition: viewdata.cxx:2080
SCTAB GetLastTab() const
Definition: scextopt.cxx:185
SCCOL nEditEndCol
Definition: viewdata.hxx:315
constexpr TypedWhichId< SvxAdjustItem > EE_PARA_JUST(EE_PARA_START+15)
void GetFillData(SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow)
Definition: viewdata.cxx:1307
const tools::Rectangle & GetOutputArea() const
constexpr TypedWhichId< ScLineBreakCell > ATTR_LINEBREAK(139)
#define SC_CURSOR_X
#define SC_CURSORPOSITIONY
static void forEachOtherView(ViewShellType *pThisViewShell, FunctionType f)
ScSplitPos SanitizeWhichActive() const
Sanitize the active split range value to not point into a grid window that would never be initialized...
Definition: viewdata.cxx:732
EEControlBits
ScRangeList maSelection
Selected cell ranges (columns/rows only).
Definition: scextopt.hxx:51
css::chart::ChartAxisLabelPosition ePos
SCCOL GetPosX(ScHSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1344
#define SC_TABLES
SCCOL CellsAtX(SCCOL nPosX, SCCOL nDir, ScHSplitPos eWhichX, sal_uInt16 nScrSizeY=SC_SIZE_NONE) const
Definition: viewdata.cxx:2549
ScTabViewShell * pViewShell
Definition: viewdata.hxx:282
sal_Int32 getTokenCount(const OString &rIn, char cTok)
std::set< value_type, Comp > mData
Definition: viewdata.hxx:137
#define SC_UNO_SHOWOBJ
Definition: unonames.hxx:548
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
static void AddPixelsWhileBackward(long &rScrY, long nEndPixels, SCROW &rPosY, SCROW nStartRow, double nPPTY, const ScDocument *pDoc, SCTAB nTabNo)
while (rScrY <= nEndPixels && rPosY >= nStartRow) add pixels of row heights converted with nPPTY to r...
Definition: viewdata.cxx:4076
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4163
void ReadUserData(const OUString &rData)
Definition: viewdata.cxx:3222
ScSplitPos
Definition: viewdata.hxx:45
double mfTabBarWidth
Width of the tabbar, relative to frame window width (0.0 ... 1.0).
Definition: scextopt.hxx:31
long AdjustBottom(long nVertMoveDelta)
SCROW GetOldCurY() const
Definition: viewdata.cxx:1324
double nPPTX
Definition: viewdata.hxx:274
void GetIndexAndPos(index_type nNearestIndex, long nNearestPosition, long nBound, index_type &nFoundIndex, long &nPosition, bool bTowards, long nDiff)
Definition: viewdata.cxx:330
void SetVisArea(const tools::Rectangle &rRect)
bool UpdateFixY(SCTAB nTab=MAXTAB+1)
Definition: viewdata.cxx:3957
SCROW nEditEndRow
Definition: viewdata.hxx:316
SAL_DLLPRIVATE void UpdateCurrentTab()
Definition: viewdata.cxx:876
void GetMarkArea(ScRange &rRange) const
Definition: markdata.cxx:112
static OutputDevice * GetDefaultDevice()
void SetPagebreakMode(bool bSet)
Definition: viewdata.cxx:1137
#define SC_HORIZONTALSPLITPOSITION_TWIPS
static UITestLogger & getInstance()
ScDocument * pDoc
Definition: viewdata.hxx:158
constexpr::Color COL_AUTO(0xFF, 0xFF, 0xFF, 0xFF)
void logEvent(const EventDescription &rDescription)
sal_uInt16 sal_Unicode
void UpdateInputHandler(bool bForce=false)
Definition: viewdata.cxx:3911
SCTAB nTabNo
Definition: viewdata.hxx:300
long GetTabBarWidth() const
Returns the current tab bar width in pixels.
Definition: tabview.cxx:874
#define SC_UNO_RASTERRESY
Definition: unonames.hxx:556
long Right() const
#define SC_UNO_SHOWGRID
Definition: unonames.hxx:545
void InsertView(EditView *pEditView, size_t nIndex=EE_APPEND)
bool IsOle() const
Definition: viewdata.cxx:3917
#define STD_COL_WIDTH
Definition: global.hxx:93
Fraction aPageZoomX
Definition: viewdata.hxx:214
void SetControlWord(EEControlBits nWord)
long GetGridWidth(ScHSplitPos eWhich)
Definition: tabview3.cxx:2971
void WriteExtOptions(ScExtDocOptions &rOpt) const
Definition: viewdata.cxx:3327
#define SC_VALUE_HIGHLIGHTING
void RecalcPixPos()
Definition: viewdata.cxx:2909
void GetPosFromPixel(long nClickX, long nClickY, ScSplitPos eWhich, SCCOL &rPosX, SCROW &rPosY, bool bTestMerge=true, bool bRepair=false, SCTAB nForTab=-1)
Definition: viewdata.cxx:2700
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:876
#define SC_TABLE_ZOOM_VALUE
SCCOL PrevCellsX(ScHSplitPos eWhichX) const
Definition: viewdata.cxx:2637
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:313
long GetGridHeight(ScVSplitPos eWhich)
Definition: tabview3.cxx:2982
SCCOL nRefStartX
Definition: viewdata.hxx:302
#define SC_SNAPTORASTER
void SetPosX(ScHSplitPos eWhich, SCCOL nNewPosX)
Definition: viewdata.cxx:2827
#define SC_VIEWID
void SetPendingRelTabBarWidth(double fRelTabBarWidth)
Sets a relative tab bar width.
Definition: tabview.cxx:868
SCCOL VisibleCellsX(ScHSplitPos eWhichX) const
Definition: viewdata.cxx:2627
void SetControlWord(EEControlBits nWord)
bool IsMultiMarked() const
Definition: markdata.hxx:83
SCCOLROW index_type
Definition: viewdata.hxx:156
void EditGrowX()
Extend the output area for the edit engine view in a horizontal direction as needed.
Definition: viewdata.cxx:1784
#define SC_HORIZONTALSPLITPOSITION
const SCROW MAXROW
Definition: address.hxx:69
#define SC_TABLE_PAGE_VIEW_ZOOM_VALUE
bool isCompatFlagSet(Compat flag)
void SetOptions(const ScViewOptions &rOpt)
Definition: viewdata.cxx:3886
#define SC_UNO_RASTERVIS
Definition: unonames.hxx:554
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:190
void UpdateInputHandler(bool bForce=false, bool bStopEditing=true)
Definition: tabvwsha.cxx:632
#define HMM_PER_TWIPS
Definition: global.hxx:91
void SetRow(SCROW nRowP)
Definition: address.hxx:275
void WriteUserData(OUString &rData)
Definition: viewdata.cxx:3162
void WriteUserDataSequence(css::uno::Sequence< css::beans::PropertyValue > &rSettings) const
Definition: viewdata.cxx:3612
#define PIXEL_PER_TWIPS
Definition: global.hxx:90
long Top() const
ScDocument * GetDocument() const
Definition: viewdata.cxx:859
bool mbShowGrid
Whether or not to display gridlines.
Definition: scextopt.hxx:64
#define SC_RASTERRESX
EEControlBits GetControlWord() const
#define SC_UNO_RASTERSUBX
Definition: unonames.hxx:557
#define SC_UNO_SHOWPAGEBR
Definition: unonames.hxx:549
#define SC_ACTIVE_TABLE
void GeIndexBackwards(index_type nNearestIndex, long nNearestPosition, long nBound, index_type &nFoundIndex, long &nPosition, bool bTowards)
Definition: viewdata.cxx:430
SCROW GetPosY(ScVSplitPos eWhich, SCTAB nForTab=-1) const
Definition: viewdata.cxx:1358
#define SC_GRIDCOLOR
const Fraction & GetZoomY() const
Definition: viewdata.hxx:460
ScSplitMode eVSplitMode
Definition: viewdata.hxx:227
#define SC_RASTERSUBX
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4737
void SetCol(SCCOL nColP)
Definition: address.hxx:279
#define SC_STD_GRIDCOLOR
Definition: viewopti.hxx:61
const char * sName
#define SC_TABLESELECTED
ScDrawView * GetScDrawView()
Definition: viewdata.cxx:3081
#define SC_POSITION_TOP
ScGridWindow * GetActiveWin()
Definition: tabview.cxx:884
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4716
void SetRefStart(SCCOL nNewX, SCROW nNewY, SCTAB nNewZ)
Definition: viewdata.cxx:4028
void GetIndexTowards(index_type nNearestIndex, long nNearestPosition, long nBound, index_type &nFoundIndex, long &nPosition, bool bTowards)
Definition: viewdata.cxx:454
void WriteUserDataSequence(css::uno::Sequence< css::beans::PropertyValue > &rValues)
ScPasteFlags
Definition: viewdata.hxx:81
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:70
#define SC_HORIZONTALSPLITMODE
SCROW VisibleCellsY(ScVSplitPos eWhichY) const
Definition: viewdata.cxx:2632
DocumentType eType
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1904
#define SC_RASTERVIS
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
SCROW nFillStartY
Definition: viewdata.hxx:309
#define SC_UNO_RASTERSUBY
Definition: unonames.hxx:558
bool IsValid() const
Definition: address.hxx:293
constexpr double nPPTX
static SC_DLLPUBLIC sal_uInt16 nStdRowHeight
Definition: global.hxx:587
void InsertTab(SCTAB nTab)
Definition: viewdata.cxx:892
bool mbFrozenPanes
true = Frozen panes; false = Normal splits.
Definition: scextopt.hxx:62
bool HasDetectiveObjects(SCTAB nTab) const
Definition: documen9.cxx:513
void SetDefaultHorizontalTextDirection(EEHorizontalTextDirection eHTextDir)
ScExtTabSettings & GetOrCreateTabSettings(SCTAB nTab)
Definition: scextopt.cxx:190
void SetTabNo(SCTAB nNewTab)
Definition: viewdata.cxx:2260
SCROW MaxRow() const
Definition: viewdata.hxx:397
#define SC_ACTIVESPLITRANGE
bool IsVertical() const
#define SC_ZOOM_TYPE
const Size & GetLOKSpecialPaperSize() const
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1062
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:875
T * get() const
#define SC_UNO_SHOWDRAW
Definition: unonames.hxx:543
void SetScaleX(const Fraction &rScaleX)
void SetTop(long v)
static css::uno::Reference< css::linguistic2::XSpellChecker1 > GetSpellChecker()
bool GetUseGridSnap() const
Size aScrSize
Definition: viewdata.hxx:289
const SCTAB SC_TAB_APPEND
Definition: address.hxx:84
bool IsMarked() const
Definition: markdata.hxx:82
#define nPixel
#define SC_VERTICAL_SPLIT_MODE
const value_type & getNearestByPosition(long nPos) const
Definition: viewdata.cxx:218
void SetDefaultItem(const SfxPoolItem &rItem)
Set the item in the default ItemSet which is created if it doesn't exist yet.
Definition: editutil.cxx:538
SvxAdjust
int i
void DeleteTab(SCTAB nTab)
Definition: viewdata.cxx:925
void InvalidateOtherViewWindows(const tools::Rectangle &rInvRect)
Point GetScrPos(SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, bool bAllowNeg=false, SCTAB nForTab=-1) const
Definition: viewdata.cxx:2319
#define MAX_INDEX
tools::Rectangle GetEditArea(ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY, vcl::Window *pWin, const ScPatternAttr *pPattern, bool bForceToTop, bool bInPrintTwips=false)
Definition: viewdata.cxx:1454
void WriteUserDataSequence(css::uno::Sequence< css::beans::PropertyValue > &rSettings, const ScViewData &rViewData, SCTAB nTab) const
Definition: viewdata.cxx:523
long nTPosX[2]
Definition: viewdata.hxx:217
static const index_type null
Definition: viewdata.hxx:128
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:172
Extended settings for the document, used in import/export filters.
Definition: scextopt.hxx:28
const SCTAB nTab
Definition: viewdata.hxx:159
void invalidateByIndex(index_type nIndex)
Definition: viewdata.cxx:157
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:406
SfxBindings & GetBindings()
Definition: viewdata.cxx:3041
ScMarkType
States GetSimpleArea() returns for the underlying selection marks, so the caller can react if the res...
Definition: viewdata.hxx:61