LibreOffice Module sc (master)  1
address.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */
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 #pragma once
21 
22 #include <rtl/ustrbuf.hxx>
23 #include <rtl/strbuf.hxx>
24 
25 #include <array>
26 #include <limits>
27 #include <ostream>
28 
29 #include "scdllapi.h"
30 #include "types.hxx"
31 #include <formula/grammar.hxx>
32 
33 #include <o3tl/typed_flags_set.hxx>
35 
36 namespace com::sun::star {
37  namespace sheet {
38  struct ExternalLinkInfo;
39  }
40 }
41 
42 namespace com::sun::star::uno { template <typename > class Sequence; }
43 
44 class ScDocument;
45 
48 typedef size_t SCSIZE;
49 
50 // Maximum possible value of data type, NOT maximum row value.
51 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
52 // included, we should not be using those stupid macros anyway.
53 #undef min
54 #undef max
55 const SCROW SCROW_MAX = ::std::numeric_limits<SCROW>::max();
56 const SCCOL SCCOL_MAX = ::std::numeric_limits<SCCOL>::max();
57 const SCTAB SCTAB_MAX = ::std::numeric_limits<SCTAB>::max();
58 const SCCOLROW SCCOLROW_MAX = ::std::numeric_limits<SCCOLROW>::max();
59 const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max();
60 
61 // Count values
62 const SCROW MAXROWCOUNT = 1048576;
63 const SCCOL MAXCOLCOUNT = 1024;
64 const SCCOL INITIALCOLCOUNT = 64; // initial number of columns we allocate memory for
66 const SCTAB MAXTABCOUNT = 10000;
67 // Maximum values
68 const SCROW MAXROW = MAXROWCOUNT - 1;
69 const SCCOL MAXCOL = MAXCOLCOUNT - 1;
70 const SCTAB MAXTAB = MAXTABCOUNT - 1;
72 const SCROW MAXROW_JUMBO = 16 * 1000 * 1000 - 1;
73 const SCCOL MAXCOL_JUMBO = 16384 - 1;
74 // Maximum tiled rendering values
75 const SCROW MAXTILEDROW = 500000;
76 // Limit the initial tab count to prevent users to set the count too high,
77 // which could cause the memory usage of blank documents to exceed the
78 // available system memory.
79 const SCTAB MAXINITTAB = 1024;
80 const SCTAB MININITTAB = 1;
81 
82 // Special values
84 const SCTAB TABLEID_DOC = SCTAB_MAX; // entire document, e.g. protect
85 const SCROW SCROWS32K = 32000; // for fuzzing
89 
90 const SCROW MAXROW_30 = 8191;
91 
92 [[nodiscard]] inline bool ValidCol( SCCOL nCol, SCCOL nMaxCol )
93 {
94  assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work
95  return nCol >= 0 && nCol <= nMaxCol;
96 }
97 
98 [[nodiscard]] inline bool ValidRow( SCROW nRow, SCROW nMaxRow)
99 {
100  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
101  return nRow >= 0 && nRow <= nMaxRow;
102 }
103 
104 [[nodiscard]] inline bool ValidTab( SCTAB nTab )
105 {
106  return nTab >= 0 && nTab <= MAXTAB;
107 }
108 
109 [[nodiscard]] inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
110 {
111  return nTab >= 0 && nTab <= nMaxTab;
112 }
113 
114 [[nodiscard]] inline bool ValidColRow( SCCOL nCol, SCROW nRow, SCCOL nMaxCol, SCROW nMaxRow )
115 {
116  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
117  return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow);
118 }
119 
120 [[nodiscard]] inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL nMaxCol, SCROW nMaxRow )
121 {
122  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
123  return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow) && ValidTab( nTab);
124 }
125 
126 [[nodiscard]] inline SCCOL SanitizeCol( SCCOL nCol, SCCOL nMaxCol )
127 {
128  assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work
129  return nCol < 0 ? 0 : (nCol > nMaxCol ? nMaxCol : nCol);
130 }
131 
132 [[nodiscard]] inline SCROW SanitizeRow( SCROW nRow, SCROW nMaxRow )
133 {
134  assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work
135  return nRow < 0 ? 0 : (nRow > nMaxRow ? nMaxRow : nRow);
136 }
137 
138 [[nodiscard]] inline SCTAB SanitizeTab( SCTAB nTab )
139 {
140  return nTab < 0 ? 0 : (nTab > MAXTAB ? MAXTAB : nTab);
141 }
142 
143 // The result of ConvertRef() is a bit group of the following:
144 enum class ScRefFlags : sal_uInt16
145 {
146  ZERO = 0x0000,
147  COL_ABS = 0x0001,
148  ROW_ABS = 0x0002,
149  TAB_ABS = 0x0004,
150  TAB_3D = 0x0008,
151  COL2_ABS = 0x0010,
152  ROW2_ABS = 0x0020,
153  TAB2_ABS = 0x0040,
154  TAB2_3D = 0x0080,
155  ROW_VALID = 0x0100,
156  COL_VALID = 0x0200,
157  TAB_VALID = 0x0400,
158  // BITS for convenience
161  // somewhat cheesy kludge to force the display of the document name even for
162  // local references. Requires TAB_3D to be valid
163  FORCE_DOC = 0x0800,
164  ROW2_VALID = 0x1000,
165  COL2_VALID = 0x2000,
166  TAB2_VALID = 0x4000,
167  VALID = 0x8000,
168 
170 
172 
173  RANGE_ABS = ADDR_ABS | COL2_ABS | ROW2_ABS | TAB2_ABS,
174 
175  ADDR_ABS_3D = ADDR_ABS | TAB_3D,
176  RANGE_ABS_3D = RANGE_ABS | TAB_3D
177 };
178 
179 namespace o3tl
180 {
181  template<> struct typed_flags<ScRefFlags> : is_typed_flags<ScRefFlags, 0xffff> {};
182 }
183 inline void applyStartToEndFlags(ScRefFlags &target,const ScRefFlags source)
184 {
185  target |= ScRefFlags(o3tl::underlyingEnumValue(source) << 4);
186 }
187 inline void applyStartToEndFlags(ScRefFlags &target)
188 {
189  target |= ScRefFlags(o3tl::underlyingEnumValue(target) << 4);
190 }
191 
192 // ScAddress
194 {
195 private:
196  // Even if the fields are in the order "row, column, tab", in all (?) the ScAddress and
197  // ScDocument APIs that take separate row, column, and tab parameters, the parameters are in the
198  // order "column, row, tab", which matches the most common (A1) address syntax, if you ignore
199  // the sheet (tab). Don't let this confuse you, like it confused me for a while.
200 
204 
205 public:
206 
207  enum Uninitialized { UNINITIALIZED };
208  enum InitializeInvalid { INITIALIZE_INVALID };
209 
210  struct Details
211  {
215 
217  eConv(eConvP), nRow(nRowP), nCol(nColP)
218  {}
220  eConv(eConvP), nRow(rAddr.Row()), nCol(rAddr.Col())
221  {}
223  eConv(eConvP), nRow(0), nCol(0)
224  {}
225  /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
226  Details( const ScDocument& rDoc, const ScAddress& rAddr );
227  };
229 
231  {
232  OUString maTabName;
233  sal_uInt16 mnFileId;
235 
237  mnFileId(0), mbExternal(false)
238  {}
239  };
240 
242  nRow(0), nCol(0), nTab(0)
243  {}
244  ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP ) :
245  nRow(nRowP), nCol(nColP), nTab(nTabP)
246  {}
250  {}
252  nRow(-1), nCol(-1), nTab(-1)
253  {}
254  ScAddress( const ScAddress& rAddress ) :
255  nRow(rAddress.nRow), nCol(rAddress.nCol), nTab(rAddress.nTab)
256  {}
257  inline ScAddress& operator=( const ScAddress& rAddress );
258 
259  inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
260 
261  SCROW Row() const
262  {
263  return nRow;
264  }
265 
266  SCCOL Col() const
267  {
268  return nCol;
269  }
270  SCTAB Tab() const
271  {
272  return nTab;
273  }
274  void SetRow( SCROW nRowP )
275  {
276  nRow = nRowP;
277  }
278  void SetCol( SCCOL nColP )
279  {
280  nCol = nColP;
281  }
282  void SetTab( SCTAB nTabP )
283  {
284  nTab = nTabP;
285  }
286  void SetInvalid()
287  {
288  nRow = -1;
289  nCol = -1;
290  nTab = -1;
291  }
292  bool IsValid() const
293  {
294  return (nRow >= 0) && (nCol >= 0) && (nTab >= 0);
295  }
296 
297  inline void PutInOrder( ScAddress& rAddress );
298 
299  void IncRow( SCROW nDelta = 1 )
300  {
301  nRow = sal::static_int_cast<SCROW>(nRow + nDelta);
302  }
303  void IncCol( SCCOL nDelta = 1 )
304  {
305  nCol = sal::static_int_cast<SCCOL>(nCol + nDelta);
306  }
307  void IncTab( SCTAB nDelta = 1 )
308  {
309  nTab = sal::static_int_cast<SCTAB>(nTab + nDelta);
310  }
311  void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
312  {
313  nColP = nCol;
314  nRowP = nRow;
315  nTabP = nTab;
316  }
317 
325  SC_DLLPUBLIC ScRefFlags Parse(
326  const OUString&, const ScDocument&,
327  const Details& rDetails = detailsOOOa1,
328  ExternalInfo* pExtInfo = nullptr,
329  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
330  sal_Int32* pSheetEndPos = nullptr,
331  const OUString* pErrRef = nullptr );
332 
333  SC_DLLPUBLIC void Format( OStringBuffer& r, ScRefFlags nFlags,
334  const ScDocument* pDocument = nullptr,
335  const Details& rDetails = detailsOOOa1) const;
336 
337  SC_DLLPUBLIC OUString Format( ScRefFlags nFlags,
338  const ScDocument* pDocument = nullptr,
339  const Details& rDetails = detailsOOOa1) const;
340 
348  [[nodiscard]] SC_DLLPUBLIC bool Move( SCCOL nDeltaX, SCROW nDeltaY, SCTAB nDeltaZ,
349  ScAddress& rErrorPos, const ScDocument* pDocument = nullptr );
350 
351  inline bool operator==( const ScAddress& rAddress ) const;
352  inline bool operator!=( const ScAddress& rAddress ) const;
353  inline bool operator<( const ScAddress& rAddress ) const;
354  inline bool operator<=( const ScAddress& rAddress ) const;
355  inline bool lessThanByRow( const ScAddress& rAddress ) const;
356 
357  inline size_t hash() const;
358 
368  OUString GetColRowString() const;
369 };
370 
371 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
372 template<typename charT, typename traits>
373 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScAddress& rAddress)
374 {
375  stream <<
376  rAddress.Tab()+1 << "!"
377  "R" << rAddress.Row()+1 <<
378  "C" << rAddress.Col()+1;
379 
380  return stream;
381 }
382 
383 inline void ScAddress::PutInOrder( ScAddress& rAddress )
384 {
385  if ( rAddress.Col() < Col() )
386  {
387  SCCOL nTmp = rAddress.Col();
388  rAddress.SetCol( Col() );
389  SetCol( nTmp );
390  }
391  if ( rAddress.Row() < Row() )
392  {
393  SCROW nTmp = rAddress.Row();
394  rAddress.SetRow( Row() );
395  SetRow( nTmp );
396  }
397  if ( rAddress.Tab() < Tab() )
398  {
399  SCTAB nTmp = rAddress.Tab();
400  rAddress.SetTab( Tab() );
401  SetTab( nTmp );
402  }
403 }
404 
405 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
406 {
407  nCol = nColP;
408  nRow = nRowP;
409  nTab = nTabP;
410 }
411 
412 inline ScAddress& ScAddress::operator=( const ScAddress& rAddress )
413 {
414  nCol = rAddress.nCol;
415  nRow = rAddress.nRow;
416  nTab = rAddress.nTab;
417  return *this;
418 }
419 
420 inline bool ScAddress::operator==( const ScAddress& rAddress ) const
421 {
422  return nRow == rAddress.nRow && nCol == rAddress.nCol && nTab == rAddress.nTab;
423 }
424 
425 inline bool ScAddress::operator!=( const ScAddress& rAddress ) const
426 {
427  return !operator==( rAddress );
428 }
429 
431 inline bool ScAddress::operator<( const ScAddress& rAddress ) const
432 {
433  if (nTab == rAddress.nTab)
434  {
435  if (nCol == rAddress.nCol)
436  return nRow < rAddress.nRow;
437  else
438  return nCol < rAddress.nCol;
439  }
440  else
441  return nTab < rAddress.nTab;
442 }
443 
444 inline bool ScAddress::operator<=( const ScAddress& rAddress ) const
445 {
446  return operator<( rAddress ) || operator==( rAddress );
447 }
448 
450 inline bool ScAddress::lessThanByRow( const ScAddress& rAddress ) const
451 {
452  if (nTab == rAddress.nTab)
453  {
454  if (nRow == rAddress.nRow)
455  return nCol < rAddress.nCol;
456  else
457  return nRow < rAddress.nRow;
458  }
459  else
460  return nTab < rAddress.nTab;
461 }
462 
463 inline size_t ScAddress::hash() const
464 {
465 #if SAL_TYPES_SIZEOFPOINTER == 8
466  // 16 bits for the columns, and 20 bits for the rows
467  return (static_cast<size_t>(nTab) << 36) ^
468  (static_cast<size_t>(nCol) << 20) ^
469  static_cast<size_t>(nRow);
470 #else
471  // Assume that there are not that many addresses with row > 2^16 AND column
472  // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
473  if (nRow <= 0xffff)
474  return (static_cast<size_t>(nTab) << 24) ^
475  (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
476  else
477  return (static_cast<size_t>(nTab) << 28) ^
478  (static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
479 #endif
480 }
481 
483 {
484  size_t operator()( const ScAddress & rAddress ) const
485  {
486  return rAddress.hash();
487  }
488 };
489 
490 [[nodiscard]] inline bool ValidAddress( const ScAddress& rAddress, SCCOL nMaxCol = MAXCOL, SCROW nMaxRow = MAXROW )
491 {
492  return ValidCol(rAddress.Col(), nMaxCol) && ValidRow(rAddress.Row(), nMaxRow) && ValidTab(rAddress.Tab());
493 }
494 
495 // ScRange
497 {
498 public:
501 
503  aStart(), aEnd()
504  {}
505 
506  ScRange( ScAddress::Uninitialized eUninitialized ) :
507  aStart( eUninitialized ), aEnd( eUninitialized )
508  {}
510  aStart( eInvalid ), aEnd( eInvalid )
511  {}
512  ScRange( const ScAddress& aInputStart, const ScAddress& aInputEnd ) :
513  aStart( aInputStart ), aEnd( aInputEnd )
514  {
515  aStart.PutInOrder( aEnd );
516  }
517  ScRange( const ScRange& rRange ) :
518  aStart( rRange.aStart ), aEnd( rRange.aEnd )
519  {}
520  ScRange( const ScAddress& rRange ) :
521  aStart( rRange ), aEnd( rRange )
522  {}
523  ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
524  aStart( nCol, nRow, nTab ), aEnd( aStart )
525  {}
526  ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ) :
527  aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 )
528  {}
529 
530  ScRange& operator=( const ScRange& rRange )
531  {
532  aStart = rRange.aStart;
533  aEnd = rRange.aEnd;
534  return *this;
535  }
536  ScRange& operator=( const ScAddress& rPos )
537  {
538  aStart = aEnd = rPos;
539  return *this;
540  }
541  void SetInvalid()
542  {
543  aStart.SetInvalid();
544  aEnd.SetInvalid();
545  }
546  bool IsValid() const
547  {
548  return aStart.IsValid() && aEnd.IsValid();
549  }
550  inline bool In( const ScAddress& ) const;
551  inline bool In( const ScRange& ) const;
552 
553  ScRefFlags Parse( const OUString&, const ScDocument&,
555  ScAddress::ExternalInfo* pExtInfo = nullptr,
556  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
557  const OUString* pErrRef = nullptr );
558 
559  ScRefFlags ParseAny( const OUString&, const ScDocument&,
560  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
561  ScRefFlags ParseCols( const ScDocument& rDoc,
562  const OUString&,
563  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
564  void ParseRows( const ScDocument& rDoc,
565  const OUString&,
566  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
567 
589  const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument& rDocument,
590  OUString& rExternDocName, OUString& rStartTabName,
591  OUString& rEndTabName, ScRefFlags& nFlags,
592  bool bOnlyAcceptSingle,
593  const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
594  const OUString* pErrRef = nullptr );
595 
616  OUString Format( const ScDocument& rDocument,
617  ScRefFlags nFlags = ScRefFlags::ZERO,
619  bool bFullAddressNotation = false ) const;
620 
621  inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
622  SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
623  void PutInOrder();
624 
632  [[nodiscard]] bool Move( SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
633  ScRange& rErrorRange, const ScDocument* pDocument = nullptr );
634 
636  [[nodiscard]] bool MoveSticky( const ScDocument& rDoc, SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
637  ScRange& rErrorRange );
638 
639  void IncColIfNotLessThan(const ScDocument& rDoc, SCCOL nStartCol, SCCOL nOffset);
640  void IncRowIfNotLessThan(const ScDocument& rDoc, SCROW nStartRow, SCROW nOffset);
641 
642  void ExtendTo( const ScRange& rRange );
643  bool Intersects( const ScRange& rRange ) const; // do two ranges intersect?
644 
645  ScRange Intersection( const ScRange& rOther ) const;
646 
648  inline bool IsEndColSticky() const;
650  inline bool IsEndRowSticky() const;
651 
655  void IncEndColSticky( const ScDocument& rDoc, SCCOL nDelta );
656 
660  void IncEndRowSticky( const ScDocument& rDoc, SCROW nDelta );
661 
662  inline bool operator==( const ScRange& rRange ) const;
663  inline bool operator!=( const ScRange& rRange ) const;
664  inline bool operator<( const ScRange& rRange ) const;
665  inline bool operator<=( const ScRange& rRange ) const;
666 
668  inline size_t hashArea() const;
670  inline size_t hashStartColumn() const;
671 };
672 
673 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
674 template<typename charT, typename traits>
675 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScRange& rRange)
676 {
677  stream << rRange.aStart;
678  if (rRange.aEnd != rRange.aStart)
679  {
680  stream << ":";
681  if (rRange.aEnd.Tab() != rRange.aStart.Tab())
682  stream << rRange.aEnd;
683  else
684  stream <<
685  "R" << rRange.aEnd.Row()+1 <<
686  "C" << rRange.aEnd.Col()+1;
687  }
688 
689  return stream;
690 }
691 
692 inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
693  SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
694 {
695  aStart.GetVars( nCol1, nRow1, nTab1 );
696  aEnd.GetVars( nCol2, nRow2, nTab2 );
697 }
698 
699 inline bool ScRange::IsEndColSticky() const
700 {
701  // Only in an actual column range, i.e. not if both columns are MAXCOL.
702  return aEnd.Col() == MAXCOL && aStart.Col() < aEnd.Col();
703 }
704 
705 inline bool ScRange::IsEndRowSticky() const
706 {
707  // Only in an actual row range, i.e. not if both rows are MAXROW.
708  return aEnd.Row() == MAXROW && aStart.Row() < aEnd.Row();
709 }
710 
711 inline bool ScRange::operator==( const ScRange& rRange ) const
712 {
713  return ( (aStart == rRange.aStart) && (aEnd == rRange.aEnd) );
714 }
715 
716 inline bool ScRange::operator!=( const ScRange& rRange ) const
717 {
718  return !operator==( rRange );
719 }
720 
722 inline bool ScRange::operator<( const ScRange& r ) const
723 {
724  return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
725 }
726 
727 inline bool ScRange::operator<=( const ScRange& rRange ) const
728 {
729  return operator<( rRange ) || operator==( rRange );
730 }
731 
732 inline bool ScRange::In( const ScAddress& rAddress ) const
733 {
734  return
735  aStart.Col() <= rAddress.Col() && rAddress.Col() <= aEnd.Col() &&
736  aStart.Row() <= rAddress.Row() && rAddress.Row() <= aEnd.Row() &&
737  aStart.Tab() <= rAddress.Tab() && rAddress.Tab() <= aEnd.Tab();
738 }
739 
740 inline bool ScRange::In( const ScRange& rRange ) const
741 {
742  return
743  aStart.Col() <= rRange.aStart.Col() && rRange.aEnd.Col() <= aEnd.Col() &&
744  aStart.Row() <= rRange.aStart.Row() && rRange.aEnd.Row() <= aEnd.Row() &&
745  aStart.Tab() <= rRange.aStart.Tab() && rRange.aEnd.Tab() <= aEnd.Tab();
746 }
747 
748 inline size_t ScRange::hashArea() const
749 {
750 #if SAL_TYPES_SIZEOFPOINTER == 8
751  // 12 bits for the columns and 20 bits for the rows
752  return
753  (static_cast<size_t>(aStart.Row()) << 44) ^
754  (static_cast<size_t>(aStart.Col()) << 32) ^
755  (static_cast<size_t>(aEnd.Col()) << 20) ^
756  static_cast<size_t>(aEnd.Row());
757 #else
758  // Assume that there are not that many ranges with identical corners so we
759  // won't have too many collisions. Also assume that more lower row and
760  // column numbers are used so that there are not too many conflicts with
761  // the columns hashed into the values, and that start row and column
762  // usually don't exceed certain values. High bits are not masked off and
763  // may overlap with lower bits of other values, e.g. if start column is
764  // greater than assumed.
765  return
766  (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
767  (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
768  (static_cast<size_t>(aEnd.Col()) << 15) ^ // end column <= 2^6
769  static_cast<size_t>(aEnd.Row()); // end row <= 2^15
770 #endif
771 }
772 
773 inline size_t ScRange::hashStartColumn() const
774 {
775 #if SAL_TYPES_SIZEOFPOINTER == 8
776  // 20 bits for the rows
777  return
778  (static_cast<size_t>(aStart.Col()) << 40) ^
779  (static_cast<size_t>(aStart.Row()) << 20) ^
780  static_cast<size_t>(aEnd.Row());
781 #else
782  // Assume that for the start row more lower row numbers are used so that
783  // there are not too many conflicts with the column hashed into the higher
784  // values.
785  return
786  (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
787  (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
788  static_cast<size_t>(aEnd.Row());
789 #endif
790 }
791 
792 [[nodiscard]] inline bool ValidRange( const ScRange& rRange, SCCOL nMaxCol = MAXCOL, SCROW nMaxRow = MAXROW )
793 {
794  return ValidAddress(rRange.aStart, nMaxCol, nMaxRow) && ValidAddress(rRange.aEnd, nMaxCol, nMaxRow);
795 }
796 
797 // ScRangePair
799 {
800 private:
801  std::array<ScRange,2> aRange;
802 
803 public:
805  {
806  aRange[0] = r.aRange[0];
807  aRange[1] = r.aRange[1];
808  }
809  ScRangePair( const ScRange& rRange1, const ScRange& rRange2 )
810  {
811  aRange[0] = rRange1;
812  aRange[1] = rRange2;
813  }
814 
815  inline ScRangePair& operator= ( const ScRangePair& rRange );
816  const ScRange& GetRange( sal_uInt16 n ) const
817  {
818  return aRange[n];
819  }
820  ScRange& GetRange( sal_uInt16 n )
821  {
822  return aRange[n];
823  }
824 };
825 
827 {
828  aRange[0] = rRange.aRange[0];
829  aRange[1] = rRange.aRange[1];
830  return *this;
831 }
832 
833 // ScRefAddress
835 {
836 private:
838  bool bRelCol;
839  bool bRelRow;
840  bool bRelTab;
841 public:
843  bRelCol(false), bRelRow(false), bRelTab(false)
844  {}
845  ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
846  aAdr(nCol, nRow, nTab),
847  bRelCol(false), bRelRow(false), bRelTab(false)
848  {}
849  ScRefAddress( const ScRefAddress& rRef ) :
850  aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
851  bRelTab(rRef.bRelTab)
852  {}
853 
854  inline ScRefAddress& operator=( const ScRefAddress& );
855 
856  bool IsRelCol() const
857  {
858  return bRelCol;
859  }
860  bool IsRelRow() const
861  {
862  return bRelRow;
863  }
864  bool IsRelTab() const
865  {
866  return bRelTab;
867  }
868 
869  void SetRelCol(bool bNewRelCol)
870  {
871  bRelCol = bNewRelCol;
872  }
873  void SetRelRow(bool bNewRelRow)
874  {
875  bRelRow = bNewRelRow;
876  }
877  void SetRelTab(bool bNewRelTab)
878  {
879  bRelTab = bNewRelTab;
880  }
881 
882  inline void Set( const ScAddress& rAdr,
883  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
884  inline void Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
885  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
886 
887  const ScAddress& GetAddress() const
888  {
889  return aAdr;
890  }
891 
892  SCCOL Col() const
893  {
894  return aAdr.Col();
895  }
896  SCROW Row() const
897  {
898  return aAdr.Row();
899  }
900  SCTAB Tab() const
901  {
902  return aAdr.Tab();
903  }
904 
905  inline bool operator == ( const ScRefAddress& r ) const;
906 
907  OUString GetRefString( const ScDocument& rDocument, SCTAB nActTab,
908  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
909 };
910 
912 {
913  aAdr = rRef.aAdr;
914  bRelCol = rRef.bRelCol;
915  bRelRow = rRef.bRelRow;
916  bRelTab = rRef.bRelTab;
917  return *this;
918 }
919 
920 inline void ScRefAddress::Set( const ScAddress& rAdr,
921  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
922 {
923  aAdr = rAdr;
924  bRelCol = bNewRelCol;
925  bRelRow = bNewRelRow;
926  bRelTab = bNewRelTab;
927 }
928 
929 inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
930  bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
931 {
932  aAdr.Set( nNewCol, nNewRow, nNewTab);
933  bRelCol = bNewRelCol;
934  bRelRow = bNewRelRow;
935  bRelTab = bNewRelTab;
936 }
937 
938 inline bool ScRefAddress::operator==( const ScRefAddress& rRefAddress ) const
939 {
940  return aAdr == rRefAddress.aAdr &&
941  bRelCol == rRefAddress.bRelCol &&
942  bRelRow == rRefAddress.bRelRow &&
943  bRelTab == rRefAddress.bRelTab;
944 }
945 
946 // Global functions
947 
948 // Special values for cells always broadcasting or listening (ScRecalcMode::ALWAYS
949 // and the like).
950 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
951 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
952 
953 template< typename T > inline void PutInOrder( T& nStart, T& nEnd )
954 {
955  if (nEnd < nStart)
956  {
957  std::swap(nStart, nEnd);
958  }
959 }
960 
961 bool ConvertSingleRef( const ScDocument& pDocument, const OUString& rRefString,
962  SCTAB nDefTab, ScRefAddress& rRefAddress,
963  const ScAddress::Details& rDetails,
964  ScAddress::ExternalInfo* pExtInfo = nullptr );
965 
966 bool ConvertDoubleRef( const ScDocument& rDocument, const OUString& rRefString,
967  SCTAB nDefTab, ScRefAddress& rStartRefAddress,
968  ScRefAddress& rEndRefAddress,
969  const ScAddress::Details& rDetails,
970  ScAddress::ExternalInfo* pExtInfo = nullptr );
971 
973 SC_DLLPUBLIC void ScColToAlpha( OUStringBuffer& rBuffer, SCCOL nCol);
974 
975 inline void ScColToAlpha( OUString& rStr, SCCOL nCol)
976 {
977  OUStringBuffer aBuf(4);
978  ScColToAlpha( aBuf, nCol);
979  rStr += aBuf;
980 }
981 
982 inline OUString ScColToAlpha( SCCOL nCol )
983 {
984  OUStringBuffer aBuf(4);
985  ScColToAlpha( aBuf, nCol);
986  return aBuf.makeStringAndClear();
987 }
988 
990 bool AlphaToCol(const ScDocument& rDoc, SCCOL& rCol, const OUString& rStr);
991 
992 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool operator==(const XclFontData &rLeft, const XclFontData &rRight)
Definition: xlstyle.cxx:519
Details(formula::FormulaGrammar::AddressConvention eConvP)
Definition: address.hxx:222
ScAddress(const ScAddress &rAddress)
Definition: address.hxx:254
void Set(const ScAddress &rAdr, bool bNewRelCol, bool bNewRelRow, bool bNewRelTab)
Definition: address.hxx:920
bool bRelTab
Definition: address.hxx:840
const SCROW SCROWS32K
Definition: address.hxx:85
void GetVars(SCCOL &nColP, SCROW &nRowP, SCTAB &nTabP) const
Definition: address.hxx:311
bool operator!=(const ScAddress &rAddress) const
Definition: address.hxx:425
size_t hashArea() const
Hash 2D area ignoring table number.
Definition: address.hxx:748
ScAddress aStart
Definition: address.hxx:499
SC_DLLPUBLIC void ScColToAlpha(OUStringBuffer &rBuffer, SCCOL nCol)
append alpha representation of column to buffer
Definition: address.cxx:1926
ScRange(const ScRange &rRange)
Definition: address.hxx:517
const SCROW MAXROW_30
Definition: address.hxx:90
bool operator!=(const XclExpString &rLeft, const XclExpString &rRight)
Definition: xestring.hxx:250
void IncTab(SCTAB nDelta=1)
Definition: address.hxx:307
SCROW Row() const
Definition: address.hxx:261
const SCCOLROW SCCOLROW_MAX
Definition: address.hxx:58
size_t hash() const
Definition: address.hxx:463
bool ConvertDoubleRef(const ScDocument &rDocument, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rStartRefAddress, ScRefAddress &rEndRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo=nullptr)
Definition: address.cxx:1522
ScRangePair & operator=(const ScRangePair &rRange)
Definition: address.hxx:826
size_t hashStartColumn() const
Hash start column and start and end rows.
Definition: address.hxx:773
void SetRelTab(bool bNewRelTab)
Definition: address.hxx:877
const SCCOL SCCOL_MAX
Definition: address.hxx:56
constexpr std::underlying_type_t< T > underlyingEnumValue(T e)
aBuf
void PutInOrder(ScAddress &rAddress)
Definition: address.hxx:383
ScRange(const ScAddress &rRange)
Definition: address.hxx:520
ScAddress aEnd
Definition: address.hxx:500
bool operator<=(const BigInt &rVal1, const BigInt &rVal2)
ScRange(ScAddress::Uninitialized eUninitialized)
Definition: address.hxx:506
const SCCOL MAXCOLCOUNT
Definition: address.hxx:63
bool operator<(const ScRange &rRange) const
Sort on upper left corner tab,col,row, if equal then use lower right too.
Definition: address.hxx:722
bool operator==(const ScRefAddress &r) const
Definition: address.hxx:938
const SCROW SCROW_MAX
Definition: address.hxx:55
ScRefAddress & operator=(const ScRefAddress &)
Definition: address.hxx:911
exports com.sun.star. sheet
ScAddress(InitializeInvalid)
Definition: address.hxx:251
bool ConvertSingleRef(const ScDocument &pDocument, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo=nullptr)
Definition: address.cxx:1500
sal_uInt16 sal_Unicode
const SCROW MAXROW_JUMBO
Definition: address.hxx:72
ScRange()
Definition: address.hxx:502
bool ValidColRowTab(SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:120
formula::FormulaGrammar::AddressConvention eConv
Definition: address.hxx:212
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:23
const SCROW MAXROW
Definition: address.hxx:68
bool ValidRange(const ScRange &rRange, SCCOL nMaxCol=MAXCOL, SCROW nMaxRow=MAXROW)
Definition: address.hxx:792
static SC_DLLPUBLIC const Details detailsOOOa1
Definition: address.hxx:228
SCTAB Tab() const
Definition: address.hxx:270
ScAddress & operator=(const ScAddress &rAddress)
Definition: address.hxx:412
void SetRow(SCROW nRowP)
Definition: address.hxx:274
SCROW SanitizeRow(SCROW nRow, SCROW nMaxRow)
Definition: address.hxx:132
SCCOL nCol
Definition: address.hxx:202
const SCCOLROW MAXCOLROW
Definition: address.hxx:71
void SetCol(SCCOL nColP)
Definition: address.hxx:278
ScRange(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2)
Definition: address.hxx:526
const SCROW MAXROWCOUNT
Definition: address.hxx:62
ScRange & operator=(const ScRange &rRange)
Definition: address.hxx:530
void PutInOrder(T &nStart, T &nEnd)
Definition: address.hxx:953
ScRefAddress(const ScRefAddress &rRef)
Definition: address.hxx:849
bool IsRelTab() const
Definition: address.hxx:864
SCCOL SanitizeCol(SCCOL nCol, SCCOL nMaxCol)
Definition: address.hxx:126
bool IsValid() const
Definition: address.hxx:292
SCROW nRow
Definition: address.hxx:201
ScRange & GetRange(sal_uInt16 n)
Definition: address.hxx:820
bool ValidCol(SCCOL nCol, SCCOL nMaxCol)
Definition: address.hxx:92
void SetTab(SCTAB nTabP)
Definition: address.hxx:282
ScRange & operator=(const ScAddress &rPos)
Definition: address.hxx:536
bool IsEndColSticky() const
If maximum end column should not be adapted during reference update.
Definition: address.hxx:699
const SCTAB SC_TAB_APPEND
Definition: address.hxx:83
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:303
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:405
sal_Int16 SCCOL
Definition: types.hxx:21
Details(formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP)
Definition: address.hxx:216
bool operator!=(const ScRange &rRange) const
Definition: address.hxx:716
void applyStartToEndFlags(ScRefFlags &target, const ScRefFlags source)
Definition: address.hxx:183
const SCTAB MININITTAB
Definition: address.hxx:80
const SCCOL MAXCOL
Definition: address.hxx:69
const SCSIZE SCSIZE_MAX
Definition: address.hxx:59
std::array< ScRange, 2 > aRange
Definition: address.hxx:801
bool IsEndRowSticky() const
If maximum end row should not be adapted during reference update.
Definition: address.hxx:705
void IncRow(SCROW nDelta=1)
Definition: address.hxx:299
const ScRange & GetRange(sal_uInt16 n) const
Definition: address.hxx:816
ScRange(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:523
InitializeInvalid
Definition: address.hxx:208
bool operator<=(const ScRange &rRange) const
Definition: address.hxx:727
void GetVars(SCCOL &nCol1, SCROW &nRow1, SCTAB &nTab1, SCCOL &nCol2, SCROW &nRow2, SCTAB &nTab2) const
Definition: address.hxx:692
bool AlphaToCol(const ScDocument &rDoc, SCCOL &rCol, const OUString &rStr)
get column number of A..IV... string
Definition: address.cxx:2541
ScRangePair(const ScRangePair &r)
Definition: address.hxx:804
bool In(const ScAddress &) const
is Address& in Range?
Definition: address.hxx:732
const SCTAB MAXTAB
Definition: address.hxx:70
bool operator<(const ScAddress &rAddress) const
Less than ordered by tab,col,row.
Definition: address.hxx:431
void SetInvalid()
Definition: address.hxx:541
bool IsValid() const
Definition: address.hxx:546
const SCROW SCROW_REPEAT_NONE
Definition: address.hxx:87
const SCTAB TABLEID_DOC
Definition: address.hxx:84
const SCTAB MAXINITTAB
Definition: address.hxx:79
ScAddress aAdr
Definition: address.hxx:837
ScRange(const ScAddress &aInputStart, const ScAddress &aInputEnd)
Definition: address.hxx:512
ScRange(ScAddress::InitializeInvalid eInvalid)
Definition: address.hxx:509
SCCOL Col() const
Definition: address.hxx:266
Details(formula::FormulaGrammar::AddressConvention eConvP, ScAddress const &rAddr)
Definition: address.hxx:219
Reference< XOutputStream > stream
#define SAL_WARN_UNUSED
SCTAB SanitizeTab(SCTAB nTab)
Definition: address.hxx:138
sal_Int32 SCROW
Definition: types.hxx:17
bool operator<(const ScDPCollection::DBType &left, const ScDPCollection::DBType &right)
Definition: dpobject.cxx:3927
const ScAddress & GetAddress() const
Definition: address.hxx:887
size_t operator()(const ScAddress &rAddress) const
Definition: address.hxx:484
const SCCOL INITIALCOLCOUNT
Definition: address.hxx:64
const SCCOL MAXCOL_JUMBO
Definition: address.hxx:73
bool IsRelCol() const
Definition: address.hxx:856
bool IsRelRow() const
Definition: address.hxx:860
SCROW Row() const
Definition: address.hxx:896
SCCOL Col() const
Definition: address.hxx:892
void SetInvalid()
Definition: address.hxx:286
const SCROW MAXTILEDROW
Definition: address.hxx:75
void SetRelCol(bool bNewRelCol)
Definition: address.hxx:869
ScRefAddress(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:845
bool ValidColRow(SCCOL nCol, SCROW nRow, SCCOL nMaxCol, SCROW nMaxRow)
Definition: address.hxx:114
bool ValidRow(SCROW nRow, SCROW nMaxRow)
Definition: address.hxx:98
bool bRelCol
Definition: address.hxx:838
SCTAB nTab
Definition: address.hxx:203
const SCCOL SC_TABSTART_NONE
Definition: address.hxx:88
ScAddress(Uninitialized)
Yes, it is what it seems to be: Uninitialized.
Definition: address.hxx:249
SCTAB Tab() const
Definition: address.hxx:900
ScAddress(SCCOL nColP, SCROW nRowP, SCTAB nTabP)
Definition: address.hxx:244
bool lessThanByRow(const ScAddress &rAddress) const
Less than ordered by tab,row,col as needed by row-wise import/export.
Definition: address.hxx:450
ScRefFlags
Definition: address.hxx:144
const SCTAB MAXTABCOUNT
limiting to 10000 for now, problem with 32 bit builds for now
Definition: address.hxx:66
const SCTAB SCTAB_MAX
Definition: address.hxx:57
ScRangePair(const ScRange &rRange1, const ScRange &rRange2)
Definition: address.hxx:809
#define SC_DLLPUBLIC
Definition: scdllapi.h:27
bool ValidTab(SCTAB nTab)
Definition: address.hxx:104
const SCCOL SCCOL_REPEAT_NONE
Definition: address.hxx:86
bool operator==(const ScAddress &rAddress) const
Definition: address.hxx:420
bool operator<=(const ScAddress &rAddress) const
Definition: address.hxx:444
sal_Int16 SCTAB
Definition: types.hxx:22
bool bRelRow
Definition: address.hxx:839
void SetRelRow(bool bNewRelRow)
Definition: address.hxx:873
bool ValidAddress(const ScAddress &rAddress, SCCOL nMaxCol=MAXCOL, SCROW nMaxRow=MAXROW)
Definition: address.hxx:490
bool operator==(const ScRange &rRange) const
Definition: address.hxx:711