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/string.hxx>
25 #include <tools/solar.h>
26 #include <rtl/ustrbuf.hxx>
27 #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
;
44 typedef sal_Int32 SCROW
;
45 typedef sal_Int16 SCCOL
;
46 typedef sal_Int16 SCTAB
;
47 typedef sal_Int32 SCCOLROW
; ///< a type capable of holding either SCCOL or SCROW
49 // temporarily signed typedefs
50 typedef sal_Int32 SCsROW
;
51 typedef sal_Int16 SCsCOL
;
52 typedef sal_Int16 SCsTAB
;
53 typedef sal_Int32 SCsCOLROW
;
55 /** size_t typedef to be able to find places where code was changed from USHORT
56 to size_t and is used to read/write from/to streams. */
57 typedef size_t SCSIZE
;
59 // Maximum possible value of data type, NOT maximum row value.
60 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
61 // included, we should not be using those stupid macros anyway.
64 const SCROW SCROW_MAX
= ::std::numeric_limits
<SCROW
>::max();
65 const SCCOL SCCOL_MAX
= ::std::numeric_limits
<SCCOL
>::max();
66 const SCTAB SCTAB_MAX
= ::std::numeric_limits
<SCTAB
>::max();
67 const SCCOLROW SCCOLROW_MAX
= ::std::numeric_limits
<SCCOLROW
>::max();
68 const SCSIZE SCSIZE_MAX
= ::std::numeric_limits
<SCSIZE
>::max();
70 // The maximum values. Defines are needed for preprocessor checks, for example
71 // in bcaslot.cxx, otherwise type safe constants are preferred.
72 #define MAXROWCOUNT_DEFINE 1048576
73 #define MAXCOLCOUNT_DEFINE 1024
76 const SCROW MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
77 const SCCOL MAXCOLCOUNT
= MAXCOLCOUNT_DEFINE
;
78 /// limiting to 10000 for now, problem with 32 bit builds for now
79 const SCTAB MAXTABCOUNT
= 10000;
80 const SCCOLROW MAXCOLROWCOUNT
= MAXROWCOUNT
;
82 const SCROW MAXROW
= MAXROWCOUNT
- 1;
83 const SCCOL MAXCOL
= MAXCOLCOUNT
- 1;
84 const SCTAB MAXTAB
= MAXTABCOUNT
- 1;
85 const SCCOLROW MAXCOLROW
= MAXROW
;
86 // Limit the initial tab count to prevent users to set the count too high,
87 // which could cause the memory usage of blank documents to exceed the
88 // available system memory.
89 const SCTAB MAXINITTAB
= 1024;
90 const SCTAB MININITTAB
= 1;
93 const SCTAB SC_TAB_APPEND
= SCTAB_MAX
;
94 const SCTAB TABLEID_DOC
= SCTAB_MAX
; // entire document, e.g. protect
95 const SCROW SCROWS32K
= 32000;
96 const SCCOL SCCOL_REPEAT_NONE
= SCCOL_MAX
;
97 const SCROW SCROW_REPEAT_NONE
= SCROW_MAX
;
99 // For future reference, place in code where more than 64k rows would need a
101 // #if SC_ROWLIMIT_MORE_THAN_64K
102 // #error row limit 64k
104 #if MAXROWCOUNT_DEFINE > 65536
105 #define SC_ROWLIMIT_MORE_THAN_64K 1
107 #define SC_ROWLIMIT_MORE_THAN_64K 0
109 const SCROW SCROWS64K
= 65536;
111 // === old stuff defines =====================================================
113 #define MAXROW_30 8191
116 #undef MAXROWCOUNT_DEFINE
117 #define MAXROWCOUNT_DEFINE 8192
118 const SCROW W16MAXROWCOUNT
= MAXROWCOUNT_DEFINE
;
119 const SCROW W16MAXROW
= W16MAXROWCOUNT
- 1;
120 #define MAXROWCOUNT W16MAXROWCOUNT
121 #define MAXROW W16MAXROW
124 // === old stuff defines end =================================================
126 inline bool ValidCol( SCCOL nCol
)
128 return static_cast<SCCOL
>(0) <= nCol
&& nCol
<= MAXCOL
;
131 inline bool ValidRow( SCROW nRow
)
133 return static_cast<SCROW
>(0) <= nRow
&& nRow
<= MAXROW
;
136 inline bool ValidTab( SCTAB nTab
)
138 return static_cast<SCTAB
>(0) <= nTab
&& nTab
<= MAXTAB
;
141 inline bool ValidTab( SCTAB nTab
, SCTAB nMaxTab
)
143 return static_cast<SCTAB
>(0) <= nTab
&& nTab
<= nMaxTab
;
146 inline bool ValidColRow( SCCOL nCol
, SCROW nRow
)
148 return ValidCol( nCol
) && ValidRow( nRow
);
151 inline bool ValidColRowTab( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
153 return ValidCol( nCol
) && ValidRow( nRow
) && ValidTab( nTab
);
156 inline SCCOL
SanitizeCol( SCCOL nCol
)
158 return nCol
< 0 ? 0 : (nCol
> MAXCOL
? MAXCOL
: nCol
);
161 inline SCROW
SanitizeRow( SCROW nRow
)
163 return nRow
< 0 ? 0 : (nRow
> MAXROW
? MAXROW
: nRow
);
166 inline SCTAB
SanitizeTab( SCTAB nTab
)
168 return nTab
< 0 ? 0 : (nTab
> MAXTAB
? MAXTAB
: nTab
);
171 inline SCTAB
SanitizeTab( SCTAB nTab
, SCTAB nMaxTab
)
173 return nTab
< 0 ? 0 : (nTab
> nMaxTab
? nMaxTab
: nTab
);
176 // === ScAddress =============================================================
178 // The old cell address is combined in one UINT32:
182 // For speed reasons access isn't done by shifting bits but by using platform
183 // dependent casts, which unfortunately also leads to aliasing problems when
184 // not using gcc -fno-strict-aliasing
186 // The result of ConvertRef() is a bit group of the following:
188 #define SCA_COL_ABSOLUTE 0x01
189 #define SCA_ROW_ABSOLUTE 0x02
190 #define SCA_TAB_ABSOLUTE 0x04
191 #define SCA_TAB_3D 0x08
192 #define SCA_COL2_ABSOLUTE 0x10
193 #define SCA_ROW2_ABSOLUTE 0x20
194 #define SCA_TAB2_ABSOLUTE 0x40
195 #define SCA_TAB2_3D 0x80
196 #define SCA_VALID_ROW 0x0100
197 #define SCA_VALID_COL 0x0200
198 #define SCA_VALID_TAB 0x0400
199 // SCA_BITS is a convience for
200 // (SCA_VALID_TAB | SCA_VALID_COL | SCA_VALID_ROW | SCA_TAB_3D | SCA_TAB_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_COL_ABSOLUTE)
201 #define SCA_BITS 0x070F
202 // somewhat cheesy kludge to force the display of the document name even for
203 // local references. Requires TAB_3D to be valid
204 #define SCA_FORCE_DOC 0x0800
205 #define SCA_VALID_ROW2 0x1000
206 #define SCA_VALID_COL2 0x2000
207 #define SCA_VALID_TAB2 0x4000
208 #define SCA_VALID 0x8000
210 #define SCA_ABS SCA_VALID \
211 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
213 #define SCR_ABS SCA_ABS \
214 | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
216 #define SCA_ABS_3D SCA_ABS | SCA_TAB_3D
217 #define SCR_ABS_3D SCR_ABS | SCA_TAB_3D
219 // === ScAddress =============================================================
230 enum Uninitialized
{ UNINITIALIZED
};
231 enum InitializeInvalid
{ INITIALIZE_INVALID
};
234 formula::FormulaGrammar::AddressConvention eConv
;
237 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, SCROW nRowP
, SCCOL nColP
)
238 : eConv( eConvP
), nRow( nRowP
), nCol( nColP
)
240 inline Details( formula::FormulaGrammar::AddressConvention eConvP
, ScAddress
const & rAddr
)
241 : eConv( eConvP
), nRow( rAddr
.Row() ), nCol( rAddr
.Col() )
243 inline Details( formula::FormulaGrammar::AddressConvention eConvP
)
244 : eConv( eConvP
), nRow( 0 ), nCol( 0 )
246 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
247 Details( const ScDocument
* pDoc
, const ScAddress
& rAddr
);
249 SC_DLLPUBLIC
static const Details detailsOOOa1
;
257 inline ExternalInfo() : mnFileId(0), mbExternal(false) {}
260 inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
261 inline ScAddress( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
262 : nRow(nRowP
), nCol(nColP
), nTab(nTabP
)
264 /** Yes, it is what it seems to be: Uninitialized. May be used for
265 performance reasons if it is initialized by other means. */
266 inline ScAddress( Uninitialized
) {}
267 inline ScAddress( InitializeInvalid
)
268 : nRow(-1), nCol(-1), nTab(-1) {}
269 inline ScAddress( const ScAddress
& r
)
270 : nRow(r
.nRow
), nCol(r
.nCol
), nTab(r
.nTab
)
272 inline ScAddress
& operator=( const ScAddress
& r
);
274 inline void Set( SCCOL nCol
, SCROW nRow
, SCTAB nTab
);
275 inline SCROW
Row() const { return nRow
; }
276 inline SCCOL
Col() const { return nCol
; }
277 inline SCTAB
Tab() const { return nTab
; }
278 inline void SetRow( SCROW nRowP
) { nRow
= nRowP
; }
279 inline void SetCol( SCCOL nColP
) { nCol
= nColP
; }
280 inline void SetTab( SCTAB nTabP
) { nTab
= nTabP
; }
281 inline void SetInvalid() { nRow
= -1; nCol
= -1; nTab
= -1; }
282 inline bool IsValid() const { return (nRow
>= 0) && (nCol
>= 0) && (nTab
>= 0); }
283 inline void PutInOrder( ScAddress
& r
);
284 inline void IncRow( SCsROW n
=1 ) { nRow
= sal::static_int_cast
<SCROW
>(nRow
+ n
); }
285 inline void IncCol( SCsCOL n
=1 ) { nCol
= sal::static_int_cast
<SCCOL
>(nCol
+ n
); }
286 inline void IncTab( SCsTAB n
=1 ) { nTab
= sal::static_int_cast
<SCTAB
>(nTab
+ n
); }
287 inline void GetVars( SCCOL
& nColP
, SCROW
& nRowP
, SCTAB
& nTabP
) const
288 { nColP
= nCol
; nRowP
= nRow
; nTabP
= nTab
; }
290 SC_DLLPUBLIC sal_uInt16
Parse( const String
&, ScDocument
* = NULL
,
291 const Details
& rDetails
= detailsOOOa1
,
292 ExternalInfo
* pExtInfo
= NULL
,
293 const ::com::sun::star::uno::Sequence
<
294 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
296 SC_DLLPUBLIC
void Format( OUString
&, sal_uInt16
= 0, const ScDocument
* = NULL
,
297 const Details
& rDetails
= detailsOOOa1
) const;
298 SC_DLLPUBLIC
void Format( String
&, sal_uInt16
= 0, const ScDocument
* = NULL
,
299 const Details
& rDetails
= detailsOOOa1
) const;
301 // The document for the maximum defined sheet number
302 SC_DLLPUBLIC
bool Move( SCsCOL dx
, SCsROW dy
, SCsTAB dz
, ScDocument
* =NULL
);
303 inline bool operator==( const ScAddress
& r
) const;
304 inline bool operator!=( const ScAddress
& r
) const;
305 inline bool operator<( const ScAddress
& r
) const;
306 inline bool operator<=( const ScAddress
& r
) const;
307 inline bool operator>( const ScAddress
& r
) const;
308 inline bool operator>=( const ScAddress
& r
) const;
310 inline size_t hash() const;
312 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
313 String
GetColRowString( bool bAbsolute
= false,
314 const Details
& rDetails
= detailsOOOa1
) const;
317 inline void ScAddress::PutInOrder( ScAddress
& r
)
319 if ( r
.Col() < Col() )
321 SCCOL nTmp
= r
.Col();
325 if ( r
.Row() < Row() )
327 SCROW nTmp
= r
.Row();
331 if ( r
.Tab() < Tab() )
333 SCTAB nTmp
= r
.Tab();
339 inline void ScAddress::Set( SCCOL nColP
, SCROW nRowP
, SCTAB nTabP
)
346 inline ScAddress
& ScAddress::operator=( const ScAddress
& r
)
354 inline bool ScAddress::operator==( const ScAddress
& r
) const
356 return nRow
== r
.nRow
&& nCol
== r
.nCol
&& nTab
== r
.nTab
;
359 inline bool ScAddress::operator!=( const ScAddress
& r
) const
361 return !operator==( r
);
364 /** Same behavior as the old sal_uInt32 nAddress < r.nAddress with encoded
365 tab|col|row bit fields. */
366 inline bool ScAddress::operator<( const ScAddress
& r
) const
371 return nRow
< r
.nRow
;
373 return nCol
< r
.nCol
;
376 return nTab
< r
.nTab
;
379 inline bool ScAddress::operator<=( const ScAddress
& r
) const
381 return operator<( r
) || operator==( r
);
384 inline bool ScAddress::operator>( const ScAddress
& r
) const
386 return !operator<=( r
);
389 inline bool ScAddress::operator>=( const ScAddress
& r
) const
391 return !operator<( r
);
395 inline size_t ScAddress::hash() const
397 // Assume that there are not that many addresses with row > 2^16 AND column
398 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
400 return (static_cast<size_t>(nTab
) << 24) ^
401 (static_cast<size_t>(nCol
) << 16) ^ static_cast<size_t>(nRow
);
403 return (static_cast<size_t>(nTab
) << 28) ^
404 (static_cast<size_t>(nCol
) << 24) ^ static_cast<size_t>(nRow
);
407 struct ScAddressHashFunctor
409 size_t operator()( const ScAddress
& rAdr
) const
415 struct ScAddressEqualFunctor
417 bool operator()( const ScAddress
& rAdr1
, const ScAddress
& rAdr2
) const
419 return rAdr1
== rAdr2
;
424 // === ScRange ===============================================================
429 ScAddress aStart
, aEnd
;
430 inline ScRange() : aStart(), aEnd() {}
431 inline ScRange( ScAddress::Uninitialized e
)
432 : aStart( e
), aEnd( e
) {}
433 inline ScRange( ScAddress::InitializeInvalid e
)
434 : aStart( e
), aEnd( e
) {}
435 inline ScRange( const ScAddress
& s
, const ScAddress
& e
)
436 : aStart( s
), aEnd( e
) { aStart
.PutInOrder( aEnd
); }
437 inline ScRange( const ScRange
& r
) : aStart( r
.aStart
), aEnd( r
.aEnd
) {}
438 inline ScRange( const ScAddress
& r
) : aStart( r
), aEnd( r
) {}
439 inline ScRange( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
440 : aStart( nCol
, nRow
, nTab
), aEnd( aStart
) {}
441 inline ScRange( SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
442 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
)
443 : aStart( nCol1
, nRow1
, nTab1
), aEnd( nCol2
, nRow2
, nTab2
) {}
445 inline ScRange
& operator=( const ScRange
& r
)
446 { aStart
= r
.aStart
; aEnd
= r
.aEnd
; return *this; }
447 inline ScRange
& operator=( const ScAddress
& rPos
)
448 { aStart
= aEnd
= rPos
; return *this; }
449 inline void SetInvalid() { aStart
.SetInvalid(); aEnd
.SetInvalid(); }
450 inline bool IsValid() const { return aStart
.IsValid() && aEnd
.IsValid(); }
451 inline bool In( const ScAddress
& ) const; ///< is Address& in Range?
452 inline bool In( const ScRange
& ) const; ///< is Range& in Range?
454 SC_DLLPUBLIC sal_uInt16
Parse( const String
&, ScDocument
* = NULL
,
455 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
456 ScAddress::ExternalInfo
* pExtInfo
= NULL
,
457 const ::com::sun::star::uno::Sequence
<
458 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
460 SC_DLLPUBLIC sal_uInt16
ParseAny( const String
&, ScDocument
* = NULL
,
461 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
462 SC_DLLPUBLIC sal_uInt16
ParseCols( const String
&, ScDocument
* = NULL
,
463 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
464 SC_DLLPUBLIC sal_uInt16
ParseRows( const String
&, ScDocument
* = NULL
,
465 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
);
467 /** Parse an Excel style reference up to and including the sheet name
468 separator '!', including detection of external documents and sheet
469 names, and in case of MOOXML import the bracketed index is used to
470 determine the actual document name passed in pExternalLinks. For
471 internal references (resulting rExternDocName empty), aStart.nTab and
472 aEnd.nTab are set, or -1 if sheet name not found.
473 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
474 encountered results in an error (NULL returned).
475 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
476 NULL for non-filter usage, in which case indices such as [1] are
479 Pointer to the position after '!' if successfully parsed, and
480 rExternDocName, rStartTabName and/or rEndTabName filled if
481 applicable. SCA_... flags set in nFlags.
482 Or if no valid document and/or sheet header could be parsed the start
483 position passed with pString.
484 Or NULL if a 3D sheet header could be parsed but
485 bOnlyAcceptSingle==true was given.
487 const sal_Unicode
* Parse_XL_Header( const sal_Unicode
* pString
, const ScDocument
* pDoc
,
488 String
& rExternDocName
, String
& rStartTabName
, String
& rEndTabName
, sal_uInt16
& nFlags
,
489 bool bOnlyAcceptSingle
,
490 const ::com::sun::star::uno::Sequence
<
491 const ::com::sun::star::sheet::ExternalLinkInfo
> * pExternalLinks
= NULL
);
493 SC_DLLPUBLIC
void Format( String
&, sal_uInt16
= 0, const ScDocument
* = NULL
,
494 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
496 SC_DLLPUBLIC
void Format( OUString
&, sal_uInt16
= 0, const ScDocument
* = NULL
,
497 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
499 inline void GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
500 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const;
501 // The document for the maximum defined sheet number
502 SC_DLLPUBLIC
bool Move( SCsCOL dx
, SCsROW dy
, SCsTAB dz
, ScDocument
* =NULL
);
503 SC_DLLPUBLIC
void Justify();
504 SC_DLLPUBLIC
void ExtendTo( const ScRange
& rRange
);
505 SC_DLLPUBLIC
bool Intersects( const ScRange
& ) const; // do two ranges intersect?
506 inline bool operator==( const ScRange
& r
) const;
507 inline bool operator!=( const ScRange
& r
) const;
508 inline bool operator<( const ScRange
& r
) const;
509 inline bool operator<=( const ScRange
& r
) const;
510 inline bool operator>( const ScRange
& r
) const;
511 inline bool operator>=( const ScRange
& r
) const;
513 /// Hash 2D area ignoring table number.
514 inline size_t hashArea() const;
515 /// Hash start column and start and end rows.
516 inline size_t hashStartColumn() const;
519 inline void ScRange::GetVars( SCCOL
& nCol1
, SCROW
& nRow1
, SCTAB
& nTab1
,
520 SCCOL
& nCol2
, SCROW
& nRow2
, SCTAB
& nTab2
) const
522 aStart
.GetVars( nCol1
, nRow1
, nTab1
);
523 aEnd
.GetVars( nCol2
, nRow2
, nTab2
);
526 inline bool ScRange::operator==( const ScRange
& r
) const
528 return ( (aStart
== r
.aStart
) && (aEnd
== r
.aEnd
) );
531 inline bool ScRange::operator!=( const ScRange
& r
) const
533 return !operator==( r
);
536 /// Sort on upper left corner, if equal then use lower right too.
537 inline bool ScRange::operator<( const ScRange
& r
) const
539 return aStart
< r
.aStart
|| (aStart
== r
.aStart
&& aEnd
< r
.aEnd
) ;
542 inline bool ScRange::operator<=( const ScRange
& r
) const
544 return operator<( r
) || operator==( r
);
547 inline bool ScRange::operator>( const ScRange
& r
) const
549 return !operator<=( r
);
552 inline bool ScRange::operator>=( const ScRange
& r
) const
554 return !operator<( r
);
557 inline bool ScRange::In( const ScAddress
& rAddr
) const
560 aStart
.Col() <= rAddr
.Col() && rAddr
.Col() <= aEnd
.Col() &&
561 aStart
.Row() <= rAddr
.Row() && rAddr
.Row() <= aEnd
.Row() &&
562 aStart
.Tab() <= rAddr
.Tab() && rAddr
.Tab() <= aEnd
.Tab();
565 inline bool ScRange::In( const ScRange
& r
) const
568 aStart
.Col() <= r
.aStart
.Col() && r
.aEnd
.Col() <= aEnd
.Col() &&
569 aStart
.Row() <= r
.aStart
.Row() && r
.aEnd
.Row() <= aEnd
.Row() &&
570 aStart
.Tab() <= r
.aStart
.Tab() && r
.aEnd
.Tab() <= aEnd
.Tab();
574 inline size_t ScRange::hashArea() const
576 // Assume that there are not that many ranges with identical corners so we
577 // won't have too many collisions. Also assume that more lower row and
578 // column numbers are used so that there are not too many conflicts with
579 // the columns hashed into the values, and that start row and column
580 // usually don't exceed certain values. High bits are not masked off and
581 // may overlap with lower bits of other values, e.g. if start column is
582 // greater than assumed.
584 (static_cast<size_t>(aStart
.Row()) << 26) ^ // start row <= 2^6
585 (static_cast<size_t>(aStart
.Col()) << 21) ^ // start column <= 2^5
586 (static_cast<size_t>(aEnd
.Col()) << 15) ^ // end column <= 2^6
587 static_cast<size_t>(aEnd
.Row()); // end row <= 2^15
591 inline size_t ScRange::hashStartColumn() const
593 // Assume that for the start row more lower row numbers are used so that
594 // there are not too many conflicts with the column hashed into the higher
597 (static_cast<size_t>(aStart
.Col()) << 24) ^ // start column <= 2^8
598 (static_cast<size_t>(aStart
.Row()) << 16) ^ // start row <= 2^8
599 static_cast<size_t>(aEnd
.Row());
603 struct ScRangeHashAreaFunctor
605 size_t operator()( const ScRange
& rRange
) const
607 return rRange
.hashArea();
611 struct ScRangeEqualFunctor
613 bool operator()( const ScRange
& rRange1
, const ScRange
& rRange2
) const
615 return rRange1
== rRange2
;
620 // === ScRangePair ===========================================================
629 ScRangePair( const ScRangePair
& r
)
630 { aRange
[0] = r
.aRange
[0]; aRange
[1] = r
.aRange
[1]; }
631 ScRangePair( const ScRange
& r1
, const ScRange
& r2
)
632 { aRange
[0] = r1
; aRange
[1] = r2
; }
634 inline ScRangePair
& operator= ( const ScRangePair
& r
);
635 const ScRange
& GetRange( sal_uInt16 n
) const { return aRange
[n
]; }
636 ScRange
& GetRange( sal_uInt16 n
) { return aRange
[n
]; }
637 inline int operator==( const ScRangePair
& ) const;
638 inline int operator!=( const ScRangePair
& ) const;
641 inline ScRangePair
& ScRangePair::operator= ( const ScRangePair
& r
)
643 aRange
[0] = r
.aRange
[0];
644 aRange
[1] = r
.aRange
[1];
648 inline int ScRangePair::operator==( const ScRangePair
& r
) const
650 return ( (aRange
[0] == r
.aRange
[0]) && (aRange
[1] == r
.aRange
[1]) );
653 inline int ScRangePair::operator!=( const ScRangePair
& r
) const
655 return !operator==( r
);
658 // === ScRefAddress ==========================================================
667 inline ScRefAddress() : bRelCol(false), bRelRow(false), bRelTab(false)
669 inline ScRefAddress( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
670 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
671 aAdr(nCol
, nRow
, nTab
),
672 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
674 inline ScRefAddress( const ScAddress
& rAdr
,
675 bool bRelColP
, bool bRelRowP
, bool bRelTabP
) :
677 bRelCol(bRelColP
), bRelRow(bRelRowP
), bRelTab(bRelTabP
)
679 inline ScRefAddress( const ScRefAddress
& rRef
) :
680 aAdr(rRef
.aAdr
), bRelCol(rRef
.bRelCol
), bRelRow(rRef
.bRelRow
),
681 bRelTab(rRef
.bRelTab
)
684 inline ScRefAddress
& operator=( const ScRefAddress
& );
686 inline bool IsRelCol() const { return bRelCol
; }
687 inline bool IsRelRow() const { return bRelRow
; }
688 inline bool IsRelTab() const { return bRelTab
; }
690 inline void SetRelCol(bool bNewRelCol
) { bRelCol
= bNewRelCol
; }
691 inline void SetRelRow(bool bNewRelRow
) { bRelRow
= bNewRelRow
; }
692 inline void SetRelTab(bool bNewRelTab
) { bRelTab
= bNewRelTab
; }
694 inline void Set( const ScAddress
& rAdr
,
695 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
696 inline void Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
697 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
);
699 inline const ScAddress
& GetAddress() const { return aAdr
; }
700 inline SCCOL
Col() const { return aAdr
.Col(); }
701 inline SCROW
Row() const { return aAdr
.Row(); }
702 inline SCTAB
Tab() const { return aAdr
.Tab(); }
704 inline int operator == ( const ScRefAddress
& r
) const;
705 inline int operator != ( const ScRefAddress
& r
) const
706 { return !(operator==(r
)); }
708 String
GetRefString( ScDocument
* pDoc
, SCTAB nActTab
,
709 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
) const;
712 inline ScRefAddress
& ScRefAddress::operator=( const ScRefAddress
& rRef
)
715 bRelCol
= rRef
.bRelCol
;
716 bRelRow
= rRef
.bRelRow
;
717 bRelTab
= rRef
.bRelTab
;
721 inline void ScRefAddress::Set( const ScAddress
& rAdr
,
722 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
725 bRelCol
= bNewRelCol
;
726 bRelRow
= bNewRelRow
;
727 bRelTab
= bNewRelTab
;
730 inline void ScRefAddress::Set( SCCOL nNewCol
, SCROW nNewRow
, SCTAB nNewTab
,
731 bool bNewRelCol
, bool bNewRelRow
, bool bNewRelTab
)
733 aAdr
.Set( nNewCol
, nNewRow
, nNewTab
);
734 bRelCol
= bNewRelCol
;
735 bRelRow
= bNewRelRow
;
736 bRelTab
= bNewRelTab
;
739 inline int ScRefAddress::operator==( const ScRefAddress
& r
) const
741 return aAdr
== r
.aAdr
&& bRelCol
== r
.bRelCol
&& bRelRow
== r
.bRelRow
&&
742 bRelTab
== r
.bRelTab
;
745 // ===========================================================================
747 // ===========================================================================
749 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
751 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
752 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
754 template< typename T
> void PutInOrder( T
& nStart
, T
& nEnd
)
765 bool ConvertSingleRef( ScDocument
* pDoc
, const String
& rRefString
,
766 SCTAB nDefTab
, ScRefAddress
& rRefAddress
,
767 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
768 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
770 bool ConvertDoubleRef(ScDocument
* pDoc
, const String
& rRefString
,
771 SCTAB nDefTab
, ScRefAddress
& rStartRefAddress
,
772 ScRefAddress
& rEndRefAddress
,
773 const ScAddress::Details
& rDetails
= ScAddress::detailsOOOa1
,
774 ScAddress::ExternalInfo
* pExtInfo
= NULL
);
776 /// append alpha representation of column to buffer
777 SC_DLLPUBLIC
void ScColToAlpha( OUStringBuffer
& rBuffer
, SCCOL nCol
);
779 inline void ScColToAlpha( String
& rStr
, SCCOL nCol
)
781 OUStringBuffer
aBuf(2);
782 ScColToAlpha( aBuf
, nCol
);
783 rStr
.Append( aBuf
.getStr(), static_cast<xub_StrLen
>(aBuf
.getLength()));
786 inline String
ScColToAlpha( SCCOL nCol
)
788 OUStringBuffer
aBuf(2);
789 ScColToAlpha( aBuf
, nCol
);
790 return aBuf
.makeStringAndClear();
793 /// get column number of A..IV... string
794 bool AlphaToCol( SCCOL
& rCol
, const String
& rStr
);
796 #endif // SC_ADDRESS_HXX
798 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */