1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SC_INC_ADDRESS_HXX
21 #define INCLUDED_SC_INC_ADDRESS_HXX
23 #include <rtl/ustrbuf.hxx>
24 #include <rtl/strbuf.hxx>
29 #include <formula/grammar.hxx>
31 #include <o3tl/typed_flags_set.hxx>
32 #include <com/sun/star/uno/Sequence.hxx>
34 namespace com
{ namespace sun
{ namespace star
{
36 struct ExternalLinkInfo
;
42 /** size_t typedef to be able to find places where code was changed from USHORT
43 to size_t and is used to read/write from/to streams. */
44 typedef size_t SCSIZE
;
46 // Maximum possible value of data type, NOT maximum row value.
47 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
48 // included, we should not be using those stupid macros anyway.
51 const SCROW SCROW_MAX
= ::std::numeric_limits
<SCROW
>::max();
52 const SCCOL SCCOL_MAX
= ::std::numeric_limits
<SCCOL
>::max();
53 const SCTAB SCTAB_MAX
= ::std::numeric_limits
<SCTAB
>::max();
54 const SCCOLROW SCCOLROW_MAX
= ::std::numeric_limits
<SCCOLROW
>::max();
55 const SCSIZE SCSIZE_MAX
= ::std::numeric_limits
<SCSIZE
>::max();
57 // The maximum values. Defines are needed for preprocessor checks, for example
58 // in bcaslot.cxx, otherwise type safe constants are preferred.
59 #define MAXROWCOUNT_DEFINE 1048576
60 #define MAXCOLCOUNT_DEFINE 1024
63 const SCROW MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
64 const SCCOL MAXCOLCOUNT
= MAXCOLCOUNT_DEFINE
;
65 /// limiting to 10000 for now, problem with 32 bit builds for now
66 const SCTAB MAXTABCOUNT
= 10000;
67 const SCCOLROW MAXCOLROWCOUNT
= MAXROWCOUNT
;
69 const SCROW MAXROW
= MAXROWCOUNT
- 1;
70 const SCCOL MAXCOL
= MAXCOLCOUNT
- 1;
71 const SCTAB MAXTAB
= MAXTABCOUNT
- 1;
72 const SCCOLROW MAXCOLROW
= MAXROW
;
73 // Maximun tiled rendering values
74 const SCROW MAXTILEDROW
= 500000;
75 // Limit the initial tab count to prevent users to set the count too high,
76 // which could cause the memory usage of blank documents to exceed the
77 // available system memory.
78 const SCTAB MAXINITTAB
= 1024;
79 const SCTAB MININITTAB
= 1;
82 const SCTAB SC_TAB_APPEND
= SCTAB_MAX
;
83 const SCTAB TABLEID_DOC
= SCTAB_MAX
; // entire document, e.g. protect
84 const SCROW SCROWS32K
= 32000;
85 const SCCOL SCCOL_REPEAT_NONE
= SCCOL_MAX
;
86 const SCROW SCROW_REPEAT_NONE
= SCROW_MAX
;
88 #define MAXROW_30 8191
90 SAL_WARN_UNUSED_RESULT
inline bool ValidCol( SCCOL nCol
)
92 return nCol
>= static_cast<SCCOL
>(0) && nCol
<= MAXCOL
;
95 SAL_WARN_UNUSED_RESULT
inline bool ValidRow( SCROW nRow
)
97 return nRow
>= static_cast<SCROW
>(0) && nRow
<= MAXROW
;
100 SAL_WARN_UNUSED_RESULT
inline bool ValidTab( SCTAB nTab
)
102 return nTab
>= static_cast<SCTAB
>(0) && nTab
<= MAXTAB
;
105 SAL_WARN_UNUSED_RESULT
inline bool ValidTab( SCTAB nTab
, SCTAB nMaxTab
)
107 return nTab
>= static_cast<SCTAB
>(0) && nTab
<= nMaxTab
;
110 SAL_WARN_UNUSED_RESULT
inline bool ValidColRow( SCCOL nCol
, SCROW nRow
)
112 return ValidCol( nCol
) && ValidRow( nRow
);
115 SAL_WARN_UNUSED_RESULT
inline bool ValidColRowTab( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
117 return ValidCol( nCol
) && ValidRow( nRow
) && ValidTab( nTab
);
120 SAL_WARN_UNUSED_RESULT
inline SCCOL
SanitizeCol( SCCOL nCol
)
122 return nCol
< 0 ? 0 : (nCol
> MAXCOL
? MAXCOL
: nCol
);
125 SAL_WARN_UNUSED_RESULT
inline SCROW
SanitizeRow( SCROW nRow
)
127 return nRow
< 0 ? 0 : (nRow
> MAXROW
? MAXROW
: nRow
);
130 SAL_WARN_UNUSED_RESULT
inline SCTAB
SanitizeTab( SCTAB nTab
)
132 return nTab
< 0 ? 0 : (nTab
> MAXTAB
? MAXTAB
: nTab
);
136 // The old cell address is combined in one UINT32:
140 // For speed reasons access isn't done by shifting bits but by using platform
141 // dependent casts, which unfortunately also leads to aliasing problems when
142 // not using gcc -fno-strict-aliasing
144 // The result of ConvertRef() is a bit group of the following:
145 enum class ScRefFlags
: sal_uInt16
159 // BITS for convience
160 BITS
= COL_ABS
| ROW_ABS
| TAB_ABS
| TAB_3D \
161 | ROW_VALID
| COL_VALID
| TAB_VALID
,
162 // somewhat cheesy kludge to force the display of the document name even for
163 // local references. Requires TAB_3D to be valid
170 ADDR_ABS
= VALID
| COL_ABS
| ROW_ABS
| TAB_ABS
,
172 RANGE_ABS
= ADDR_ABS
| COL2_ABS
| ROW2_ABS
| TAB2_ABS
,
174 ADDR_ABS_3D
= ADDR_ABS
| TAB_3D
,
175 RANGE_ABS_3D
= RANGE_ABS
| TAB_3D
180 template<> struct typed_flags
<ScRefFlags
> : is_typed_flags
<ScRefFlags
, 0xffff> {};
182 inline void applyStartToEndFlags(ScRefFlags
&target
,const ScRefFlags source
)
184 target
|= ScRefFlags((std::underlying_type
<ScRefFlags
>::type
)source
<< 4);
186 inline void applyStartToEndFlags(ScRefFlags
&target
)
188 target
|= ScRefFlags((std::underlying_type
<ScRefFlags
>::type
)target
<< 4);
201 enum Uninitialized
{ UNINITIALIZED
};
202 enum InitializeInvalid
{ INITIALIZE_INVALID
};
206 formula::FormulaGrammar::AddressConvention eConv
;
210 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, SCROW nRowP
, SCCOL nColP
) :
211 eConv(eConvP
), nRow(nRowP
), nCol(nColP
)
213 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, ScAddress
const & rAddr
) :
214 eConv(eConvP
), nRow(rAddr
.Row()), nCol(rAddr
.Col())
216 inline Details( formula::FormulaGrammar::AddressConvention eConvP
) :
217 eConv(eConvP
), nRow(0), nCol(0)
219 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
220 Details( const ScDocument
* pDoc
, const ScAddress
& rAddr
);
222 SC_DLLPUBLIC
static const Details detailsOOOa1
;
230 inline ExternalInfo() :
231 mnFileId(0), mbExternal(false)
236 nRow(0), nCol(0), nTab(0)
238 inline ScAddress( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
) :
239 nRow(nRowP
), nCol(nColP
), nTab(nTabP
)
241 /** Yes, it is what it seems to be: Uninitialized. May be used for
242 performance reasons if it is initialized by other means. */
243 inline ScAddress( Uninitialized
)
245 inline ScAddress( InitializeInvalid
) :
246 nRow(-1), nCol(-1), nTab(-1)
248 inline ScAddress( const ScAddress
& rAddress
) :
249 nRow(rAddress
.nRow
), nCol(rAddress
.nCol
), nTab(rAddress
.nTab
)
251 inline ScAddress
& operator=( const ScAddress
& rAddress
);
253 inline void Set( SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
255 inline SCROW
Row() const
260 inline SCCOL
Col() const
264 inline SCTAB
Tab() const
268 inline void SetRow( SCROW nRowP
)
272 inline void SetCol( SCCOL nColP
)
276 inline void SetTab( SCTAB nTabP
)
280 inline void SetInvalid()
286 inline bool IsValid() const
288 return (nRow
>= 0) && (nCol
>= 0) && (nTab
>= 0);
291 inline void PutInOrder( ScAddress
& rAddress
);
293 inline void IncRow( SCsROW nDelta
= 1 )
295 nRow
= sal::static_int_cast
<SCROW
>(nRow
+ nDelta
);
297 inline void IncCol( SCsCOL nDelta
= 1 )
299 nCol
= sal::static_int_cast
<SCCOL
>(nCol
+ nDelta
);
301 inline void IncTab( SCsTAB nDelta
= 1 )
303 nTab
= sal::static_int_cast
<SCTAB
>(nTab
+ nDelta
);
305 inline void GetVars( SCCOL
& nColP
, SCROW
& nRowP
, SCTAB
& nTabP
) const
314 If given and Parse() successfully parsed a sheet name it returns
315 the end position (exclusive) behind the sheet name AND a
316 following sheet name separator. This independent of whether the
317 resulting reference is fully valid or not.
319 SC_DLLPUBLIC ScRefFlags
Parse(
320 const OUString
&, ScDocument
* = nullptr,
321 const Details
& rDetails
= detailsOOOa1
,
322 ExternalInfo
* pExtInfo
= nullptr,
323 const css::uno::Sequence
<css::sheet::ExternalLinkInfo
>* pExternalLinks
= nullptr,
324 sal_Int32
* pSheetEndPos
= nullptr,
325 const OUString
* pErrRef
= nullptr );
327 SC_DLLPUBLIC
void Format( OStringBuffer
& r
, ScRefFlags nFlags
,
328 const ScDocument
* pDocument
= nullptr,
329 const Details
& rDetails
= detailsOOOa1
) const;
331 SC_DLLPUBLIC OUString
Format( ScRefFlags nFlags
,
332 const ScDocument
* pDocument
= nullptr,
333 const Details
& rDetails
= detailsOOOa1
) const;
337 If FALSE is returned, the positions contain <0 or >MAX...
338 values if shifted out of bounds.
340 The document for the maximum defined sheet number.
342 SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT
bool Move( SCsCOL nDeltaX
, SCsROW nDeltaY
, SCsTAB nDeltaZ
,
343 ScAddress
& rErrorPos
, ScDocument
* pDocument
= nullptr );
345 inline bool operator==( const ScAddress
& rAddress
) const;
346 inline bool operator!=( const ScAddress
& rAddress
) const;
347 inline bool operator<( const ScAddress
& rAddress
) const;
348 inline bool operator<=( const ScAddress
& rAddress
) const;
350 inline size_t hash() const;
352 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
353 OUString
GetColRowString() const;
356 inline void ScAddress::PutInOrder( ScAddress
& rAddress
)
358 if ( rAddress
.Col() < Col() )
360 SCCOL nTmp
= rAddress
.Col();
361 rAddress
.SetCol( Col() );
364 if ( rAddress
.Row() < Row() )
366 SCROW nTmp
= rAddress
.Row();
367 rAddress
.SetRow( Row() );
370 if ( rAddress
.Tab() < Tab() )
372 SCTAB nTmp
= rAddress
.Tab();
373 rAddress
.SetTab( Tab() );
378 inline void ScAddress::Set( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
385 inline ScAddress
& ScAddress::operator=( const ScAddress
& rAddress
)
387 nCol
= rAddress
.nCol
;
388 nRow
= rAddress
.nRow
;
389 nTab
= rAddress
.nTab
;
393 inline bool ScAddress::operator==( const ScAddress
& rAddress
) const
395 return nRow
== rAddress
.nRow
&& nCol
== rAddress
.nCol
&& nTab
== rAddress
.nTab
;
398 inline bool ScAddress::operator!=( const ScAddress
& rAddress
) const
400 return !operator==( rAddress
);
403 /** Same behavior as the old sal_uInt32 nAddress < r.nAddress with encoded
404 tab|col|row bit fields. */
405 inline bool ScAddress::operator<( const ScAddress
& rAddress
) const
407 if (nTab
== rAddress
.nTab
)
409 if (nCol
== rAddress
.nCol
)
410 return nRow
< rAddress
.nRow
;
412 return nCol
< rAddress
.nCol
;
415 return nTab
< rAddress
.nTab
;
418 inline bool ScAddress::operator<=( const ScAddress
& rAddress
) const
420 return operator<( rAddress
) || operator==( rAddress
);
423 inline size_t ScAddress::hash() const
425 // Assume that there are not that many addresses with row > 2^16 AND column
426 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
428 return (static_cast<size_t>(nTab
) << 24) ^
429 (static_cast<size_t>(nCol
) << 16) ^ static_cast<size_t>(nRow
);
431 return (static_cast<size_t>(nTab
) << 28) ^
432 (static_cast<size_t>(nCol
) << 24) ^ static_cast<size_t>(nRow
);
435 struct ScAddressHashFunctor
437 size_t operator()( const ScAddress
& rAddress
) const
439 return rAddress
.hash();
443 inline bool ValidAddress( const ScAddress
& rAddress
)
445 return ValidCol(rAddress
.Col()) && ValidRow(rAddress
.Row()) && ValidTab(rAddress
.Tab());
459 inline ScRange( ScAddress::Uninitialized eUninitialized
) :
460 aStart( eUninitialized
), aEnd( eUninitialized
)
462 inline ScRange( ScAddress::InitializeInvalid eInvalid
) :
463 aStart( eInvalid
), aEnd( eInvalid
)
465 inline ScRange( const ScAddress
& aInputStart
, const ScAddress
& aInputEnd
) :
466 aStart( aInputStart
), aEnd( aInputEnd
)
468 aStart
.PutInOrder( aEnd
);
470 inline ScRange( const ScRange
& rRange
) :
471 aStart( rRange
.aStart
), aEnd( rRange
.aEnd
)
473 inline ScRange( const ScAddress
& rRange
) :
474 aStart( rRange
), aEnd( rRange
)
476 inline ScRange( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) :
477 aStart( nCol
, nRow
, nTab
), aEnd( aStart
)
479 inline ScRange( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
, SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
) :
480 aStart( nCol1
, nRow1
, nTab1
), aEnd( nCol2
, nRow2
, nTab2
)
483 inline ScRange
& operator=( const ScRange
& rRange
)
485 aStart
= rRange
.aStart
;
489 inline ScRange
& operator=( const ScAddress
& rPos
)
491 aStart
= aEnd
= rPos
;
494 inline void SetInvalid()
499 inline bool IsValid() const
501 return aStart
.IsValid() && aEnd
.IsValid();
503 inline bool In( const ScAddress
& ) const; ///< is Address& in Range?
504 inline bool In( const ScRange
& ) const; ///< is Range& in Range?
506 SC_DLLPUBLIC ScRefFlags
Parse( const OUString
&, ScDocument
* = nullptr,
507 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
508 ScAddress::ExternalInfo
* pExtInfo
= nullptr,
509 const css::uno::Sequence
<css::sheet::ExternalLinkInfo
>* pExternalLinks
= nullptr,
510 const OUString
* pErrRef
= nullptr );
512 SC_DLLPUBLIC ScRefFlags
ParseAny( const OUString
&, ScDocument
*,
513 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
514 SC_DLLPUBLIC ScRefFlags
ParseCols( const OUString
&, ScDocument
*,
515 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
516 SC_DLLPUBLIC
void ParseRows( const OUString
&, ScDocument
*,
517 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
519 /** Parse an Excel style reference up to and including the sheet name
520 separator '!', including detection of external documents and sheet
521 names, and in case of MOOXML import the bracketed index is used to
522 determine the actual document name passed in pExternalLinks. For
523 internal references (resulting rExternDocName empty), aStart.nTab and
524 aEnd.nTab are set, or -1 if sheet name not found.
525 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
526 encountered results in an error (NULL returned).
527 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
528 NULL for non-filter usage, in which case indices such as [1] are
530 @param pErrRef pointer to "#REF!" string if to be accepted.
532 Pointer to the position after '!' if successfully parsed, and
533 rExternDocName, rStartTabName and/or rEndTabName filled if
534 applicable. ScRefFlags::... flags set in nFlags.
535 Or if no valid document and/or sheet header could be parsed the start
536 position passed with pString.
537 Or NULL if a 3D sheet header could be parsed but
538 bOnlyAcceptSingle==true was given.
540 const sal_Unicode
* Parse_XL_Header( const sal_Unicode
* pString
, const ScDocument
* pDocument
,
541 OUString
& rExternDocName
, OUString
& rStartTabName
,
542 OUString
& rEndTabName
, ScRefFlags
& nFlags
,
543 bool bOnlyAcceptSingle
,
544 const css::uno::Sequence
<css::sheet::ExternalLinkInfo
>* pExternalLinks
= nullptr,
545 const OUString
* pErrRef
= nullptr );
547 /** Returns string with formatted cell range from aStart to aEnd,
548 according to provided address convention.
552 Pointer to document which is used for example to get tab names.
554 Provide information about required address convention.
555 Supported address conventions are:
556 CONV_OOO 'doc'#sheet.A1:sheet2.B2
557 CONV_XL_A1, [doc]sheet:sheet2!A1:B2
558 CONV_XL_OOX, [#]sheet:sheet2!A1:B2
559 CONV_XL_R1C1, [doc]sheet:sheet2!R1C1:R2C2
560 @param bFullAddressNotation
561 If TRUE, the full address notation will be used.
562 For example in case all columns are used, "A1:AMJ177" is full address notation
563 and "1:177" is shortened address notation.
565 String contains formatted cell range in address convention
567 SC_DLLPUBLIC OUString
Format( ScRefFlags nFlags
= ScRefFlags::ZERO
,
568 const ScDocument
* pDocument
= nullptr,
569 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
570 bool bFullAddressNotation
= false ) const;
572 inline void GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
573 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const;
574 SC_DLLPUBLIC
void PutInOrder();
578 If FALSE is returned, the positions contain <0 or >MAX...
579 values if shifted out of bounds.
581 The document for the maximum defined sheet number.
583 SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT
bool Move( SCsCOL aDeltaX
, SCsROW aDeltaY
, SCsTAB aDeltaZ
,
584 ScRange
& rErrorRange
, ScDocument
* pDocument
= nullptr );
586 /** Same as Move() but with sticky end col/row anchors. */
587 SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT
bool MoveSticky( SCsCOL aDeltaX
, SCsROW aDeltaY
, SCsTAB aDeltaZ
,
588 ScRange
& rErrorRange
);
590 SC_DLLPUBLIC
void IncColIfNotLessThan(SCCOL nStartCol
, SCsCOL nOffset
);
591 SC_DLLPUBLIC
void IncRowIfNotLessThan(SCROW nStartRow
, SCsROW nOffset
);
593 SC_DLLPUBLIC
void ExtendTo( const ScRange
& rRange
);
594 SC_DLLPUBLIC
bool Intersects( const ScRange
& rRange
) const; // do two ranges intersect?
596 ScRange
Intersection( const ScRange
& rOther
) const;
598 /// If maximum end column should not be adapted during reference update.
599 inline bool IsEndColSticky() const;
600 /// If maximum end row should not be adapted during reference update.
601 inline bool IsEndRowSticky() const;
603 /** Increment or decrement end column unless sticky or until it becomes
604 sticky. Checks if the range encompasses at least two columns so should
605 be called before adjusting the start column. */
606 void IncEndColSticky( SCsCOL nDelta
);
608 /** Increment or decrement end row unless sticky or until it becomes
609 sticky. Checks if the range encompasses at least two rows so should
610 be called before adjusting the start row. */
611 void IncEndRowSticky( SCsROW nDelta
);
613 inline bool operator==( const ScRange
& rRange
) const;
614 inline bool operator!=( const ScRange
& rRange
) const;
615 inline bool operator<( const ScRange
& rRange
) const;
616 inline bool operator<=( const ScRange
& rRange
) const;
618 /// Hash 2D area ignoring table number.
619 inline size_t hashArea() const;
620 /// Hash start column and start and end rows.
621 inline size_t hashStartColumn() const;
624 inline void ScRange::GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
625 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const
627 aStart
.GetVars( nCol1
, nRow1
, nTab1
);
628 aEnd
.GetVars( nCol2
, nRow2
, nTab2
);
631 inline bool ScRange::IsEndColSticky() const
633 // Only in an actual column range, i.e. not if both columns are MAXCOL.
634 return aEnd
.Col() == MAXCOL
&& aStart
.Col() < aEnd
.Col();
637 inline bool ScRange::IsEndRowSticky() const
639 // Only in an actual row range, i.e. not if both rows are MAXROW.
640 return aEnd
.Row() == MAXROW
&& aStart
.Row() < aEnd
.Row();
643 inline bool ScRange::operator==( const ScRange
& rRange
) const
645 return ( (aStart
== rRange
.aStart
) && (aEnd
== rRange
.aEnd
) );
648 inline bool ScRange::operator!=( const ScRange
& rRange
) const
650 return !operator==( rRange
);
653 /// Sort on upper left corner, if equal then use lower right too.
654 inline bool ScRange::operator<( const ScRange
& r
) const
656 return aStart
< r
.aStart
|| (aStart
== r
.aStart
&& aEnd
< r
.aEnd
) ;
659 inline bool ScRange::operator<=( const ScRange
& rRange
) const
661 return operator<( rRange
) || operator==( rRange
);
664 inline bool ScRange::In( const ScAddress
& rAddress
) const
667 aStart
.Col() <= rAddress
.Col() && rAddress
.Col() <= aEnd
.Col() &&
668 aStart
.Row() <= rAddress
.Row() && rAddress
.Row() <= aEnd
.Row() &&
669 aStart
.Tab() <= rAddress
.Tab() && rAddress
.Tab() <= aEnd
.Tab();
672 inline bool ScRange::In( const ScRange
& rRange
) const
675 aStart
.Col() <= rRange
.aStart
.Col() && rRange
.aEnd
.Col() <= aEnd
.Col() &&
676 aStart
.Row() <= rRange
.aStart
.Row() && rRange
.aEnd
.Row() <= aEnd
.Row() &&
677 aStart
.Tab() <= rRange
.aStart
.Tab() && rRange
.aEnd
.Tab() <= aEnd
.Tab();
680 inline size_t ScRange::hashArea() const
682 // Assume that there are not that many ranges with identical corners so we
683 // won't have too many collisions. Also assume that more lower row and
684 // column numbers are used so that there are not too many conflicts with
685 // the columns hashed into the values, and that start row and column
686 // usually don't exceed certain values. High bits are not masked off and
687 // may overlap with lower bits of other values, e.g. if start column is
688 // greater than assumed.
690 (static_cast<size_t>(aStart
.Row()) << 26) ^ // start row <= 2^6
691 (static_cast<size_t>(aStart
.Col()) << 21) ^ // start column <= 2^5
692 (static_cast<size_t>(aEnd
.Col()) << 15) ^ // end column <= 2^6
693 static_cast<size_t>(aEnd
.Row()); // end row <= 2^15
696 inline size_t ScRange::hashStartColumn() const
698 // Assume that for the start row more lower row numbers are used so that
699 // there are not too many conflicts with the column hashed into the higher
702 (static_cast<size_t>(aStart
.Col()) << 24) ^ // start column <= 2^8
703 (static_cast<size_t>(aStart
.Row()) << 16) ^ // start row <= 2^8
704 static_cast<size_t>(aEnd
.Row());
707 inline bool ValidRange( const ScRange
& rRange
)
709 return ValidAddress(rRange
.aStart
) && ValidAddress(rRange
.aEnd
);
719 ScRangePair( const ScRangePair
& r
)
721 aRange
[0] = r
.aRange
[0];
722 aRange
[1] = r
.aRange
[1];
724 ScRangePair( const ScRange
& rRange1
, const ScRange
& rRange2
)
730 inline ScRangePair
& operator= ( const ScRangePair
& rRange
);
731 const ScRange
& GetRange( sal_uInt16 n
) const
735 ScRange
& GetRange( sal_uInt16 n
)
741 inline ScRangePair
& ScRangePair::operator= ( const ScRangePair
& rRange
)
743 aRange
[0] = rRange
.aRange
[0];
744 aRange
[1] = rRange
.aRange
[1];
757 inline ScRefAddress() :
758 bRelCol(false), bRelRow(false), bRelTab(false)
760 inline ScRefAddress( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
761 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
762 aAdr(nCol
, nRow
, nTab
),
763 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
765 inline ScRefAddress( const ScRefAddress
& rRef
) :
766 aAdr(rRef
.aAdr
), bRelCol(rRef
.bRelCol
), bRelRow(rRef
.bRelRow
),
767 bRelTab(rRef
.bRelTab
)
770 inline ScRefAddress
& operator=( const ScRefAddress
& );
772 inline bool IsRelCol() const
776 inline bool IsRelRow() const
780 inline bool IsRelTab() const
785 inline void SetRelCol(bool bNewRelCol
)
787 bRelCol
= bNewRelCol
;
789 inline void SetRelRow(bool bNewRelRow
)
791 bRelRow
= bNewRelRow
;
793 inline void SetRelTab(bool bNewRelTab
)
795 bRelTab
= bNewRelTab
;
798 inline void Set( const ScAddress
& rAdr
,
799 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
800 inline void Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
801 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
803 inline const ScAddress
& GetAddress() const
808 inline SCCOL
Col() const
812 inline SCROW
Row() const
816 inline SCTAB
Tab() const
821 inline bool operator == ( const ScRefAddress
& r
) const;
823 OUString
GetRefString( ScDocument
* pDocument
, SCTAB nActTab
,
824 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
827 inline ScRefAddress
& ScRefAddress::operator=( const ScRefAddress
& rRef
)
830 bRelCol
= rRef
.bRelCol
;
831 bRelRow
= rRef
.bRelRow
;
832 bRelTab
= rRef
.bRelTab
;
836 inline void ScRefAddress::Set( const ScAddress
& rAdr
,
837 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
840 bRelCol
= bNewRelCol
;
841 bRelRow
= bNewRelRow
;
842 bRelTab
= bNewRelTab
;
845 inline void ScRefAddress::Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
846 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
848 aAdr
.Set( nNewCol
, nNewRow
, nNewTab
);
849 bRelCol
= bNewRelCol
;
850 bRelRow
= bNewRelRow
;
851 bRelTab
= bNewRelTab
;
854 inline bool ScRefAddress::operator==( const ScRefAddress
& rRefAddress
) const
856 return aAdr
== rRefAddress
.aAdr
&&
857 bRelCol
== rRefAddress
.bRelCol
&&
858 bRelRow
== rRefAddress
.bRelRow
&&
859 bRelTab
== rRefAddress
.bRelTab
;
864 // Special values for cells always broadcasting or listening (ScRecalcMode::ALWAYS
866 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
867 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
869 template< typename T
> void PutInOrder( T
& nStart
, T
& nEnd
)
880 bool ConvertSingleRef( ScDocument
* pDocument
, const OUString
& rRefString
,
881 SCTAB nDefTab
, ScRefAddress
& rRefAddress
,
882 const ScAddress::Details
& rDetails
,
883 ScAddress::ExternalInfo
* pExtInfo
= nullptr );
885 bool ConvertDoubleRef( ScDocument
* pDocument
, const OUString
& rRefString
,
886 SCTAB nDefTab
, ScRefAddress
& rStartRefAddress
,
887 ScRefAddress
& rEndRefAddress
,
888 const ScAddress::Details
& rDetails
,
889 ScAddress::ExternalInfo
* pExtInfo
= nullptr );
891 /// append alpha representation of column to buffer
892 SC_DLLPUBLIC
void ScColToAlpha( OUStringBuffer
& rBuffer
, SCCOL nCol
);
894 inline void ScColToAlpha( OUString
& rStr
, SCCOL nCol
)
896 OUStringBuffer
aBuf(2);
897 ScColToAlpha( aBuf
, nCol
);
898 rStr
+= aBuf
.makeStringAndClear();
901 inline OUString
ScColToAlpha( SCCOL nCol
)
903 OUStringBuffer
aBuf(2);
904 ScColToAlpha( aBuf
, nCol
);
905 return aBuf
.makeStringAndClear();
908 /// get column number of A..IV... string
909 bool AlphaToCol( SCCOL
& rCol
, const OUString
& rStr
);
911 #endif // INCLUDED_SC_INC_ADDRESS_HXX
913 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */