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 <tools/stream.hxx>
24 #include <rtl/ustrbuf.hxx>
25 #include <rtl/strbuf.hxx>
26 #include <osl/endian.h>
31 #include <formula/grammar.hxx>
33 #include <com/sun/star/uno/Sequence.hxx>
35 namespace com
{ namespace sun
{ namespace star
{
37 struct ExternalLinkInfo
;
43 /** size_t typedef to be able to find places where code was changed from USHORT
44 to size_t and is used to read/write from/to streams. */
45 typedef size_t SCSIZE
;
47 // Maximum possible value of data type, NOT maximum row value.
48 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
49 // included, we should not be using those stupid macros anyway.
52 const SCROW SCROW_MAX
= ::std::numeric_limits
<SCROW
>::max();
53 const SCCOL SCCOL_MAX
= ::std::numeric_limits
<SCCOL
>::max();
54 const SCTAB SCTAB_MAX
= ::std::numeric_limits
<SCTAB
>::max();
55 const SCCOLROW SCCOLROW_MAX
= ::std::numeric_limits
<SCCOLROW
>::max();
56 const SCSIZE SCSIZE_MAX
= ::std::numeric_limits
<SCSIZE
>::max();
58 // The maximum values. Defines are needed for preprocessor checks, for example
59 // in bcaslot.cxx, otherwise type safe constants are preferred.
60 #define MAXROWCOUNT_DEFINE 1048576
61 #define MAXCOLCOUNT_DEFINE 1024
64 const SCROW MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
65 const SCCOL MAXCOLCOUNT
= MAXCOLCOUNT_DEFINE
;
66 /// limiting to 10000 for now, problem with 32 bit builds for now
67 const SCTAB MAXTABCOUNT
= 10000;
68 const SCCOLROW MAXCOLROWCOUNT
= MAXROWCOUNT
;
70 const SCROW MAXROW
= MAXROWCOUNT
- 1;
71 const SCCOL MAXCOL
= MAXCOLCOUNT
- 1;
72 const SCTAB MAXTAB
= MAXTABCOUNT
- 1;
73 const SCCOLROW MAXCOLROW
= MAXROW
;
74 // Limit the initial tab count to prevent users to set the count too high,
75 // which could cause the memory usage of blank documents to exceed the
76 // available system memory.
77 const SCTAB MAXINITTAB
= 1024;
78 const SCTAB MININITTAB
= 1;
81 const SCTAB SC_TAB_APPEND
= SCTAB_MAX
;
82 const SCTAB TABLEID_DOC
= SCTAB_MAX
; // entire document, e.g. protect
83 const SCROW SCROWS32K
= 32000;
84 const SCCOL SCCOL_REPEAT_NONE
= SCCOL_MAX
;
85 const SCROW SCROW_REPEAT_NONE
= SCROW_MAX
;
87 #define MAXROW_30 8191
89 SAL_WARN_UNUSED_RESULT
inline bool ValidCol( SCCOL nCol
)
91 return nCol
>= static_cast<SCCOL
>(0) && nCol
<= MAXCOL
;
94 SAL_WARN_UNUSED_RESULT
inline bool ValidRow( SCROW nRow
)
96 return nRow
>= static_cast<SCROW
>(0) && nRow
<= MAXROW
;
99 SAL_WARN_UNUSED_RESULT
inline bool ValidTab( SCTAB nTab
)
101 return nTab
>= static_cast<SCTAB
>(0) && nTab
<= MAXTAB
;
104 SAL_WARN_UNUSED_RESULT
inline bool ValidTab( SCTAB nTab
, SCTAB nMaxTab
)
106 return nTab
>= static_cast<SCTAB
>(0) && nTab
<= nMaxTab
;
109 SAL_WARN_UNUSED_RESULT
inline bool ValidColRow( SCCOL nCol
, SCROW nRow
)
111 return ValidCol( nCol
) && ValidRow( nRow
);
114 SAL_WARN_UNUSED_RESULT
inline bool ValidColRowTab( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
116 return ValidCol( nCol
) && ValidRow( nRow
) && ValidTab( nTab
);
119 SAL_WARN_UNUSED_RESULT
inline SCCOL
SanitizeCol( SCCOL nCol
)
121 return nCol
< 0 ? 0 : (nCol
> MAXCOL
? MAXCOL
: nCol
);
124 SAL_WARN_UNUSED_RESULT
inline SCROW
SanitizeRow( SCROW nRow
)
126 return nRow
< 0 ? 0 : (nRow
> MAXROW
? MAXROW
: nRow
);
129 SAL_WARN_UNUSED_RESULT
inline SCTAB
SanitizeTab( SCTAB nTab
)
131 return nTab
< 0 ? 0 : (nTab
> MAXTAB
? MAXTAB
: nTab
);
134 SAL_WARN_UNUSED_RESULT
inline SCTAB
SanitizeTab( SCTAB nTab
, SCTAB nMaxTab
)
136 return nTab
< 0 ? 0 : (nTab
> nMaxTab
? nMaxTab
: nTab
);
140 // The old cell address is combined in one UINT32:
144 // For speed reasons access isn't done by shifting bits but by using platform
145 // dependent casts, which unfortunately also leads to aliasing problems when
146 // not using gcc -fno-strict-aliasing
148 // The result of ConvertRef() is a bit group of the following:
150 #define SCA_COL_ABSOLUTE 0x01
151 #define SCA_ROW_ABSOLUTE 0x02
152 #define SCA_TAB_ABSOLUTE 0x04
153 #define SCA_TAB_3D 0x08
154 #define SCA_COL2_ABSOLUTE 0x10
155 #define SCA_ROW2_ABSOLUTE 0x20
156 #define SCA_TAB2_ABSOLUTE 0x40
157 #define SCA_TAB2_3D 0x80
158 #define SCA_VALID_ROW 0x0100
159 #define SCA_VALID_COL 0x0200
160 #define SCA_VALID_TAB 0x0400
161 // SCA_BITS is a convience for
162 // (SCA_VALID_TAB | SCA_VALID_COL | SCA_VALID_ROW | SCA_TAB_3D | SCA_TAB_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_COL_ABSOLUTE)
163 #define SCA_BITS 0x070F
164 // somewhat cheesy kludge to force the display of the document name even for
165 // local references. Requires TAB_3D to be valid
166 #define SCA_FORCE_DOC 0x0800
167 #define SCA_VALID_ROW2 0x1000
168 #define SCA_VALID_COL2 0x2000
169 #define SCA_VALID_TAB2 0x4000
170 #define SCA_VALID 0x8000
172 #define SCA_ABS SCA_VALID | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
174 #define SCR_ABS SCA_ABS | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
176 #define SCA_ABS_3D SCA_ABS | SCA_TAB_3D
177 #define SCR_ABS_3D SCR_ABS | SCA_TAB_3D
189 enum Uninitialized
{ UNINITIALIZED
};
190 enum InitializeInvalid
{ INITIALIZE_INVALID
};
194 formula::FormulaGrammar::AddressConvention eConv
;
198 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, SCROW nRowP
, SCCOL nColP
) :
199 eConv(eConvP
), nRow(nRowP
), nCol(nColP
)
201 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, ScAddress
const & rAddr
) :
202 eConv(eConvP
), nRow(rAddr
.Row()), nCol(rAddr
.Col())
204 inline Details( formula::FormulaGrammar::AddressConvention eConvP
) :
205 eConv(eConvP
), nRow(0), nCol(0)
207 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
208 Details( const ScDocument
* pDoc
, const ScAddress
& rAddr
);
210 SC_DLLPUBLIC
static const Details detailsOOOa1
;
218 inline ExternalInfo() :
219 mnFileId(0), mbExternal(false)
224 nRow(0), nCol(0), nTab(0)
226 inline ScAddress( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
) :
227 nRow(nRowP
), nCol(nColP
), nTab(nTabP
)
229 /** Yes, it is what it seems to be: Uninitialized. May be used for
230 performance reasons if it is initialized by other means. */
231 inline ScAddress( Uninitialized
)
233 inline ScAddress( InitializeInvalid
) :
234 nRow(-1), nCol(-1), nTab(-1)
236 inline ScAddress( const ScAddress
& rAddress
) :
237 nRow(rAddress
.nRow
), nCol(rAddress
.nCol
), nTab(rAddress
.nTab
)
239 inline ScAddress
& operator=( const ScAddress
& rAddress
);
241 inline void Set( SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
243 inline SCROW
Row() const
248 inline SCCOL
Col() const
252 inline SCTAB
Tab() const
256 inline void SetRow( SCROW nRowP
)
260 inline void SetCol( SCCOL nColP
)
264 inline void SetTab( SCTAB nTabP
)
268 inline void SetInvalid()
274 inline bool IsValid() const
276 return (nRow
>= 0) && (nCol
>= 0) && (nTab
>= 0);
279 inline void PutInOrder( ScAddress
& rAddress
);
281 inline void IncRow( SCsROW nDelta
= 1 )
283 nRow
= sal::static_int_cast
<SCROW
>(nRow
+ nDelta
);
285 inline void IncCol( SCsCOL nDelta
= 1 )
287 nCol
= sal::static_int_cast
<SCCOL
>(nCol
+ nDelta
);
289 inline void IncTab( SCsTAB nDelta
= 1 )
291 nTab
= sal::static_int_cast
<SCTAB
>(nTab
+ nDelta
);
293 inline void GetVars( SCCOL
& nColP
, SCROW
& nRowP
, SCTAB
& nTabP
) const
300 SC_DLLPUBLIC sal_uInt16
Parse(
301 const OUString
&, ScDocument
* = NULL
,
302 const Details
& rDetails
= detailsOOOa1
,
303 ExternalInfo
* pExtInfo
= NULL
,
304 const css::uno::Sequence
<css::sheet::ExternalLinkInfo
>* pExternalLinks
= NULL
);
306 SC_DLLPUBLIC
void Format( OStringBuffer
& r
, sal_uInt16 nFlags
= 0,
307 const ScDocument
* pDocument
= NULL
,
308 const Details
& rDetails
= detailsOOOa1
) const;
310 SC_DLLPUBLIC OUString
Format( sal_uInt16 nFlags
= 0,
311 const ScDocument
* pDocument
= NULL
,
312 const Details
& rDetails
= detailsOOOa1
) const;
314 // The document for the maximum defined sheet number
315 SC_DLLPUBLIC
bool Move( SCsCOL nDeltaX
, SCsROW nDeltaY
, SCsTAB nDeltaZ
,
316 ScDocument
* pDocument
= NULL
);
318 inline bool operator==( const ScAddress
& rAddress
) const;
319 inline bool operator!=( const ScAddress
& rAddress
) const;
320 inline bool operator<( const ScAddress
& rAddress
) const;
321 inline bool operator<=( const ScAddress
& rAddress
) const;
322 inline bool operator>( const ScAddress
& rAddress
) const;
323 inline bool operator>=( const ScAddress
& rAddress
) const;
325 inline size_t hash() const;
327 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
328 OUString
GetColRowString( bool bAbsolute
= false,
329 const Details
& rDetails
= detailsOOOa1
) const;
332 inline void ScAddress::PutInOrder( ScAddress
& rAddress
)
334 if ( rAddress
.Col() < Col() )
336 SCCOL nTmp
= rAddress
.Col();
337 rAddress
.SetCol( Col() );
340 if ( rAddress
.Row() < Row() )
342 SCROW nTmp
= rAddress
.Row();
343 rAddress
.SetRow( Row() );
346 if ( rAddress
.Tab() < Tab() )
348 SCTAB nTmp
= rAddress
.Tab();
349 rAddress
.SetTab( Tab() );
354 inline void ScAddress::Set( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
361 inline ScAddress
& ScAddress::operator=( const ScAddress
& rAddress
)
363 nCol
= rAddress
.nCol
;
364 nRow
= rAddress
.nRow
;
365 nTab
= rAddress
.nTab
;
369 inline bool ScAddress::operator==( const ScAddress
& rAddress
) const
371 return nRow
== rAddress
.nRow
&& nCol
== rAddress
.nCol
&& nTab
== rAddress
.nTab
;
374 inline bool ScAddress::operator!=( const ScAddress
& rAddress
) const
376 return !operator==( rAddress
);
379 /** Same behavior as the old sal_uInt32 nAddress < r.nAddress with encoded
380 tab|col|row bit fields. */
381 inline bool ScAddress::operator<( const ScAddress
& rAddress
) const
383 if (nTab
== rAddress
.nTab
)
385 if (nCol
== rAddress
.nCol
)
386 return nRow
< rAddress
.nRow
;
388 return nCol
< rAddress
.nCol
;
391 return nTab
< rAddress
.nTab
;
394 inline bool ScAddress::operator<=( const ScAddress
& rAddress
) const
396 return operator<( rAddress
) || operator==( rAddress
);
399 inline bool ScAddress::operator>( const ScAddress
& rAddress
) const
401 return !operator<=( rAddress
);
404 inline bool ScAddress::operator>=( const ScAddress
& rAddress
) const
406 return !operator<( rAddress
);
409 inline size_t ScAddress::hash() const
411 // Assume that there are not that many addresses with row > 2^16 AND column
412 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
414 return (static_cast<size_t>(nTab
) << 24) ^
415 (static_cast<size_t>(nCol
) << 16) ^ static_cast<size_t>(nRow
);
417 return (static_cast<size_t>(nTab
) << 28) ^
418 (static_cast<size_t>(nCol
) << 24) ^ static_cast<size_t>(nRow
);
421 struct ScAddressHashFunctor
423 size_t operator()( const ScAddress
& rAddress
) const
425 return rAddress
.hash();
429 struct ScAddressEqualFunctor
431 bool operator()( const ScAddress
& rAdr1
, const ScAddress
& rAdr2
) const
433 return rAdr1
== rAdr2
;
437 inline bool ValidAddress( const ScAddress
& rAddress
)
439 return ValidCol(rAddress
.Col()) && ValidRow(rAddress
.Row()) && ValidTab(rAddress
.Tab());
453 inline ScRange( ScAddress::Uninitialized eUninitialized
) :
454 aStart( eUninitialized
), aEnd( eUninitialized
)
456 inline ScRange( ScAddress::InitializeInvalid eInvalid
) :
457 aStart( eInvalid
), aEnd( eInvalid
)
459 inline ScRange( const ScAddress
& aInputStart
, const ScAddress
& aInputEnd
) :
460 aStart( aInputStart
), aEnd( aInputEnd
)
462 aStart
.PutInOrder( aEnd
);
464 inline ScRange( const ScRange
& rRange
) :
465 aStart( rRange
.aStart
), aEnd( rRange
.aEnd
)
467 inline ScRange( const ScAddress
& rRange
) :
468 aStart( rRange
), aEnd( rRange
)
470 inline ScRange( SCCOL nCol
, SCROW nRow
, SCTAB nTab
) :
471 aStart( nCol
, nRow
, nTab
), aEnd( aStart
)
473 inline ScRange( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
, SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
) :
474 aStart( nCol1
, nRow1
, nTab1
), aEnd( nCol2
, nRow2
, nTab2
)
477 inline ScRange
& operator=( const ScRange
& rRange
)
479 aStart
= rRange
.aStart
;
483 inline ScRange
& operator=( const ScAddress
& rPos
)
485 aStart
= aEnd
= rPos
;
488 inline void SetInvalid()
493 inline bool IsValid() const
495 return aStart
.IsValid() && aEnd
.IsValid();
497 inline bool In( const ScAddress
& ) const; ///< is Address& in Range?
498 inline bool In( const ScRange
& ) const; ///< is Range& in Range?
500 SC_DLLPUBLIC sal_uInt16
Parse( const OUString
&, ScDocument
* = NULL
,
501 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
502 ScAddress::ExternalInfo
* pExtInfo
= NULL
,
503 const css::uno::Sequence
<css::sheet::ExternalLinkInfo
>* pExternalLinks
= NULL
);
505 SC_DLLPUBLIC sal_uInt16
ParseAny( const OUString
&, ScDocument
* = NULL
,
506 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
507 SC_DLLPUBLIC sal_uInt16
ParseCols( const OUString
&, ScDocument
* = NULL
,
508 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
509 SC_DLLPUBLIC sal_uInt16
ParseRows( const OUString
&, ScDocument
* = NULL
,
510 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
512 /** Parse an Excel style reference up to and including the sheet name
513 separator '!', including detection of external documents and sheet
514 names, and in case of MOOXML import the bracketed index is used to
515 determine the actual document name passed in pExternalLinks. For
516 internal references (resulting rExternDocName empty), aStart.nTab and
517 aEnd.nTab are set, or -1 if sheet name not found.
518 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
519 encountered results in an error (NULL returned).
520 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
521 NULL for non-filter usage, in which case indices such as [1] are
524 Pointer to the position after '!' if successfully parsed, and
525 rExternDocName, rStartTabName and/or rEndTabName filled if
526 applicable. SCA_... flags set in nFlags.
527 Or if no valid document and/or sheet header could be parsed the start
528 position passed with pString.
529 Or NULL if a 3D sheet header could be parsed but
530 bOnlyAcceptSingle==true was given.
532 const sal_Unicode
* Parse_XL_Header( const sal_Unicode
* pString
, const ScDocument
* pDocument
,
533 OUString
& rExternDocName
, OUString
& rStartTabName
,
534 OUString
& rEndTabName
, sal_uInt16
& nFlags
,
535 bool bOnlyAcceptSingle
,
536 const css::uno::Sequence
<css::sheet::ExternalLinkInfo
>* pExternalLinks
= NULL
);
538 SC_DLLPUBLIC OUString
Format(sal_uInt16 nFlags
= 0, const ScDocument
* pDocument
= NULL
,
539 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
541 inline void GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
542 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const;
543 // The document for the maximum defined sheet number
544 SC_DLLPUBLIC
bool Move( SCsCOL aDeltaX
, SCsROW aDeltaY
, SCsTAB aDeltaZ
, ScDocument
* pDocument
= NULL
);
545 SC_DLLPUBLIC
void Justify();
546 SC_DLLPUBLIC
void ExtendTo( const ScRange
& rRange
);
547 SC_DLLPUBLIC
bool Intersects( const ScRange
& rRange
) const; // do two ranges intersect?
549 ScRange
Intersection( const ScRange
& rOther
) const;
552 inline bool operator==( const ScRange
& rRange
) const;
553 inline bool operator!=( const ScRange
& rRange
) const;
554 inline bool operator<( const ScRange
& rRange
) const;
555 inline bool operator<=( const ScRange
& rRange
) const;
556 inline bool operator>( const ScRange
& rRange
) const;
557 inline bool operator>=( const ScRange
& rRange
) const;
559 /// Hash 2D area ignoring table number.
560 inline size_t hashArea() const;
561 /// Hash start column and start and end rows.
562 inline size_t hashStartColumn() const;
565 inline void ScRange::GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
566 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const
568 aStart
.GetVars( nCol1
, nRow1
, nTab1
);
569 aEnd
.GetVars( nCol2
, nRow2
, nTab2
);
572 inline bool ScRange::operator==( const ScRange
& rRange
) const
574 return ( (aStart
== rRange
.aStart
) && (aEnd
== rRange
.aEnd
) );
577 inline bool ScRange::operator!=( const ScRange
& rRange
) const
579 return !operator==( rRange
);
582 /// Sort on upper left corner, if equal then use lower right too.
583 inline bool ScRange::operator<( const ScRange
& r
) const
585 return aStart
< r
.aStart
|| (aStart
== r
.aStart
&& aEnd
< r
.aEnd
) ;
588 inline bool ScRange::operator<=( const ScRange
& rRange
) const
590 return operator<( rRange
) || operator==( rRange
);
593 inline bool ScRange::operator>( const ScRange
& rRange
) const
595 return !operator<=( rRange
);
598 inline bool ScRange::operator>=( const ScRange
& rRange
) const
600 return !operator<( rRange
);
603 inline bool ScRange::In( const ScAddress
& rAddress
) const
606 aStart
.Col() <= rAddress
.Col() && rAddress
.Col() <= aEnd
.Col() &&
607 aStart
.Row() <= rAddress
.Row() && rAddress
.Row() <= aEnd
.Row() &&
608 aStart
.Tab() <= rAddress
.Tab() && rAddress
.Tab() <= aEnd
.Tab();
611 inline bool ScRange::In( const ScRange
& rRange
) const
614 aStart
.Col() <= rRange
.aStart
.Col() && rRange
.aEnd
.Col() <= aEnd
.Col() &&
615 aStart
.Row() <= rRange
.aStart
.Row() && rRange
.aEnd
.Row() <= aEnd
.Row() &&
616 aStart
.Tab() <= rRange
.aStart
.Tab() && rRange
.aEnd
.Tab() <= aEnd
.Tab();
619 inline size_t ScRange::hashArea() const
621 // Assume that there are not that many ranges with identical corners so we
622 // won't have too many collisions. Also assume that more lower row and
623 // column numbers are used so that there are not too many conflicts with
624 // the columns hashed into the values, and that start row and column
625 // usually don't exceed certain values. High bits are not masked off and
626 // may overlap with lower bits of other values, e.g. if start column is
627 // greater than assumed.
629 (static_cast<size_t>(aStart
.Row()) << 26) ^ // start row <= 2^6
630 (static_cast<size_t>(aStart
.Col()) << 21) ^ // start column <= 2^5
631 (static_cast<size_t>(aEnd
.Col()) << 15) ^ // end column <= 2^6
632 static_cast<size_t>(aEnd
.Row()); // end row <= 2^15
635 inline size_t ScRange::hashStartColumn() const
637 // Assume that for the start row more lower row numbers are used so that
638 // there are not too many conflicts with the column hashed into the higher
641 (static_cast<size_t>(aStart
.Col()) << 24) ^ // start column <= 2^8
642 (static_cast<size_t>(aStart
.Row()) << 16) ^ // start row <= 2^8
643 static_cast<size_t>(aEnd
.Row());
646 struct ScRangeHashAreaFunctor
648 size_t operator()( const ScRange
& rRange
) const
650 return rRange
.hashArea();
654 struct ScRangeEqualFunctor
656 bool operator()( const ScRange
& rRange1
, const ScRange
& rRange2
) const
658 return rRange1
== rRange2
;
662 inline bool ValidRange( const ScRange
& rRange
)
664 return ValidAddress(rRange
.aStart
) && ValidAddress(rRange
.aEnd
);
676 ScRangePair( const ScRangePair
& r
)
678 aRange
[0] = r
.aRange
[0];
679 aRange
[1] = r
.aRange
[1];
681 ScRangePair( const ScRange
& rRange1
, const ScRange
& rRange2
)
687 inline ScRangePair
& operator= ( const ScRangePair
& rRange
);
688 const ScRange
& GetRange( sal_uInt16 n
) const
692 ScRange
& GetRange( sal_uInt16 n
)
696 inline bool operator==( const ScRangePair
& ) const;
697 inline bool operator!=( const ScRangePair
& ) const;
700 inline ScRangePair
& ScRangePair::operator= ( const ScRangePair
& rRange
)
702 aRange
[0] = rRange
.aRange
[0];
703 aRange
[1] = rRange
.aRange
[1];
707 inline bool ScRangePair::operator==( const ScRangePair
& rRange
) const
709 return (aRange
[0] == rRange
.aRange
[0]) &&
710 (aRange
[1] == rRange
.aRange
[1]);
713 inline bool ScRangePair::operator!=( const ScRangePair
& rRange
) const
715 return !operator==( rRange
);
727 inline ScRefAddress() :
728 bRelCol(false), bRelRow(false), bRelTab(false)
730 inline ScRefAddress( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
731 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
732 aAdr(nCol
, nRow
, nTab
),
733 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
735 inline ScRefAddress( const ScAddress
& rAdr
,
736 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
738 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
740 inline ScRefAddress( const ScRefAddress
& rRef
) :
741 aAdr(rRef
.aAdr
), bRelCol(rRef
.bRelCol
), bRelRow(rRef
.bRelRow
),
742 bRelTab(rRef
.bRelTab
)
745 inline ScRefAddress
& operator=( const ScRefAddress
& );
747 inline bool IsRelCol() const
751 inline bool IsRelRow() const
755 inline bool IsRelTab() const
760 inline void SetRelCol(bool bNewRelCol
)
762 bRelCol
= bNewRelCol
;
764 inline void SetRelRow(bool bNewRelRow
)
766 bRelRow
= bNewRelRow
;
768 inline void SetRelTab(bool bNewRelTab
)
770 bRelTab
= bNewRelTab
;
773 inline void Set( const ScAddress
& rAdr
,
774 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
775 inline void Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
776 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
778 inline const ScAddress
& GetAddress() const
783 inline SCCOL
Col() const
787 inline SCROW
Row() const
791 inline SCTAB
Tab() const
796 inline bool operator == ( const ScRefAddress
& r
) const;
797 inline bool operator != ( const ScRefAddress
& r
) const
799 return !(operator==(r
));
802 OUString
GetRefString( ScDocument
* pDocument
, SCTAB nActTab
,
803 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
806 inline ScRefAddress
& ScRefAddress::operator=( const ScRefAddress
& rRef
)
809 bRelCol
= rRef
.bRelCol
;
810 bRelRow
= rRef
.bRelRow
;
811 bRelTab
= rRef
.bRelTab
;
815 inline void ScRefAddress::Set( const ScAddress
& rAdr
,
816 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
819 bRelCol
= bNewRelCol
;
820 bRelRow
= bNewRelRow
;
821 bRelTab
= bNewRelTab
;
824 inline void ScRefAddress::Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
825 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
827 aAdr
.Set( nNewCol
, nNewRow
, nNewTab
);
828 bRelCol
= bNewRelCol
;
829 bRelRow
= bNewRelRow
;
830 bRelTab
= bNewRelTab
;
833 inline bool ScRefAddress::operator==( const ScRefAddress
& rRefAddress
) const
835 return aAdr
== rRefAddress
.aAdr
&&
836 bRelCol
== rRefAddress
.bRelCol
&&
837 bRelRow
== rRefAddress
.bRelRow
&&
838 bRelTab
== rRefAddress
.bRelTab
;
843 // Special values for cells always broadcasting or listening (ScRecalcMode::ALWAYS
845 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
846 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
848 template< typename T
> void PutInOrder( T
& nStart
, T
& nEnd
)
859 bool ConvertSingleRef( ScDocument
* pDocument
, const OUString
& rRefString
,
860 SCTAB nDefTab
, ScRefAddress
& rRefAddress
,
861 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
862 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
864 bool ConvertDoubleRef( ScDocument
* pDocument
, const OUString
& rRefString
,
865 SCTAB nDefTab
, ScRefAddress
& rStartRefAddress
,
866 ScRefAddress
& rEndRefAddress
,
867 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
868 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
870 /// append alpha representation of column to buffer
871 SC_DLLPUBLIC
void ScColToAlpha( OUStringBuffer
& rBuffer
, SCCOL nCol
);
873 inline void ScColToAlpha( OUString
& rStr
, SCCOL nCol
)
875 OUStringBuffer
aBuf(2);
876 ScColToAlpha( aBuf
, nCol
);
877 rStr
+= aBuf
.makeStringAndClear();
880 inline OUString
ScColToAlpha( SCCOL nCol
)
882 OUStringBuffer
aBuf(2);
883 ScColToAlpha( aBuf
, nCol
);
884 return aBuf
.makeStringAndClear();
887 /// get column number of A..IV... string
888 bool AlphaToCol( SCCOL
& rCol
, const OUString
& rStr
);
890 #endif // INCLUDED_SC_INC_ADDRESS_HXX
892 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */