xref: /aoo41x/main/sc/inc/address.hxx (revision 38d50f7b)
1*38d50f7bSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*38d50f7bSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*38d50f7bSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*38d50f7bSAndrew Rist  * distributed with this work for additional information
6*38d50f7bSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*38d50f7bSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*38d50f7bSAndrew Rist  * "License"); you may not use this file except in compliance
9*38d50f7bSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*38d50f7bSAndrew Rist  *
11*38d50f7bSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*38d50f7bSAndrew Rist  *
13*38d50f7bSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*38d50f7bSAndrew Rist  * software distributed under the License is distributed on an
15*38d50f7bSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*38d50f7bSAndrew Rist  * KIND, either express or implied.  See the License for the
17*38d50f7bSAndrew Rist  * specific language governing permissions and limitations
18*38d50f7bSAndrew Rist  * under the License.
19*38d50f7bSAndrew Rist  *
20*38d50f7bSAndrew Rist  *************************************************************/
21*38d50f7bSAndrew Rist 
22*38d50f7bSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef SC_ADDRESS_HXX
25cdf0e10cSrcweir #define SC_ADDRESS_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <tools/stream.hxx>
28cdf0e10cSrcweir #include <tools/string.hxx>
29cdf0e10cSrcweir #include <tools/solar.h>
30cdf0e10cSrcweir #include <tools/debug.hxx>
31cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
32cdf0e10cSrcweir #include <osl/endian.h>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #ifndef INCLUDED_LIMITS
35cdf0e10cSrcweir #include <limits>
36cdf0e10cSrcweir #define INCLUDED_LIMITS
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir #include "scdllapi.h"
39cdf0e10cSrcweir #include <formula/grammar.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir namespace com { namespace sun { namespace star {
44cdf0e10cSrcweir     namespace sheet {
45cdf0e10cSrcweir         struct ExternalLinkInfo;
46cdf0e10cSrcweir     }
47cdf0e10cSrcweir }}}
48cdf0e10cSrcweir 
49cdf0e10cSrcweir class ScDocument;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir // The typedefs
52cdf0e10cSrcweir typedef sal_Int32 SCROW;
53cdf0e10cSrcweir typedef sal_Int16 SCCOL;
54cdf0e10cSrcweir typedef sal_Int16 SCTAB;
55cdf0e10cSrcweir typedef sal_Int32 SCCOLROW;     // a type capable of holding either SCCOL or SCROW
56cdf0e10cSrcweir 
57cdf0e10cSrcweir // temporarily signed typedefs
58cdf0e10cSrcweir typedef sal_Int32 SCsROW;
59cdf0e10cSrcweir typedef sal_Int16 SCsCOL;
60cdf0e10cSrcweir typedef sal_Int16 SCsTAB;
61cdf0e10cSrcweir typedef sal_Int32 SCsCOLROW;
62cdf0e10cSrcweir 
63cdf0e10cSrcweir // size_t typedef to be able to find places where code was changed from USHORT
64cdf0e10cSrcweir // to size_t and is used to read/write from/to streams.
65cdf0e10cSrcweir typedef size_t SCSIZE;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir // Maximum possible value of data type, NOT maximum row value.
68cdf0e10cSrcweir // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
69cdf0e10cSrcweir // included, we should not be using those stupid macros anyway.
70cdf0e10cSrcweir #undef min
71cdf0e10cSrcweir #undef max
72cdf0e10cSrcweir const SCROW    SCROW_MAX    = ::std::numeric_limits<SCROW>::max();
73cdf0e10cSrcweir const SCCOL    SCCOL_MAX    = ::std::numeric_limits<SCCOL>::max();
74cdf0e10cSrcweir const SCTAB    SCTAB_MAX    = ::std::numeric_limits<SCTAB>::max();
75cdf0e10cSrcweir const SCCOLROW SCCOLROW_MAX = ::std::numeric_limits<SCCOLROW>::max();
76cdf0e10cSrcweir const SCSIZE   SCSIZE_MAX   = ::std::numeric_limits<SCSIZE>::max();
77cdf0e10cSrcweir 
78cdf0e10cSrcweir // A define to handle critical sections we hopefully don't need very often.
79cdf0e10cSrcweir #define SC_ROWLIMIT_MORE_THAN_32K 1     /* set to 1 if we throw the switch */
80cdf0e10cSrcweir 
81cdf0e10cSrcweir // The maximum values. Defines are needed for preprocessor checks, for example
82cdf0e10cSrcweir // in bcaslot.cxx, otherwise type safe constants are preferred.
83cdf0e10cSrcweir //#define MAXROWCOUNT_DEFINE 65536
84cdf0e10cSrcweir #define MAXROWCOUNT_DEFINE 1048576
85cdf0e10cSrcweir #define MAXCOLCOUNT_DEFINE 1024
86cdf0e10cSrcweir 
87cdf0e10cSrcweir // Count values
88cdf0e10cSrcweir const SCROW       MAXROWCOUNT    = MAXROWCOUNT_DEFINE;
89cdf0e10cSrcweir const SCCOL       MAXCOLCOUNT    = MAXCOLCOUNT_DEFINE;
90cdf0e10cSrcweir const SCTAB       MAXTABCOUNT    = 256;
91cdf0e10cSrcweir const SCCOLROW    MAXCOLROWCOUNT = MAXROWCOUNT;
92cdf0e10cSrcweir // Maximum values
93cdf0e10cSrcweir const SCROW       MAXROW         = MAXROWCOUNT - 1;
94cdf0e10cSrcweir const SCCOL       MAXCOL         = MAXCOLCOUNT - 1;
95cdf0e10cSrcweir const SCTAB       MAXTAB         = MAXTABCOUNT - 1;
96cdf0e10cSrcweir const SCCOLROW    MAXCOLROW      = MAXROW;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 
99cdf0e10cSrcweir // Special values
100cdf0e10cSrcweir const SCTAB SC_TAB_APPEND     = SCTAB_MAX;
101cdf0e10cSrcweir const SCTAB TABLEID_DOC       = SCTAB_MAX;  // entire document, e.g. protect
102cdf0e10cSrcweir const SCROW SCROWS32K         = 32000;
103cdf0e10cSrcweir const SCCOL SCCOL_REPEAT_NONE = SCCOL_MAX;
104cdf0e10cSrcweir const SCROW SCROW_REPEAT_NONE = SCROW_MAX;
105cdf0e10cSrcweir 
106cdf0e10cSrcweir 
107cdf0e10cSrcweir // We hope to get rid of the binary file format. If not, these are the places
108cdf0e10cSrcweir // we'd have to investigate because variable types changed. Just place code in
109cdf0e10cSrcweir // #if SC_ROWLIMIT_STREAM_ACCESS for now.
110cdf0e10cSrcweir #define SC_ROWLIMIT_STREAM_ACCESS 0
111cdf0e10cSrcweir // usage:
112cdf0e10cSrcweir //#if SC_ROWLIMIT_STREAM_ACCESS
113cdf0e10cSrcweir //#error address types changed!
114cdf0e10cSrcweir //... code ...
115cdf0e10cSrcweir //#endif // SC_ROWLIMIT_STREAM_ACCESS
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 
118cdf0e10cSrcweir // For future reference, place in code where more than 64k rows would need a
119cdf0e10cSrcweir // special handling:
120cdf0e10cSrcweir // #if SC_ROWLIMIT_MORE_THAN_64K
121cdf0e10cSrcweir // #error row limit 64k
122cdf0e10cSrcweir // #endif
123cdf0e10cSrcweir #if MAXROWCOUNT_DEFINE > 65536
124cdf0e10cSrcweir #define SC_ROWLIMIT_MORE_THAN_64K 1
125cdf0e10cSrcweir #else
126cdf0e10cSrcweir #define SC_ROWLIMIT_MORE_THAN_64K 0
127cdf0e10cSrcweir #endif
128cdf0e10cSrcweir const SCROW SCROWS64K = 65536;
129cdf0e10cSrcweir 
130cdf0e10cSrcweir // === old stuff defines =====================================================
131cdf0e10cSrcweir 
132cdf0e10cSrcweir #define MAXROW_30   8191
133cdf0e10cSrcweir #define MAXROW_40   31999
134cdf0e10cSrcweir 
135cdf0e10cSrcweir #ifdef SC_LIMIT_ROWS
136cdf0e10cSrcweir #undef MAXROWCOUNT_DEFINE
137cdf0e10cSrcweir #define MAXROWCOUNT_DEFINE 8192
138cdf0e10cSrcweir const SCROW W16MAXROWCOUNT = MAXROWCOUNT_DEFINE;
139cdf0e10cSrcweir const SCROW W16MAXROW = W16MAXROWCOUNT - 1;
140cdf0e10cSrcweir #define MAXROWCOUNT W16MAXROWCOUNT
141cdf0e10cSrcweir #define MAXROW      W16MAXROW
142cdf0e10cSrcweir #endif
143cdf0e10cSrcweir 
144cdf0e10cSrcweir #define VALIDCOL(nCol)                  (ValidCol(nCol))
145cdf0e10cSrcweir #define VALIDROW(nRow)                  (ValidRow(nRow))
146cdf0e10cSrcweir #define VALIDTAB(nTab)                  (ValidTab(nTab))
147cdf0e10cSrcweir #define VALIDCOLROW(nCol,nRow)          (ValidColRow(nCol,nRow))
148cdf0e10cSrcweir #define VALIDCOLROWTAB(nCol,nRow,nTab)  (ValidColRowTab(nCol,nRow,nTab))
149cdf0e10cSrcweir 
150cdf0e10cSrcweir // === old stuff defines end =================================================
151cdf0e10cSrcweir 
ValidCol(SCCOL nCol)152cdf0e10cSrcweir inline bool ValidCol( SCCOL nCol )
153cdf0e10cSrcweir {
154cdf0e10cSrcweir     return static_cast<SCCOL>(0) <= nCol && nCol <= MAXCOL;
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
ValidRow(SCROW nRow)157cdf0e10cSrcweir inline bool ValidRow( SCROW nRow )
158cdf0e10cSrcweir {
159cdf0e10cSrcweir     return static_cast<SCROW>(0) <= nRow && nRow <= MAXROW;
160cdf0e10cSrcweir }
161cdf0e10cSrcweir 
ValidTab(SCTAB nTab)162cdf0e10cSrcweir inline bool ValidTab( SCTAB nTab )
163cdf0e10cSrcweir {
164cdf0e10cSrcweir     return static_cast<SCTAB>(0) <= nTab && nTab <= MAXTAB;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
ValidTab(SCTAB nTab,SCTAB nMaxTab)167cdf0e10cSrcweir inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     return static_cast<SCTAB>(0) <= nTab && nTab <= nMaxTab;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir 
ValidColRow(SCCOL nCol,SCROW nRow)172cdf0e10cSrcweir inline bool ValidColRow( SCCOL nCol, SCROW nRow )
173cdf0e10cSrcweir {
174cdf0e10cSrcweir     return ValidCol( nCol) && ValidRow( nRow);
175cdf0e10cSrcweir }
176cdf0e10cSrcweir 
ValidColRowTab(SCCOL nCol,SCROW nRow,SCTAB nTab)177cdf0e10cSrcweir inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir     return ValidCol( nCol) && ValidRow( nRow) && ValidTab( nTab);
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
SanitizeCol(SCCOL nCol)182cdf0e10cSrcweir inline SCCOL SanitizeCol( SCCOL nCol )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     return nCol < 0 ? 0 : (nCol > MAXCOL ? MAXCOL : nCol);
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
SanitizeRow(SCROW nRow)187cdf0e10cSrcweir inline SCROW SanitizeRow( SCROW nRow )
188cdf0e10cSrcweir {
189cdf0e10cSrcweir     return nRow < 0 ? 0 : (nRow > MAXROW ? MAXROW : nRow);
190cdf0e10cSrcweir }
191cdf0e10cSrcweir 
SanitizeTab(SCTAB nTab)192cdf0e10cSrcweir inline SCTAB SanitizeTab( SCTAB nTab )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir     return nTab < 0 ? 0 : (nTab > MAXTAB ? MAXTAB : nTab);
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
SanitizeTab(SCTAB nTab,SCTAB nMaxTab)197cdf0e10cSrcweir inline SCTAB SanitizeTab( SCTAB nTab, SCTAB nMaxTab )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir     return nTab < 0 ? 0 : (nTab > nMaxTab ? nMaxTab : nTab);
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir // === ScAddress =============================================================
203cdf0e10cSrcweir 
204cdf0e10cSrcweir // The old cell address is combined in one UINT32:
205cdf0e10cSrcweir // +---+---+-------+
206cdf0e10cSrcweir // |Tab|Col|  Row  |
207cdf0e10cSrcweir // +---+---+-------+
208cdf0e10cSrcweir // For speed reasons access isn't done by shifting bits but by using platform
209cdf0e10cSrcweir // dependent casts, which unfortunately also leads to aliasing problems when
210cdf0e10cSrcweir // not using gcc -fno-strict-aliasing
211cdf0e10cSrcweir 
212cdf0e10cSrcweir // The result of ConvertRef() is a bit group of the following:
213cdf0e10cSrcweir 
214cdf0e10cSrcweir #define SCA_COL_ABSOLUTE    0x01
215cdf0e10cSrcweir #define SCA_ROW_ABSOLUTE    0x02
216cdf0e10cSrcweir #define SCA_TAB_ABSOLUTE    0x04
217cdf0e10cSrcweir #define SCA_TAB_3D          0x08
218cdf0e10cSrcweir #define SCA_COL2_ABSOLUTE   0x10
219cdf0e10cSrcweir #define SCA_ROW2_ABSOLUTE   0x20
220cdf0e10cSrcweir #define SCA_TAB2_ABSOLUTE   0x40
221cdf0e10cSrcweir #define SCA_TAB2_3D         0x80
222cdf0e10cSrcweir #define SCA_VALID_ROW       0x0100
223cdf0e10cSrcweir #define SCA_VALID_COL       0x0200
224cdf0e10cSrcweir #define SCA_VALID_TAB       0x0400
225cdf0e10cSrcweir // somewhat cheesy kludge to force the display of the document name even for
226cdf0e10cSrcweir // local references.  Requires TAB_3D to be valid
227cdf0e10cSrcweir #define SCA_FORCE_DOC       0x0800
228cdf0e10cSrcweir #define SCA_VALID_ROW2      0x1000
229cdf0e10cSrcweir #define SCA_VALID_COL2      0x2000
230cdf0e10cSrcweir #define SCA_VALID_TAB2      0x4000
231cdf0e10cSrcweir #define SCA_VALID           0x8000
232cdf0e10cSrcweir 
233cdf0e10cSrcweir #define SCA_ABS               SCA_VALID \
234cdf0e10cSrcweir                             | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
235cdf0e10cSrcweir 
236cdf0e10cSrcweir #define SCR_ABS               SCA_ABS \
237cdf0e10cSrcweir                             | SCA_COL2_ABSOLUTE | SCA_ROW2_ABSOLUTE | SCA_TAB2_ABSOLUTE
238cdf0e10cSrcweir 
239cdf0e10cSrcweir #define SCA_ABS_3D          SCA_ABS | SCA_TAB_3D
240cdf0e10cSrcweir #define SCR_ABS_3D          SCR_ABS | SCA_TAB_3D
241cdf0e10cSrcweir 
242cdf0e10cSrcweir // === ScAddress =============================================================
243cdf0e10cSrcweir 
244cdf0e10cSrcweir class ScAddress
245cdf0e10cSrcweir {
246cdf0e10cSrcweir private:
247cdf0e10cSrcweir     SCROW   nRow;
248cdf0e10cSrcweir     SCCOL   nCol;
249cdf0e10cSrcweir     SCTAB   nTab;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir public:
252cdf0e10cSrcweir 
253cdf0e10cSrcweir     enum Uninitialized      { UNINITIALIZED };
254cdf0e10cSrcweir     enum InitializeInvalid  { INITIALIZE_INVALID };
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     struct Details {
257cdf0e10cSrcweir         formula::FormulaGrammar::AddressConvention  eConv;
258cdf0e10cSrcweir         SCROW       nRow;
259cdf0e10cSrcweir         SCCOL       nCol;
DetailsScAddress::Details260cdf0e10cSrcweir         inline Details( formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP )
261cdf0e10cSrcweir             : eConv( eConvP ), nRow( nRowP ), nCol( nColP )
262cdf0e10cSrcweir             {}
DetailsScAddress::Details263cdf0e10cSrcweir         inline Details( formula::FormulaGrammar::AddressConvention eConvP, ScAddress const & rAddr )
264cdf0e10cSrcweir             : eConv( eConvP ), nRow( rAddr.Row() ), nCol( rAddr.Col() )
265cdf0e10cSrcweir             {}
DetailsScAddress::Details266cdf0e10cSrcweir         inline Details( formula::FormulaGrammar::AddressConvention eConvP)
267cdf0e10cSrcweir             : eConv( eConvP ), nRow( 0 ), nCol( 0 )
268cdf0e10cSrcweir             {}
269cdf0e10cSrcweir         /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
270cdf0e10cSrcweir         Details( const ScDocument* pDoc, const ScAddress & rAddr );
271cdf0e10cSrcweir //UNUSED2009-05 void SetPos( const ScDocument* pDoc, const ScAddress & rAddr );
272cdf0e10cSrcweir     };
273cdf0e10cSrcweir     SC_DLLPUBLIC static const Details detailsOOOa1;
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     struct ExternalInfo
276cdf0e10cSrcweir     {
277cdf0e10cSrcweir         String      maTabName;
278cdf0e10cSrcweir         sal_uInt16  mnFileId;
279cdf0e10cSrcweir         bool        mbExternal;
280cdf0e10cSrcweir 
ExternalInfoScAddress::ExternalInfo281cdf0e10cSrcweir         inline ExternalInfo() : mnFileId(0), mbExternal(false) {}
282cdf0e10cSrcweir     };
283cdf0e10cSrcweir 
ScAddress()284cdf0e10cSrcweir     inline ScAddress() : nRow(0), nCol(0), nTab(0) {}
ScAddress(SCCOL nColP,SCROW nRowP,SCTAB nTabP)285cdf0e10cSrcweir     inline ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
286cdf0e10cSrcweir         : nRow(nRowP), nCol(nColP), nTab(nTabP)
287cdf0e10cSrcweir         {}
288cdf0e10cSrcweir     /** Yes, it is what it seems to be: Uninitialized. May be used for
289cdf0e10cSrcweir         performance reasons if it is initialized by other means. */
ScAddress(Uninitialized)290cdf0e10cSrcweir     inline ScAddress( Uninitialized ) {}
ScAddress(InitializeInvalid)291cdf0e10cSrcweir     inline ScAddress( InitializeInvalid )
292cdf0e10cSrcweir         : nRow(-1), nCol(-1), nTab(-1) {}
ScAddress(const ScAddress & r)293cdf0e10cSrcweir     inline ScAddress( const ScAddress& r )
294cdf0e10cSrcweir         : nRow(r.nRow), nCol(r.nCol), nTab(r.nTab)
295cdf0e10cSrcweir         {}
296cdf0e10cSrcweir     inline ScAddress& operator=( const ScAddress& r );
297cdf0e10cSrcweir 
298cdf0e10cSrcweir     inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
Row() const299cdf0e10cSrcweir     inline SCROW Row() const { return nRow; }
Col() const300cdf0e10cSrcweir     inline SCCOL Col() const { return nCol; }
Tab() const301cdf0e10cSrcweir     inline SCTAB Tab() const { return nTab; }
SetRow(SCROW nRowP)302cdf0e10cSrcweir     inline void SetRow( SCROW nRowP ) { nRow = nRowP; }
SetCol(SCCOL nColP)303cdf0e10cSrcweir     inline void SetCol( SCCOL nColP ) { nCol = nColP; }
SetTab(SCTAB nTabP)304cdf0e10cSrcweir     inline void SetTab( SCTAB nTabP ) { nTab = nTabP; }
SetInvalid()305cdf0e10cSrcweir     inline void SetInvalid() { nRow = -1; nCol = -1; nTab = -1; }
IsValid() const306cdf0e10cSrcweir     inline bool IsValid() const { return (nRow >= 0) && (nCol >= 0) && (nTab >= 0); }
307cdf0e10cSrcweir     inline void PutInOrder( ScAddress& r );
IncRow(SCsROW n=1)308cdf0e10cSrcweir     inline void IncRow( SCsROW n=1 ) { nRow = sal::static_int_cast<SCROW>(nRow + n); }
IncCol(SCsCOL n=1)309cdf0e10cSrcweir     inline void IncCol( SCsCOL n=1 ) { nCol = sal::static_int_cast<SCCOL>(nCol + n); }
IncTab(SCsTAB n=1)310cdf0e10cSrcweir     inline void IncTab( SCsTAB n=1 ) { nTab = sal::static_int_cast<SCTAB>(nTab + n); }
GetVars(SCCOL & nColP,SCROW & nRowP,SCTAB & nTabP) const311cdf0e10cSrcweir     inline void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
312cdf0e10cSrcweir     { nColP = nCol; nRowP = nRow; nTabP = nTab; }
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     SC_DLLPUBLIC sal_uInt16 Parse( const String&, ScDocument* = NULL,
315cdf0e10cSrcweir                   const Details& rDetails = detailsOOOa1,
316cdf0e10cSrcweir                   ExternalInfo* pExtInfo = NULL,
317cdf0e10cSrcweir                   const ::com::sun::star::uno::Sequence<
318cdf0e10cSrcweir                     const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     SC_DLLPUBLIC void Format( String&, sal_uInt16 = 0, ScDocument* = NULL,
321cdf0e10cSrcweir                  const Details& rDetails = detailsOOOa1) const;
322cdf0e10cSrcweir 
323cdf0e10cSrcweir     // The document for the maximum defined sheet number
324cdf0e10cSrcweir     SC_DLLPUBLIC bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
325cdf0e10cSrcweir     inline bool operator==( const ScAddress& r ) const;
326cdf0e10cSrcweir     inline bool operator!=( const ScAddress& r ) const;
327cdf0e10cSrcweir     inline bool operator<( const ScAddress& r ) const;
328cdf0e10cSrcweir     inline bool operator<=( const ScAddress& r ) const;
329cdf0e10cSrcweir     inline bool operator>( const ScAddress& r ) const;
330cdf0e10cSrcweir     inline bool operator>=( const ScAddress& r ) const;
331cdf0e10cSrcweir 
332cdf0e10cSrcweir     inline size_t hash() const;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     /// "A1" or "$A$1" or R1C1 or R[1]C[1]
335cdf0e10cSrcweir     String GetColRowString( bool bAbsolute = sal_False,
336cdf0e10cSrcweir                             const Details& rDetails = detailsOOOa1) const;
337cdf0e10cSrcweir };
338cdf0e10cSrcweir 
PutInOrder(ScAddress & r)339cdf0e10cSrcweir inline void ScAddress::PutInOrder( ScAddress& r )
340cdf0e10cSrcweir {
341cdf0e10cSrcweir     if ( r.Col() < Col() )
342cdf0e10cSrcweir     {
343cdf0e10cSrcweir         SCCOL nTmp = r.Col();
344cdf0e10cSrcweir         r.SetCol( Col() );
345cdf0e10cSrcweir         SetCol( nTmp );
346cdf0e10cSrcweir     }
347cdf0e10cSrcweir     if ( r.Row() < Row() )
348cdf0e10cSrcweir     {
349cdf0e10cSrcweir         SCROW nTmp = r.Row();
350cdf0e10cSrcweir         r.SetRow( Row() );
351cdf0e10cSrcweir         SetRow( nTmp );
352cdf0e10cSrcweir     }
353cdf0e10cSrcweir     if ( r.Tab() < Tab() )
354cdf0e10cSrcweir     {
355cdf0e10cSrcweir         SCTAB nTmp = r.Tab();
356cdf0e10cSrcweir         r.SetTab( Tab() );
357cdf0e10cSrcweir         SetTab( nTmp );
358cdf0e10cSrcweir     }
359cdf0e10cSrcweir }
360cdf0e10cSrcweir 
Set(SCCOL nColP,SCROW nRowP,SCTAB nTabP)361cdf0e10cSrcweir inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
362cdf0e10cSrcweir {
363cdf0e10cSrcweir     nCol = nColP;
364cdf0e10cSrcweir     nRow = nRowP;
365cdf0e10cSrcweir     nTab = nTabP;
366cdf0e10cSrcweir }
367cdf0e10cSrcweir 
operator =(const ScAddress & r)368cdf0e10cSrcweir inline ScAddress& ScAddress::operator=( const ScAddress& r )
369cdf0e10cSrcweir {
370cdf0e10cSrcweir     nCol = r.nCol;
371cdf0e10cSrcweir     nRow = r.nRow;
372cdf0e10cSrcweir     nTab = r.nTab;
373cdf0e10cSrcweir     return *this;
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
operator ==(const ScAddress & r) const376cdf0e10cSrcweir inline bool ScAddress::operator==( const ScAddress& r ) const
377cdf0e10cSrcweir {
378cdf0e10cSrcweir     return nRow == r.nRow && nCol == r.nCol && nTab == r.nTab;
379cdf0e10cSrcweir }
380cdf0e10cSrcweir 
operator !=(const ScAddress & r) const381cdf0e10cSrcweir inline bool ScAddress::operator!=( const ScAddress& r ) const
382cdf0e10cSrcweir {
383cdf0e10cSrcweir     return !operator==( r );
384cdf0e10cSrcweir }
385cdf0e10cSrcweir 
operator <(const ScAddress & r) const386cdf0e10cSrcweir inline bool ScAddress::operator<( const ScAddress& r ) const
387cdf0e10cSrcweir {
388cdf0e10cSrcweir     // Same behavior as the old sal_uInt32 nAddress < r.nAddress with encoded
389cdf0e10cSrcweir     // tab|col|row bit fields.
390cdf0e10cSrcweir     if (nTab == r.nTab)
391cdf0e10cSrcweir     {
392cdf0e10cSrcweir         if (nCol == r.nCol)
393cdf0e10cSrcweir             return nRow < r.nRow;
394cdf0e10cSrcweir         else
395cdf0e10cSrcweir             return nCol < r.nCol;
396cdf0e10cSrcweir     }
397cdf0e10cSrcweir     else
398cdf0e10cSrcweir         return nTab < r.nTab;
399cdf0e10cSrcweir }
400cdf0e10cSrcweir 
operator <=(const ScAddress & r) const401cdf0e10cSrcweir inline bool ScAddress::operator<=( const ScAddress& r ) const
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     return operator<( r ) || operator==( r );
404cdf0e10cSrcweir }
405cdf0e10cSrcweir 
operator >(const ScAddress & r) const406cdf0e10cSrcweir inline bool ScAddress::operator>( const ScAddress& r ) const
407cdf0e10cSrcweir {
408cdf0e10cSrcweir     return !operator<=( r );
409cdf0e10cSrcweir }
410cdf0e10cSrcweir 
operator >=(const ScAddress & r) const411cdf0e10cSrcweir inline bool ScAddress::operator>=( const ScAddress& r ) const
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     return !operator<( r );
414cdf0e10cSrcweir }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 
hash() const417cdf0e10cSrcweir inline size_t ScAddress::hash() const
418cdf0e10cSrcweir {
419cdf0e10cSrcweir     // Assume that there are not that many addresses with row > 2^16 AND column
420cdf0e10cSrcweir     // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
421cdf0e10cSrcweir     if (nRow <= 0xffff)
422cdf0e10cSrcweir         return (static_cast<size_t>(nTab) << 24) ^
423cdf0e10cSrcweir             (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
424cdf0e10cSrcweir     else
425cdf0e10cSrcweir         return (static_cast<size_t>(nTab) << 28) ^
426cdf0e10cSrcweir             (static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
427cdf0e10cSrcweir }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir struct ScAddressHashFunctor
430cdf0e10cSrcweir {
operator ()ScAddressHashFunctor431cdf0e10cSrcweir     size_t operator()( const ScAddress & rAdr ) const
432cdf0e10cSrcweir     {
433cdf0e10cSrcweir         return rAdr.hash();
434cdf0e10cSrcweir     }
435cdf0e10cSrcweir };
436cdf0e10cSrcweir 
437cdf0e10cSrcweir struct ScAddressEqualFunctor
438cdf0e10cSrcweir {
operator ()ScAddressEqualFunctor439cdf0e10cSrcweir     bool operator()( const ScAddress & rAdr1, const ScAddress & rAdr2 ) const
440cdf0e10cSrcweir     {
441cdf0e10cSrcweir         return rAdr1 == rAdr2;
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir };
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 
446cdf0e10cSrcweir // === ScRange ===============================================================
447cdf0e10cSrcweir 
448cdf0e10cSrcweir class ScRange
449cdf0e10cSrcweir {
450cdf0e10cSrcweir public:
451cdf0e10cSrcweir     ScAddress aStart, aEnd;
ScRange()452cdf0e10cSrcweir     inline ScRange() : aStart(), aEnd() {}
ScRange(ScAddress::Uninitialized e)453cdf0e10cSrcweir     inline ScRange( ScAddress::Uninitialized e )
454cdf0e10cSrcweir         : aStart( e ), aEnd( e ) {}
ScRange(ScAddress::InitializeInvalid e)455cdf0e10cSrcweir     inline ScRange( ScAddress::InitializeInvalid e )
456cdf0e10cSrcweir         : aStart( e ), aEnd( e ) {}
ScRange(const ScAddress & s,const ScAddress & e)457cdf0e10cSrcweir     inline ScRange( const ScAddress& s, const ScAddress& e )
458cdf0e10cSrcweir         : aStart( s ), aEnd( e ) { aStart.PutInOrder( aEnd ); }
ScRange(const ScRange & r)459cdf0e10cSrcweir     inline ScRange( const ScRange& r ) : aStart( r.aStart ), aEnd( r.aEnd ) {}
ScRange(const ScAddress & r)460cdf0e10cSrcweir     inline ScRange( const ScAddress& r ) : aStart( r ), aEnd( r ) {}
ScRange(SCCOL nCol,SCROW nRow,SCTAB nTab)461cdf0e10cSrcweir     inline ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab )
462cdf0e10cSrcweir         : aStart( nCol, nRow, nTab ), aEnd( aStart ) {}
ScRange(SCCOL nCol1,SCROW nRow1,SCTAB nTab1,SCCOL nCol2,SCROW nRow2,SCTAB nTab2)463cdf0e10cSrcweir     inline ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
464cdf0e10cSrcweir              SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
465cdf0e10cSrcweir         : aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 ) {}
466cdf0e10cSrcweir 
operator =(const ScRange & r)467cdf0e10cSrcweir     inline ScRange& operator=( const ScRange& r )
468cdf0e10cSrcweir     { aStart = r.aStart; aEnd = r.aEnd; return *this; }
operator =(const ScAddress & rPos)469cdf0e10cSrcweir     inline ScRange& operator=( const ScAddress& rPos )
470cdf0e10cSrcweir     { aStart = aEnd = rPos; return *this; }
SetInvalid()471cdf0e10cSrcweir     inline void SetInvalid() { aStart.SetInvalid(); aEnd.SetInvalid(); }
IsValid() const472cdf0e10cSrcweir     inline bool IsValid() const { return aStart.IsValid() && aEnd.IsValid(); }
473cdf0e10cSrcweir     inline bool In( const ScAddress& ) const;   // is Address& in Range?
474cdf0e10cSrcweir     inline bool In( const ScRange& ) const;     // is Range& in Range?
475cdf0e10cSrcweir 
476cdf0e10cSrcweir     sal_uInt16 Parse( const String&, ScDocument* = NULL,
477cdf0e10cSrcweir                   const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
478cdf0e10cSrcweir                   ScAddress::ExternalInfo* pExtInfo = NULL,
479cdf0e10cSrcweir                   const ::com::sun::star::uno::Sequence<
480cdf0e10cSrcweir                     const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
481cdf0e10cSrcweir 
482cdf0e10cSrcweir     sal_uInt16 ParseAny( const String&, ScDocument* = NULL,
483cdf0e10cSrcweir                      const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
484cdf0e10cSrcweir     SC_DLLPUBLIC sal_uInt16 ParseCols( const String&, ScDocument* = NULL,
485cdf0e10cSrcweir                      const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
486cdf0e10cSrcweir     SC_DLLPUBLIC sal_uInt16 ParseRows( const String&, ScDocument* = NULL,
487cdf0e10cSrcweir                      const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
488cdf0e10cSrcweir 
489cdf0e10cSrcweir     /** Parse an Excel style reference up to and including the sheet name
490cdf0e10cSrcweir         separator '!', including detection of external documents and sheet
491cdf0e10cSrcweir         names, and in case of MOOXML import the bracketed index is used to
492cdf0e10cSrcweir         determine the actual document name passed in pExternalLinks. For
493cdf0e10cSrcweir         internal references (resulting rExternDocName empty), aStart.nTab and
494cdf0e10cSrcweir         aEnd.nTab are set, or -1 if sheet name not found.
495cdf0e10cSrcweir         @param bOnlyAcceptSingle  If <TRUE/>, a 3D reference (Sheet1:Sheet2)
496cdf0e10cSrcweir             encountered results in an error (NULL returned).
497cdf0e10cSrcweir         @param pExternalLinks  pointer to ExternalLinkInfo sequence, may be
498cdf0e10cSrcweir             NULL for non-filter usage, in which case indices such as [1] are
499cdf0e10cSrcweir             not resolved.
500cdf0e10cSrcweir         @returns
501cdf0e10cSrcweir             Pointer to the position after '!' if successfully parsed, and
502cdf0e10cSrcweir             rExternDocName, rStartTabName and/or rEndTabName filled if
503cdf0e10cSrcweir             applicable. SCA_... flags set in nFlags.
504cdf0e10cSrcweir             Or if no valid document and/or sheet header could be parsed the start
505cdf0e10cSrcweir             position passed with pString.
506cdf0e10cSrcweir             Or NULL if a 3D sheet header could be parsed but
507cdf0e10cSrcweir             bOnlyAcceptSingle==true was given.
508cdf0e10cSrcweir      */
509cdf0e10cSrcweir     const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument* pDoc,
510cdf0e10cSrcweir             String& rExternDocName, String& rStartTabName, String& rEndTabName, sal_uInt16& nFlags,
511cdf0e10cSrcweir             bool bOnlyAcceptSingle,
512cdf0e10cSrcweir             const ::com::sun::star::uno::Sequence<
513cdf0e10cSrcweir                 const ::com::sun::star::sheet::ExternalLinkInfo > * pExternalLinks = NULL );
514cdf0e10cSrcweir 
515cdf0e10cSrcweir     SC_DLLPUBLIC void Format( String&, sal_uInt16 = 0, ScDocument* = NULL,
516cdf0e10cSrcweir                  const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 ) const;
517cdf0e10cSrcweir 
518cdf0e10cSrcweir     inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
519cdf0e10cSrcweir         SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
520cdf0e10cSrcweir     // The document for the maximum defined sheet number
521cdf0e10cSrcweir     SC_DLLPUBLIC bool Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* =NULL );
522cdf0e10cSrcweir     SC_DLLPUBLIC void Justify();
523cdf0e10cSrcweir     SC_DLLPUBLIC void ExtendTo( const ScRange& rRange );
524cdf0e10cSrcweir     SC_DLLPUBLIC bool Intersects( const ScRange& ) const;    // do two ranges intersect?
525cdf0e10cSrcweir     inline bool operator==( const ScRange& r ) const;
526cdf0e10cSrcweir     inline bool operator!=( const ScRange& r ) const;
527cdf0e10cSrcweir     inline bool operator<( const ScRange& r ) const;
528cdf0e10cSrcweir     inline bool operator<=( const ScRange& r ) const;
529cdf0e10cSrcweir     inline bool operator>( const ScRange& r ) const;
530cdf0e10cSrcweir     inline bool operator>=( const ScRange& r ) const;
531cdf0e10cSrcweir 
532cdf0e10cSrcweir     /// Hash 2D area ignoring table number.
533cdf0e10cSrcweir     inline size_t hashArea() const;
534cdf0e10cSrcweir     /// Hash start column and start and end rows.
535cdf0e10cSrcweir     inline size_t hashStartColumn() const;
536cdf0e10cSrcweir };
537cdf0e10cSrcweir 
GetVars(SCCOL & nCol1,SCROW & nRow1,SCTAB & nTab1,SCCOL & nCol2,SCROW & nRow2,SCTAB & nTab2) const538cdf0e10cSrcweir inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
539cdf0e10cSrcweir         SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
540cdf0e10cSrcweir {
541cdf0e10cSrcweir     aStart.GetVars( nCol1, nRow1, nTab1 );
542cdf0e10cSrcweir     aEnd.GetVars( nCol2, nRow2, nTab2 );
543cdf0e10cSrcweir }
544cdf0e10cSrcweir 
operator ==(const ScRange & r) const545cdf0e10cSrcweir inline bool ScRange::operator==( const ScRange& r ) const
546cdf0e10cSrcweir {
547cdf0e10cSrcweir     return ( (aStart == r.aStart) && (aEnd == r.aEnd) );
548cdf0e10cSrcweir }
549cdf0e10cSrcweir 
operator !=(const ScRange & r) const550cdf0e10cSrcweir inline bool ScRange::operator!=( const ScRange& r ) const
551cdf0e10cSrcweir {
552cdf0e10cSrcweir     return !operator==( r );
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir // Sort on upper left corner, if equal then use lower right too.
operator <(const ScRange & r) const556cdf0e10cSrcweir inline bool ScRange::operator<( const ScRange& r ) const
557cdf0e10cSrcweir {
558cdf0e10cSrcweir     return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
559cdf0e10cSrcweir }
560cdf0e10cSrcweir 
operator <=(const ScRange & r) const561cdf0e10cSrcweir inline bool ScRange::operator<=( const ScRange& r ) const
562cdf0e10cSrcweir {
563cdf0e10cSrcweir     return operator<( r ) || operator==( r );
564cdf0e10cSrcweir }
565cdf0e10cSrcweir 
operator >(const ScRange & r) const566cdf0e10cSrcweir inline bool ScRange::operator>( const ScRange& r ) const
567cdf0e10cSrcweir {
568cdf0e10cSrcweir     return !operator<=( r );
569cdf0e10cSrcweir }
570cdf0e10cSrcweir 
operator >=(const ScRange & r) const571cdf0e10cSrcweir inline bool ScRange::operator>=( const ScRange& r ) const
572cdf0e10cSrcweir {
573cdf0e10cSrcweir     return !operator<( r );
574cdf0e10cSrcweir }
575cdf0e10cSrcweir 
In(const ScAddress & rAddr) const576cdf0e10cSrcweir inline bool ScRange::In( const ScAddress& rAddr ) const
577cdf0e10cSrcweir {
578cdf0e10cSrcweir     return
579cdf0e10cSrcweir         aStart.Col() <= rAddr.Col() && rAddr.Col() <= aEnd.Col() &&
580cdf0e10cSrcweir         aStart.Row() <= rAddr.Row() && rAddr.Row() <= aEnd.Row() &&
581cdf0e10cSrcweir         aStart.Tab() <= rAddr.Tab() && rAddr.Tab() <= aEnd.Tab();
582cdf0e10cSrcweir }
583cdf0e10cSrcweir 
In(const ScRange & r) const584cdf0e10cSrcweir inline bool ScRange::In( const ScRange& r ) const
585cdf0e10cSrcweir {
586cdf0e10cSrcweir     return
587cdf0e10cSrcweir         aStart.Col() <= r.aStart.Col() && r.aEnd.Col() <= aEnd.Col() &&
588cdf0e10cSrcweir         aStart.Row() <= r.aStart.Row() && r.aEnd.Row() <= aEnd.Row() &&
589cdf0e10cSrcweir         aStart.Tab() <= r.aStart.Tab() && r.aEnd.Tab() <= aEnd.Tab();
590cdf0e10cSrcweir }
591cdf0e10cSrcweir 
592cdf0e10cSrcweir 
hashArea() const593cdf0e10cSrcweir inline size_t ScRange::hashArea() const
594cdf0e10cSrcweir {
595cdf0e10cSrcweir     // Assume that there are not that many ranges with identical corners so we
596cdf0e10cSrcweir     // won't have too many collisions. Also assume that more lower row and
597cdf0e10cSrcweir     // column numbers are used so that there are not too many conflicts with
598cdf0e10cSrcweir     // the columns hashed into the values, and that start row and column
599cdf0e10cSrcweir     // usually don't exceed certain values. High bits are not masked off and
600cdf0e10cSrcweir     // may overlap with lower bits of other values, e.g. if start column is
601cdf0e10cSrcweir     // greater than assumed.
602cdf0e10cSrcweir     return
603cdf0e10cSrcweir         (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
604cdf0e10cSrcweir         (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
605cdf0e10cSrcweir         (static_cast<size_t>(aEnd.Col()) << 15) ^   // end column <= 2^6
606cdf0e10cSrcweir         static_cast<size_t>(aEnd.Row());            // end row <= 2^15
607cdf0e10cSrcweir }
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 
hashStartColumn() const610cdf0e10cSrcweir inline size_t ScRange::hashStartColumn() const
611cdf0e10cSrcweir {
612cdf0e10cSrcweir     // Assume that for the start row more lower row numbers are used so that
613cdf0e10cSrcweir     // there are not too many conflicts with the column hashed into the higher
614cdf0e10cSrcweir     // values.
615cdf0e10cSrcweir     return
616cdf0e10cSrcweir         (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
617cdf0e10cSrcweir         (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
618cdf0e10cSrcweir         static_cast<size_t>(aEnd.Row());
619cdf0e10cSrcweir }
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 
622cdf0e10cSrcweir struct ScRangeHashAreaFunctor
623cdf0e10cSrcweir {
operator ()ScRangeHashAreaFunctor624cdf0e10cSrcweir     size_t operator()( const ScRange & rRange ) const
625cdf0e10cSrcweir     {
626cdf0e10cSrcweir         return rRange.hashArea();
627cdf0e10cSrcweir     }
628cdf0e10cSrcweir };
629cdf0e10cSrcweir 
630cdf0e10cSrcweir struct ScRangeEqualFunctor
631cdf0e10cSrcweir {
operator ()ScRangeEqualFunctor632cdf0e10cSrcweir     bool operator()( const ScRange & rRange1, const ScRange & rRange2 ) const
633cdf0e10cSrcweir     {
634cdf0e10cSrcweir         return rRange1 == rRange2;
635cdf0e10cSrcweir     }
636cdf0e10cSrcweir };
637cdf0e10cSrcweir 
638cdf0e10cSrcweir 
639cdf0e10cSrcweir // === ScRangePair ===========================================================
640cdf0e10cSrcweir 
641cdf0e10cSrcweir class ScRangePair
642cdf0e10cSrcweir {
643cdf0e10cSrcweir private:
644cdf0e10cSrcweir     ScRange aRange[2];
645cdf0e10cSrcweir 
646cdf0e10cSrcweir public:
ScRangePair()647cdf0e10cSrcweir     ScRangePair() {}
ScRangePair(const ScRangePair & r)648cdf0e10cSrcweir     ScRangePair( const ScRangePair& r )
649cdf0e10cSrcweir         { aRange[0] = r.aRange[0]; aRange[1] = r.aRange[1]; }
ScRangePair(const ScRange & r1,const ScRange & r2)650cdf0e10cSrcweir     ScRangePair( const ScRange& r1, const ScRange& r2 )
651cdf0e10cSrcweir         {  aRange[0] = r1; aRange[1] = r2; }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir     inline ScRangePair& operator= ( const ScRangePair& r );
GetRange(sal_uInt16 n) const654cdf0e10cSrcweir     const ScRange&      GetRange( sal_uInt16 n ) const { return aRange[n]; }
GetRange(sal_uInt16 n)655cdf0e10cSrcweir     ScRange&            GetRange( sal_uInt16 n ) { return aRange[n]; }
656cdf0e10cSrcweir     inline int operator==( const ScRangePair& ) const;
657cdf0e10cSrcweir     inline int operator!=( const ScRangePair& ) const;
658cdf0e10cSrcweir };
659cdf0e10cSrcweir 
operator =(const ScRangePair & r)660cdf0e10cSrcweir inline ScRangePair& ScRangePair::operator= ( const ScRangePair& r )
661cdf0e10cSrcweir {
662cdf0e10cSrcweir     aRange[0] = r.aRange[0];
663cdf0e10cSrcweir     aRange[1] = r.aRange[1];
664cdf0e10cSrcweir     return *this;
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
operator ==(const ScRangePair & r) const667cdf0e10cSrcweir inline int ScRangePair::operator==( const ScRangePair& r ) const
668cdf0e10cSrcweir {
669cdf0e10cSrcweir     return ( (aRange[0] == r.aRange[0]) && (aRange[1] == r.aRange[1]) );
670cdf0e10cSrcweir }
671cdf0e10cSrcweir 
operator !=(const ScRangePair & r) const672cdf0e10cSrcweir inline int ScRangePair::operator!=( const ScRangePair& r ) const
673cdf0e10cSrcweir {
674cdf0e10cSrcweir     return !operator==( r );
675cdf0e10cSrcweir }
676cdf0e10cSrcweir 
677cdf0e10cSrcweir // === ScRefAddress ==========================================================
678cdf0e10cSrcweir 
679cdf0e10cSrcweir class ScRefAddress
680cdf0e10cSrcweir {
681cdf0e10cSrcweir             ScAddress           aAdr;
682cdf0e10cSrcweir             bool                bRelCol;
683cdf0e10cSrcweir             bool                bRelRow;
684cdf0e10cSrcweir             bool                bRelTab;
685cdf0e10cSrcweir public:
ScRefAddress()686cdf0e10cSrcweir     inline ScRefAddress() : bRelCol(false), bRelRow(false), bRelTab(false)
687cdf0e10cSrcweir         {}
ScRefAddress(SCCOL nCol,SCROW nRow,SCTAB nTab,bool bRelColP,bool bRelRowP,bool bRelTabP)688cdf0e10cSrcweir     inline ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab,
689cdf0e10cSrcweir             bool bRelColP, bool bRelRowP, bool bRelTabP ) :
690cdf0e10cSrcweir         aAdr(nCol, nRow, nTab),
691cdf0e10cSrcweir         bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
692cdf0e10cSrcweir         {}
ScRefAddress(const ScAddress & rAdr,bool bRelColP,bool bRelRowP,bool bRelTabP)693cdf0e10cSrcweir     inline ScRefAddress( const ScAddress& rAdr,
694cdf0e10cSrcweir             bool bRelColP, bool bRelRowP, bool bRelTabP ) :
695cdf0e10cSrcweir         aAdr(rAdr),
696cdf0e10cSrcweir         bRelCol(bRelColP), bRelRow(bRelRowP), bRelTab(bRelTabP)
697cdf0e10cSrcweir         {}
ScRefAddress(const ScRefAddress & rRef)698cdf0e10cSrcweir     inline ScRefAddress( const ScRefAddress& rRef ) :
699cdf0e10cSrcweir             aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
700cdf0e10cSrcweir             bRelTab(rRef.bRelTab)
701cdf0e10cSrcweir             {}
702cdf0e10cSrcweir 
703cdf0e10cSrcweir     inline  ScRefAddress&   operator=( const ScRefAddress& );
704cdf0e10cSrcweir 
IsRelCol() const705cdf0e10cSrcweir     inline  bool    IsRelCol() const { return bRelCol; }
IsRelRow() const706cdf0e10cSrcweir     inline  bool    IsRelRow() const { return bRelRow; }
IsRelTab() const707cdf0e10cSrcweir     inline  bool    IsRelTab() const { return bRelTab; }
708cdf0e10cSrcweir 
SetRelCol(bool bNewRelCol)709cdf0e10cSrcweir     inline  void    SetRelCol(bool bNewRelCol) { bRelCol = bNewRelCol; }
SetRelRow(bool bNewRelRow)710cdf0e10cSrcweir     inline  void    SetRelRow(bool bNewRelRow) { bRelRow = bNewRelRow; }
SetRelTab(bool bNewRelTab)711cdf0e10cSrcweir     inline  void    SetRelTab(bool bNewRelTab) { bRelTab = bNewRelTab; }
712cdf0e10cSrcweir 
713cdf0e10cSrcweir     inline  void    Set( const ScAddress& rAdr,
714cdf0e10cSrcweir                         bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
715cdf0e10cSrcweir     inline  void    Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
716cdf0e10cSrcweir                         bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
717cdf0e10cSrcweir 
GetAddress() const718cdf0e10cSrcweir     inline  const ScAddress&    GetAddress() const { return aAdr; }
Col() const719cdf0e10cSrcweir     inline  SCCOL   Col() const { return aAdr.Col(); }
Row() const720cdf0e10cSrcweir     inline  SCROW   Row() const { return aAdr.Row(); }
Tab() const721cdf0e10cSrcweir     inline  SCTAB   Tab() const { return aAdr.Tab(); }
722cdf0e10cSrcweir 
723cdf0e10cSrcweir     inline  int     operator == ( const ScRefAddress& r ) const;
operator !=(const ScRefAddress & r) const724cdf0e10cSrcweir     inline  int     operator != ( const ScRefAddress& r ) const
725cdf0e10cSrcweir                     { return !(operator==(r)); }
726cdf0e10cSrcweir 
727cdf0e10cSrcweir             String  GetRefString( ScDocument* pDoc, SCTAB nActTab,
728cdf0e10cSrcweir                                   const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
729cdf0e10cSrcweir };
730cdf0e10cSrcweir 
operator =(const ScRefAddress & rRef)731cdf0e10cSrcweir inline ScRefAddress& ScRefAddress::operator=( const ScRefAddress& rRef )
732cdf0e10cSrcweir {
733cdf0e10cSrcweir     aAdr = rRef.aAdr;
734cdf0e10cSrcweir     bRelCol = rRef.bRelCol;
735cdf0e10cSrcweir     bRelRow = rRef.bRelRow;
736cdf0e10cSrcweir     bRelTab = rRef.bRelTab;
737cdf0e10cSrcweir     return *this;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir 
Set(const ScAddress & rAdr,bool bNewRelCol,bool bNewRelRow,bool bNewRelTab)740cdf0e10cSrcweir inline void ScRefAddress::Set( const ScAddress& rAdr,
741cdf0e10cSrcweir         bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
742cdf0e10cSrcweir {
743cdf0e10cSrcweir     aAdr = rAdr;
744cdf0e10cSrcweir     bRelCol = bNewRelCol;
745cdf0e10cSrcweir     bRelRow = bNewRelRow;
746cdf0e10cSrcweir     bRelTab = bNewRelTab;
747cdf0e10cSrcweir }
748cdf0e10cSrcweir 
Set(SCCOL nNewCol,SCROW nNewRow,SCTAB nNewTab,bool bNewRelCol,bool bNewRelRow,bool bNewRelTab)749cdf0e10cSrcweir inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
750cdf0e10cSrcweir         bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir     aAdr.Set( nNewCol, nNewRow, nNewTab);
753cdf0e10cSrcweir     bRelCol = bNewRelCol;
754cdf0e10cSrcweir     bRelRow = bNewRelRow;
755cdf0e10cSrcweir     bRelTab = bNewRelTab;
756cdf0e10cSrcweir }
757cdf0e10cSrcweir 
operator ==(const ScRefAddress & r) const758cdf0e10cSrcweir inline int ScRefAddress::operator==( const ScRefAddress& r ) const
759cdf0e10cSrcweir {
760cdf0e10cSrcweir     return aAdr == r.aAdr && bRelCol == r.bRelCol && bRelRow == r.bRelRow &&
761cdf0e10cSrcweir         bRelTab == r.bRelTab;
762cdf0e10cSrcweir }
763cdf0e10cSrcweir 
764cdf0e10cSrcweir // ===========================================================================
765cdf0e10cSrcweir // Global functions
766cdf0e10cSrcweir // ===========================================================================
767cdf0e10cSrcweir 
768cdf0e10cSrcweir // Special values for cells always broadcasting or listening (RECALCMODE_ALWAYS
769cdf0e10cSrcweir // and the like).
770cdf0e10cSrcweir #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
771cdf0e10cSrcweir #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
772cdf0e10cSrcweir 
PutInOrder(T & nStart,T & nEnd)773cdf0e10cSrcweir template< typename T > void PutInOrder( T& nStart, T& nEnd )
774cdf0e10cSrcweir {
775cdf0e10cSrcweir     if (nEnd < nStart)
776cdf0e10cSrcweir     {
777cdf0e10cSrcweir         T nTemp;
778cdf0e10cSrcweir         nTemp = nEnd;
779cdf0e10cSrcweir         nEnd = nStart;
780cdf0e10cSrcweir         nStart = nTemp;
781cdf0e10cSrcweir     }
782cdf0e10cSrcweir }
783cdf0e10cSrcweir 
784cdf0e10cSrcweir bool ConvertSingleRef( ScDocument* pDoc, const String& rRefString,
785cdf0e10cSrcweir         SCTAB nDefTab, ScRefAddress& rRefAddress,
786cdf0e10cSrcweir         const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
787cdf0e10cSrcweir         ScAddress::ExternalInfo* pExtInfo = NULL );
788cdf0e10cSrcweir 
789cdf0e10cSrcweir bool ConvertDoubleRef(ScDocument* pDoc, const String& rRefString,
790cdf0e10cSrcweir         SCTAB nDefTab, ScRefAddress& rStartRefAddress,
791cdf0e10cSrcweir         ScRefAddress& rEndRefAddress,
792cdf0e10cSrcweir         const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
793cdf0e10cSrcweir         ScAddress::ExternalInfo* pExtInfo = NULL );
794cdf0e10cSrcweir 
795cdf0e10cSrcweir /// append alpha representation of column to buffer
796cdf0e10cSrcweir SC_DLLPUBLIC void ScColToAlpha( rtl::OUStringBuffer& rBuffer, SCCOL nCol);
797cdf0e10cSrcweir 
ScColToAlpha(String & rStr,SCCOL nCol)798cdf0e10cSrcweir inline void ScColToAlpha( String& rStr, SCCOL nCol)
799cdf0e10cSrcweir {
800cdf0e10cSrcweir     rtl::OUStringBuffer aBuf(2);
801cdf0e10cSrcweir     ScColToAlpha( aBuf, nCol);
802cdf0e10cSrcweir     rStr.Append( aBuf.getStr(), static_cast<xub_StrLen>(aBuf.getLength()));
803cdf0e10cSrcweir }
804cdf0e10cSrcweir 
ScColToAlpha(SCCOL nCol)805cdf0e10cSrcweir inline String ScColToAlpha( SCCOL nCol )
806cdf0e10cSrcweir {
807cdf0e10cSrcweir     rtl::OUStringBuffer aBuf(2);
808cdf0e10cSrcweir     ScColToAlpha( aBuf, nCol);
809cdf0e10cSrcweir     return aBuf.makeStringAndClear();
810cdf0e10cSrcweir }
811cdf0e10cSrcweir 
812cdf0e10cSrcweir /// get column number of A..IV... string
813cdf0e10cSrcweir bool AlphaToCol( SCCOL& rCol, const String& rStr);
814cdf0e10cSrcweir 
815cdf0e10cSrcweir #endif // SC_ADDRESS_HXX
816cdf0e10cSrcweir 
817