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

Generated by: LCOV version 1.10