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 SC_ADDRESS_HXX
21 #define SC_ADDRESS_HXX
23 #include <tools/stream.hxx>
24 #include <tools/solar.h>
25 #include <rtl/ustrbuf.hxx>
26 #include <osl/endian.h>
30 #include <formula/grammar.hxx>
32 #include <com/sun/star/uno/Sequence.hxx>
34 namespace com
{ namespace sun
{ namespace star
{
36 struct ExternalLinkInfo
;
43 typedef sal_Int32 SCROW
;
44 typedef sal_Int16 SCCOL
;
45 typedef sal_Int16 SCTAB
;
46 typedef sal_Int32 SCCOLROW
; ///< a type capable of holding either SCCOL or SCROW
48 // temporarily signed typedefs
49 typedef sal_Int32 SCsROW
;
50 typedef sal_Int16 SCsCOL
;
51 typedef sal_Int16 SCsTAB
;
52 typedef sal_Int32 SCsCOLROW
;
54 /** size_t typedef to be able to find places where code was changed from USHORT
55 to size_t and is used to read/write from/to streams. */
56 typedef size_t SCSIZE
;
58 // Maximum possible value of data type, NOT maximum row value.
59 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
60 // included, we should not be using those stupid macros anyway.
63 const SCROW SCROW_MAX
= ::std::numeric_limits
<SCROW
>::max();
64 const SCCOL SCCOL_MAX
= ::std::numeric_limits
<SCCOL
>::max();
65 const SCTAB SCTAB_MAX
= ::std::numeric_limits
<SCTAB
>::max();
66 const SCCOLROW SCCOLROW_MAX
= ::std::numeric_limits
<SCCOLROW
>::max();
67 const SCSIZE SCSIZE_MAX
= ::std::numeric_limits
<SCSIZE
>::max();
69 // The maximum values. Defines are needed for preprocessor checks, for example
70 // in bcaslot.cxx, otherwise type safe constants are preferred.
71 #define MAXROWCOUNT_DEFINE 1048576
72 #define MAXCOLCOUNT_DEFINE 1024
75 const SCROW MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
76 const SCCOL MAXCOLCOUNT
= MAXCOLCOUNT_DEFINE
;
77 /// limiting to 10000 for now, problem with 32 bit builds for now
78 const SCTAB MAXTABCOUNT
= 10000;
79 const SCCOLROW MAXCOLROWCOUNT
= MAXROWCOUNT
;
81 const SCROW MAXROW
= MAXROWCOUNT
- 1;
82 const SCCOL MAXCOL
= MAXCOLCOUNT
- 1;
83 const SCTAB MAXTAB
= MAXTABCOUNT
- 1;
84 const SCCOLROW MAXCOLROW
= MAXROW
;
85 // Limit the initial tab count to prevent users to set the count too high,
86 // which could cause the memory usage of blank documents to exceed the
87 // available system memory.
88 const SCTAB MAXINITTAB
= 1024;
89 const SCTAB MININITTAB
= 1;
92 const SCTAB SC_TAB_APPEND
= SCTAB_MAX
;
93 const SCTAB TABLEID_DOC
= SCTAB_MAX
; // entire document, e.g. protect
94 const SCROW SCROWS32K
= 32000;
95 const SCCOL SCCOL_REPEAT_NONE
= SCCOL_MAX
;
96 const SCROW SCROW_REPEAT_NONE
= SCROW_MAX
;
98 // For future reference, place in code where more than 64k rows would need a
100 // #if SC_ROWLIMIT_MORE_THAN_64K
101 // #error row limit 64k
103 #if MAXROWCOUNT_DEFINE > 65536
104 #define SC_ROWLIMIT_MORE_THAN_64K 1
106 #define SC_ROWLIMIT_MORE_THAN_64K 0
108 const SCROW SCROWS64K
= 65536;
111 #define MAXROW_30 8191
114 #undef MAXROWCOUNT_DEFINE
115 #define MAXROWCOUNT_DEFINE 8192
116 const SCROW W16MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
117 const SCROW W16MAXROW
= W16MAXROWCOUNT
- 1;
118 #define MAXROWCOUNT W16MAXROWCOUNT
119 #define MAXROW W16MAXROW
122 // old stuff defines end
123 inline bool ValidCol( SCCOL nCol
)
125 return static_cast<SCCOL
>(0) <= nCol
&& nCol
<= MAXCOL
;
128 inline bool ValidRow( SCROW nRow
)
130 return static_cast<SCROW
>(0) <= nRow
&& nRow
<= MAXROW
;
133 inline bool ValidTab( SCTAB nTab
)
135 return static_cast<SCTAB
>(0) <= nTab
&& nTab
<= MAXTAB
;
138 inline bool ValidTab( SCTAB nTab
, SCTAB nMaxTab
)
140 return static_cast<SCTAB
>(0) <= nTab
&& nTab
<= nMaxTab
;
143 inline bool ValidColRow( SCCOL nCol
, SCROW nRow
)
145 return ValidCol( nCol
) && ValidRow( nRow
);
148 inline bool ValidColRowTab( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
150 return ValidCol( nCol
) && ValidRow( nRow
) && ValidTab( nTab
);
153 inline SCCOL
SanitizeCol( SCCOL nCol
)
155 return nCol
< 0 ? 0 : (nCol
> MAXCOL
? MAXCOL
: nCol
);
158 inline SCROW
SanitizeRow( SCROW nRow
)
160 return nRow
< 0 ? 0 : (nRow
> MAXROW
? MAXROW
: nRow
);
163 inline SCTAB
SanitizeTab( SCTAB nTab
)
165 return nTab
< 0 ? 0 : (nTab
> MAXTAB
? MAXTAB
: nTab
);
168 inline SCTAB
SanitizeTab( SCTAB nTab
, SCTAB nMaxTab
)
170 return nTab
< 0 ? 0 : (nTab
> nMaxTab
? nMaxTab
: nTab
);
174 // The old cell address is combined in one UINT32:
178 // For speed reasons access isn't done by shifting bits but by using platform
179 // dependent casts, which unfortunately also leads to aliasing problems when
180 // not using gcc -fno-strict-aliasing
182 // The result of ConvertRef() is a bit group of the following:
184 #define SCA_COL_ABSOLUTE 0x01
185 #define SCA_ROW_ABSOLUTE 0x02
186 #define SCA_TAB_ABSOLUTE 0x04
187 #define SCA_TAB_3D 0x08
188 #define SCA_COL2_ABSOLUTE 0x10
189 #define SCA_ROW2_ABSOLUTE 0x20
190 #define SCA_TAB2_ABSOLUTE 0x40
191 #define SCA_TAB2_3D 0x80
192 #define SCA_VALID_ROW 0x0100
193 #define SCA_VALID_COL 0x0200
194 #define SCA_VALID_TAB 0x0400
195 // SCA_BITS is a convience for
196 // (SCA_VALID_TAB | SCA_VALID_COL | SCA_VALID_ROW | SCA_TAB_3D | SCA_TAB_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_COL_ABSOLUTE)
197 #define SCA_BITS 0x070F
198 // somewhat cheesy kludge to force the display of the document name even for
199 // local references. Requires TAB_3D to be valid
200 #define SCA_FORCE_DOC 0x0800
201 #define SCA_VALID_ROW2 0x1000
202 #define SCA_VALID_COL2 0x2000
203 #define SCA_VALID_TAB2 0x4000
204 #define SCA_VALID 0x8000
206 #define SCA_ABS SCA_VALID \
207 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
209 #define SCR_ABS SCA_ABS \
210 | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
212 #define SCA_ABS_3D SCA_ABS | SCA_TAB_3D
213 #define SCR_ABS_3D SCR_ABS | SCA_TAB_3D
225 enum Uninitialized
{ UNINITIALIZED
};
226 enum InitializeInvalid
{ INITIALIZE_INVALID
};
229 formula::FormulaGrammar::AddressConvention eConv
;
232 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, SCROW nRowP
, SCCOL nColP
)
233 : eConv( eConvP
), nRow( nRowP
), nCol( nColP
)
235 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, ScAddress
const & rAddr
)
236 : eConv( eConvP
), nRow( rAddr
.Row() ), nCol( rAddr
.Col() )
238 inline Details( formula::FormulaGrammar::AddressConvention eConvP
)
239 : eConv( eConvP
), nRow( 0 ), nCol( 0 )
241 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
242 Details( const ScDocument
* pDoc
, const ScAddress
& rAddr
);
244 SC_DLLPUBLIC
static const Details detailsOOOa1
;
252 inline ExternalInfo() : mnFileId(0), mbExternal(false) {}
255 inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
256 inline ScAddress( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
257 : nRow(nRowP
), nCol(nColP
), nTab(nTabP
)
259 /** Yes, it is what it seems to be: Uninitialized. May be used for
260 performance reasons if it is initialized by other means. */
261 inline ScAddress( Uninitialized
) {}
262 inline ScAddress( InitializeInvalid
)
263 : nRow(-1), nCol(-1), nTab(-1) {}
264 inline ScAddress( const ScAddress
& r
)
265 : nRow(r
.nRow
), nCol(r
.nCol
), nTab(r
.nTab
)
267 inline ScAddress
& operator=( const ScAddress
& r
);
269 inline void Set( SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
270 inline SCROW
Row() const { return nRow
; }
271 inline SCCOL
Col() const { return nCol
; }
272 inline SCTAB
Tab() const { return nTab
; }
273 inline void SetRow( SCROW nRowP
) { nRow
= nRowP
; }
274 inline void SetCol( SCCOL nColP
) { nCol
= nColP
; }
275 inline void SetTab( SCTAB nTabP
) { nTab
= nTabP
; }
276 inline void SetInvalid() { nRow
= -1; nCol
= -1; nTab
= -1; }
277 inline bool IsValid() const { return (nRow
>= 0) && (nCol
>= 0) && (nTab
>= 0); }
278 inline void PutInOrder( ScAddress
& r
);
279 inline void IncRow( SCsROW n
=1 ) { nRow
= sal::static_int_cast
<SCROW
>(nRow
+ n
); }
280 inline void IncCol( SCsCOL n
=1 ) { nCol
= sal::static_int_cast
<SCCOL
>(nCol
+ n
); }
281 inline void IncTab( SCsTAB n
=1 ) { nTab
= sal::static_int_cast
<SCTAB
>(nTab
+ n
); }
282 inline void GetVars( SCCOL
& nColP
, SCROW
& nRowP
, SCTAB
& nTabP
) const
283 { nColP
= nCol
; nRowP
= nRow
; nTabP
= nTab
; }
285 SC_DLLPUBLIC sal_uInt16
Parse( const OUString
&, ScDocument
* = NULL
,
286 const Details
& rDetails
= detailsOOOa1
,
287 ExternalInfo
* pExtInfo
= NULL
,
288 const ::com::sun::star::uno::Sequence
<
289 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
291 SC_DLLPUBLIC OUString
Format( sal_uInt16
= 0, const ScDocument
* = NULL
,
292 const Details
& rDetails
= detailsOOOa1
) const;
294 // The document for the maximum defined sheet number
295 SC_DLLPUBLIC
bool Move( SCsCOL dx
, SCsROW dy
, SCsTAB dz
, ScDocument
* =NULL
);
296 inline bool operator==( const ScAddress
& r
) const;
297 inline bool operator!=( const ScAddress
& r
) const;
298 inline bool operator<( const ScAddress
& r
) const;
299 inline bool operator<=( const ScAddress
& r
) const;
300 inline bool operator>( const ScAddress
& r
) const;
301 inline bool operator>=( const ScAddress
& r
) const;
303 inline size_t hash() const;
305 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
306 OUString
GetColRowString( bool bAbsolute
= false,
307 const Details
& rDetails
= detailsOOOa1
) const;
310 inline void ScAddress::PutInOrder( ScAddress
& r
)
312 if ( r
.Col() < Col() )
314 SCCOL nTmp
= r
.Col();
318 if ( r
.Row() < Row() )
320 SCROW nTmp
= r
.Row();
324 if ( r
.Tab() < Tab() )
326 SCTAB nTmp
= r
.Tab();
332 inline void ScAddress::Set( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
339 inline ScAddress
& ScAddress::operator=( const ScAddress
& r
)
347 inline bool ScAddress::operator==( const ScAddress
& r
) const
349 return nRow
== r
.nRow
&& nCol
== r
.nCol
&& nTab
== r
.nTab
;
352 inline bool ScAddress::operator!=( const ScAddress
& r
) const
354 return !operator==( r
);
357 /** Same behavior as the old sal_uInt32 nAddress < r.nAddress with encoded
358 tab|col|row bit fields. */
359 inline bool ScAddress::operator<( const ScAddress
& r
) const
364 return nRow
< r
.nRow
;
366 return nCol
< r
.nCol
;
369 return nTab
< r
.nTab
;
372 inline bool ScAddress::operator<=( const ScAddress
& r
) const
374 return operator<( r
) || operator==( r
);
377 inline bool ScAddress::operator>( const ScAddress
& r
) const
379 return !operator<=( r
);
382 inline bool ScAddress::operator>=( const ScAddress
& r
) const
384 return !operator<( r
);
387 inline size_t ScAddress::hash() const
389 // Assume that there are not that many addresses with row > 2^16 AND column
390 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
392 return (static_cast<size_t>(nTab
) << 24) ^
393 (static_cast<size_t>(nCol
) << 16) ^ static_cast<size_t>(nRow
);
395 return (static_cast<size_t>(nTab
) << 28) ^
396 (static_cast<size_t>(nCol
) << 24) ^ static_cast<size_t>(nRow
);
399 struct ScAddressHashFunctor
401 size_t operator()( const ScAddress
& rAdr
) const
407 struct ScAddressEqualFunctor
409 bool operator()( const ScAddress
& rAdr1
, const ScAddress
& rAdr2
) const
411 return rAdr1
== rAdr2
;
415 inline bool ValidAddress( const ScAddress
& rAddr
)
417 return ValidCol(rAddr
.Col()) && ValidRow(rAddr
.Row()) && ValidTab(rAddr
.Tab());
424 ScAddress aStart
, aEnd
;
425 inline ScRange() : aStart(), aEnd() {}
426 inline ScRange( ScAddress::Uninitialized e
)
427 : aStart( e
), aEnd( e
) {}
428 inline ScRange( ScAddress::InitializeInvalid e
)
429 : aStart( e
), aEnd( e
) {}
430 inline ScRange( const ScAddress
& s
, const ScAddress
& e
)
431 : aStart( s
), aEnd( e
) { aStart
.PutInOrder( aEnd
); }
432 inline ScRange( const ScRange
& r
) : aStart( r
.aStart
), aEnd( r
.aEnd
) {}
433 inline ScRange( const ScAddress
& r
) : aStart( r
), aEnd( r
) {}
434 inline ScRange( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
435 : aStart( nCol
, nRow
, nTab
), aEnd( aStart
) {}
436 inline ScRange( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
437 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
)
438 : aStart( nCol1
, nRow1
, nTab1
), aEnd( nCol2
, nRow2
, nTab2
) {}
440 inline ScRange
& operator=( const ScRange
& r
)
441 { aStart
= r
.aStart
; aEnd
= r
.aEnd
; return *this; }
442 inline ScRange
& operator=( const ScAddress
& rPos
)
443 { aStart
= aEnd
= rPos
; return *this; }
444 inline void SetInvalid() { aStart
.SetInvalid(); aEnd
.SetInvalid(); }
445 inline bool IsValid() const { return aStart
.IsValid() && aEnd
.IsValid(); }
446 inline bool In( const ScAddress
& ) const; ///< is Address& in Range?
447 inline bool In( const ScRange
& ) const; ///< is Range& in Range?
449 SC_DLLPUBLIC sal_uInt16
Parse( const OUString
&, ScDocument
* = NULL
,
450 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
451 ScAddress::ExternalInfo
* pExtInfo
= NULL
,
452 const ::com::sun::star::uno::Sequence
<
453 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
455 SC_DLLPUBLIC sal_uInt16
ParseAny( const OUString
&, ScDocument
* = NULL
,
456 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
457 SC_DLLPUBLIC sal_uInt16
ParseCols( const OUString
&, ScDocument
* = NULL
,
458 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
459 SC_DLLPUBLIC sal_uInt16
ParseRows( const OUString
&, ScDocument
* = NULL
,
460 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
462 /** Parse an Excel style reference up to and including the sheet name
463 separator '!', including detection of external documents and sheet
464 names, and in case of MOOXML import the bracketed index is used to
465 determine the actual document name passed in pExternalLinks. For
466 internal references (resulting rExternDocName empty), aStart.nTab and
467 aEnd.nTab are set, or -1 if sheet name not found.
468 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
469 encountered results in an error (NULL returned).
470 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
471 NULL for non-filter usage, in which case indices such as [1] are
474 Pointer to the position after '!' if successfully parsed, and
475 rExternDocName, rStartTabName and/or rEndTabName filled if
476 applicable. SCA_... flags set in nFlags.
477 Or if no valid document and/or sheet header could be parsed the start
478 position passed with pString.
479 Or NULL if a 3D sheet header could be parsed but
480 bOnlyAcceptSingle==true was given.
482 const sal_Unicode
* Parse_XL_Header( const sal_Unicode
* pString
, const ScDocument
* pDoc
,
483 OUString
& rExternDocName
, OUString
& rStartTabName
, OUString
& rEndTabName
, sal_uInt16
& nFlags
,
484 bool bOnlyAcceptSingle
,
485 const ::com::sun::star::uno::Sequence
<
486 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
488 SC_DLLPUBLIC OUString
Format(sal_uInt16
= 0, const ScDocument
* = NULL
,
489 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
491 inline void GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
492 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const;
493 // The document for the maximum defined sheet number
494 SC_DLLPUBLIC
bool Move( SCsCOL dx
, SCsROW dy
, SCsTAB dz
, ScDocument
* =NULL
);
495 SC_DLLPUBLIC
void Justify();
496 SC_DLLPUBLIC
void ExtendTo( const ScRange
& rRange
);
497 SC_DLLPUBLIC
bool Intersects( const ScRange
& ) const; // do two ranges intersect?
499 inline bool operator==( const ScRange
& r
) const;
500 inline bool operator!=( const ScRange
& r
) const;
501 inline bool operator<( const ScRange
& r
) const;
502 inline bool operator<=( const ScRange
& r
) const;
503 inline bool operator>( const ScRange
& r
) const;
504 inline bool operator>=( const ScRange
& r
) const;
506 /// Hash 2D area ignoring table number.
507 inline size_t hashArea() const;
508 /// Hash start column and start and end rows.
509 inline size_t hashStartColumn() const;
512 inline void ScRange::GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
513 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const
515 aStart
.GetVars( nCol1
, nRow1
, nTab1
);
516 aEnd
.GetVars( nCol2
, nRow2
, nTab2
);
519 inline bool ScRange::operator==( const ScRange
& r
) const
521 return ( (aStart
== r
.aStart
) && (aEnd
== r
.aEnd
) );
524 inline bool ScRange::operator!=( const ScRange
& r
) const
526 return !operator==( r
);
529 /// Sort on upper left corner, if equal then use lower right too.
530 inline bool ScRange::operator<( const ScRange
& r
) const
532 return aStart
< r
.aStart
|| (aStart
== r
.aStart
&& aEnd
< r
.aEnd
) ;
535 inline bool ScRange::operator<=( const ScRange
& r
) const
537 return operator<( r
) || operator==( r
);
540 inline bool ScRange::operator>( const ScRange
& r
) const
542 return !operator<=( r
);
545 inline bool ScRange::operator>=( const ScRange
& r
) const
547 return !operator<( r
);
550 inline bool ScRange::In( const ScAddress
& rAddr
) const
553 aStart
.Col() <= rAddr
.Col() && rAddr
.Col() <= aEnd
.Col() &&
554 aStart
.Row() <= rAddr
.Row() && rAddr
.Row() <= aEnd
.Row() &&
555 aStart
.Tab() <= rAddr
.Tab() && rAddr
.Tab() <= aEnd
.Tab();
558 inline bool ScRange::In( const ScRange
& r
) const
561 aStart
.Col() <= r
.aStart
.Col() && r
.aEnd
.Col() <= aEnd
.Col() &&
562 aStart
.Row() <= r
.aStart
.Row() && r
.aEnd
.Row() <= aEnd
.Row() &&
563 aStart
.Tab() <= r
.aStart
.Tab() && r
.aEnd
.Tab() <= aEnd
.Tab();
566 inline size_t ScRange::hashArea() const
568 // Assume that there are not that many ranges with identical corners so we
569 // won't have too many collisions. Also assume that more lower row and
570 // column numbers are used so that there are not too many conflicts with
571 // the columns hashed into the values, and that start row and column
572 // usually don't exceed certain values. High bits are not masked off and
573 // may overlap with lower bits of other values, e.g. if start column is
574 // greater than assumed.
576 (static_cast<size_t>(aStart
.Row()) << 26) ^ // start row <= 2^6
577 (static_cast<size_t>(aStart
.Col()) << 21) ^ // start column <= 2^5
578 (static_cast<size_t>(aEnd
.Col()) << 15) ^ // end column <= 2^6
579 static_cast<size_t>(aEnd
.Row()); // end row <= 2^15
582 inline size_t ScRange::hashStartColumn() const
584 // Assume that for the start row more lower row numbers are used so that
585 // there are not too many conflicts with the column hashed into the higher
588 (static_cast<size_t>(aStart
.Col()) << 24) ^ // start column <= 2^8
589 (static_cast<size_t>(aStart
.Row()) << 16) ^ // start row <= 2^8
590 static_cast<size_t>(aEnd
.Row());
593 struct ScRangeHashAreaFunctor
595 size_t operator()( const ScRange
& rRange
) const
597 return rRange
.hashArea();
601 struct ScRangeEqualFunctor
603 bool operator()( const ScRange
& rRange1
, const ScRange
& rRange2
) const
605 return rRange1
== rRange2
;
609 inline bool ValidRange( const ScRange
& rRange
)
611 return ValidAddress(rRange
.aStart
) && ValidAddress(rRange
.aEnd
);
622 ScRangePair( const ScRangePair
& r
)
623 { aRange
[0] = r
.aRange
[0]; aRange
[1] = r
.aRange
[1]; }
624 ScRangePair( const ScRange
& r1
, const ScRange
& r2
)
625 { aRange
[0] = r1
; aRange
[1] = r2
; }
627 inline ScRangePair
& operator= ( const ScRangePair
& r
);
628 const ScRange
& GetRange( sal_uInt16 n
) const { return aRange
[n
]; }
629 ScRange
& GetRange( sal_uInt16 n
) { return aRange
[n
]; }
630 inline int operator==( const ScRangePair
& ) const;
631 inline int operator!=( const ScRangePair
& ) const;
634 inline ScRangePair
& ScRangePair::operator= ( const ScRangePair
& r
)
636 aRange
[0] = r
.aRange
[0];
637 aRange
[1] = r
.aRange
[1];
641 inline int ScRangePair::operator==( const ScRangePair
& r
) const
643 return ( (aRange
[0] == r
.aRange
[0]) && (aRange
[1] == r
.aRange
[1]) );
646 inline int ScRangePair::operator!=( const ScRangePair
& r
) const
648 return !operator==( r
);
659 inline ScRefAddress() : bRelCol(false), bRelRow(false), bRelTab(false)
661 inline ScRefAddress( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
662 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
663 aAdr(nCol
, nRow
, nTab
),
664 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
666 inline ScRefAddress( const ScAddress
& rAdr
,
667 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
669 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
671 inline ScRefAddress( const ScRefAddress
& rRef
) :
672 aAdr(rRef
.aAdr
), bRelCol(rRef
.bRelCol
), bRelRow(rRef
.bRelRow
),
673 bRelTab(rRef
.bRelTab
)
676 inline ScRefAddress
& operator=( const ScRefAddress
& );
678 inline bool IsRelCol() const { return bRelCol
; }
679 inline bool IsRelRow() const { return bRelRow
; }
680 inline bool IsRelTab() const { return bRelTab
; }
682 inline void SetRelCol(bool bNewRelCol
) { bRelCol
= bNewRelCol
; }
683 inline void SetRelRow(bool bNewRelRow
) { bRelRow
= bNewRelRow
; }
684 inline void SetRelTab(bool bNewRelTab
) { bRelTab
= bNewRelTab
; }
686 inline void Set( const ScAddress
& rAdr
,
687 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
688 inline void Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
689 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
691 inline const ScAddress
& GetAddress() const { return aAdr
; }
692 inline SCCOL
Col() const { return aAdr
.Col(); }
693 inline SCROW
Row() const { return aAdr
.Row(); }
694 inline SCTAB
Tab() const { return aAdr
.Tab(); }
696 inline int operator == ( const ScRefAddress
& r
) const;
697 inline int operator != ( const ScRefAddress
& r
) const
698 { return !(operator==(r
)); }
700 OUString
GetRefString( ScDocument
* pDoc
, SCTAB nActTab
,
701 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
704 inline ScRefAddress
& ScRefAddress::operator=( const ScRefAddress
& rRef
)
707 bRelCol
= rRef
.bRelCol
;
708 bRelRow
= rRef
.bRelRow
;
709 bRelTab
= rRef
.bRelTab
;
713 inline void ScRefAddress::Set( const ScAddress
& rAdr
,
714 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
717 bRelCol
= bNewRelCol
;
718 bRelRow
= bNewRelRow
;
719 bRelTab
= bNewRelTab
;
722 inline void ScRefAddress::Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
723 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
725 aAdr
.Set( nNewCol
, nNewRow
, nNewTab
);
726 bRelCol
= bNewRelCol
;
727 bRelRow
= bNewRelRow
;
728 bRelTab
= bNewRelTab
;
731 inline int ScRefAddress::operator==( const ScRefAddress
& r
) const
733 return aAdr
== r
.aAdr
&& bRelCol
== r
.bRelCol
&& bRelRow
== r
.bRelRow
&&
734 bRelTab
== r
.bRelTab
;
739 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
741 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
742 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
744 template< typename T
> void PutInOrder( T
& nStart
, T
& nEnd
)
755 bool ConvertSingleRef( ScDocument
* pDoc
, const OUString
& rRefString
,
756 SCTAB nDefTab
, ScRefAddress
& rRefAddress
,
757 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
758 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
760 bool ConvertDoubleRef(ScDocument
* pDoc
, const OUString
& rRefString
,
761 SCTAB nDefTab
, ScRefAddress
& rStartRefAddress
,
762 ScRefAddress
& rEndRefAddress
,
763 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
764 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
766 /// append alpha representation of column to buffer
767 SC_DLLPUBLIC
void ScColToAlpha( OUStringBuffer
& rBuffer
, SCCOL nCol
);
769 inline void ScColToAlpha( OUString
& rStr
, SCCOL nCol
)
771 OUStringBuffer
aBuf(2);
772 ScColToAlpha( aBuf
, nCol
);
773 rStr
+= aBuf
.makeStringAndClear();
776 inline OUString
ScColToAlpha( SCCOL nCol
)
778 OUStringBuffer
aBuf(2);
779 ScColToAlpha( aBuf
, nCol
);
780 return aBuf
.makeStringAndClear();
783 /// get column number of A..IV... string
784 bool AlphaToCol( SCCOL
& rCol
, const OUString
& rStr
);
786 #endif // SC_ADDRESS_HXX
788 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */