1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: address.hxx,v $
10 * $Revision: 1.17.30.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifndef SC_ADDRESS_HXX
32 #define SC_ADDRESS_HXX
34 #include <tools/stream.hxx>
35 #include <tools/string.hxx>
36 #include <tools/solar.h>
37 #include <tools/debug.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <osl/endian.h>
41 #ifndef INCLUDED_LIMITS
43 #define INCLUDED_LIMITS
46 #include <formula/grammar.hxx>
48 #include <com/sun/star/uno/Sequence.hxx>
50 namespace com
{ namespace sun
{ namespace star
{
52 struct ExternalLinkInfo
;
59 typedef sal_Int32 SCROW
;
60 typedef sal_Int16 SCCOL
;
61 typedef sal_Int16 SCTAB
;
62 typedef sal_Int32 SCCOLROW
; // a type capable of holding either SCCOL or SCROW
64 // temporarily signed typedefs
65 typedef sal_Int32 SCsROW
;
66 typedef sal_Int16 SCsCOL
;
67 typedef sal_Int16 SCsTAB
;
68 typedef sal_Int32 SCsCOLROW
;
70 // size_t typedef to be able to find places where code was changed from USHORT
71 // to size_t and is used to read/write from/to streams.
72 typedef size_t SCSIZE
;
74 // Maximum possible value of data type, NOT maximum row value.
75 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
76 // included, we should not be using those stupid macros anyway.
79 const SCROW SCROW_MAX
= ::std::numeric_limits
<SCROW
>::max();
80 const SCCOL SCCOL_MAX
= ::std::numeric_limits
<SCCOL
>::max();
81 const SCTAB SCTAB_MAX
= ::std::numeric_limits
<SCTAB
>::max();
82 const SCCOLROW SCCOLROW_MAX
= ::std::numeric_limits
<SCCOLROW
>::max();
83 const SCSIZE SCSIZE_MAX
= ::std::numeric_limits
<SCSIZE
>::max();
85 // A define to handle critical sections we hopefully don't need very often.
86 #define SC_ROWLIMIT_MORE_THAN_32K 1 /* set to 1 if we throw the switch */
88 // The maximum values. Defines are needed for preprocessor checks in
89 // bcaslot.cxx, otherwise type safe constants are preferred.
90 #define MAXROWCOUNT_DEFINE 1048576
91 #define MAXCOLCOUNT_DEFINE 1024
94 const SCROW MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
95 const SCCOL MAXCOLCOUNT
= MAXCOLCOUNT_DEFINE
;
96 const SCTAB MAXTABCOUNT
= 256;
97 const SCCOLROW MAXCOLROWCOUNT
= MAXROWCOUNT
;
99 const SCROW MAXROW
= MAXROWCOUNT
- 1;
100 const SCCOL MAXCOL
= MAXCOLCOUNT
- 1;
101 const SCTAB MAXTAB
= MAXTABCOUNT
- 1;
102 const SCCOLROW MAXCOLROW
= MAXROW
;
106 const SCTAB SC_TAB_APPEND
= SCTAB_MAX
;
107 const SCTAB TABLEID_DOC
= SCTAB_MAX
; // entire document, e.g. protect
108 const SCROW SCROWS32K
= 32000;
109 const SCCOL SCCOL_REPEAT_NONE
= SCCOL_MAX
;
110 const SCROW SCROW_REPEAT_NONE
= SCROW_MAX
;
113 // We hope to get rid of the binary file format. If not, these are the places
114 // we'd have to investigate because variable types changed. Just place code in
115 // #if SC_ROWLIMIT_STREAM_ACCESS for now.
116 #define SC_ROWLIMIT_STREAM_ACCESS 0
118 //#if SC_ROWLIMIT_STREAM_ACCESS
119 //#error address types changed!
121 //#endif // SC_ROWLIMIT_STREAM_ACCESS
124 // For future reference, place in code where more than 64k rows would need a
126 // #if SC_ROWLIMIT_MORE_THAN_64K
127 // #error row limit 64k
129 #define SC_ROWLIMIT_MORE_THAN_64K 0 /* set to 1 if we throw the switch */
130 const SCROW SCROWS64K
= 65536;
132 // === old stuff defines =====================================================
135 // Under 16bit Windows rows still had to be limited to 8192.
136 // (define manually for testing)
137 #define SC_LIMIT_ROWS
140 #define MAXROW_30 8191
141 #define MAXROW_40 31999
144 #undef MAXROWCOUNT_DEFINE
145 #define MAXROWCOUNT_DEFINE 8192
146 const SCROW W16MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
147 const SCROW W16MAXROW
= W16MAXROWCOUNT
- 1;
148 #define MAXROWCOUNT W16MAXROWCOUNT
149 #define MAXROW W16MAXROW
152 #define VALIDCOL(nCol) (ValidCol(nCol))
153 #define VALIDROW(nRow) (ValidRow(nRow))
154 #define VALIDTAB(nTab) (ValidTab(nTab))
155 #define VALIDCOLROW(nCol,nRow) (ValidColRow(nCol,nRow))
156 #define VALIDCOLROWTAB(nCol,nRow,nTab) (ValidColRowTab(nCol,nRow,nTab))
158 // === old stuff defines end =================================================
160 inline bool ValidCol( SCCOL nCol
)
162 return static_cast<SCCOL
>(0) <= nCol
&& nCol
<= MAXCOL
;
165 inline bool ValidRow( SCROW nRow
)
167 return static_cast<SCROW
>(0) <= nRow
&& nRow
<= MAXROW
;
170 inline bool ValidTab( SCTAB nTab
)
172 return static_cast<SCTAB
>(0) <= nTab
&& nTab
<= MAXTAB
;
175 inline bool ValidTab( SCTAB nTab
, SCTAB nMaxTab
)
177 return static_cast<SCTAB
>(0) <= nTab
&& nTab
<= nMaxTab
;
180 inline bool ValidColRow( SCCOL nCol
, SCROW nRow
)
182 return ValidCol( nCol
) && ValidRow( nRow
);
185 inline bool ValidColRowTab( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
187 return ValidCol( nCol
) && ValidRow( nRow
) && ValidTab( nTab
);
190 inline SCCOL
SanitizeCol( SCCOL nCol
)
192 return nCol
< 0 ? 0 : (nCol
> MAXCOL
? MAXCOL
: nCol
);
195 inline SCROW
SanitizeRow( SCROW nRow
)
197 return nRow
< 0 ? 0 : (nRow
> MAXROW
? MAXROW
: nRow
);
200 inline SCTAB
SanitizeTab( SCTAB nTab
)
202 return nTab
< 0 ? 0 : (nTab
> MAXTAB
? MAXTAB
: nTab
);
205 inline SCTAB
SanitizeTab( SCTAB nTab
, SCTAB nMaxTab
)
207 return nTab
< 0 ? 0 : (nTab
> nMaxTab
? nMaxTab
: nTab
);
210 // === ScAddress =============================================================
212 // The old cell address is combined in one UINT32:
216 // For speed reasons access isn't done by shifting bits but by using platform
217 // dependent casts, which unfortunately also leads to aliasing problems when
218 // not using gcc -fno-strict-aliasing
220 // The result of ConvertRef() is a bit group of the following:
222 #define SCA_COL_ABSOLUTE 0x01
223 #define SCA_ROW_ABSOLUTE 0x02
224 #define SCA_TAB_ABSOLUTE 0x04
225 #define SCA_TAB_3D 0x08
226 #define SCA_COL2_ABSOLUTE 0x10
227 #define SCA_ROW2_ABSOLUTE 0x20
228 #define SCA_TAB2_ABSOLUTE 0x40
229 #define SCA_TAB2_3D 0x80
230 #define SCA_VALID_ROW 0x0100
231 #define SCA_VALID_COL 0x0200
232 #define SCA_VALID_TAB 0x0400
233 // SCA_BITS is a convience for
234 // (SCA_VALID_TAB | SCA_VALID_COL | SCA_VALID_ROW | SCA_TAB_3D | SCA_TAB_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_COL_ABSOLUTE)
235 #define SCA_BITS 0x070F
236 // somewhat cheesy kludge to force the display of the document name even for
237 // local references. Requires TAB_3D to be valid
238 #define SCA_FORCE_DOC 0x0800
239 #define SCA_VALID_ROW2 0x1000
240 #define SCA_VALID_COL2 0x2000
241 #define SCA_VALID_TAB2 0x4000
242 #define SCA_VALID 0x8000
244 #define SCA_ABS SCA_VALID \
245 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
247 #define SCR_ABS SCA_ABS \
248 | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
250 #define SCA_ABS_3D SCA_ABS | SCA_TAB_3D
251 #define SCR_ABS_3D SCR_ABS | SCA_TAB_3D
253 // === ScAddress =============================================================
264 enum Uninitialized
{ UNINITIALIZED
};
265 enum InitializeInvalid
{ INITIALIZE_INVALID
};
268 formula::FormulaGrammar::AddressConvention eConv
;
271 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, SCROW nRowP
, SCCOL nColP
)
272 : eConv( eConvP
), nRow( nRowP
), nCol( nColP
)
274 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, ScAddress
const & rAddr
)
275 : eConv( eConvP
), nRow( rAddr
.Row() ), nCol( rAddr
.Col() )
277 inline Details( formula::FormulaGrammar::AddressConvention eConvP
)
278 : eConv( eConvP
), nRow( 0 ), nCol( 0 )
280 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
281 Details( const ScDocument
* pDoc
, const ScAddress
& rAddr
);
282 void SetPos( const ScDocument
* pDoc
, const ScAddress
& rAddr
);
284 SC_DLLPUBLIC
static const Details detailsOOOa1
;
292 inline ExternalInfo() : mnFileId(0), mbExternal(false) {}
295 inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
296 inline ScAddress( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
297 : nRow(nRowP
), nCol(nColP
), nTab(nTabP
)
299 /** Yes, it is what it seems to be: Uninitialized. May be used for
300 performance reasons if it is initialized by other means. */
301 inline ScAddress( Uninitialized
) {}
302 inline ScAddress( InitializeInvalid
)
303 : nRow(-1), nCol(-1), nTab(-1) {}
304 inline ScAddress( const ScAddress
& r
)
305 : nRow(r
.nRow
), nCol(r
.nCol
), nTab(r
.nTab
)
307 inline ScAddress
& operator=( const ScAddress
& r
);
309 inline void Set( SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
310 inline SCROW
Row() const { return nRow
; }
311 inline SCCOL
Col() const { return nCol
; }
312 inline SCTAB
Tab() const { return nTab
; }
313 inline void SetRow( SCROW nRowP
) { nRow
= nRowP
; }
314 inline void SetCol( SCCOL nColP
) { nCol
= nColP
; }
315 inline void SetTab( SCTAB nTabP
) { nTab
= nTabP
; }
316 inline void SetInvalid() { nRow
= -1; nCol
= -1; nTab
= -1; }
317 inline bool IsValid() const { return (nRow
>= 0) && (nCol
>= 0) && (nTab
>= 0); }
318 inline void PutInOrder( ScAddress
& r
);
319 inline void IncRow( SCsROW n
=1 ) { nRow
= sal::static_int_cast
<SCROW
>(nRow
+ n
); }
320 inline void IncCol( SCsCOL n
=1 ) { nCol
= sal::static_int_cast
<SCCOL
>(nCol
+ n
); }
321 inline void IncTab( SCsTAB n
=1 ) { nTab
= sal::static_int_cast
<SCTAB
>(nTab
+ n
); }
322 inline void GetVars( SCCOL
& nColP
, SCROW
& nRowP
, SCTAB
& nTabP
) const
323 { nColP
= nCol
; nRowP
= nRow
; nTabP
= nTab
; }
325 SC_DLLPUBLIC USHORT
Parse( const String
&, ScDocument
* = NULL
,
326 const Details
& rDetails
= detailsOOOa1
,
327 ExternalInfo
* pExtInfo
= NULL
,
328 const ::com::sun::star::uno::Sequence
<
329 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
331 SC_DLLPUBLIC
void Format( String
&, USHORT
= 0, ScDocument
* = NULL
,
332 const Details
& rDetails
= detailsOOOa1
) const;
334 // The document for the maximum defined sheet number
335 SC_DLLPUBLIC
bool Move( SCsCOL dx
, SCsROW dy
, SCsTAB dz
, ScDocument
* =NULL
);
336 inline bool operator==( const ScAddress
& r
) const;
337 inline bool operator!=( const ScAddress
& r
) const;
338 inline bool operator<( const ScAddress
& r
) const;
339 inline bool operator<=( const ScAddress
& r
) const;
340 inline bool operator>( const ScAddress
& r
) const;
341 inline bool operator>=( const ScAddress
& r
) const;
343 inline size_t hash() const;
345 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
346 String
GetColRowString( bool bAbsolute
= FALSE
,
347 const Details
& rDetails
= detailsOOOa1
) const;
350 inline void ScAddress::PutInOrder( ScAddress
& r
)
352 if ( r
.Col() < Col() )
354 SCCOL nTmp
= r
.Col();
358 if ( r
.Row() < Row() )
360 SCROW nTmp
= r
.Row();
364 if ( r
.Tab() < Tab() )
366 SCTAB nTmp
= r
.Tab();
372 inline void ScAddress::Set( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
379 inline ScAddress
& ScAddress::operator=( const ScAddress
& r
)
387 inline bool ScAddress::operator==( const ScAddress
& r
) const
389 return nRow
== r
.nRow
&& nCol
== r
.nCol
&& nTab
== r
.nTab
;
392 inline bool ScAddress::operator!=( const ScAddress
& r
) const
394 return !operator==( r
);
397 inline bool ScAddress::operator<( const ScAddress
& r
) const
399 // Same behavior as the old UINT32 nAddress < r.nAddress with encoded
400 // tab|col|row bit fields.
404 return nRow
< r
.nRow
;
406 return nCol
< r
.nCol
;
409 return nTab
< r
.nTab
;
412 inline bool ScAddress::operator<=( const ScAddress
& r
) const
414 return operator<( r
) || operator==( r
);
417 inline bool ScAddress::operator>( const ScAddress
& r
) const
419 return !operator<=( r
);
422 inline bool ScAddress::operator>=( const ScAddress
& r
) const
424 return !operator<( r
);
428 inline size_t ScAddress::hash() const
430 // Assume that there are not that many addresses with row > 2^16 AND column
431 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
433 return (static_cast<size_t>(nTab
) << 24) ^
434 (static_cast<size_t>(nCol
) << 16) ^ static_cast<size_t>(nRow
);
436 return (static_cast<size_t>(nTab
) << 28) ^
437 (static_cast<size_t>(nCol
) << 24) ^ static_cast<size_t>(nRow
);
441 // === ScRange ===============================================================
446 ScAddress aStart
, aEnd
;
447 inline ScRange() : aStart(), aEnd() {}
448 inline ScRange( ScAddress::Uninitialized e
)
449 : aStart( e
), aEnd( e
) {}
450 inline ScRange( ScAddress::InitializeInvalid e
)
451 : aStart( e
), aEnd( e
) {}
452 inline ScRange( const ScAddress
& s
, const ScAddress
& e
)
453 : aStart( s
), aEnd( e
) { aStart
.PutInOrder( aEnd
); }
454 inline ScRange( const ScRange
& r
) : aStart( r
.aStart
), aEnd( r
.aEnd
) {}
455 inline ScRange( const ScAddress
& r
) : aStart( r
), aEnd( r
) {}
456 inline ScRange( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
457 : aStart( nCol
, nRow
, nTab
), aEnd( aStart
) {}
458 inline ScRange( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
459 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
)
460 : aStart( nCol1
, nRow1
, nTab1
), aEnd( nCol2
, nRow2
, nTab2
) {}
462 inline ScRange
& operator=( const ScRange
& r
)
463 { aStart
= r
.aStart
; aEnd
= r
.aEnd
; return *this; }
464 inline ScRange
& operator=( const ScAddress
& rPos
)
465 { aStart
= aEnd
= rPos
; return *this; }
466 inline void SetInvalid() { aStart
.SetInvalid(); aEnd
.SetInvalid(); }
467 inline bool IsValid() const { return aStart
.IsValid() && aEnd
.IsValid(); }
468 inline bool In( const ScAddress
& ) const; // is Address& in Range?
469 inline bool In( const ScRange
& ) const; // is Range& in Range?
471 USHORT
Parse( const String
&, ScDocument
* = NULL
,
472 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
473 ScAddress::ExternalInfo
* pExtInfo
= NULL
,
474 const ::com::sun::star::uno::Sequence
<
475 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
477 USHORT
ParseAny( const String
&, ScDocument
* = NULL
,
478 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
479 SC_DLLPUBLIC USHORT
ParseCols( const String
&, ScDocument
* = NULL
,
480 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
481 SC_DLLPUBLIC USHORT
ParseRows( const String
&, ScDocument
* = NULL
,
482 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
484 /** Parse an Excel style reference up to and including the sheet name
485 separator '!', including detection of external documents and sheet
486 names, and in case of MOOXML import the bracketed index is used to
487 determine the actual document name passed in pExternalLinks. For
488 internal references (resulting rExternDocName empty), aStart.nTab and
489 aEnd.nTab are set, or -1 if sheet name not found.
490 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
491 encountered results in an error (NULL returned).
492 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
493 NULL for non-filter usage, in which case indices such as [1] are
496 Pointer to the position after '!' if successfully parsed, and
497 rExternDocName, rStartTabName and/or rEndTabName filled if
498 applicable. SCA_... flags set in nFlags.
499 Or if no valid document and/or sheet header could be parsed the start
500 position passed with pString.
501 Or NULL if a 3D sheet header could be parsed but
502 bOnlyAcceptSingle==true was given.
504 const sal_Unicode
* Parse_XL_Header( const sal_Unicode
* pString
, const ScDocument
* pDoc
,
505 String
& rExternDocName
, String
& rStartTabName
, String
& rEndTabName
, USHORT
& nFlags
,
506 bool bOnlyAcceptSingle
,
507 const ::com::sun::star::uno::Sequence
<
508 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
510 SC_DLLPUBLIC
void Format( String
&, USHORT
= 0, ScDocument
* = NULL
,
511 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
513 inline void GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
514 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const;
515 // The document for the maximum defined sheet number
516 SC_DLLPUBLIC
bool Move( SCsCOL dx
, SCsROW dy
, SCsTAB dz
, ScDocument
* =NULL
);
517 SC_DLLPUBLIC
void Justify();
518 SC_DLLPUBLIC
void ExtendTo( const ScRange
& rRange
);
519 SC_DLLPUBLIC
bool Intersects( const ScRange
& ) const; // do two ranges intersect?
520 inline bool operator==( const ScRange
& r
) const;
521 inline bool operator!=( const ScRange
& r
) const;
522 inline bool operator<( const ScRange
& r
) const;
523 inline bool operator<=( const ScRange
& r
) const;
524 inline bool operator>( const ScRange
& r
) const;
525 inline bool operator>=( const ScRange
& r
) const;
527 inline size_t hash() const;
528 inline size_t hashStartColumn() const;
531 inline void ScRange::GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
532 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const
534 aStart
.GetVars( nCol1
, nRow1
, nTab1
);
535 aEnd
.GetVars( nCol2
, nRow2
, nTab2
);
538 inline bool ScRange::operator==( const ScRange
& r
) const
540 return ( (aStart
== r
.aStart
) && (aEnd
== r
.aEnd
) );
543 inline bool ScRange::operator!=( const ScRange
& r
) const
545 return !operator==( r
);
548 // Sort on upper left corner, if equal then use lower right too.
549 inline bool ScRange::operator<( const ScRange
& r
) const
551 return aStart
< r
.aStart
|| (aStart
== r
.aStart
&& aEnd
< r
.aEnd
) ;
554 inline bool ScRange::operator<=( const ScRange
& r
) const
556 return operator<( r
) || operator==( r
);
559 inline bool ScRange::operator>( const ScRange
& r
) const
561 return !operator<=( r
);
564 inline bool ScRange::operator>=( const ScRange
& r
) const
566 return !operator<( r
);
569 inline bool ScRange::In( const ScAddress
& rAddr
) const
572 aStart
.Col() <= rAddr
.Col() && rAddr
.Col() <= aEnd
.Col() &&
573 aStart
.Row() <= rAddr
.Row() && rAddr
.Row() <= aEnd
.Row() &&
574 aStart
.Tab() <= rAddr
.Tab() && rAddr
.Tab() <= aEnd
.Tab();
577 inline bool ScRange::In( const ScRange
& r
) const
580 aStart
.Col() <= r
.aStart
.Col() && r
.aEnd
.Col() <= aEnd
.Col() &&
581 aStart
.Row() <= r
.aStart
.Row() && r
.aEnd
.Row() <= aEnd
.Row() &&
582 aStart
.Tab() <= r
.aStart
.Tab() && r
.aEnd
.Tab() <= aEnd
.Tab();
586 inline size_t ScRange::hash() const
588 // Assume that there are not that many ranges with identical corners so we
589 // won't have too many collisions. Also assume that more lower row and
590 // column numbers are used so that there are not too many conflicts with
591 // the columns hashed into the values, and that start row and column
592 // usually don't exceed certain values. High bits are not masked off and
593 // may overlap with lower bits of other values, e.g. if start column is
594 // greater than assumed.
596 (static_cast<size_t>(aStart
.Row()) << 26) ^ // start row <= 2^6
597 (static_cast<size_t>(aStart
.Col()) << 21) ^ // start column <= 2^5
598 (static_cast<size_t>(aEnd
.Col()) << 15) ^ // end column <= 2^6
599 static_cast<size_t>(aEnd
.Row()); // end row <= 2^15
603 inline size_t ScRange::hashStartColumn() const
605 // Assume that for the start row more lower row numbers are used so that
606 // there are not too many conflicts with the column hashed into the higher
609 (static_cast<size_t>(aStart
.Col()) << 24) ^ // start column <= 2^8
610 (static_cast<size_t>(aStart
.Row()) << 16) ^ // start row <= 2^8
611 static_cast<size_t>(aEnd
.Row());
615 // === ScRangePair ===========================================================
624 ScRangePair( const ScRangePair
& r
)
625 { aRange
[0] = r
.aRange
[0]; aRange
[1] = r
.aRange
[1]; }
626 ScRangePair( const ScRange
& r1
, const ScRange
& r2
)
627 { aRange
[0] = r1
; aRange
[1] = r2
; }
629 inline ScRangePair
& operator= ( const ScRangePair
& r
);
630 const ScRange
& GetRange( USHORT n
) const { return aRange
[n
]; }
631 ScRange
& GetRange( USHORT n
) { return aRange
[n
]; }
632 inline int operator==( const ScRangePair
& ) const;
633 inline int operator!=( const ScRangePair
& ) const;
636 inline ScRangePair
& ScRangePair::operator= ( const ScRangePair
& r
)
638 aRange
[0] = r
.aRange
[0];
639 aRange
[1] = r
.aRange
[1];
643 inline int ScRangePair::operator==( const ScRangePair
& r
) const
645 return ( (aRange
[0] == r
.aRange
[0]) && (aRange
[1] == r
.aRange
[1]) );
648 inline int ScRangePair::operator!=( const ScRangePair
& r
) const
650 return !operator==( r
);
653 // === ScRefAddress ==========================================================
662 inline ScRefAddress() : bRelCol(false), bRelRow(false), bRelTab(false)
664 inline ScRefAddress( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
665 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
666 aAdr(nCol
, nRow
, nTab
),
667 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
669 inline ScRefAddress( const ScAddress
& rAdr
,
670 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
672 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
674 inline ScRefAddress( const ScRefAddress
& rRef
) :
675 aAdr(rRef
.aAdr
), bRelCol(rRef
.bRelCol
), bRelRow(rRef
.bRelRow
),
676 bRelTab(rRef
.bRelTab
)
679 inline ScRefAddress
& operator=( const ScRefAddress
& );
681 inline bool IsRelCol() const { return bRelCol
; }
682 inline bool IsRelRow() const { return bRelRow
; }
683 inline bool IsRelTab() const { return bRelTab
; }
685 inline void SetRelCol(bool bNewRelCol
) { bRelCol
= bNewRelCol
; }
686 inline void SetRelRow(bool bNewRelRow
) { bRelRow
= bNewRelRow
; }
687 inline void SetRelTab(bool bNewRelTab
) { bRelTab
= bNewRelTab
; }
689 inline void Set( const ScAddress
& rAdr
,
690 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
691 inline void Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
692 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
694 inline const ScAddress
& GetAddress() const { return aAdr
; }
695 inline SCCOL
Col() const { return aAdr
.Col(); }
696 inline SCROW
Row() const { return aAdr
.Row(); }
697 inline SCTAB
Tab() const { return aAdr
.Tab(); }
699 inline int operator == ( const ScRefAddress
& r
) const;
700 inline int operator != ( const ScRefAddress
& r
) const
701 { return !(operator==(r
)); }
703 String
GetRefString( ScDocument
* pDoc
, SCTAB nActTab
,
704 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
707 inline ScRefAddress
& ScRefAddress::operator=( const ScRefAddress
& rRef
)
710 bRelCol
= rRef
.bRelCol
;
711 bRelRow
= rRef
.bRelRow
;
712 bRelTab
= rRef
.bRelTab
;
716 inline void ScRefAddress::Set( const ScAddress
& rAdr
,
717 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
720 bRelCol
= bNewRelCol
;
721 bRelRow
= bNewRelRow
;
722 bRelTab
= bNewRelTab
;
725 inline void ScRefAddress::Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
726 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
728 aAdr
.Set( nNewCol
, nNewRow
, nNewTab
);
729 bRelCol
= bNewRelCol
;
730 bRelRow
= bNewRelRow
;
731 bRelTab
= bNewRelTab
;
734 inline int ScRefAddress::operator==( const ScRefAddress
& r
) const
736 return aAdr
== r
.aAdr
&& bRelCol
== r
.bRelCol
&& bRelRow
== r
.bRelRow
&&
737 bRelTab
== r
.bRelTab
;
740 // ===========================================================================
742 // ===========================================================================
744 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
746 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
747 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
749 template< typename T
> void PutInOrder( T
& nStart
, T
& nEnd
)
760 bool ConvertSingleRef( ScDocument
* pDoc
, const String
& rRefString
,
761 SCTAB nDefTab
, ScRefAddress
& rRefAddress
,
762 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
764 bool ConvertDoubleRef(ScDocument
* pDoc
, const String
& rRefString
,
765 SCTAB nDefTab
, ScRefAddress
& rStartRefAddress
,
766 ScRefAddress
& rEndRefAddress
,
767 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
769 /// append alpha representation of column to buffer
770 SC_DLLPUBLIC
void ScColToAlpha( rtl::OUStringBuffer
& rBuffer
, SCCOL nCol
);
772 inline void ScColToAlpha( String
& rStr
, SCCOL nCol
)
774 rtl::OUStringBuffer
aBuf(2);
775 ScColToAlpha( aBuf
, nCol
);
776 rStr
.Append( aBuf
.getStr(), static_cast<xub_StrLen
>(aBuf
.getLength()));
779 inline String
ScColToAlpha( SCCOL nCol
)
781 rtl::OUStringBuffer
aBuf(2);
782 ScColToAlpha( aBuf
, nCol
);
783 return aBuf
.makeStringAndClear();
786 /// get column number of A..IV... string
787 bool AlphaToCol( SCCOL
& rCol
, const String
& rStr
);
789 #endif // SC_ADDRESS_HXX