Bump version to 4.3-4
[LibreOffice.git] / sc / inc / address.hxx
blob2018dfed9a499d385809cf4d36048e2bb9585110
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 INCLUDED_SC_INC_ADDRESS_HXX
21 #define INCLUDED_SC_INC_ADDRESS_HXX
23 #include <tools/stream.hxx>
24 #include <rtl/ustrbuf.hxx>
25 #include <osl/endian.h>
27 #include <limits>
28 #include "scdllapi.h"
29 #include "types.hxx"
30 #include <formula/grammar.hxx>
32 #include <com/sun/star/uno/Sequence.hxx>
34 namespace com { namespace sun { namespace star {
35 namespace sheet {
36 struct ExternalLinkInfo;
38 }}}
40 class ScDocument;
42 /** size_t typedef to be able to find places where code was changed from USHORT
43 to size_t and is used to read/write from/to streams. */
44 typedef size_t SCSIZE;
46 // Maximum possible value of data type, NOT maximum row value.
47 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
48 // included, we should not be using those stupid macros anyway.
49 #undef min
50 #undef max
51 const SCROW SCROW_MAX = ::std::numeric_limits<SCROW>::max();
52 const SCCOL SCCOL_MAX = ::std::numeric_limits<SCCOL>::max();
53 const SCTAB SCTAB_MAX = ::std::numeric_limits<SCTAB>::max();
54 const SCCOLROW SCCOLROW_MAX = ::std::numeric_limits<SCCOLROW>::max();
55 const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max();
57 // The maximum values. Defines are needed for preprocessor checks, for example
58 // in bcaslot.cxx, otherwise type safe constants are preferred.
59 #define MAXROWCOUNT_DEFINE 1048576
60 #define MAXCOLCOUNT_DEFINE 1024
62 // Count values
63 const SCROW MAXROWCOUNT = MAXROWCOUNT_DEFINE;
64 const SCCOL MAXCOLCOUNT = MAXCOLCOUNT_DEFINE;
65 /// limiting to 10000 for now, problem with 32 bit builds for now
66 const SCTAB MAXTABCOUNT = 10000;
67 const SCCOLROW MAXCOLROWCOUNT = MAXROWCOUNT;
68 // Maximum values
69 const SCROW MAXROW = MAXROWCOUNT - 1;
70 const SCCOL MAXCOL = MAXCOLCOUNT - 1;
71 const SCTAB MAXTAB = MAXTABCOUNT - 1;
72 const SCCOLROW MAXCOLROW = MAXROW;
73 // Limit the initial tab count to prevent users to set the count too high,
74 // which could cause the memory usage of blank documents to exceed the
75 // available system memory.
76 const SCTAB MAXINITTAB = 1024;
77 const SCTAB MININITTAB = 1;
79 // Special values
80 const SCTAB SC_TAB_APPEND = SCTAB_MAX;
81 const SCTAB TABLEID_DOC = SCTAB_MAX; // entire document, e.g. protect
82 const SCROW SCROWS32K = 32000;
83 const SCCOL SCCOL_REPEAT_NONE = SCCOL_MAX;
84 const SCROW SCROW_REPEAT_NONE = SCROW_MAX;
86 // For future reference, place in code where more than 64k rows would need a
87 // special handling:
88 // #if SC_ROWLIMIT_MORE_THAN_64K
89 // #error row limit 64k
90 // #endif
91 #if MAXROWCOUNT_DEFINE > 65536
92 #define SC_ROWLIMIT_MORE_THAN_64K 1
93 #else
94 #define SC_ROWLIMIT_MORE_THAN_64K 0
95 #endif
96 const SCROW SCROWS64K = 65536;
98 // old stuff defines
99 #define MAXROW_30 8191
101 #ifdef SC_LIMIT_ROWS
102 #undef MAXROWCOUNT_DEFINE
103 #define MAXROWCOUNT_DEFINE 8192
104 const SCROW W16MAXROWCOUNT = MAXROWCOUNT_DEFINE;
105 const SCROW W16MAXROW = W16MAXROWCOUNT - 1;
106 #define MAXROWCOUNT W16MAXROWCOUNT
107 #define MAXROW W16MAXROW
108 #endif
110 // old stuff defines end
111 SAL_WARN_UNUSED_RESULT inline bool ValidCol( SCCOL nCol )
113 return static_cast<SCCOL>(0) <= nCol && nCol <= MAXCOL;
116 SAL_WARN_UNUSED_RESULT inline bool ValidRow( SCROW nRow )
118 return static_cast<SCROW>(0) <= nRow && nRow <= MAXROW;
121 SAL_WARN_UNUSED_RESULT inline bool ValidTab( SCTAB nTab )
123 return static_cast<SCTAB>(0) <= nTab && nTab <= MAXTAB;
126 SAL_WARN_UNUSED_RESULT inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
128 return static_cast<SCTAB>(0) <= nTab && nTab <= nMaxTab;
131 SAL_WARN_UNUSED_RESULT inline bool ValidColRow( SCCOL nCol, SCROW nRow )
133 return ValidCol( nCol) && ValidRow( nRow);
136 SAL_WARN_UNUSED_RESULT inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab )
138 return ValidCol( nCol) && ValidRow( nRow) && ValidTab( nTab);
141 SAL_WARN_UNUSED_RESULT inline SCCOL SanitizeCol( SCCOL nCol )
143 return nCol < 0 ? 0 : (nCol > MAXCOL ? MAXCOL : nCol);
146 SAL_WARN_UNUSED_RESULT inline SCROW SanitizeRow( SCROW nRow )
148 return nRow < 0 ? 0 : (nRow > MAXROW ? MAXROW : nRow);
151 SAL_WARN_UNUSED_RESULT inline SCTAB SanitizeTab( SCTAB nTab )
153 return nTab < 0 ? 0 : (nTab > MAXTAB ? MAXTAB : nTab);
156 SAL_WARN_UNUSED_RESULT inline SCTAB SanitizeTab( SCTAB nTab, SCTAB nMaxTab )
158 return nTab < 0 ? 0 : (nTab > nMaxTab ? nMaxTab : nTab);
161 // ScAddress
162 // The old cell address is combined in one UINT32:
163 // +---+---+-------+
164 // |Tab|Col| Row |
165 // +---+---+-------+
166 // For speed reasons access isn't done by shifting bits but by using platform
167 // dependent casts, which unfortunately also leads to aliasing problems when
168 // not using gcc -fno-strict-aliasing
170 // The result of ConvertRef() is a bit group of the following:
172 #define SCA_COL_ABSOLUTE 0x01
173 #define SCA_ROW_ABSOLUTE 0x02
174 #define SCA_TAB_ABSOLUTE 0x04
175 #define SCA_TAB_3D 0x08
176 #define SCA_COL2_ABSOLUTE 0x10
177 #define SCA_ROW2_ABSOLUTE 0x20
178 #define SCA_TAB2_ABSOLUTE 0x40
179 #define SCA_TAB2_3D 0x80
180 #define SCA_VALID_ROW 0x0100
181 #define SCA_VALID_COL 0x0200
182 #define SCA_VALID_TAB 0x0400
183 // SCA_BITS is a convience for
184 // (SCA_VALID_TAB | SCA_VALID_COL | SCA_VALID_ROW | SCA_TAB_3D | SCA_TAB_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_COL_ABSOLUTE)
185 #define SCA_BITS 0x070F
186 // somewhat cheesy kludge to force the display of the document name even for
187 // local references. Requires TAB_3D to be valid
188 #define SCA_FORCE_DOC 0x0800
189 #define SCA_VALID_ROW2 0x1000
190 #define SCA_VALID_COL2 0x2000
191 #define SCA_VALID_TAB2 0x4000
192 #define SCA_VALID 0x8000
194 #define SCA_ABS SCA_VALID | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
196 #define SCR_ABS SCA_ABS | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
198 #define SCA_ABS_3D SCA_ABS | SCA_TAB_3D
199 #define SCR_ABS_3D SCR_ABS | SCA_TAB_3D
201 // ScAddress
202 class ScAddress
204 private:
205 SCROW nRow;
206 SCCOL nCol;
207 SCTAB nTab;
209 public:
211 enum Uninitialized { UNINITIALIZED };
212 enum InitializeInvalid { INITIALIZE_INVALID };
214 struct Details
216 formula::FormulaGrammar::AddressConvention eConv;
217 SCROW nRow;
218 SCCOL nCol;
220 inline Details( formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP ) :
221 eConv(eConvP), nRow(nRowP), nCol(nColP)
223 inline Details( formula::FormulaGrammar::AddressConvention eConvP, ScAddress const & rAddr ) :
224 eConv(eConvP), nRow(rAddr.Row()), nCol(rAddr.Col())
226 inline Details( formula::FormulaGrammar::AddressConvention eConvP) :
227 eConv(eConvP), nRow(0), nCol(0)
229 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
230 Details( const ScDocument* pDoc, const ScAddress & rAddr );
232 SC_DLLPUBLIC static const Details detailsOOOa1;
234 struct ExternalInfo
236 OUString maTabName;
237 sal_uInt16 mnFileId;
238 bool mbExternal;
240 inline ExternalInfo() :
241 mnFileId(0), mbExternal(false)
245 inline ScAddress() :
246 nRow(0), nCol(0), nTab(0)
248 inline ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP ) :
249 nRow(nRowP), nCol(nColP), nTab(nTabP)
251 /** Yes, it is what it seems to be: Uninitialized. May be used for
252 performance reasons if it is initialized by other means. */
253 inline ScAddress( Uninitialized )
255 inline ScAddress( InitializeInvalid ) :
256 nRow(-1), nCol(-1), nTab(-1)
258 inline ScAddress( const ScAddress& rAddress ) :
259 nRow(rAddress.nRow), nCol(rAddress.nCol), nTab(rAddress.nTab)
261 inline ScAddress& operator=( const ScAddress& rAddress );
263 inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
265 inline SCROW Row() const
267 return nRow;
270 inline SCCOL Col() const
272 return nCol;
274 inline SCTAB Tab() const
276 return nTab;
278 inline void SetRow( SCROW nRowP )
280 nRow = nRowP;
282 inline void SetCol( SCCOL nColP )
284 nCol = nColP;
286 inline void SetTab( SCTAB nTabP )
288 nTab = nTabP;
290 inline void SetInvalid()
292 nRow = -1;
293 nCol = -1;
294 nTab = -1;
296 inline bool IsValid() const
298 return (nRow >= 0) && (nCol >= 0) && (nTab >= 0);
301 inline void PutInOrder( ScAddress& rAddress );
303 inline void IncRow( SCsROW nDelta = 1 )
305 nRow = sal::static_int_cast<SCROW>(nRow + nDelta);
307 inline void IncCol( SCsCOL nDelta = 1 )
309 nCol = sal::static_int_cast<SCCOL>(nCol + nDelta);
311 inline void IncTab( SCsTAB nDelta = 1 )
313 nTab = sal::static_int_cast<SCTAB>(nTab + nDelta);
315 inline void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
317 nColP = nCol;
318 nRowP = nRow;
319 nTabP = nTab;
322 SC_DLLPUBLIC sal_uInt16 Parse(
323 const OUString&, ScDocument* = NULL,
324 const Details& rDetails = detailsOOOa1,
325 ExternalInfo* pExtInfo = NULL,
326 const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = NULL );
328 SC_DLLPUBLIC OUString Format( sal_uInt16 nFlags = 0,
329 const ScDocument* pDocument = NULL,
330 const Details& rDetails = detailsOOOa1) const;
332 // The document for the maximum defined sheet number
333 SC_DLLPUBLIC bool Move( SCsCOL nDeltaX, SCsROW nDeltaY, SCsTAB nDeltaZ,
334 ScDocument* pDocument = NULL );
336 inline bool operator==( const ScAddress& rAddress ) const;
337 inline bool operator!=( const ScAddress& rAddress ) const;
338 inline bool operator<( const ScAddress& rAddress ) const;
339 inline bool operator<=( const ScAddress& rAddress ) const;
340 inline bool operator>( const ScAddress& rAddress ) const;
341 inline bool operator>=( const ScAddress& rAddress ) const;
343 inline size_t hash() const;
345 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
346 OUString GetColRowString( bool bAbsolute = false,
347 const Details& rDetails = detailsOOOa1) const;
350 inline void ScAddress::PutInOrder( ScAddress& rAddress )
352 if ( rAddress.Col() < Col() )
354 SCCOL nTmp = rAddress.Col();
355 rAddress.SetCol( Col() );
356 SetCol( nTmp );
358 if ( rAddress.Row() < Row() )
360 SCROW nTmp = rAddress.Row();
361 rAddress.SetRow( Row() );
362 SetRow( nTmp );
364 if ( rAddress.Tab() < Tab() )
366 SCTAB nTmp = rAddress.Tab();
367 rAddress.SetTab( Tab() );
368 SetTab( nTmp );
372 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
374 nCol = nColP;
375 nRow = nRowP;
376 nTab = nTabP;
379 inline ScAddress& ScAddress::operator=( const ScAddress& rAddress )
381 nCol = rAddress.nCol;
382 nRow = rAddress.nRow;
383 nTab = rAddress.nTab;
384 return *this;
387 inline bool ScAddress::operator==( const ScAddress& rAddress ) const
389 return nRow == rAddress.nRow && nCol == rAddress.nCol && nTab == rAddress.nTab;
392 inline bool ScAddress::operator!=( const ScAddress& rAddress ) const
394 return !operator==( rAddress );
397 /** Same behavior as the old sal_uInt32 nAddress < r.nAddress with encoded
398 tab|col|row bit fields. */
399 inline bool ScAddress::operator<( const ScAddress& rAddress ) const
401 if (nTab == rAddress.nTab)
403 if (nCol == rAddress.nCol)
404 return nRow < rAddress.nRow;
405 else
406 return nCol < rAddress.nCol;
408 else
409 return nTab < rAddress.nTab;
412 inline bool ScAddress::operator<=( const ScAddress& rAddress ) const
414 return operator<( rAddress ) || operator==( rAddress );
417 inline bool ScAddress::operator>( const ScAddress& rAddress ) const
419 return !operator<=( rAddress );
422 inline bool ScAddress::operator>=( const ScAddress& rAddress ) const
424 return !operator<( rAddress );
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 & rAddress ) const
443 return rAddress.hash();
447 struct ScAddressEqualFunctor
449 bool operator()( const ScAddress & rAdr1, const ScAddress & rAdr2 ) const
451 return rAdr1 == rAdr2;
455 inline bool ValidAddress( const ScAddress& rAddress )
457 return ValidCol(rAddress.Col()) && ValidRow(rAddress.Row()) && ValidTab(rAddress.Tab());
460 // ScRange
461 class ScRange
463 public:
464 ScAddress aStart;
465 ScAddress aEnd;
467 inline ScRange() :
468 aStart(), aEnd()
471 inline ScRange( ScAddress::Uninitialized eUninitialized ) :
472 aStart( eUninitialized ), aEnd( eUninitialized )
474 inline ScRange( ScAddress::InitializeInvalid eInvalid ) :
475 aStart( eInvalid ), aEnd( eInvalid )
477 inline ScRange( const ScAddress& aInputStart, const ScAddress& aInputEnd ) :
478 aStart( aInputStart ), aEnd( aInputEnd )
480 aStart.PutInOrder( aEnd );
482 inline ScRange( const ScRange& rRange ) :
483 aStart( rRange.aStart ), aEnd( rRange.aEnd )
485 inline ScRange( const ScAddress& rRange ) :
486 aStart( rRange ), aEnd( rRange )
488 inline ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
489 aStart( nCol, nRow, nTab ), aEnd( aStart )
491 inline ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ) :
492 aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 )
495 inline ScRange& operator=( const ScRange& rRange )
497 aStart = rRange.aStart;
498 aEnd = rRange.aEnd;
499 return *this;
501 inline ScRange& operator=( const ScAddress& rPos )
503 aStart = aEnd = rPos;
504 return *this;
506 inline void SetInvalid()
508 aStart.SetInvalid();
509 aEnd.SetInvalid();
511 inline bool IsValid() const
513 return aStart.IsValid() && aEnd.IsValid();
515 inline bool In( const ScAddress& ) const; ///< is Address& in Range?
516 inline bool In( const ScRange& ) const; ///< is Range& in Range?
518 SC_DLLPUBLIC sal_uInt16 Parse( const OUString&, ScDocument* = NULL,
519 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
520 ScAddress::ExternalInfo* pExtInfo = NULL,
521 const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = NULL );
523 SC_DLLPUBLIC sal_uInt16 ParseAny( const OUString&, ScDocument* = NULL,
524 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
525 SC_DLLPUBLIC sal_uInt16 ParseCols( const OUString&, ScDocument* = NULL,
526 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
527 SC_DLLPUBLIC sal_uInt16 ParseRows( const OUString&, ScDocument* = NULL,
528 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
530 /** Parse an Excel style reference up to and including the sheet name
531 separator '!', including detection of external documents and sheet
532 names, and in case of MOOXML import the bracketed index is used to
533 determine the actual document name passed in pExternalLinks. For
534 internal references (resulting rExternDocName empty), aStart.nTab and
535 aEnd.nTab are set, or -1 if sheet name not found.
536 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
537 encountered results in an error (NULL returned).
538 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
539 NULL for non-filter usage, in which case indices such as [1] are
540 not resolved.
541 @returns
542 Pointer to the position after '!' if successfully parsed, and
543 rExternDocName, rStartTabName and/or rEndTabName filled if
544 applicable. SCA_... flags set in nFlags.
545 Or if no valid document and/or sheet header could be parsed the start
546 position passed with pString.
547 Or NULL if a 3D sheet header could be parsed but
548 bOnlyAcceptSingle==true was given.
550 const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument* pDocument,
551 OUString& rExternDocName, OUString& rStartTabName,
552 OUString& rEndTabName, sal_uInt16& nFlags,
553 bool bOnlyAcceptSingle,
554 const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = NULL );
556 SC_DLLPUBLIC OUString Format(sal_uInt16 nFlags= 0, const ScDocument* pDocument = NULL,
557 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
559 inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
560 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
561 // The document for the maximum defined sheet number
562 SC_DLLPUBLIC bool Move( SCsCOL aDeltaX, SCsROW aDeltaY, SCsTAB aDeltaZ, ScDocument* pDocument = NULL );
563 SC_DLLPUBLIC void Justify();
564 SC_DLLPUBLIC void ExtendTo( const ScRange& rRange );
565 SC_DLLPUBLIC bool Intersects( const ScRange& rRange ) const; // do two ranges intersect?
566 void PutInOrder();
567 inline bool operator==( const ScRange& rRange ) const;
568 inline bool operator!=( const ScRange& rRange ) const;
569 inline bool operator<( const ScRange& rRange ) const;
570 inline bool operator<=( const ScRange& rRange ) const;
571 inline bool operator>( const ScRange& rRange ) const;
572 inline bool operator>=( const ScRange& rRange ) const;
574 /// Hash 2D area ignoring table number.
575 inline size_t hashArea() const;
576 /// Hash start column and start and end rows.
577 inline size_t hashStartColumn() const;
580 inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
581 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
583 aStart.GetVars( nCol1, nRow1, nTab1 );
584 aEnd.GetVars( nCol2, nRow2, nTab2 );
587 inline bool ScRange::operator==( const ScRange& rRange ) const
589 return ( (aStart == rRange.aStart) && (aEnd == rRange.aEnd) );
592 inline bool ScRange::operator!=( const ScRange& rRange ) const
594 return !operator==( rRange );
597 /// Sort on upper left corner, if equal then use lower right too.
598 inline bool ScRange::operator<( const ScRange& r ) const
600 return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
603 inline bool ScRange::operator<=( const ScRange& rRange ) const
605 return operator<( rRange ) || operator==( rRange );
608 inline bool ScRange::operator>( const ScRange& rRange ) const
610 return !operator<=( rRange );
613 inline bool ScRange::operator>=( const ScRange& rRange ) const
615 return !operator<( rRange );
618 inline bool ScRange::In( const ScAddress& rAddress ) const
620 return
621 aStart.Col() <= rAddress.Col() && rAddress.Col() <= aEnd.Col() &&
622 aStart.Row() <= rAddress.Row() && rAddress.Row() <= aEnd.Row() &&
623 aStart.Tab() <= rAddress.Tab() && rAddress.Tab() <= aEnd.Tab();
626 inline bool ScRange::In( const ScRange& rRange ) const
628 return
629 aStart.Col() <= rRange.aStart.Col() && rRange.aEnd.Col() <= aEnd.Col() &&
630 aStart.Row() <= rRange.aStart.Row() && rRange.aEnd.Row() <= aEnd.Row() &&
631 aStart.Tab() <= rRange.aStart.Tab() && rRange.aEnd.Tab() <= aEnd.Tab();
634 inline size_t ScRange::hashArea() const
636 // Assume that there are not that many ranges with identical corners so we
637 // won't have too many collisions. Also assume that more lower row and
638 // column numbers are used so that there are not too many conflicts with
639 // the columns hashed into the values, and that start row and column
640 // usually don't exceed certain values. High bits are not masked off and
641 // may overlap with lower bits of other values, e.g. if start column is
642 // greater than assumed.
643 return
644 (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
645 (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
646 (static_cast<size_t>(aEnd.Col()) << 15) ^ // end column <= 2^6
647 static_cast<size_t>(aEnd.Row()); // end row <= 2^15
650 inline size_t ScRange::hashStartColumn() const
652 // Assume that for the start row more lower row numbers are used so that
653 // there are not too many conflicts with the column hashed into the higher
654 // values.
655 return
656 (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
657 (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
658 static_cast<size_t>(aEnd.Row());
661 struct ScRangeHashAreaFunctor
663 size_t operator()( const ScRange & rRange ) const
665 return rRange.hashArea();
669 struct ScRangeEqualFunctor
671 bool operator()( const ScRange & rRange1, const ScRange & rRange2 ) const
673 return rRange1 == rRange2;
677 inline bool ValidRange( const ScRange& rRange )
679 return ValidAddress(rRange.aStart) && ValidAddress(rRange.aEnd);
682 // ScRangePair
683 class ScRangePair
685 private:
686 ScRange aRange[2];
688 public:
689 ScRangePair()
691 ScRangePair( const ScRangePair& r )
693 aRange[0] = r.aRange[0];
694 aRange[1] = r.aRange[1];
696 ScRangePair( const ScRange& rRange1, const ScRange& rRange2 )
698 aRange[0] = rRange1;
699 aRange[1] = rRange2;
702 inline ScRangePair& operator= ( const ScRangePair& rRange );
703 const ScRange& GetRange( sal_uInt16 n ) const
705 return aRange[n];
707 ScRange& GetRange( sal_uInt16 n )
709 return aRange[n];
711 inline bool operator==( const ScRangePair& ) const;
712 inline bool operator!=( const ScRangePair& ) const;
715 inline ScRangePair& ScRangePair::operator= ( const ScRangePair& rRange )
717 aRange[0] = rRange.aRange[0];
718 aRange[1] = rRange.aRange[1];
719 return *this;
722 inline bool ScRangePair::operator==( const ScRangePair& rRange ) const
724 return (aRange[0] == rRange.aRange[0]) &&
725 (aRange[1] == rRange.aRange[1]);
728 inline bool ScRangePair::operator!=( const ScRangePair& rRange ) const
730 return !operator==( rRange );
733 // ScRefAddress
734 class ScRefAddress
736 private:
737 ScAddress aAdr;
738 bool bRelCol;
739 bool bRelRow;
740 bool bRelTab;
741 public:
742 inline ScRefAddress() :
743 bRelCol(false), bRelRow(false), bRelTab(false)
745 inline ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab,
746 bool bRelColP, bool bRelRowP, bool bRelTabP ) :
747 aAdr(nCol, nRow, nTab),
748 bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
750 inline ScRefAddress( const ScAddress& rAdr,
751 bool bRelColP, bool bRelRowP, bool bRelTabP ) :
752 aAdr(rAdr),
753 bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
755 inline ScRefAddress( const ScRefAddress& rRef ) :
756 aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
757 bRelTab(rRef.bRelTab)
760 inline ScRefAddress& operator=( const ScRefAddress& );
762 inline bool IsRelCol() const
764 return bRelCol;
766 inline bool IsRelRow() const
768 return bRelRow;
770 inline bool IsRelTab() const
772 return bRelTab;
775 inline void SetRelCol(bool bNewRelCol)
777 bRelCol = bNewRelCol;
779 inline void SetRelRow(bool bNewRelRow)
781 bRelRow = bNewRelRow;
783 inline void SetRelTab(bool bNewRelTab)
785 bRelTab = bNewRelTab;
788 inline void Set( const ScAddress& rAdr,
789 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
790 inline void Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
791 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
793 inline const ScAddress& GetAddress() const
795 return aAdr;
798 inline SCCOL Col() const
800 return aAdr.Col();
802 inline SCROW Row() const
804 return aAdr.Row();
806 inline SCTAB Tab() const
808 return aAdr.Tab();
811 inline bool operator == ( const ScRefAddress& r ) const;
812 inline bool operator != ( const ScRefAddress& r ) const
814 return !(operator==(r));
817 OUString GetRefString( ScDocument* pDocument, SCTAB nActTab,
818 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
821 inline ScRefAddress& ScRefAddress::operator=( const ScRefAddress& rRef )
823 aAdr = rRef.aAdr;
824 bRelCol = rRef.bRelCol;
825 bRelRow = rRef.bRelRow;
826 bRelTab = rRef.bRelTab;
827 return *this;
830 inline void ScRefAddress::Set( const ScAddress& rAdr,
831 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
833 aAdr = rAdr;
834 bRelCol = bNewRelCol;
835 bRelRow = bNewRelRow;
836 bRelTab = bNewRelTab;
839 inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
840 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
842 aAdr.Set( nNewCol, nNewRow, nNewTab);
843 bRelCol = bNewRelCol;
844 bRelRow = bNewRelRow;
845 bRelTab = bNewRelTab;
848 inline bool ScRefAddress::operator==( const ScRefAddress& rRefAddress ) const
850 return aAdr == rRefAddress.aAdr &&
851 bRelCol == rRefAddress.bRelCol &&
852 bRelRow == rRefAddress.bRelRow &&
853 bRelTab == rRefAddress.bRelTab;
856 // Global functions
858 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
859 // and the like).
860 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
861 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
863 template< typename T > void PutInOrder( T& nStart, T& nEnd )
865 if (nEnd < nStart)
867 T nTemp;
868 nTemp = nEnd;
869 nEnd = nStart;
870 nStart = nTemp;
874 bool ConvertSingleRef( ScDocument* pDocument, const OUString& rRefString,
875 SCTAB nDefTab, ScRefAddress& rRefAddress,
876 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
877 ScAddress::ExternalInfo* pExtInfo = NULL );
879 bool ConvertDoubleRef( ScDocument* pDocument, const OUString& rRefString,
880 SCTAB nDefTab, ScRefAddress& rStartRefAddress,
881 ScRefAddress& rEndRefAddress,
882 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
883 ScAddress::ExternalInfo* pExtInfo = NULL );
885 /// append alpha representation of column to buffer
886 SC_DLLPUBLIC void ScColToAlpha( OUStringBuffer& rBuffer, SCCOL nCol);
888 inline void ScColToAlpha( OUString& rStr, SCCOL nCol)
890 OUStringBuffer aBuf(2);
891 ScColToAlpha( aBuf, nCol);
892 rStr += aBuf.makeStringAndClear();
895 inline OUString ScColToAlpha( SCCOL nCol )
897 OUStringBuffer aBuf(2);
898 ScColToAlpha( aBuf, nCol);
899 return aBuf.makeStringAndClear();
902 /// get column number of A..IV... string
903 bool AlphaToCol( SCCOL& rCol, const OUString& rStr);
905 #endif // INCLUDED_SC_INC_ADDRESS_HXX
907 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */