merged tag ooo/OOO330_m14
[LibreOffice.git] / sc / inc / address.hxx
blobc5d49632292ef853f6104249b502e5a9d942e136
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #ifndef SC_ADDRESS_HXX
29 #define SC_ADDRESS_HXX
31 #include <tools/stream.hxx>
32 #include <tools/string.hxx>
33 #include <tools/solar.h>
34 #include <tools/debug.hxx>
35 #include <rtl/ustrbuf.hxx>
36 #include <osl/endian.h>
38 #ifndef INCLUDED_LIMITS
39 #include <limits>
40 #define INCLUDED_LIMITS
41 #endif
42 #include "scdllapi.h"
43 #include <formula/grammar.hxx>
45 #include <com/sun/star/uno/Sequence.hxx>
47 namespace com { namespace sun { namespace star {
48 namespace sheet {
49 struct ExternalLinkInfo;
51 }}}
53 class ScDocument;
55 // The typedefs
56 typedef sal_Int32 SCROW;
57 typedef sal_Int16 SCCOL;
58 typedef sal_Int16 SCTAB;
59 typedef sal_Int32 SCCOLROW; // a type capable of holding either SCCOL or SCROW
61 // temporarily signed typedefs
62 typedef sal_Int32 SCsROW;
63 typedef sal_Int16 SCsCOL;
64 typedef sal_Int16 SCsTAB;
65 typedef sal_Int32 SCsCOLROW;
67 // size_t typedef to be able to find places where code was changed from USHORT
68 // to size_t and is used to read/write from/to streams.
69 typedef size_t SCSIZE;
71 // Maximum possible value of data type, NOT maximum row value.
72 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
73 // included, we should not be using those stupid macros anyway.
74 #undef min
75 #undef max
76 const SCROW SCROW_MAX = ::std::numeric_limits<SCROW>::max();
77 const SCCOL SCCOL_MAX = ::std::numeric_limits<SCCOL>::max();
78 const SCTAB SCTAB_MAX = ::std::numeric_limits<SCTAB>::max();
79 const SCCOLROW SCCOLROW_MAX = ::std::numeric_limits<SCCOLROW>::max();
80 const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max();
82 // A define to handle critical sections we hopefully don't need very often.
83 #define SC_ROWLIMIT_MORE_THAN_32K 1 /* set to 1 if we throw the switch */
85 // The maximum values. Defines are needed for preprocessor checks, for example
86 // in bcaslot.cxx, otherwise type safe constants are preferred.
87 //#define MAXROWCOUNT_DEFINE 65536
88 #define MAXROWCOUNT_DEFINE 1048576
89 #define MAXCOLCOUNT_DEFINE 1024
91 // Count values
92 const SCROW MAXROWCOUNT = MAXROWCOUNT_DEFINE;
93 const SCCOL MAXCOLCOUNT = MAXCOLCOUNT_DEFINE;
94 const SCTAB MAXTABCOUNT = 256;
95 const SCCOLROW MAXCOLROWCOUNT = MAXROWCOUNT;
96 // Maximum values
97 const SCROW MAXROW = MAXROWCOUNT - 1;
98 const SCCOL MAXCOL = MAXCOLCOUNT - 1;
99 const SCTAB MAXTAB = MAXTABCOUNT - 1;
100 const SCCOLROW MAXCOLROW = MAXROW;
103 // Special values
104 const SCTAB SC_TAB_APPEND = SCTAB_MAX;
105 const SCTAB TABLEID_DOC = SCTAB_MAX; // entire document, e.g. protect
106 const SCROW SCROWS32K = 32000;
107 const SCCOL SCCOL_REPEAT_NONE = SCCOL_MAX;
108 const SCROW SCROW_REPEAT_NONE = SCROW_MAX;
111 // We hope to get rid of the binary file format. If not, these are the places
112 // we'd have to investigate because variable types changed. Just place code in
113 // #if SC_ROWLIMIT_STREAM_ACCESS for now.
114 #define SC_ROWLIMIT_STREAM_ACCESS 0
115 // usage:
116 //#if SC_ROWLIMIT_STREAM_ACCESS
117 //#error address types changed!
118 //... code ...
119 //#endif // SC_ROWLIMIT_STREAM_ACCESS
122 // For future reference, place in code where more than 64k rows would need a
123 // special handling:
124 // #if SC_ROWLIMIT_MORE_THAN_64K
125 // #error row limit 64k
126 // #endif
127 #if MAXROWCOUNT_DEFINE > 65536
128 #define SC_ROWLIMIT_MORE_THAN_64K 1
129 #else
130 #define SC_ROWLIMIT_MORE_THAN_64K 0
131 #endif
132 const SCROW SCROWS64K = 65536;
134 // === old stuff defines =====================================================
136 #ifdef WIN
137 // Under 16bit Windows rows still had to be limited to 8192.
138 // (define manually for testing)
139 #define SC_LIMIT_ROWS
140 #endif
142 #define MAXROW_30 8191
143 #define MAXROW_40 31999
145 #ifdef SC_LIMIT_ROWS
146 #undef MAXROWCOUNT_DEFINE
147 #define MAXROWCOUNT_DEFINE 8192
148 const SCROW W16MAXROWCOUNT = MAXROWCOUNT_DEFINE;
149 const SCROW W16MAXROW = W16MAXROWCOUNT - 1;
150 #define MAXROWCOUNT W16MAXROWCOUNT
151 #define MAXROW W16MAXROW
152 #endif
154 #define VALIDCOL(nCol) (ValidCol(nCol))
155 #define VALIDROW(nRow) (ValidRow(nRow))
156 #define VALIDTAB(nTab) (ValidTab(nTab))
157 #define VALIDCOLROW(nCol,nRow) (ValidColRow(nCol,nRow))
158 #define VALIDCOLROWTAB(nCol,nRow,nTab) (ValidColRowTab(nCol,nRow,nTab))
160 // === old stuff defines end =================================================
162 inline bool ValidCol( SCCOL nCol )
164 return static_cast<SCCOL>(0) <= nCol && nCol <= MAXCOL;
167 inline bool ValidRow( SCROW nRow )
169 return static_cast<SCROW>(0) <= nRow && nRow <= MAXROW;
172 inline bool ValidTab( SCTAB nTab )
174 return static_cast<SCTAB>(0) <= nTab && nTab <= MAXTAB;
177 inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
179 return static_cast<SCTAB>(0) <= nTab && nTab <= nMaxTab;
182 inline bool ValidColRow( SCCOL nCol, SCROW nRow )
184 return ValidCol( nCol) && ValidRow( nRow);
187 inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab )
189 return ValidCol( nCol) && ValidRow( nRow) && ValidTab( nTab);
192 inline SCCOL SanitizeCol( SCCOL nCol )
194 return nCol < 0 ? 0 : (nCol > MAXCOL ? MAXCOL : nCol);
197 inline SCROW SanitizeRow( SCROW nRow )
199 return nRow < 0 ? 0 : (nRow > MAXROW ? MAXROW : nRow);
202 inline SCTAB SanitizeTab( SCTAB nTab )
204 return nTab < 0 ? 0 : (nTab > MAXTAB ? MAXTAB : nTab);
207 inline SCTAB SanitizeTab( SCTAB nTab, SCTAB nMaxTab )
209 return nTab < 0 ? 0 : (nTab > nMaxTab ? nMaxTab : nTab);
212 // === ScAddress =============================================================
214 // The old cell address is combined in one UINT32:
215 // +---+---+-------+
216 // |Tab|Col| Row |
217 // +---+---+-------+
218 // For speed reasons access isn't done by shifting bits but by using platform
219 // dependent casts, which unfortunately also leads to aliasing problems when
220 // not using gcc -fno-strict-aliasing
222 // The result of ConvertRef() is a bit group of the following:
224 #define SCA_COL_ABSOLUTE 0x01
225 #define SCA_ROW_ABSOLUTE 0x02
226 #define SCA_TAB_ABSOLUTE 0x04
227 #define SCA_TAB_3D 0x08
228 #define SCA_COL2_ABSOLUTE 0x10
229 #define SCA_ROW2_ABSOLUTE 0x20
230 #define SCA_TAB2_ABSOLUTE 0x40
231 #define SCA_TAB2_3D 0x80
232 #define SCA_VALID_ROW 0x0100
233 #define SCA_VALID_COL 0x0200
234 #define SCA_VALID_TAB 0x0400
235 // somewhat cheesy kludge to force the display of the document name even for
236 // local references. Requires TAB_3D to be valid
237 #define SCA_FORCE_DOC 0x0800
238 #define SCA_VALID_ROW2 0x1000
239 #define SCA_VALID_COL2 0x2000
240 #define SCA_VALID_TAB2 0x4000
241 #define SCA_VALID 0x8000
243 #define SCA_ABS SCA_VALID \
244 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
246 #define SCR_ABS SCA_ABS \
247 | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
249 #define SCA_ABS_3D SCA_ABS | SCA_TAB_3D
250 #define SCR_ABS_3D SCR_ABS | SCA_TAB_3D
252 // === ScAddress =============================================================
254 class ScAddress
256 private:
257 SCROW nRow;
258 SCCOL nCol;
259 SCTAB nTab;
261 public:
263 enum Uninitialized { UNINITIALIZED };
264 enum InitializeInvalid { INITIALIZE_INVALID };
266 struct Details {
267 formula::FormulaGrammar::AddressConvention eConv;
268 SCROW nRow;
269 SCCOL nCol;
270 inline Details( formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP )
271 : eConv( eConvP ), nRow( nRowP ), nCol( nColP )
273 inline Details( formula::FormulaGrammar::AddressConvention eConvP, ScAddress const & rAddr )
274 : eConv( eConvP ), nRow( rAddr.Row() ), nCol( rAddr.Col() )
276 inline Details( formula::FormulaGrammar::AddressConvention eConvP)
277 : eConv( eConvP ), nRow( 0 ), nCol( 0 )
279 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
280 Details( const ScDocument* pDoc, const ScAddress & rAddr );
281 //UNUSED2009-05 void SetPos( const ScDocument* pDoc, const ScAddress & rAddr );
283 SC_DLLPUBLIC static const Details detailsOOOa1;
285 struct ExternalInfo
287 String maTabName;
288 sal_uInt16 mnFileId;
289 bool mbExternal;
291 inline ExternalInfo() : mnFileId(0), mbExternal(false) {}
294 inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
295 inline ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
296 : nRow(nRowP), nCol(nColP), nTab(nTabP)
298 /** Yes, it is what it seems to be: Uninitialized. May be used for
299 performance reasons if it is initialized by other means. */
300 inline ScAddress( Uninitialized ) {}
301 inline ScAddress( InitializeInvalid )
302 : nRow(-1), nCol(-1), nTab(-1) {}
303 inline ScAddress( const ScAddress& r )
304 : nRow(r.nRow), nCol(r.nCol), nTab(r.nTab)
306 inline ScAddress& operator=( const ScAddress& r );
308 inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
309 inline SCROW Row() const { return nRow; }
310 inline SCCOL Col() const { return nCol; }
311 inline SCTAB Tab() const { return nTab; }
312 inline void SetRow( SCROW nRowP ) { nRow = nRowP; }
313 inline void SetCol( SCCOL nColP ) { nCol = nColP; }
314 inline void SetTab( SCTAB nTabP ) { nTab = nTabP; }
315 inline void SetInvalid() { nRow = -1; nCol = -1; nTab = -1; }
316 inline bool IsValid() const { return (nRow >= 0) && (nCol >= 0) && (nTab >= 0); }
317 inline void PutInOrder( ScAddress& r );
318 inline void IncRow( SCsROW n=1 ) { nRow = sal::static_int_cast<SCROW>(nRow + n); }
319 inline void IncCol( SCsCOL n=1 ) { nCol = sal::static_int_cast<SCCOL>(nCol + n); }
320 inline void IncTab( SCsTAB n=1 ) { nTab = sal::static_int_cast<SCTAB>(nTab + n); }
321 inline void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
322 { nColP = nCol; nRowP = nRow; nTabP = nTab; }
324 SC_DLLPUBLIC USHORT Parse( const String&, ScDocument* = NULL,
325 const Details& rDetails = detailsOOOa1,
326 ExternalInfo* pExtInfo = NULL,
327 const ::com::sun::star::uno::Sequence<
328 const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
330 SC_DLLPUBLIC void Format( String&, USHORT = 0, ScDocument* = NULL,
331 const Details& rDetails = detailsOOOa1) const;
333 // The document for the maximum defined sheet number
334 SC_DLLPUBLIC bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
335 inline bool operator==( const ScAddress& r ) const;
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;
342 inline size_t hash() const;
344 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
345 String GetColRowString( bool bAbsolute = FALSE,
346 const Details& rDetails = detailsOOOa1) const;
349 inline void ScAddress::PutInOrder( ScAddress& r )
351 if ( r.Col() < Col() )
353 SCCOL nTmp = r.Col();
354 r.SetCol( Col() );
355 SetCol( nTmp );
357 if ( r.Row() < Row() )
359 SCROW nTmp = r.Row();
360 r.SetRow( Row() );
361 SetRow( nTmp );
363 if ( r.Tab() < Tab() )
365 SCTAB nTmp = r.Tab();
366 r.SetTab( Tab() );
367 SetTab( nTmp );
371 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
373 nCol = nColP;
374 nRow = nRowP;
375 nTab = nTabP;
378 inline ScAddress& ScAddress::operator=( const ScAddress& r )
380 nCol = r.nCol;
381 nRow = r.nRow;
382 nTab = r.nTab;
383 return *this;
386 inline bool ScAddress::operator==( const ScAddress& r ) const
388 return nRow == r.nRow && nCol == r.nCol && nTab == r.nTab;
391 inline bool ScAddress::operator!=( const ScAddress& r ) const
393 return !operator==( r );
396 inline bool ScAddress::operator<( const ScAddress& r ) const
398 // Same behavior as the old UINT32 nAddress < r.nAddress with encoded
399 // tab|col|row bit fields.
400 if (nTab == r.nTab)
402 if (nCol == r.nCol)
403 return nRow < r.nRow;
404 else
405 return nCol < r.nCol;
407 else
408 return nTab < r.nTab;
411 inline bool ScAddress::operator<=( const ScAddress& r ) const
413 return operator<( r ) || operator==( r );
416 inline bool ScAddress::operator>( const ScAddress& r ) const
418 return !operator<=( r );
421 inline bool ScAddress::operator>=( const ScAddress& r ) const
423 return !operator<( r );
427 inline size_t ScAddress::hash() const
429 // Assume that there are not that many addresses with row > 2^16 AND column
430 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
431 if (nRow <= 0xffff)
432 return (static_cast<size_t>(nTab) << 24) ^
433 (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
434 else
435 return (static_cast<size_t>(nTab) << 28) ^
436 (static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
439 struct ScAddressHashFunctor
441 size_t operator()( const ScAddress & rAdr ) const
443 return rAdr.hash();
447 struct ScAddressEqualFunctor
449 bool operator()( const ScAddress & rAdr1, const ScAddress & rAdr2 ) const
451 return rAdr1 == rAdr2;
456 // === ScRange ===============================================================
458 class ScRange
460 public:
461 ScAddress aStart, aEnd;
462 inline ScRange() : aStart(), aEnd() {}
463 inline ScRange( ScAddress::Uninitialized e )
464 : aStart( e ), aEnd( e ) {}
465 inline ScRange( ScAddress::InitializeInvalid e )
466 : aStart( e ), aEnd( e ) {}
467 inline ScRange( const ScAddress& s, const ScAddress& e )
468 : aStart( s ), aEnd( e ) { aStart.PutInOrder( aEnd ); }
469 inline ScRange( const ScRange& r ) : aStart( r.aStart ), aEnd( r.aEnd ) {}
470 inline ScRange( const ScAddress& r ) : aStart( r ), aEnd( r ) {}
471 inline ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab )
472 : aStart( nCol, nRow, nTab ), aEnd( aStart ) {}
473 inline ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
474 SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
475 : aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 ) {}
477 inline ScRange& operator=( const ScRange& r )
478 { aStart = r.aStart; aEnd = r.aEnd; return *this; }
479 inline ScRange& operator=( const ScAddress& rPos )
480 { aStart = aEnd = rPos; return *this; }
481 inline void SetInvalid() { aStart.SetInvalid(); aEnd.SetInvalid(); }
482 inline bool IsValid() const { return aStart.IsValid() && aEnd.IsValid(); }
483 inline bool In( const ScAddress& ) const; // is Address& in Range?
484 inline bool In( const ScRange& ) const; // is Range& in Range?
486 USHORT Parse( const String&, ScDocument* = NULL,
487 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
488 ScAddress::ExternalInfo* pExtInfo = NULL,
489 const ::com::sun::star::uno::Sequence<
490 const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
492 USHORT ParseAny( const String&, ScDocument* = NULL,
493 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
494 SC_DLLPUBLIC USHORT ParseCols( const String&, ScDocument* = NULL,
495 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
496 SC_DLLPUBLIC USHORT ParseRows( const String&, ScDocument* = NULL,
497 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
499 /** Parse an Excel style reference up to and including the sheet name
500 separator '!', including detection of external documents and sheet
501 names, and in case of MOOXML import the bracketed index is used to
502 determine the actual document name passed in pExternalLinks. For
503 internal references (resulting rExternDocName empty), aStart.nTab and
504 aEnd.nTab are set, or -1 if sheet name not found.
505 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
506 encountered results in an error (NULL returned).
507 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
508 NULL for non-filter usage, in which case indices such as [1] are
509 not resolved.
510 @returns
511 Pointer to the position after '!' if successfully parsed, and
512 rExternDocName, rStartTabName and/or rEndTabName filled if
513 applicable. SCA_... flags set in nFlags.
514 Or if no valid document and/or sheet header could be parsed the start
515 position passed with pString.
516 Or NULL if a 3D sheet header could be parsed but
517 bOnlyAcceptSingle==true was given.
519 const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument* pDoc,
520 String& rExternDocName, String& rStartTabName, String& rEndTabName, USHORT& nFlags,
521 bool bOnlyAcceptSingle,
522 const ::com::sun::star::uno::Sequence<
523 const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
525 SC_DLLPUBLIC void Format( String&, USHORT = 0, ScDocument* = NULL,
526 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 ) const;
528 inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
529 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
530 // The document for the maximum defined sheet number
531 SC_DLLPUBLIC bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
532 SC_DLLPUBLIC void Justify();
533 SC_DLLPUBLIC void ExtendTo( const ScRange& rRange );
534 SC_DLLPUBLIC bool Intersects( const ScRange& ) const; // do two ranges intersect?
535 inline bool operator==( const ScRange& r ) const;
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;
542 /// Hash 2D area ignoring table number.
543 inline size_t hashArea() const;
544 /// Hash start column and start and end rows.
545 inline size_t hashStartColumn() const;
548 inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
549 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
551 aStart.GetVars( nCol1, nRow1, nTab1 );
552 aEnd.GetVars( nCol2, nRow2, nTab2 );
555 inline bool ScRange::operator==( const ScRange& r ) const
557 return ( (aStart == r.aStart) && (aEnd == r.aEnd) );
560 inline bool ScRange::operator!=( const ScRange& r ) const
562 return !operator==( r );
565 // Sort on upper left corner, if equal then use lower right too.
566 inline bool ScRange::operator<( const ScRange& r ) const
568 return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
571 inline bool ScRange::operator<=( const ScRange& r ) const
573 return operator<( r ) || operator==( r );
576 inline bool ScRange::operator>( const ScRange& r ) const
578 return !operator<=( r );
581 inline bool ScRange::operator>=( const ScRange& r ) const
583 return !operator<( r );
586 inline bool ScRange::In( const ScAddress& rAddr ) const
588 return
589 aStart.Col() <= rAddr.Col() && rAddr.Col() <= aEnd.Col() &&
590 aStart.Row() <= rAddr.Row() && rAddr.Row() <= aEnd.Row() &&
591 aStart.Tab() <= rAddr.Tab() && rAddr.Tab() <= aEnd.Tab();
594 inline bool ScRange::In( const ScRange& r ) const
596 return
597 aStart.Col() <= r.aStart.Col() && r.aEnd.Col() <= aEnd.Col() &&
598 aStart.Row() <= r.aStart.Row() && r.aEnd.Row() <= aEnd.Row() &&
599 aStart.Tab() <= r.aStart.Tab() && r.aEnd.Tab() <= aEnd.Tab();
603 inline size_t ScRange::hashArea() const
605 // Assume that there are not that many ranges with identical corners so we
606 // won't have too many collisions. Also assume that more lower row and
607 // column numbers are used so that there are not too many conflicts with
608 // the columns hashed into the values, and that start row and column
609 // usually don't exceed certain values. High bits are not masked off and
610 // may overlap with lower bits of other values, e.g. if start column is
611 // greater than assumed.
612 return
613 (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
614 (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
615 (static_cast<size_t>(aEnd.Col()) << 15) ^ // end column <= 2^6
616 static_cast<size_t>(aEnd.Row()); // end row <= 2^15
620 inline size_t ScRange::hashStartColumn() const
622 // Assume that for the start row more lower row numbers are used so that
623 // there are not too many conflicts with the column hashed into the higher
624 // values.
625 return
626 (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
627 (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
628 static_cast<size_t>(aEnd.Row());
632 struct ScRangeHashAreaFunctor
634 size_t operator()( const ScRange & rRange ) const
636 return rRange.hashArea();
640 struct ScRangeEqualFunctor
642 bool operator()( const ScRange & rRange1, const ScRange & rRange2 ) const
644 return rRange1 == rRange2;
649 // === ScRangePair ===========================================================
651 class ScRangePair
653 private:
654 ScRange aRange[2];
656 public:
657 ScRangePair() {}
658 ScRangePair( const ScRangePair& r )
659 { aRange[0] = r.aRange[0]; aRange[1] = r.aRange[1]; }
660 ScRangePair( const ScRange& r1, const ScRange& r2 )
661 { aRange[0] = r1; aRange[1] = r2; }
663 inline ScRangePair& operator= ( const ScRangePair& r );
664 const ScRange& GetRange( USHORT n ) const { return aRange[n]; }
665 ScRange& GetRange( USHORT n ) { return aRange[n]; }
666 inline int operator==( const ScRangePair& ) const;
667 inline int operator!=( const ScRangePair& ) const;
670 inline ScRangePair& ScRangePair::operator= ( const ScRangePair& r )
672 aRange[0] = r.aRange[0];
673 aRange[1] = r.aRange[1];
674 return *this;
677 inline int ScRangePair::operator==( const ScRangePair& r ) const
679 return ( (aRange[0] == r.aRange[0]) && (aRange[1] == r.aRange[1]) );
682 inline int ScRangePair::operator!=( const ScRangePair& r ) const
684 return !operator==( r );
687 // === ScRefAddress ==========================================================
689 class ScRefAddress
691 ScAddress aAdr;
692 bool bRelCol;
693 bool bRelRow;
694 bool bRelTab;
695 public:
696 inline ScRefAddress() : bRelCol(false), bRelRow(false), bRelTab(false)
698 inline ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab,
699 bool bRelColP, bool bRelRowP, bool bRelTabP ) :
700 aAdr(nCol, nRow, nTab),
701 bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
703 inline ScRefAddress( const ScAddress& rAdr,
704 bool bRelColP, bool bRelRowP, bool bRelTabP ) :
705 aAdr(rAdr),
706 bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
708 inline ScRefAddress( const ScRefAddress& rRef ) :
709 aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
710 bRelTab(rRef.bRelTab)
713 inline ScRefAddress& operator=( const ScRefAddress& );
715 inline bool IsRelCol() const { return bRelCol; }
716 inline bool IsRelRow() const { return bRelRow; }
717 inline bool IsRelTab() const { return bRelTab; }
719 inline void SetRelCol(bool bNewRelCol) { bRelCol = bNewRelCol; }
720 inline void SetRelRow(bool bNewRelRow) { bRelRow = bNewRelRow; }
721 inline void SetRelTab(bool bNewRelTab) { bRelTab = bNewRelTab; }
723 inline void Set( const ScAddress& rAdr,
724 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
725 inline void Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
726 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
728 inline const ScAddress& GetAddress() const { return aAdr; }
729 inline SCCOL Col() const { return aAdr.Col(); }
730 inline SCROW Row() const { return aAdr.Row(); }
731 inline SCTAB Tab() const { return aAdr.Tab(); }
733 inline int operator == ( const ScRefAddress& r ) const;
734 inline int operator != ( const ScRefAddress& r ) const
735 { return !(operator==(r)); }
737 String GetRefString( ScDocument* pDoc, SCTAB nActTab,
738 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
741 inline ScRefAddress& ScRefAddress::operator=( const ScRefAddress& rRef )
743 aAdr = rRef.aAdr;
744 bRelCol = rRef.bRelCol;
745 bRelRow = rRef.bRelRow;
746 bRelTab = rRef.bRelTab;
747 return *this;
750 inline void ScRefAddress::Set( const ScAddress& rAdr,
751 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
753 aAdr = rAdr;
754 bRelCol = bNewRelCol;
755 bRelRow = bNewRelRow;
756 bRelTab = bNewRelTab;
759 inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
760 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
762 aAdr.Set( nNewCol, nNewRow, nNewTab);
763 bRelCol = bNewRelCol;
764 bRelRow = bNewRelRow;
765 bRelTab = bNewRelTab;
768 inline int ScRefAddress::operator==( const ScRefAddress& r ) const
770 return aAdr == r.aAdr && bRelCol == r.bRelCol && bRelRow == r.bRelRow &&
771 bRelTab == r.bRelTab;
774 // ===========================================================================
775 // Global functions
776 // ===========================================================================
778 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
779 // and the like).
780 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
781 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
783 template< typename T > void PutInOrder( T& nStart, T& nEnd )
785 if (nEnd < nStart)
787 T nTemp;
788 nTemp = nEnd;
789 nEnd = nStart;
790 nStart = nTemp;
794 bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
795 SCTAB nDefTab, ScRefAddress& rRefAddress,
796 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
797 ScAddress::ExternalInfo* pExtInfo = NULL );
799 bool ConvertDoubleRef(ScDocument* pDoc, const String& rRefString,
800 SCTAB nDefTab, ScRefAddress& rStartRefAddress,
801 ScRefAddress& rEndRefAddress,
802 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
803 ScAddress::ExternalInfo* pExtInfo = NULL );
805 /// append alpha representation of column to buffer
806 SC_DLLPUBLIC void ScColToAlpha( rtl::OUStringBuffer& rBuffer, SCCOL nCol);
808 inline void ScColToAlpha( String& rStr, SCCOL nCol)
810 rtl::OUStringBuffer aBuf(2);
811 ScColToAlpha( aBuf, nCol);
812 rStr.Append( aBuf.getStr(), static_cast<xub_StrLen>(aBuf.getLength()));
815 inline String ScColToAlpha( SCCOL nCol )
817 rtl::OUStringBuffer aBuf(2);
818 ScColToAlpha( aBuf, nCol);
819 return aBuf.makeStringAndClear();
822 /// get column number of A..IV... string
823 bool AlphaToCol( SCCOL& rCol, const String& rStr);
825 #endif // SC_ADDRESS_HXX