LCOV - code coverage report
Current view: top level - sc/inc - address.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 237 278 85.3 %
Date: 2014-11-03 Functions: 79 87 90.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10