bump product version to 4.1.6.2
[LibreOffice.git] / sc / inc / address.hxx
blob2f59565463937ff20445b59574a6f13b1b708295
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 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>
29 #include <limits>
30 #include "scdllapi.h"
31 #include <formula/grammar.hxx>
33 #include <com/sun/star/uno/Sequence.hxx>
35 namespace com { namespace sun { namespace star {
36 namespace sheet {
37 struct ExternalLinkInfo;
39 }}}
41 class ScDocument;
43 // The typedefs
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.
62 #undef min
63 #undef max
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
75 // Count values
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;
81 // Maximum values
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;
92 // Special values
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
100 // special handling:
101 // #if SC_ROWLIMIT_MORE_THAN_64K
102 // #error row limit 64k
103 // #endif
104 #if MAXROWCOUNT_DEFINE > 65536
105 #define SC_ROWLIMIT_MORE_THAN_64K 1
106 #else
107 #define SC_ROWLIMIT_MORE_THAN_64K 0
108 #endif
109 const SCROW SCROWS64K = 65536;
111 // === old stuff defines =====================================================
113 #define MAXROW_30 8191
115 #ifdef SC_LIMIT_ROWS
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
122 #endif
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:
179 // +---+---+-------+
180 // |Tab|Col| Row |
181 // +---+---+-------+
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 =============================================================
221 class ScAddress
223 private:
224 SCROW nRow;
225 SCCOL nCol;
226 SCTAB nTab;
228 public:
230 enum Uninitialized { UNINITIALIZED };
231 enum InitializeInvalid { INITIALIZE_INVALID };
233 struct Details {
234 formula::FormulaGrammar::AddressConvention eConv;
235 SCROW nRow;
236 SCCOL nCol;
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;
251 struct ExternalInfo
253 OUString maTabName;
254 sal_uInt16 mnFileId;
255 bool mbExternal;
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();
322 r.SetCol( Col() );
323 SetCol( nTmp );
325 if ( r.Row() < Row() )
327 SCROW nTmp = r.Row();
328 r.SetRow( Row() );
329 SetRow( nTmp );
331 if ( r.Tab() < Tab() )
333 SCTAB nTmp = r.Tab();
334 r.SetTab( Tab() );
335 SetTab( nTmp );
339 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
341 nCol = nColP;
342 nRow = nRowP;
343 nTab = nTabP;
346 inline ScAddress& ScAddress::operator=( const ScAddress& r )
348 nCol = r.nCol;
349 nRow = r.nRow;
350 nTab = r.nTab;
351 return *this;
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
368 if (nTab == r.nTab)
370 if (nCol == r.nCol)
371 return nRow < r.nRow;
372 else
373 return nCol < r.nCol;
375 else
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.
399 if (nRow <= 0xffff)
400 return (static_cast<size_t>(nTab) << 24) ^
401 (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
402 else
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
411 return rAdr.hash();
415 struct ScAddressEqualFunctor
417 bool operator()( const ScAddress & rAdr1, const ScAddress & rAdr2 ) const
419 return rAdr1 == rAdr2;
424 // === ScRange ===============================================================
426 class ScRange
428 public:
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
477 not resolved.
478 @returns
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
559 return
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
567 return
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.
583 return
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
595 // values.
596 return
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 ===========================================================
622 class ScRangePair
624 private:
625 ScRange aRange[2];
627 public:
628 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];
645 return *this;
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 ==========================================================
660 class ScRefAddress
662 ScAddress aAdr;
663 bool bRelCol;
664 bool bRelRow;
665 bool bRelTab;
666 public:
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 ) :
676 aAdr(rAdr),
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 )
714 aAdr = rRef.aAdr;
715 bRelCol = rRef.bRelCol;
716 bRelRow = rRef.bRelRow;
717 bRelTab = rRef.bRelTab;
718 return *this;
721 inline void ScRefAddress::Set( const ScAddress& rAdr,
722 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
724 aAdr = rAdr;
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 // ===========================================================================
746 // Global functions
747 // ===========================================================================
749 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
750 // and the like).
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 )
756 if (nEnd < nStart)
758 T nTemp;
759 nTemp = nEnd;
760 nEnd = nStart;
761 nStart = nTemp;
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: */