sw lok: assign a parent window to property dialog
[LibreOffice.git] / sc / inc / address.hxx
bloba3c7040a21d53065dd896c1c2553f43551100d16
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SC_INC_ADDRESS_HXX
21 #define INCLUDED_SC_INC_ADDRESS_HXX
23 #include <rtl/ustrbuf.hxx>
24 #include <rtl/strbuf.hxx>
26 #include <limits>
27 #include <ostream>
29 #include "scdllapi.h"
30 #include "types.hxx"
31 #include <formula/grammar.hxx>
33 #include <o3tl/typed_flags_set.hxx>
34 #include <com/sun/star/uno/Sequence.hxx>
36 namespace com { namespace sun { namespace star {
37 namespace sheet {
38 struct ExternalLinkInfo;
40 }}}
42 class ScDocument;
44 /** size_t typedef to be able to find places where code was changed from USHORT
45 to size_t and is used to read/write from/to streams. */
46 typedef size_t SCSIZE;
48 // Maximum possible value of data type, NOT maximum row value.
49 // MSC confuses numeric_limit max() with macro max() if vcl/wintypes.hxx is
50 // included, we should not be using those stupid macros anyway.
51 #undef min
52 #undef max
53 const SCROW SCROW_MAX = ::std::numeric_limits<SCROW>::max();
54 const SCCOL SCCOL_MAX = ::std::numeric_limits<SCCOL>::max();
55 const SCTAB SCTAB_MAX = ::std::numeric_limits<SCTAB>::max();
56 const SCCOLROW SCCOLROW_MAX = ::std::numeric_limits<SCCOLROW>::max();
57 const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max();
59 // The maximum values. Defines are needed for preprocessor checks, for example
60 // in bcaslot.cxx, otherwise type safe constants are preferred.
61 #define MAXROWCOUNT_DEFINE 1048576
62 #define MAXCOLCOUNT_DEFINE 1024
64 // Count values
65 const SCROW MAXROWCOUNT = MAXROWCOUNT_DEFINE;
66 const SCCOL MAXCOLCOUNT = MAXCOLCOUNT_DEFINE;
67 /// limiting to 10000 for now, problem with 32 bit builds for now
68 const SCTAB MAXTABCOUNT = 10000;
69 const SCCOLROW MAXCOLROWCOUNT = MAXROWCOUNT;
70 // Maximum values
71 const SCROW MAXROW = MAXROWCOUNT - 1;
72 const SCCOL MAXCOL = MAXCOLCOUNT - 1;
73 const SCTAB MAXTAB = MAXTABCOUNT - 1;
74 const SCCOLROW MAXCOLROW = MAXROW;
75 // Maximun tiled rendering values
76 const SCROW MAXTILEDROW = 500000;
77 // Limit the initial tab count to prevent users to set the count too high,
78 // which could cause the memory usage of blank documents to exceed the
79 // available system memory.
80 const SCTAB MAXINITTAB = 1024;
81 const SCTAB MININITTAB = 1;
83 // Special values
84 const SCTAB SC_TAB_APPEND = SCTAB_MAX;
85 const SCTAB TABLEID_DOC = SCTAB_MAX; // entire document, e.g. protect
86 const SCROW SCROWS32K = 32000;
87 const SCCOL SCCOL_REPEAT_NONE = SCCOL_MAX;
88 const SCROW SCROW_REPEAT_NONE = SCROW_MAX;
90 #define MAXROW_30 8191
92 SAL_WARN_UNUSED_RESULT inline bool ValidCol( SCCOL nCol )
94 return nCol >= 0 && nCol <= MAXCOL;
97 SAL_WARN_UNUSED_RESULT inline bool ValidRow( SCROW nRow )
99 return nRow >= 0 && nRow <= MAXROW;
102 SAL_WARN_UNUSED_RESULT inline bool ValidTab( SCTAB nTab )
104 return nTab >= 0 && nTab <= MAXTAB;
107 SAL_WARN_UNUSED_RESULT inline bool ValidTab( SCTAB nTab, SCTAB nMaxTab )
109 return nTab >= 0 && nTab <= nMaxTab;
112 SAL_WARN_UNUSED_RESULT inline bool ValidColRow( SCCOL nCol, SCROW nRow )
114 return ValidCol( nCol) && ValidRow( nRow);
117 SAL_WARN_UNUSED_RESULT inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab )
119 return ValidCol( nCol) && ValidRow( nRow) && ValidTab( nTab);
122 SAL_WARN_UNUSED_RESULT inline SCCOL SanitizeCol( SCCOL nCol )
124 return nCol < 0 ? 0 : std::min(nCol, MAXCOL);
127 SAL_WARN_UNUSED_RESULT inline SCROW SanitizeRow( SCROW nRow )
129 return nRow < 0 ? 0 : std::min(nRow, MAXROW);
132 SAL_WARN_UNUSED_RESULT inline SCTAB SanitizeTab( SCTAB nTab )
134 return nTab < 0 ? 0 : std::min(nTab, MAXTAB);
137 // The result of ConvertRef() is a bit group of the following:
138 enum class ScRefFlags : sal_uInt16
140 ZERO = 0x0000,
141 COL_ABS = 0x0001,
142 ROW_ABS = 0x0002,
143 TAB_ABS = 0x0004,
144 TAB_3D = 0x0008,
145 COL2_ABS = 0x0010,
146 ROW2_ABS = 0x0020,
147 TAB2_ABS = 0x0040,
148 TAB2_3D = 0x0080,
149 ROW_VALID = 0x0100,
150 COL_VALID = 0x0200,
151 TAB_VALID = 0x0400,
152 // BITS for convenience
153 BITS = COL_ABS | ROW_ABS | TAB_ABS | TAB_3D
154 | ROW_VALID | COL_VALID | TAB_VALID,
155 // somewhat cheesy kludge to force the display of the document name even for
156 // local references. Requires TAB_3D to be valid
157 FORCE_DOC = 0x0800,
158 ROW2_VALID = 0x1000,
159 COL2_VALID = 0x2000,
160 TAB2_VALID = 0x4000,
161 VALID = 0x8000,
163 TAB_ABS_3D = TAB_ABS | TAB_3D,
165 ADDR_ABS = VALID | COL_ABS | ROW_ABS | TAB_ABS,
167 RANGE_ABS = ADDR_ABS | COL2_ABS | ROW2_ABS | TAB2_ABS,
169 ADDR_ABS_3D = ADDR_ABS | TAB_3D,
170 RANGE_ABS_3D = RANGE_ABS | TAB_3D
173 namespace o3tl
175 template<> struct typed_flags<ScRefFlags> : is_typed_flags<ScRefFlags, 0xffff> {};
177 inline void applyStartToEndFlags(ScRefFlags &target,const ScRefFlags source)
179 target |= ScRefFlags(static_cast<std::underlying_type<ScRefFlags>::type>(source) << 4);
181 inline void applyStartToEndFlags(ScRefFlags &target)
183 target |= ScRefFlags(static_cast<std::underlying_type<ScRefFlags>::type>(target) << 4);
186 // ScAddress
187 class SAL_WARN_UNUSED ScAddress
189 private:
190 // Even if the fields are in the order "row, column, tab", in all (?) the ScAddress and
191 // ScDocument APIs that take separate row, column, and tab parameters, the parameters are in the
192 // order "column, row, tab", which matches the most common (A1) address syntax, if you ignore
193 // the sheet (tab). Don't let this confuse you, like it confused me for a while.
195 SCROW nRow;
196 SCCOL nCol;
197 SCTAB nTab;
199 public:
201 enum Uninitialized { UNINITIALIZED };
202 enum InitializeInvalid { INITIALIZE_INVALID };
204 struct Details
206 formula::FormulaGrammar::AddressConvention eConv;
207 SCROW nRow;
208 SCCOL nCol;
210 Details( formula::FormulaGrammar::AddressConvention eConvP, SCROW nRowP, SCCOL nColP ) :
211 eConv(eConvP), nRow(nRowP), nCol(nColP)
213 Details( formula::FormulaGrammar::AddressConvention eConvP, ScAddress const & rAddr ) :
214 eConv(eConvP), nRow(rAddr.Row()), nCol(rAddr.Col())
216 Details( formula::FormulaGrammar::AddressConvention eConvP) :
217 eConv(eConvP), nRow(0), nCol(0)
219 /* Use the formula::FormulaGrammar::AddressConvention associated with rAddr::Tab() */
220 Details( const ScDocument* pDoc, const ScAddress & rAddr );
222 SC_DLLPUBLIC static const Details detailsOOOa1;
224 struct ExternalInfo
226 OUString maTabName;
227 sal_uInt16 mnFileId;
228 bool mbExternal;
230 ExternalInfo() :
231 mnFileId(0), mbExternal(false)
235 ScAddress() :
236 nRow(0), nCol(0), nTab(0)
238 ScAddress( SCCOL nColP, SCROW nRowP, SCTAB nTabP ) :
239 nRow(nRowP), nCol(nColP), nTab(nTabP)
241 /** Yes, it is what it seems to be: Uninitialized. May be used for
242 performance reasons if it is initialized by other means. */
243 ScAddress( Uninitialized )
245 ScAddress( InitializeInvalid ) :
246 nRow(-1), nCol(-1), nTab(-1)
248 ScAddress( const ScAddress& rAddress ) :
249 nRow(rAddress.nRow), nCol(rAddress.nCol), nTab(rAddress.nTab)
251 inline ScAddress& operator=( const ScAddress& rAddress );
253 inline void Set( SCCOL nCol, SCROW nRow, SCTAB nTab );
255 SCROW Row() const
257 return nRow;
260 SCCOL Col() const
262 return nCol;
264 SCTAB Tab() const
266 return nTab;
268 void SetRow( SCROW nRowP )
270 nRow = nRowP;
272 void SetCol( SCCOL nColP )
274 nCol = nColP;
276 void SetTab( SCTAB nTabP )
278 nTab = nTabP;
280 void SetInvalid()
282 nRow = -1;
283 nCol = -1;
284 nTab = -1;
286 bool IsValid() const
288 return (nRow >= 0) && (nCol >= 0) && (nTab >= 0);
291 inline void PutInOrder( ScAddress& rAddress );
293 void IncRow( SCROW nDelta = 1 )
295 nRow = sal::static_int_cast<SCROW>(nRow + nDelta);
297 void IncCol( SCCOL nDelta = 1 )
299 nCol = sal::static_int_cast<SCCOL>(nCol + nDelta);
301 void IncTab( SCTAB nDelta = 1 )
303 nTab = sal::static_int_cast<SCTAB>(nTab + nDelta);
305 void GetVars( SCCOL& nColP, SCROW& nRowP, SCTAB& nTabP ) const
307 nColP = nCol;
308 nRowP = nRow;
309 nTabP = nTab;
313 @param pSheetEndPos
314 If given and Parse() successfully parsed a sheet name it returns
315 the end position (exclusive) behind the sheet name AND a
316 following sheet name separator. This independent of whether the
317 resulting reference is fully valid or not.
319 SC_DLLPUBLIC ScRefFlags Parse(
320 const OUString&, const ScDocument* = nullptr,
321 const Details& rDetails = detailsOOOa1,
322 ExternalInfo* pExtInfo = nullptr,
323 const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
324 sal_Int32* pSheetEndPos = nullptr,
325 const OUString* pErrRef = nullptr );
327 SC_DLLPUBLIC void Format( OStringBuffer& r, ScRefFlags nFlags,
328 const ScDocument* pDocument = nullptr,
329 const Details& rDetails = detailsOOOa1) const;
331 SC_DLLPUBLIC OUString Format( ScRefFlags nFlags,
332 const ScDocument* pDocument = nullptr,
333 const Details& rDetails = detailsOOOa1) const;
336 @param rErrorPos
337 If FALSE is returned, the positions contain <0 or >MAX...
338 values if shifted out of bounds.
339 @param pDocument
340 The document for the maximum defined sheet number.
342 SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT bool Move( SCCOL nDeltaX, SCROW nDeltaY, SCTAB nDeltaZ,
343 ScAddress& rErrorPos, const ScDocument* pDocument = nullptr );
345 inline bool operator==( const ScAddress& rAddress ) const;
346 inline bool operator!=( const ScAddress& rAddress ) const;
347 inline bool operator<( const ScAddress& rAddress ) const;
348 inline bool operator<=( const ScAddress& rAddress ) const;
349 inline bool lessThanByRow( const ScAddress& rAddress ) const;
351 inline size_t hash() const;
354 * Create a human-readable string representation of the cell address. You
355 * cannot specify precise formatting with this method; use Format() if you
356 * need to specify how the address needs to be formatted.
358 * The address string does not display sheet name.
360 * @return human-readable string representation of the cell address.
362 OUString GetColRowString() const;
365 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
366 template<typename charT, typename traits>
367 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScAddress& rAddress)
369 stream <<
370 rAddress.Tab()+1 << "!"
371 "R" << rAddress.Row()+1 <<
372 "C" << rAddress.Col()+1;
374 return stream;
377 inline void ScAddress::PutInOrder( ScAddress& rAddress )
379 if ( rAddress.Col() < Col() )
381 SCCOL nTmp = rAddress.Col();
382 rAddress.SetCol( Col() );
383 SetCol( nTmp );
385 if ( rAddress.Row() < Row() )
387 SCROW nTmp = rAddress.Row();
388 rAddress.SetRow( Row() );
389 SetRow( nTmp );
391 if ( rAddress.Tab() < Tab() )
393 SCTAB nTmp = rAddress.Tab();
394 rAddress.SetTab( Tab() );
395 SetTab( nTmp );
399 inline void ScAddress::Set( SCCOL nColP, SCROW nRowP, SCTAB nTabP )
401 nCol = nColP;
402 nRow = nRowP;
403 nTab = nTabP;
406 inline ScAddress& ScAddress::operator=( const ScAddress& rAddress )
408 nCol = rAddress.nCol;
409 nRow = rAddress.nRow;
410 nTab = rAddress.nTab;
411 return *this;
414 inline bool ScAddress::operator==( const ScAddress& rAddress ) const
416 return nRow == rAddress.nRow && nCol == rAddress.nCol && nTab == rAddress.nTab;
419 inline bool ScAddress::operator!=( const ScAddress& rAddress ) const
421 return !operator==( rAddress );
424 /** Less than ordered by tab,col,row. */
425 inline bool ScAddress::operator<( const ScAddress& rAddress ) const
427 if (nTab == rAddress.nTab)
429 if (nCol == rAddress.nCol)
430 return nRow < rAddress.nRow;
431 else
432 return nCol < rAddress.nCol;
434 else
435 return nTab < rAddress.nTab;
438 inline bool ScAddress::operator<=( const ScAddress& rAddress ) const
440 return operator<( rAddress ) || operator==( rAddress );
443 /** Less than ordered by tab,row,col as needed by row-wise import/export */
444 inline bool ScAddress::lessThanByRow( const ScAddress& rAddress ) const
446 if (nTab == rAddress.nTab)
448 if (nRow == rAddress.nRow)
449 return nCol < rAddress.nCol;
450 else
451 return nRow < rAddress.nRow;
453 else
454 return nTab < rAddress.nTab;
457 inline size_t ScAddress::hash() const
459 // Assume that there are not that many addresses with row > 2^16 AND column
460 // > 2^8 AND sheet > 2^8 so we won't have too many collisions.
461 if (nRow <= 0xffff)
462 return (static_cast<size_t>(nTab) << 24) ^
463 (static_cast<size_t>(nCol) << 16) ^ static_cast<size_t>(nRow);
464 else
465 return (static_cast<size_t>(nTab) << 28) ^
466 (static_cast<size_t>(nCol) << 24) ^ static_cast<size_t>(nRow);
469 struct ScAddressHashFunctor
471 size_t operator()( const ScAddress & rAddress ) const
473 return rAddress.hash();
477 inline bool ValidAddress( const ScAddress& rAddress )
479 return ValidCol(rAddress.Col()) && ValidRow(rAddress.Row()) && ValidTab(rAddress.Tab());
482 // ScRange
483 class SAL_WARN_UNUSED ScRange
485 public:
486 ScAddress aStart;
487 ScAddress aEnd;
489 ScRange() :
490 aStart(), aEnd()
493 ScRange( ScAddress::Uninitialized eUninitialized ) :
494 aStart( eUninitialized ), aEnd( eUninitialized )
496 ScRange( ScAddress::InitializeInvalid eInvalid ) :
497 aStart( eInvalid ), aEnd( eInvalid )
499 ScRange( const ScAddress& aInputStart, const ScAddress& aInputEnd ) :
500 aStart( aInputStart ), aEnd( aInputEnd )
502 aStart.PutInOrder( aEnd );
504 ScRange( const ScRange& rRange ) :
505 aStart( rRange.aStart ), aEnd( rRange.aEnd )
507 ScRange( const ScAddress& rRange ) :
508 aStart( rRange ), aEnd( rRange )
510 ScRange( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
511 aStart( nCol, nRow, nTab ), aEnd( aStart )
513 ScRange( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ) :
514 aStart( nCol1, nRow1, nTab1 ), aEnd( nCol2, nRow2, nTab2 )
517 ScRange& operator=( const ScRange& rRange )
519 aStart = rRange.aStart;
520 aEnd = rRange.aEnd;
521 return *this;
523 ScRange& operator=( const ScAddress& rPos )
525 aStart = aEnd = rPos;
526 return *this;
528 void SetInvalid()
530 aStart.SetInvalid();
531 aEnd.SetInvalid();
533 bool IsValid() const
535 return aStart.IsValid() && aEnd.IsValid();
537 inline bool In( const ScAddress& ) const; ///< is Address& in Range?
538 inline bool In( const ScRange& ) const; ///< is Range& in Range?
540 SC_DLLPUBLIC ScRefFlags Parse( const OUString&, const ScDocument* = nullptr,
541 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
542 ScAddress::ExternalInfo* pExtInfo = nullptr,
543 const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
544 const OUString* pErrRef = nullptr );
546 SC_DLLPUBLIC ScRefFlags ParseAny( const OUString&, const ScDocument*,
547 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
548 SC_DLLPUBLIC ScRefFlags ParseCols( const OUString&,
549 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
550 SC_DLLPUBLIC void ParseRows( const OUString&,
551 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1 );
553 /** Parse an Excel style reference up to and including the sheet name
554 separator '!', including detection of external documents and sheet
555 names, and in case of MOOXML import the bracketed index is used to
556 determine the actual document name passed in pExternalLinks. For
557 internal references (resulting rExternDocName empty), aStart.nTab and
558 aEnd.nTab are set, or -1 if sheet name not found.
559 @param bOnlyAcceptSingle If <TRUE/>, a 3D reference (Sheet1:Sheet2)
560 encountered results in an error (NULL returned).
561 @param pExternalLinks pointer to ExternalLinkInfo sequence, may be
562 NULL for non-filter usage, in which case indices such as [1] are
563 not resolved.
564 @param pErrRef pointer to "#REF!" string if to be accepted.
565 @returns
566 Pointer to the position after '!' if successfully parsed, and
567 rExternDocName, rStartTabName and/or rEndTabName filled if
568 applicable. ScRefFlags::... flags set in nFlags.
569 Or if no valid document and/or sheet header could be parsed the start
570 position passed with pString.
571 Or NULL if a 3D sheet header could be parsed but
572 bOnlyAcceptSingle==true was given.
574 const sal_Unicode* Parse_XL_Header( const sal_Unicode* pString, const ScDocument* pDocument,
575 OUString& rExternDocName, OUString& rStartTabName,
576 OUString& rEndTabName, ScRefFlags& nFlags,
577 bool bOnlyAcceptSingle,
578 const css::uno::Sequence<css::sheet::ExternalLinkInfo>* pExternalLinks = nullptr,
579 const OUString* pErrRef = nullptr );
581 /** Returns string with formatted cell range from aStart to aEnd,
582 according to provided address convention.
583 @param nFlags
584 Cell reference flags
585 @param pDocument
586 Pointer to document which is used for example to get tab names.
587 @param rDetails
588 Provide information about required address convention.
589 Supported address conventions are:
590 CONV_OOO 'doc'#sheet.A1:sheet2.B2
591 CONV_XL_A1, [doc]sheet:sheet2!A1:B2
592 CONV_XL_OOX, [#]sheet:sheet2!A1:B2
593 CONV_XL_R1C1, [doc]sheet:sheet2!R1C1:R2C2
594 @param bFullAddressNotation
595 If TRUE, the full address notation will be used.
596 For example in case all columns are used, "A1:AMJ177" is full address notation
597 and "1:177" is shortened address notation.
598 @returns
599 String contains formatted cell range in address convention
601 SC_DLLPUBLIC OUString Format( ScRefFlags nFlags = ScRefFlags::ZERO,
602 const ScDocument* pDocument = nullptr,
603 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1,
604 bool bFullAddressNotation = false ) const;
606 inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
607 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
608 SC_DLLPUBLIC void PutInOrder();
611 @param rErrorRange
612 If FALSE is returned, the positions contain <0 or >MAX...
613 values if shifted out of bounds.
614 @param pDocument
615 The document for the maximum defined sheet number.
617 SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT bool Move( SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
618 ScRange& rErrorRange, const ScDocument* pDocument = nullptr );
620 /** Same as Move() but with sticky end col/row anchors. */
621 SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT bool MoveSticky( SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ,
622 ScRange& rErrorRange );
624 SC_DLLPUBLIC void IncColIfNotLessThan(SCCOL nStartCol, SCCOL nOffset);
625 SC_DLLPUBLIC void IncRowIfNotLessThan(SCROW nStartRow, SCROW nOffset);
627 SC_DLLPUBLIC void ExtendTo( const ScRange& rRange );
628 SC_DLLPUBLIC bool Intersects( const ScRange& rRange ) const; // do two ranges intersect?
630 ScRange Intersection( const ScRange& rOther ) const;
632 /// If maximum end column should not be adapted during reference update.
633 inline bool IsEndColSticky() const;
634 /// If maximum end row should not be adapted during reference update.
635 inline bool IsEndRowSticky() const;
637 /** Increment or decrement end column unless sticky or until it becomes
638 sticky. Checks if the range encompasses at least two columns so should
639 be called before adjusting the start column. */
640 void IncEndColSticky( SCCOL nDelta );
642 /** Increment or decrement end row unless sticky or until it becomes
643 sticky. Checks if the range encompasses at least two rows so should
644 be called before adjusting the start row. */
645 void IncEndRowSticky( SCROW nDelta );
647 inline bool operator==( const ScRange& rRange ) const;
648 inline bool operator!=( const ScRange& rRange ) const;
649 inline bool operator<( const ScRange& rRange ) const;
650 inline bool operator<=( const ScRange& rRange ) const;
652 /// Hash 2D area ignoring table number.
653 inline size_t hashArea() const;
654 /// Hash start column and start and end rows.
655 inline size_t hashStartColumn() const;
658 // For use in SAL_DEBUG etc. Output format not guaranteed to be stable.
659 template<typename charT, typename traits>
660 inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ScRange& rRange)
662 stream << rRange.aStart;
663 if (rRange.aEnd != rRange.aStart)
665 stream << ":";
666 if (rRange.aEnd.Tab() != rRange.aStart.Tab())
667 stream << rRange.aEnd;
668 else
669 stream <<
670 "R" << rRange.aEnd.Row()+1 <<
671 "C" << rRange.aEnd.Col()+1;
674 return stream;
677 inline void ScRange::GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
678 SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const
680 aStart.GetVars( nCol1, nRow1, nTab1 );
681 aEnd.GetVars( nCol2, nRow2, nTab2 );
684 inline bool ScRange::IsEndColSticky() const
686 // Only in an actual column range, i.e. not if both columns are MAXCOL.
687 return aEnd.Col() == MAXCOL && aStart.Col() < aEnd.Col();
690 inline bool ScRange::IsEndRowSticky() const
692 // Only in an actual row range, i.e. not if both rows are MAXROW.
693 return aEnd.Row() == MAXROW && aStart.Row() < aEnd.Row();
696 inline bool ScRange::operator==( const ScRange& rRange ) const
698 return ( (aStart == rRange.aStart) && (aEnd == rRange.aEnd) );
701 inline bool ScRange::operator!=( const ScRange& rRange ) const
703 return !operator==( rRange );
706 /// Sort on upper left corner tab,col,row, if equal then use lower right too.
707 inline bool ScRange::operator<( const ScRange& r ) const
709 return aStart < r.aStart || (aStart == r.aStart && aEnd < r.aEnd) ;
712 inline bool ScRange::operator<=( const ScRange& rRange ) const
714 return operator<( rRange ) || operator==( rRange );
717 inline bool ScRange::In( const ScAddress& rAddress ) const
719 return
720 aStart.Col() <= rAddress.Col() && rAddress.Col() <= aEnd.Col() &&
721 aStart.Row() <= rAddress.Row() && rAddress.Row() <= aEnd.Row() &&
722 aStart.Tab() <= rAddress.Tab() && rAddress.Tab() <= aEnd.Tab();
725 inline bool ScRange::In( const ScRange& rRange ) const
727 return
728 aStart.Col() <= rRange.aStart.Col() && rRange.aEnd.Col() <= aEnd.Col() &&
729 aStart.Row() <= rRange.aStart.Row() && rRange.aEnd.Row() <= aEnd.Row() &&
730 aStart.Tab() <= rRange.aStart.Tab() && rRange.aEnd.Tab() <= aEnd.Tab();
733 inline size_t ScRange::hashArea() const
735 // Assume that there are not that many ranges with identical corners so we
736 // won't have too many collisions. Also assume that more lower row and
737 // column numbers are used so that there are not too many conflicts with
738 // the columns hashed into the values, and that start row and column
739 // usually don't exceed certain values. High bits are not masked off and
740 // may overlap with lower bits of other values, e.g. if start column is
741 // greater than assumed.
742 return
743 (static_cast<size_t>(aStart.Row()) << 26) ^ // start row <= 2^6
744 (static_cast<size_t>(aStart.Col()) << 21) ^ // start column <= 2^5
745 (static_cast<size_t>(aEnd.Col()) << 15) ^ // end column <= 2^6
746 static_cast<size_t>(aEnd.Row()); // end row <= 2^15
749 inline size_t ScRange::hashStartColumn() const
751 // Assume that for the start row more lower row numbers are used so that
752 // there are not too many conflicts with the column hashed into the higher
753 // values.
754 return
755 (static_cast<size_t>(aStart.Col()) << 24) ^ // start column <= 2^8
756 (static_cast<size_t>(aStart.Row()) << 16) ^ // start row <= 2^8
757 static_cast<size_t>(aEnd.Row());
760 inline bool ValidRange( const ScRange& rRange )
762 return ValidAddress(rRange.aStart) && ValidAddress(rRange.aEnd);
765 // ScRangePair
766 class SAL_WARN_UNUSED ScRangePair
768 private:
769 ScRange aRange[2];
771 public:
772 ScRangePair( const ScRangePair& r )
774 aRange[0] = r.aRange[0];
775 aRange[1] = r.aRange[1];
777 ScRangePair( const ScRange& rRange1, const ScRange& rRange2 )
779 aRange[0] = rRange1;
780 aRange[1] = rRange2;
783 inline ScRangePair& operator= ( const ScRangePair& rRange );
784 const ScRange& GetRange( sal_uInt16 n ) const
786 return aRange[n];
788 ScRange& GetRange( sal_uInt16 n )
790 return aRange[n];
794 inline ScRangePair& ScRangePair::operator= ( const ScRangePair& rRange )
796 aRange[0] = rRange.aRange[0];
797 aRange[1] = rRange.aRange[1];
798 return *this;
801 // ScRefAddress
802 class SAL_WARN_UNUSED ScRefAddress
804 private:
805 ScAddress aAdr;
806 bool bRelCol;
807 bool bRelRow;
808 bool bRelTab;
809 public:
810 ScRefAddress() :
811 bRelCol(false), bRelRow(false), bRelTab(false)
813 ScRefAddress( SCCOL nCol, SCROW nRow, SCTAB nTab ) :
814 aAdr(nCol, nRow, nTab),
815 bRelCol(false), bRelRow(false), bRelTab(false)
817 ScRefAddress( const ScRefAddress& rRef ) :
818 aAdr(rRef.aAdr), bRelCol(rRef.bRelCol), bRelRow(rRef.bRelRow),
819 bRelTab(rRef.bRelTab)
822 inline ScRefAddress& operator=( const ScRefAddress& );
824 bool IsRelCol() const
826 return bRelCol;
828 bool IsRelRow() const
830 return bRelRow;
832 bool IsRelTab() const
834 return bRelTab;
837 void SetRelCol(bool bNewRelCol)
839 bRelCol = bNewRelCol;
841 void SetRelRow(bool bNewRelRow)
843 bRelRow = bNewRelRow;
845 void SetRelTab(bool bNewRelTab)
847 bRelTab = bNewRelTab;
850 inline void Set( const ScAddress& rAdr,
851 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
852 inline void Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
853 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab );
855 const ScAddress& GetAddress() const
857 return aAdr;
860 SCCOL Col() const
862 return aAdr.Col();
864 SCROW Row() const
866 return aAdr.Row();
868 SCTAB Tab() const
870 return aAdr.Tab();
873 inline bool operator == ( const ScRefAddress& r ) const;
875 OUString GetRefString( const ScDocument* pDocument, SCTAB nActTab,
876 const ScAddress::Details& rDetails = ScAddress::detailsOOOa1) const;
879 inline ScRefAddress& ScRefAddress::operator=( const ScRefAddress& rRef )
881 aAdr = rRef.aAdr;
882 bRelCol = rRef.bRelCol;
883 bRelRow = rRef.bRelRow;
884 bRelTab = rRef.bRelTab;
885 return *this;
888 inline void ScRefAddress::Set( const ScAddress& rAdr,
889 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
891 aAdr = rAdr;
892 bRelCol = bNewRelCol;
893 bRelRow = bNewRelRow;
894 bRelTab = bNewRelTab;
897 inline void ScRefAddress::Set( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab,
898 bool bNewRelCol, bool bNewRelRow, bool bNewRelTab )
900 aAdr.Set( nNewCol, nNewRow, nNewTab);
901 bRelCol = bNewRelCol;
902 bRelRow = bNewRelRow;
903 bRelTab = bNewRelTab;
906 inline bool ScRefAddress::operator==( const ScRefAddress& rRefAddress ) const
908 return aAdr == rRefAddress.aAdr &&
909 bRelCol == rRefAddress.bRelCol &&
910 bRelRow == rRefAddress.bRelRow &&
911 bRelTab == rRefAddress.bRelTab;
914 // Global functions
916 // Special values for cells always broadcasting or listening (ScRecalcMode::ALWAYS
917 // and the like).
918 #define BCA_BRDCST_ALWAYS ScAddress( 0, SCROW_MAX, 0 )
919 #define BCA_LISTEN_ALWAYS ScRange( BCA_BRDCST_ALWAYS, BCA_BRDCST_ALWAYS )
921 template< typename T > void PutInOrder( T& nStart, T& nEnd )
923 if (nEnd < nStart)
925 std::swap(nStart, nEnd);
929 bool ConvertSingleRef( const ScDocument* pDocument, const OUString& rRefString,
930 SCTAB nDefTab, ScRefAddress& rRefAddress,
931 const ScAddress::Details& rDetails,
932 ScAddress::ExternalInfo* pExtInfo = nullptr );
934 bool ConvertDoubleRef( const ScDocument* pDocument, const OUString& rRefString,
935 SCTAB nDefTab, ScRefAddress& rStartRefAddress,
936 ScRefAddress& rEndRefAddress,
937 const ScAddress::Details& rDetails,
938 ScAddress::ExternalInfo* pExtInfo = nullptr );
940 /// append alpha representation of column to buffer
941 SC_DLLPUBLIC void ScColToAlpha( OUStringBuffer& rBuffer, SCCOL nCol);
943 inline void ScColToAlpha( OUString& rStr, SCCOL nCol)
945 OUStringBuffer aBuf(2);
946 ScColToAlpha( aBuf, nCol);
947 rStr += aBuf.makeStringAndClear();
950 inline OUString ScColToAlpha( SCCOL nCol )
952 OUStringBuffer aBuf(2);
953 ScColToAlpha( aBuf, nCol);
954 return aBuf.makeStringAndClear();
957 /// get column number of A..IV... string
958 bool AlphaToCol( SCCOL& rCol, const OUString& rStr);
960 #endif // INCLUDED_SC_INC_ADDRESS_HXX
962 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */