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 //UNUSED2009-05 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
);
440 struct ScAddressHashFunctor
442 size_t operator()( const ScAddress
& rAdr
) const
448 struct ScAddressEqualFunctor
450 bool operator()( const ScAddress
& rAdr1
, const ScAddress
& rAdr2
) const
452 return rAdr1
== rAdr2
;
457 // === ScRange ===============================================================
462 ScAddress aStart
, aEnd
;
463 inline ScRange() : aStart(), aEnd() {}
464 inline ScRange( ScAddress::Uninitialized e
)
465 : aStart( e
), aEnd( e
) {}
466 inline ScRange( ScAddress::InitializeInvalid e
)
467 : aStart( e
), aEnd( e
) {}
468 inline ScRange( const ScAddress
& s
, const ScAddress
& e
)
469 : aStart( s
), aEnd( e
) { aStart
.PutInOrder( aEnd
); }
470 inline ScRange( const ScRange
& r
) : aStart( r
.aStart
), aEnd( r
.aEnd
) {}
471 inline ScRange( const ScAddress
& r
) : aStart( r
), aEnd( r
) {}
472 inline ScRange( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
473 : aStart( nCol
, nRow
, nTab
), aEnd( aStart
) {}
474 inline ScRange( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
475 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
)
476 : aStart( nCol1
, nRow1
, nTab1
), aEnd( nCol2
, nRow2
, nTab2
) {}
478 inline ScRange
& operator=( const ScRange
& r
)
479 { aStart
= r
.aStart
; aEnd
= r
.aEnd
; return *this; }
480 inline ScRange
& operator=( const ScAddress
& rPos
)
481 { aStart
= aEnd
= rPos
; return *this; }
482 inline void SetInvalid() { aStart
.SetInvalid(); aEnd
.SetInvalid(); }
483 inline bool IsValid() const { return aStart
.IsValid() && aEnd
.IsValid(); }
484 inline bool In( const ScAddress
& ) const; // is Address& in Range?
485 inline bool In( const ScRange
& ) const; // is Range& in Range?
487 USHORT
Parse( const String
&, ScDocument
* = NULL
,
488 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
489 ScAddress::ExternalInfo
* pExtInfo
= NULL
,
490 const ::com::sun::star::uno::Sequence
<
491 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
493 USHORT
ParseAny( const String
&, ScDocument
* = NULL
,
494 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
495 SC_DLLPUBLIC USHORT
ParseCols( const String
&, ScDocument
* = NULL
,
496 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
497 SC_DLLPUBLIC USHORT
ParseRows( const String
&, ScDocument
* = NULL
,
498 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
500 /** Parse an Excel style reference up to and including the sheet name
501 separator '!', including detection of external documents and sheet
502 names, and in case of MOOXML import the bracketed index is used to
503 determine the actual document name passed in pExternalLinks. For
504 internal references (resulting rExternDocName empty), aStart.nTab and
505 aEnd.nTab are set, or -1 if sheet name not found.
506 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
507 encountered results in an error (NULL returned).
508 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
509 NULL for non-filter usage, in which case indices such as [1] are
512 Pointer to the position after '!' if successfully parsed, and
513 rExternDocName, rStartTabName and/or rEndTabName filled if
514 applicable. SCA_... flags set in nFlags.
515 Or if no valid document and/or sheet header could be parsed the start
516 position passed with pString.
517 Or NULL if a 3D sheet header could be parsed but
518 bOnlyAcceptSingle==true was given.
520 const sal_Unicode
* Parse_XL_Header( const sal_Unicode
* pString
, const ScDocument
* pDoc
,
521 String
& rExternDocName
, String
& rStartTabName
, String
& rEndTabName
, USHORT
& nFlags
,
522 bool bOnlyAcceptSingle
,
523 const ::com::sun::star::uno::Sequence
<
524 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
526 SC_DLLPUBLIC
void Format( String
&, USHORT
= 0, ScDocument
* = NULL
,
527 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
529 inline void GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
530 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const;
531 // The document for the maximum defined sheet number
532 SC_DLLPUBLIC
bool Move( SCsCOL dx
, SCsROW dy
, SCsTAB dz
, ScDocument
* =NULL
);
533 SC_DLLPUBLIC
void Justify();
534 SC_DLLPUBLIC
void ExtendTo( const ScRange
& rRange
);
535 SC_DLLPUBLIC
bool Intersects( const ScRange
& ) const; // do two ranges intersect?
536 inline bool operator==( const ScRange
& r
) const;
537 inline bool operator!=( const ScRange
& r
) const;
538 inline bool operator<( const ScRange
& r
) const;
539 inline bool operator<=( const ScRange
& r
) const;
540 inline bool operator>( const ScRange
& r
) const;
541 inline bool operator>=( const ScRange
& r
) const;
543 /// Hash 2D area ignoring table number.
544 inline size_t hashArea() const;
545 /// Hash start column and start and end rows.
546 inline size_t hashStartColumn() const;
549 inline void ScRange::GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
550 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const
552 aStart
.GetVars( nCol1
, nRow1
, nTab1
);
553 aEnd
.GetVars( nCol2
, nRow2
, nTab2
);
556 inline bool ScRange::operator==( const ScRange
& r
) const
558 return ( (aStart
== r
.aStart
) && (aEnd
== r
.aEnd
) );
561 inline bool ScRange::operator!=( const ScRange
& r
) const
563 return !operator==( r
);
566 // Sort on upper left corner, if equal then use lower right too.
567 inline bool ScRange::operator<( const ScRange
& r
) const
569 return aStart
< r
.aStart
|| (aStart
== r
.aStart
&& aEnd
< r
.aEnd
) ;
572 inline bool ScRange::operator<=( const ScRange
& r
) const
574 return operator<( r
) || operator==( r
);
577 inline bool ScRange::operator>( const ScRange
& r
) const
579 return !operator<=( r
);
582 inline bool ScRange::operator>=( const ScRange
& r
) const
584 return !operator<( r
);
587 inline bool ScRange::In( const ScAddress
& rAddr
) const
590 aStart
.Col() <= rAddr
.Col() && rAddr
.Col() <= aEnd
.Col() &&
591 aStart
.Row() <= rAddr
.Row() && rAddr
.Row() <= aEnd
.Row() &&
592 aStart
.Tab() <= rAddr
.Tab() && rAddr
.Tab() <= aEnd
.Tab();
595 inline bool ScRange::In( const ScRange
& r
) const
598 aStart
.Col() <= r
.aStart
.Col() && r
.aEnd
.Col() <= aEnd
.Col() &&
599 aStart
.Row() <= r
.aStart
.Row() && r
.aEnd
.Row() <= aEnd
.Row() &&
600 aStart
.Tab() <= r
.aStart
.Tab() && r
.aEnd
.Tab() <= aEnd
.Tab();
604 inline size_t ScRange::hashArea() const
606 // Assume that there are not that many ranges with identical corners so we
607 // won't have too many collisions. Also assume that more lower row and
608 // column numbers are used so that there are not too many conflicts with
609 // the columns hashed into the values, and that start row and column
610 // usually don't exceed certain values. High bits are not masked off and
611 // may overlap with lower bits of other values, e.g. if start column is
612 // greater than assumed.
614 (static_cast<size_t>(aStart
.Row()) << 26) ^ // start row <= 2^6
615 (static_cast<size_t>(aStart
.Col()) << 21) ^ // start column <= 2^5
616 (static_cast<size_t>(aEnd
.Col()) << 15) ^ // end column <= 2^6
617 static_cast<size_t>(aEnd
.Row()); // end row <= 2^15
621 inline size_t ScRange::hashStartColumn() const
623 // Assume that for the start row more lower row numbers are used so that
624 // there are not too many conflicts with the column hashed into the higher
627 (static_cast<size_t>(aStart
.Col()) << 24) ^ // start column <= 2^8
628 (static_cast<size_t>(aStart
.Row()) << 16) ^ // start row <= 2^8
629 static_cast<size_t>(aEnd
.Row());
633 struct ScRangeHashAreaFunctor
635 size_t operator()( const ScRange
& rRange
) const
637 return rRange
.hashArea();
641 struct ScRangeEqualFunctor
643 bool operator()( const ScRange
& rRange1
, const ScRange
& rRange2
) const
645 return rRange1
== rRange2
;
650 // === ScRangePair ===========================================================
659 ScRangePair( const ScRangePair
& r
)
660 { aRange
[0] = r
.aRange
[0]; aRange
[1] = r
.aRange
[1]; }
661 ScRangePair( const ScRange
& r1
, const ScRange
& r2
)
662 { aRange
[0] = r1
; aRange
[1] = r2
; }
664 inline ScRangePair
& operator= ( const ScRangePair
& r
);
665 const ScRange
& GetRange( USHORT n
) const { return aRange
[n
]; }
666 ScRange
& GetRange( USHORT n
) { return aRange
[n
]; }
667 inline int operator==( const ScRangePair
& ) const;
668 inline int operator!=( const ScRangePair
& ) const;
671 inline ScRangePair
& ScRangePair::operator= ( const ScRangePair
& r
)
673 aRange
[0] = r
.aRange
[0];
674 aRange
[1] = r
.aRange
[1];
678 inline int ScRangePair::operator==( const ScRangePair
& r
) const
680 return ( (aRange
[0] == r
.aRange
[0]) && (aRange
[1] == r
.aRange
[1]) );
683 inline int ScRangePair::operator!=( const ScRangePair
& r
) const
685 return !operator==( r
);
688 // === ScRefAddress ==========================================================
697 inline ScRefAddress() : bRelCol(false), bRelRow(false), bRelTab(false)
699 inline ScRefAddress( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
700 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
701 aAdr(nCol
, nRow
, nTab
),
702 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
704 inline ScRefAddress( const ScAddress
& rAdr
,
705 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
707 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
709 inline ScRefAddress( const ScRefAddress
& rRef
) :
710 aAdr(rRef
.aAdr
), bRelCol(rRef
.bRelCol
), bRelRow(rRef
.bRelRow
),
711 bRelTab(rRef
.bRelTab
)
714 inline ScRefAddress
& operator=( const ScRefAddress
& );
716 inline bool IsRelCol() const { return bRelCol
; }
717 inline bool IsRelRow() const { return bRelRow
; }
718 inline bool IsRelTab() const { return bRelTab
; }
720 inline void SetRelCol(bool bNewRelCol
) { bRelCol
= bNewRelCol
; }
721 inline void SetRelRow(bool bNewRelRow
) { bRelRow
= bNewRelRow
; }
722 inline void SetRelTab(bool bNewRelTab
) { bRelTab
= bNewRelTab
; }
724 inline void Set( const ScAddress
& rAdr
,
725 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
726 inline void Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
727 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
729 inline const ScAddress
& GetAddress() const { return aAdr
; }
730 inline SCCOL
Col() const { return aAdr
.Col(); }
731 inline SCROW
Row() const { return aAdr
.Row(); }
732 inline SCTAB
Tab() const { return aAdr
.Tab(); }
734 inline int operator == ( const ScRefAddress
& r
) const;
735 inline int operator != ( const ScRefAddress
& r
) const
736 { return !(operator==(r
)); }
738 String
GetRefString( ScDocument
* pDoc
, SCTAB nActTab
,
739 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
742 inline ScRefAddress
& ScRefAddress::operator=( const ScRefAddress
& rRef
)
745 bRelCol
= rRef
.bRelCol
;
746 bRelRow
= rRef
.bRelRow
;
747 bRelTab
= rRef
.bRelTab
;
751 inline void ScRefAddress::Set( const ScAddress
& rAdr
,
752 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
755 bRelCol
= bNewRelCol
;
756 bRelRow
= bNewRelRow
;
757 bRelTab
= bNewRelTab
;
760 inline void ScRefAddress::Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
761 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
763 aAdr
.Set( nNewCol
, nNewRow
, nNewTab
);
764 bRelCol
= bNewRelCol
;
765 bRelRow
= bNewRelRow
;
766 bRelTab
= bNewRelTab
;
769 inline int ScRefAddress::operator==( const ScRefAddress
& r
) const
771 return aAdr
== r
.aAdr
&& bRelCol
== r
.bRelCol
&& bRelRow
== r
.bRelRow
&&
772 bRelTab
== r
.bRelTab
;
775 // ===========================================================================
777 // ===========================================================================
779 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
781 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
782 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
784 template< typename T
> void PutInOrder( T
& nStart
, T
& nEnd
)
795 bool ConvertSingleRef( ScDocument
* pDoc
, const String
& rRefString
,
796 SCTAB nDefTab
, ScRefAddress
& rRefAddress
,
797 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
798 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
800 bool ConvertDoubleRef(ScDocument
* pDoc
, const String
& rRefString
,
801 SCTAB nDefTab
, ScRefAddress
& rStartRefAddress
,
802 ScRefAddress
& rEndRefAddress
,
803 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
804 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
806 /// append alpha representation of column to buffer
807 SC_DLLPUBLIC
void ScColToAlpha( rtl::OUStringBuffer
& rBuffer
, SCCOL nCol
);
809 inline void ScColToAlpha( String
& rStr
, SCCOL nCol
)
811 rtl::OUStringBuffer
aBuf(2);
812 ScColToAlpha( aBuf
, nCol
);
813 rStr
.Append( aBuf
.getStr(), static_cast<xub_StrLen
>(aBuf
.getLength()));
816 inline String
ScColToAlpha( SCCOL nCol
)
818 rtl::OUStringBuffer
aBuf(2);
819 ScColToAlpha( aBuf
, nCol
);
820 return aBuf
.makeStringAndClear();
823 /// get column number of A..IV... string
824 bool AlphaToCol( SCCOL
& rCol
, const String
& rStr
);
826 #endif // SC_ADDRESS_HXX