Impress Remote 1.0.5, tag sdremote-1.0.5
[LibreOffice.git] / sc / inc / address.hxx
blob13a144352937ac4b09b780606175589e46d917b1
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 #define VALIDCOL(nCol) (ValidCol(nCol))
125 #define VALIDROW(nRow) (ValidRow(nRow))
126 #define VALIDTAB(nTab) (ValidTab(nTab))
127 #define VALIDCOLROW(nCol,nRow) (ValidColRow(nCol,nRow))
129 // === old stuff defines end =================================================
131 inline bool ValidCol( SCCOL nCol )
133 return static_cast<SCCOL>(0) <= nCol && nCol <= MAXCOL;
136 inline bool ValidRow( SCROW nRow )
138 return static_cast<SCROW>(0) <= nRow && nRow <= MAXROW;
141 inline bool ValidTab( SCTAB nTab )
143 return static_cast<SCTAB>(0) <= nTab && nTab <= MAXTAB;
146 inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
148 return static_cast<SCTAB>(0) <= nTab && nTab <= nMaxTab;
151 inline bool ValidColRow( SCCOL nCol, SCROW nRow )
153 return ValidCol( nCol) && ValidRow( nRow);
156 inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab )
158 return ValidCol( nCol) && ValidRow( nRow) && ValidTab( nTab);
161 inline SCCOL SanitizeCol( SCCOL nCol )
163 return nCol < 0 ? 0 : (nCol > MAXCOL ? MAXCOL : nCol);
166 inline SCROW SanitizeRow( SCROW nRow )
168 return nRow < 0 ? 0 : (nRow > MAXROW ? MAXROW : nRow);
171 inline SCTAB SanitizeTab( SCTAB nTab )
173 return nTab < 0 ? 0 : (nTab > MAXTAB ? MAXTAB : nTab);
176 inline SCTAB SanitizeTab( SCTAB nTab, SCTAB nMaxTab )
178 return nTab < 0 ? 0 : (nTab > nMaxTab ? nMaxTab : nTab);
181 // === ScAddress =============================================================
183 // The old cell address is combined in one UINT32:
184 // +---+---+-------+
185 // |Tab|Col| Row |
186 // +---+---+-------+
187 // For speed reasons access isn't done by shifting bits but by using platform
188 // dependent casts, which unfortunately also leads to aliasing problems when
189 // not using gcc -fno-strict-aliasing
191 // The result of ConvertRef() is a bit group of the following:
193 #define SCA_COL_ABSOLUTE 0x01
194 #define SCA_ROW_ABSOLUTE 0x02
195 #define SCA_TAB_ABSOLUTE 0x04
196 #define SCA_TAB_3D 0x08
197 #define SCA_COL2_ABSOLUTE 0x10
198 #define SCA_ROW2_ABSOLUTE 0x20
199 #define SCA_TAB2_ABSOLUTE 0x40
200 #define SCA_TAB2_3D 0x80
201 #define SCA_VALID_ROW 0x0100
202 #define SCA_VALID_COL 0x0200
203 #define SCA_VALID_TAB 0x0400
204 // SCA_BITS is a convience for
205 // (SCA_VALID_TAB | SCA_VALID_COL | SCA_VALID_ROW | SCA_TAB_3D | SCA_TAB_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_COL_ABSOLUTE)
206 #define SCA_BITS 0x070F
207 // somewhat cheesy kludge to force the display of the document name even for
208 // local references. Requires TAB_3D to be valid
209 #define SCA_FORCE_DOC 0x0800
210 #define SCA_VALID_ROW2 0x1000
211 #define SCA_VALID_COL2 0x2000
212 #define SCA_VALID_TAB2 0x4000
213 #define SCA_VALID 0x8000
215 #define SCA_ABS SCA_VALID \
216 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
218 #define SCR_ABS SCA_ABS \
219 | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
221 #define SCA_ABS_3D SCA_ABS | SCA_TAB_3D
222 #define SCR_ABS_3D SCR_ABS | SCA_TAB_3D
224 // === ScAddress =============================================================
226 class ScAddress
228 private:
229 SCROW nRow;
230 SCCOL nCol;
231 SCTAB nTab;
233 public:
235 enum Uninitialized { UNINITIALIZED };
236 enum InitializeInvalid { INITIALIZE_INVALID };
238 struct Details {
239 formula::FormulaGrammar::AddressConvention eConv;
240 SCROW nRow;
241 SCCOL nCol;
242 inline Details( formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP )
243 : eConv( eConvP ), nRow( nRowP ), nCol( nColP )
245 inline Details( formula::FormulaGrammar::AddressConvention eConvP, ScAddress const & rAddr )
246 : eConv( eConvP ), nRow( rAddr.Row() ), nCol( rAddr.Col() )
248 inline Details( formula::FormulaGrammar::AddressConvention eConvP)
249 : eConv( eConvP ), nRow( 0 ), nCol( 0 )
251 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
252 Details( const ScDocument* pDoc, const ScAddress & rAddr );
254 SC_DLLPUBLIC static const Details detailsOOOa1;
256 struct ExternalInfo
258 ::rtl::OUString maTabName;
259 sal_uInt16 mnFileId;
260 bool mbExternal;
262 inline ExternalInfo() : mnFileId(0), mbExternal(false) {}
265 inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
266 inline ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
267 : nRow(nRowP), nCol(nColP), nTab(nTabP)
269 /** Yes, it is what it seems to be: Uninitialized. May be used for
270 performance reasons if it is initialized by other means. */
271 inline ScAddress( Uninitialized ) {}
272 inline ScAddress( InitializeInvalid )
273 : nRow(-1), nCol(-1), nTab(-1) {}
274 inline ScAddress( const ScAddress& r )
275 : nRow(r.nRow), nCol(r.nCol), nTab(r.nTab)
277 inline ScAddress& operator=( const ScAddress& r );
279 inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
280 inline SCROW Row() const { return nRow; }
281 inline SCCOL Col() const { return nCol; }
282 inline SCTAB Tab() const { return nTab; }
283 inline void SetRow( SCROW nRowP ) { nRow = nRowP; }
284 inline void SetCol( SCCOL nColP ) { nCol = nColP; }
285 inline void SetTab( SCTAB nTabP ) { nTab = nTabP; }
286 inline void SetInvalid() { nRow = -1; nCol = -1; nTab = -1; }
287 inline bool IsValid() const { return (nRow >= 0) && (nCol >= 0) && (nTab >= 0); }
288 inline void PutInOrder( ScAddress& r );
289 inline void IncRow( SCsROW n=1 ) { nRow = sal::static_int_cast<SCROW>(nRow + n); }
290 inline void IncCol( SCsCOL n=1 ) { nCol = sal::static_int_cast<SCCOL>(nCol + n); }
291 inline void IncTab( SCsTAB n=1 ) { nTab = sal::static_int_cast<SCTAB>(nTab + n); }
292 inline void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
293 { nColP = nCol; nRowP = nRow; nTabP = nTab; }
295 SC_DLLPUBLIC sal_uInt16 Parse( const String&, ScDocument* = NULL,
296 const Details& rDetails = detailsOOOa1,
297 ExternalInfo* pExtInfo = NULL,
298 const ::com::sun::star::uno::Sequence<
299 const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
301 SC_DLLPUBLIC void Format( rtl::OUString&, sal_uInt16 = 0, const ScDocument* = NULL,
302 const Details& rDetails = detailsOOOa1) const;
303 SC_DLLPUBLIC void Format( String&, sal_uInt16 = 0, const ScDocument* = NULL,
304 const Details& rDetails = detailsOOOa1) const;
306 // The document for the maximum defined sheet number
307 SC_DLLPUBLIC bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
308 inline bool operator==( const ScAddress& r ) const;
309 inline bool operator!=( const ScAddress& r ) const;
310 inline bool operator<( const ScAddress& r ) const;
311 inline bool operator<=( const ScAddress& r ) const;
312 inline bool operator>( const ScAddress& r ) const;
313 inline bool operator>=( const ScAddress& r ) const;
315 inline size_t hash() const;
317 /// "A1" or "$A$1" or R1C1 or R[1]C[1]
318 String GetColRowString( bool bAbsolute = false,
319 const Details& rDetails = detailsOOOa1) const;
322 inline void ScAddress::PutInOrder( ScAddress& r )
324 if ( r.Col() < Col() )
326 SCCOL nTmp = r.Col();
327 r.SetCol( Col() );
328 SetCol( nTmp );
330 if ( r.Row() < Row() )
332 SCROW nTmp = r.Row();
333 r.SetRow( Row() );
334 SetRow( nTmp );
336 if ( r.Tab() < Tab() )
338 SCTAB nTmp = r.Tab();
339 r.SetTab( Tab() );
340 SetTab( nTmp );
344 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
346 nCol = nColP;
347 nRow = nRowP;
348 nTab = nTabP;
351 inline ScAddress& ScAddress::operator=( const ScAddress& r )
353 nCol = r.nCol;
354 nRow = r.nRow;
355 nTab = r.nTab;
356 return *this;
359 inline bool ScAddress::operator==( const ScAddress& r ) const
361 return nRow == r.nRow && nCol == r.nCol && nTab == r.nTab;
364 inline bool ScAddress::operator!=( const ScAddress& r ) const
366 return !operator==( r );
369 /** Same behavior as the old sal_uInt32 nAddress < r.nAddress with encoded
370 tab|col|row bit fields. */
371 inline bool ScAddress::operator<( const ScAddress& r ) const
373 if (nTab == r.nTab)
375 if (nCol == r.nCol)
376 return nRow < r.nRow;
377 else
378 return nCol < r.nCol;
380 else
381 return nTab < r.nTab;
384 inline bool ScAddress::operator<=( const ScAddress& r ) const
386 return operator<( r ) || operator==( r );
389 inline bool ScAddress::operator>( const ScAddress& r ) const
391 return !operator<=( r );
394 inline bool ScAddress::operator>=( const ScAddress& r ) const
396 return !operator<( r );
400 inline size_t ScAddress::hash() const
402 // Assume that there are not that many addresses with row > 2^16 AND column
403 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
404 if (nRow <= 0xffff)
405 return (static_cast<size_t>(nTab) << 24) ^
406 (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
407 else
408 return (static_cast<size_t>(nTab) << 28) ^
409 (static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
412 struct ScAddressHashFunctor
414 size_t operator()( const ScAddress & rAdr ) const
416 return rAdr.hash();
420 struct ScAddressEqualFunctor
422 bool operator()( const ScAddress & rAdr1, const ScAddress & rAdr2 ) const
424 return rAdr1 == rAdr2;
429 // === ScRange ===============================================================
431 class ScRange
433 public:
434 ScAddress aStart, aEnd;
435 inline ScRange() : aStart(), aEnd() {}
436 inline ScRange( ScAddress::Uninitialized e )
437 : aStart( e ), aEnd( e ) {}
438 inline ScRange( ScAddress::InitializeInvalid e )
439 : aStart( e ), aEnd( e ) {}
440 inline ScRange( const ScAddress& s, const ScAddress& e )
441 : aStart( s ), aEnd( e ) { aStart.PutInOrder( aEnd ); }
442 inline ScRange( const ScRange& r ) : aStart( r.aStart ), aEnd( r.aEnd ) {}
443 inline ScRange( const ScAddress& r ) : aStart( r ), aEnd( r ) {}
444 inline ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab )
445 : aStart( nCol, nRow, nTab ), aEnd( aStart ) {}
446 inline ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
447 SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
448 : aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 ) {}
450 inline ScRange& operator=( const ScRange& r )
451 { aStart = r.aStart; aEnd = r.aEnd; return *this; }
452 inline ScRange& operator=( const ScAddress& rPos )
453 { aStart = aEnd = rPos; return *this; }
454 inline void SetInvalid() { aStart.SetInvalid(); aEnd.SetInvalid(); }
455 inline bool IsValid() const { return aStart.IsValid() && aEnd.IsValid(); }
456 inline bool In( const ScAddress& ) const; ///< is Address& in Range?
457 inline bool In( const ScRange& ) const; ///< is Range& in Range?
459 sal_uInt16 Parse( const String&, ScDocument* = NULL,
460 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
461 ScAddress::ExternalInfo* pExtInfo = NULL,
462 const ::com::sun::star::uno::Sequence<
463 const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
465 SC_DLLPUBLIC sal_uInt16 ParseAny( const String&, ScDocument* = NULL,
466 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
467 SC_DLLPUBLIC sal_uInt16 ParseCols( const String&, ScDocument* = NULL,
468 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
469 SC_DLLPUBLIC sal_uInt16 ParseRows( const String&, ScDocument* = NULL,
470 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
472 /** Parse an Excel style reference up to and including the sheet name
473 separator '!', including detection of external documents and sheet
474 names, and in case of MOOXML import the bracketed index is used to
475 determine the actual document name passed in pExternalLinks. For
476 internal references (resulting rExternDocName empty), aStart.nTab and
477 aEnd.nTab are set, or -1 if sheet name not found.
478 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
479 encountered results in an error (NULL returned).
480 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
481 NULL for non-filter usage, in which case indices such as [1] are
482 not resolved.
483 @returns
484 Pointer to the position after '!' if successfully parsed, and
485 rExternDocName, rStartTabName and/or rEndTabName filled if
486 applicable. SCA_... flags set in nFlags.
487 Or if no valid document and/or sheet header could be parsed the start
488 position passed with pString.
489 Or NULL if a 3D sheet header could be parsed but
490 bOnlyAcceptSingle==true was given.
492 const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument* pDoc,
493 String& rExternDocName, String& rStartTabName, String& rEndTabName, sal_uInt16& nFlags,
494 bool bOnlyAcceptSingle,
495 const ::com::sun::star::uno::Sequence<
496 const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
498 SC_DLLPUBLIC void Format( String&, sal_uInt16 = 0, const ScDocument* = NULL,
499 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 ) const;
501 SC_DLLPUBLIC void Format( rtl::OUString&, sal_uInt16 = 0, const ScDocument* = NULL,
502 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 ) const;
504 inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
505 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
506 // The document for the maximum defined sheet number
507 SC_DLLPUBLIC bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
508 SC_DLLPUBLIC void Justify();
509 SC_DLLPUBLIC void ExtendTo( const ScRange& rRange );
510 SC_DLLPUBLIC bool Intersects( const ScRange& ) const; // do two ranges intersect?
511 inline bool operator==( const ScRange& r ) const;
512 inline bool operator!=( const ScRange& r ) const;
513 inline bool operator<( const ScRange& r ) const;
514 inline bool operator<=( const ScRange& r ) const;
515 inline bool operator>( const ScRange& r ) const;
516 inline bool operator>=( const ScRange& r ) const;
518 /// Hash 2D area ignoring table number.
519 inline size_t hashArea() const;
520 /// Hash start column and start and end rows.
521 inline size_t hashStartColumn() const;
524 inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
525 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
527 aStart.GetVars( nCol1, nRow1, nTab1 );
528 aEnd.GetVars( nCol2, nRow2, nTab2 );
531 inline bool ScRange::operator==( const ScRange& r ) const
533 return ( (aStart == r.aStart) && (aEnd == r.aEnd) );
536 inline bool ScRange::operator!=( const ScRange& r ) const
538 return !operator==( r );
541 /// Sort on upper left corner, if equal then use lower right too.
542 inline bool ScRange::operator<( const ScRange& r ) const
544 return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
547 inline bool ScRange::operator<=( const ScRange& r ) const
549 return operator<( r ) || operator==( r );
552 inline bool ScRange::operator>( const ScRange& r ) const
554 return !operator<=( r );
557 inline bool ScRange::operator>=( const ScRange& r ) const
559 return !operator<( r );
562 inline bool ScRange::In( const ScAddress& rAddr ) const
564 return
565 aStart.Col() <= rAddr.Col() && rAddr.Col() <= aEnd.Col() &&
566 aStart.Row() <= rAddr.Row() && rAddr.Row() <= aEnd.Row() &&
567 aStart.Tab() <= rAddr.Tab() && rAddr.Tab() <= aEnd.Tab();
570 inline bool ScRange::In( const ScRange& r ) const
572 return
573 aStart.Col() <= r.aStart.Col() && r.aEnd.Col() <= aEnd.Col() &&
574 aStart.Row() <= r.aStart.Row() && r.aEnd.Row() <= aEnd.Row() &&
575 aStart.Tab() <= r.aStart.Tab() && r.aEnd.Tab() <= aEnd.Tab();
579 inline size_t ScRange::hashArea() const
581 // Assume that there are not that many ranges with identical corners so we
582 // won't have too many collisions. Also assume that more lower row and
583 // column numbers are used so that there are not too many conflicts with
584 // the columns hashed into the values, and that start row and column
585 // usually don't exceed certain values. High bits are not masked off and
586 // may overlap with lower bits of other values, e.g. if start column is
587 // greater than assumed.
588 return
589 (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
590 (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
591 (static_cast<size_t>(aEnd.Col()) << 15) ^ // end column <= 2^6
592 static_cast<size_t>(aEnd.Row()); // end row <= 2^15
596 inline size_t ScRange::hashStartColumn() const
598 // Assume that for the start row more lower row numbers are used so that
599 // there are not too many conflicts with the column hashed into the higher
600 // values.
601 return
602 (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
603 (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
604 static_cast<size_t>(aEnd.Row());
608 struct ScRangeHashAreaFunctor
610 size_t operator()( const ScRange & rRange ) const
612 return rRange.hashArea();
616 struct ScRangeEqualFunctor
618 bool operator()( const ScRange & rRange1, const ScRange & rRange2 ) const
620 return rRange1 == rRange2;
625 // === ScRangePair ===========================================================
627 class ScRangePair
629 private:
630 ScRange aRange[2];
632 public:
633 ScRangePair() {}
634 ScRangePair( const ScRangePair& r )
635 { aRange[0] = r.aRange[0]; aRange[1] = r.aRange[1]; }
636 ScRangePair( const ScRange& r1, const ScRange& r2 )
637 { aRange[0] = r1; aRange[1] = r2; }
639 inline ScRangePair& operator= ( const ScRangePair& r );
640 const ScRange& GetRange( sal_uInt16 n ) const { return aRange[n]; }
641 ScRange& GetRange( sal_uInt16 n ) { return aRange[n]; }
642 inline int operator==( const ScRangePair& ) const;
643 inline int operator!=( const ScRangePair& ) const;
646 inline ScRangePair& ScRangePair::operator= ( const ScRangePair& r )
648 aRange[0] = r.aRange[0];
649 aRange[1] = r.aRange[1];
650 return *this;
653 inline int ScRangePair::operator==( const ScRangePair& r ) const
655 return ( (aRange[0] == r.aRange[0]) && (aRange[1] == r.aRange[1]) );
658 inline int ScRangePair::operator!=( const ScRangePair& r ) const
660 return !operator==( r );
663 // === ScRefAddress ==========================================================
665 class ScRefAddress
667 ScAddress aAdr;
668 bool bRelCol;
669 bool bRelRow;
670 bool bRelTab;
671 public:
672 inline ScRefAddress() : bRelCol(false), bRelRow(false), bRelTab(false)
674 inline ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab,
675 bool bRelColP, bool bRelRowP, bool bRelTabP ) :
676 aAdr(nCol, nRow, nTab),
677 bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
679 inline ScRefAddress( const ScAddress& rAdr,
680 bool bRelColP, bool bRelRowP, bool bRelTabP ) :
681 aAdr(rAdr),
682 bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
684 inline ScRefAddress( const ScRefAddress& rRef ) :
685 aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
686 bRelTab(rRef.bRelTab)
689 inline ScRefAddress& operator=( const ScRefAddress& );
691 inline bool IsRelCol() const { return bRelCol; }
692 inline bool IsRelRow() const { return bRelRow; }
693 inline bool IsRelTab() const { return bRelTab; }
695 inline void SetRelCol(bool bNewRelCol) { bRelCol = bNewRelCol; }
696 inline void SetRelRow(bool bNewRelRow) { bRelRow = bNewRelRow; }
697 inline void SetRelTab(bool bNewRelTab) { bRelTab = bNewRelTab; }
699 inline void Set( const ScAddress& rAdr,
700 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
701 inline void Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
702 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
704 inline const ScAddress& GetAddress() const { return aAdr; }
705 inline SCCOL Col() const { return aAdr.Col(); }
706 inline SCROW Row() const { return aAdr.Row(); }
707 inline SCTAB Tab() const { return aAdr.Tab(); }
709 inline int operator == ( const ScRefAddress& r ) const;
710 inline int operator != ( const ScRefAddress& r ) const
711 { return !(operator==(r)); }
713 String GetRefString( ScDocument* pDoc, SCTAB nActTab,
714 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
717 inline ScRefAddress& ScRefAddress::operator=( const ScRefAddress& rRef )
719 aAdr = rRef.aAdr;
720 bRelCol = rRef.bRelCol;
721 bRelRow = rRef.bRelRow;
722 bRelTab = rRef.bRelTab;
723 return *this;
726 inline void ScRefAddress::Set( const ScAddress& rAdr,
727 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
729 aAdr = rAdr;
730 bRelCol = bNewRelCol;
731 bRelRow = bNewRelRow;
732 bRelTab = bNewRelTab;
735 inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
736 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
738 aAdr.Set( nNewCol, nNewRow, nNewTab);
739 bRelCol = bNewRelCol;
740 bRelRow = bNewRelRow;
741 bRelTab = bNewRelTab;
744 inline int ScRefAddress::operator==( const ScRefAddress& r ) const
746 return aAdr == r.aAdr && bRelCol == r.bRelCol && bRelRow == r.bRelRow &&
747 bRelTab == r.bRelTab;
750 // ===========================================================================
751 // Global functions
752 // ===========================================================================
754 // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
755 // and the like).
756 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
757 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
759 template< typename T > void PutInOrder( T& nStart, T& nEnd )
761 if (nEnd < nStart)
763 T nTemp;
764 nTemp = nEnd;
765 nEnd = nStart;
766 nStart = nTemp;
770 bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
771 SCTAB nDefTab, ScRefAddress& rRefAddress,
772 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
773 ScAddress::ExternalInfo* pExtInfo = NULL );
775 bool ConvertDoubleRef(ScDocument* pDoc, const String& rRefString,
776 SCTAB nDefTab, ScRefAddress& rStartRefAddress,
777 ScRefAddress& rEndRefAddress,
778 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
779 ScAddress::ExternalInfo* pExtInfo = NULL );
781 /// append alpha representation of column to buffer
782 SC_DLLPUBLIC void ScColToAlpha( rtl::OUStringBuffer& rBuffer, SCCOL nCol);
784 inline void ScColToAlpha( String& rStr, SCCOL nCol)
786 rtl::OUStringBuffer aBuf(2);
787 ScColToAlpha( aBuf, nCol);
788 rStr.Append( aBuf.getStr(), static_cast<xub_StrLen>(aBuf.getLength()));
791 inline String ScColToAlpha( SCCOL nCol )
793 rtl::OUStringBuffer aBuf(2);
794 ScColToAlpha( aBuf, nCol);
795 return aBuf.makeStringAndClear();
798 /// get column number of A..IV... string
799 bool AlphaToCol( SCCOL& rCol, const String& rStr);
801 #endif // SC_ADDRESS_HXX
803 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */