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