LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/core/inc - bcaslot.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 36 42 85.7 %
Date: 2013-07-09 Functions: 22 28 78.6 %
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_BCASLOT_HXX
      21             : #define SC_BCASLOT_HXX
      22             : 
      23             : #include <set>
      24             : #include <boost/unordered_set.hpp>
      25             : #include <functional>
      26             : #include <svl/broadcast.hxx>
      27             : 
      28             : #include "global.hxx"
      29             : #include "brdcst.hxx"
      30             : 
      31             : /**
      32             :     Used in a Unique Associative Container.
      33             :  */
      34             : 
      35        2039 : class ScBroadcastArea
      36             : {
      37             : private:
      38             :     ScBroadcastArea*    pUpdateChainNext;
      39             :     SvtBroadcaster      aBroadcaster;
      40             :     ScRange             aRange;
      41             :     sal_uLong               nRefCount;
      42             :     sal_Bool                bInUpdateChain;
      43             : 
      44             : public:
      45        2963 :             ScBroadcastArea( const ScRange& rRange )
      46             :                 : pUpdateChainNext( NULL ), aRange( rRange ),
      47        2963 :                 nRefCount( 0 ), bInUpdateChain( false ) {}
      48        5939 :     inline SvtBroadcaster&       GetBroadcaster()       { return aBroadcaster; }
      49             :     inline const SvtBroadcaster& GetBroadcaster() const { return aBroadcaster; }
      50        5574 :     inline void         UpdateRange( const ScRange& rNewRange )
      51        5574 :                             { aRange = rNewRange; }
      52        9946 :     inline const ScRange&   GetRange() const { return aRange; }
      53             :     inline const ScAddress& GetStart() const { return aRange.aStart; }
      54             :     inline const ScAddress& GetEnd() const { return aRange.aEnd; }
      55        2820 :     inline void         IncRef() { ++nRefCount; }
      56        1909 :     inline sal_uLong        DecRef() { return nRefCount ? --nRefCount : 0; }
      57         108 :     inline sal_uLong        GetRef() { return nRefCount; }
      58           0 :     inline ScBroadcastArea* GetUpdateChainNext() const { return pUpdateChainNext; }
      59           0 :     inline void         SetUpdateChainNext( ScBroadcastArea* p ) { pUpdateChainNext = p; }
      60           6 :     inline sal_Bool         IsInUpdateChain() const { return bInUpdateChain; }
      61           0 :     inline void         SetInUpdateChain( sal_Bool b ) { bInUpdateChain = b; }
      62             : 
      63             :     /** Equalness of this or range. */
      64             :     inline  bool        operator==( const ScBroadcastArea & rArea ) const;
      65             : };
      66             : 
      67        3662 : inline bool ScBroadcastArea::operator==( const ScBroadcastArea & rArea ) const
      68             : {
      69        3662 :     return aRange == rArea.aRange;
      70             : }
      71             : 
      72             : //=============================================================================
      73             : 
      74             : struct ScBroadcastAreaEntry
      75             : {
      76             :     ScBroadcastArea* mpArea;
      77             :     mutable bool     mbErasure;     ///< TRUE if marked for erasure in this set
      78             : 
      79        8394 :     ScBroadcastAreaEntry( ScBroadcastArea* p ) : mpArea( p), mbErasure( false) {}
      80             : };
      81             : 
      82             : struct ScBroadcastAreaHash
      83             : {
      84        8394 :     size_t operator()( const ScBroadcastAreaEntry& rEntry ) const
      85             :     {
      86        8394 :         return rEntry.mpArea->GetRange().hashArea();
      87             :     }
      88             : };
      89             : 
      90             : struct ScBroadcastAreaEqual
      91             : {
      92        3662 :     bool operator()( const ScBroadcastAreaEntry& rEntry1, const ScBroadcastAreaEntry& rEntry2) const
      93             :     {
      94        3662 :         return *rEntry1.mpArea == *rEntry2.mpArea;
      95             :     }
      96             : };
      97             : 
      98             : typedef ::boost::unordered_set< ScBroadcastAreaEntry, ScBroadcastAreaHash, ScBroadcastAreaEqual > ScBroadcastAreas;
      99             : 
     100             : //=============================================================================
     101             : 
     102             : struct ScBroadcastAreaBulkHash
     103             : {
     104         137 :     size_t operator()( const ScBroadcastArea* p ) const
     105             :     {
     106         137 :         return reinterpret_cast<size_t>(p);
     107             :     }
     108             : };
     109             : 
     110             : struct ScBroadcastAreaBulkEqual
     111             : {
     112          23 :     bool operator()( const ScBroadcastArea* p1, const ScBroadcastArea* p2) const
     113             :     {
     114          23 :         return p1 == p2;
     115             :     }
     116             : };
     117             : 
     118             : typedef ::boost::unordered_set< const ScBroadcastArea*, ScBroadcastAreaBulkHash,
     119             :         ScBroadcastAreaBulkEqual > ScBroadcastAreasBulk;
     120             : 
     121             : //=============================================================================
     122             : 
     123             : class ScBroadcastAreaSlotMachine;
     124             : 
     125             : /// Collection of BroadcastAreas
     126             : class ScBroadcastAreaSlot
     127             : {
     128             : private:
     129             :     ScBroadcastAreas    aBroadcastAreaTbl;
     130             :     mutable ScBroadcastArea aTmpSeekBroadcastArea;      // for FindBroadcastArea()
     131             :     ScDocument*         pDoc;
     132             :     ScBroadcastAreaSlotMachine* pBASM;
     133             :     bool                mbInBroadcastIteration;
     134             : 
     135             :     ScBroadcastAreas::const_iterator  FindBroadcastArea( const ScRange& rRange ) const;
     136             : 
     137             :     /**
     138             :         More hypothetical (memory would probably be doomed anyway) check
     139             :         whether there would be an overflow when adding an area, setting the
     140             :         proper state if so.
     141             : 
     142             :         @return sal_True if a HardRecalcState is effective and area is not to be
     143             :         added.
     144             :       */
     145             :     bool                CheckHardRecalcStateCondition() const;
     146             : 
     147             :     /** Finally erase all areas pushed as to-be-erased. */
     148             :     void                FinallyEraseAreas();
     149             : 
     150        1706 :     bool                isMarkedErased( const ScBroadcastAreas::iterator& rIter )
     151             :                             {
     152        1706 :                                 return (*rIter).mbErasure;
     153             :                             }
     154             : 
     155             : public:
     156             :                         ScBroadcastAreaSlot( ScDocument* pDoc,
     157             :                                         ScBroadcastAreaSlotMachine* pBASM );
     158             :                         ~ScBroadcastAreaSlot();
     159             :     const ScBroadcastAreas& GetBroadcastAreas() const
     160             :                                             { return aBroadcastAreaTbl; }
     161             : 
     162             :     /**
     163             :         Only here new ScBroadcastArea objects are created, prevention of dupes.
     164             : 
     165             :         @param rpArea
     166             :             If NULL, a new ScBroadcastArea is created and assigned ton the
     167             :             reference if a matching area wasn't found. If a matching area was
     168             :             found, that is assigned. In any case, the SvtListener is added to
     169             :             the broadcaster.
     170             : 
     171             :             If not NULL then no listeners are startet, only the area is
     172             :             inserted and the reference count incremented. Effectively the same
     173             :             as InsertListeningArea(), so use that instead.
     174             : 
     175             :         @return
     176             :             sal_True if rpArea passed was NULL and ScBroadcastArea is newly
     177             :             created.
     178             :      */
     179             :     bool                StartListeningArea( const ScRange& rRange,
     180             :                                             SvtListener* pListener,
     181             :                                             ScBroadcastArea*& rpArea );
     182             : 
     183             :     /**
     184             :         Insert a ScBroadcastArea obtained via StartListeningArea() to
     185             :         subsequent slots.
     186             :      */
     187             :     void                InsertListeningArea( ScBroadcastArea* pArea );
     188             : 
     189             :     void                EndListeningArea( const ScRange& rRange,
     190             :                                             SvtListener* pListener,
     191             :                                             ScBroadcastArea*& rpArea );
     192             :     sal_Bool                AreaBroadcast( const ScHint& rHint );
     193             :     /// @return sal_True if at least one broadcast occurred.
     194             :     sal_Bool                AreaBroadcastInRange( const ScRange& rRange,
     195             :                                               const ScHint& rHint );
     196             :     void                DelBroadcastAreasInRange( const ScRange& rRange );
     197             :     void                UpdateRemove( UpdateRefMode eUpdateRefMode,
     198             :                                         const ScRange& rRange,
     199             :                                         SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
     200             :     void                UpdateRemoveArea( ScBroadcastArea* pArea );
     201             :     void                UpdateInsert( ScBroadcastArea* pArea );
     202             : 
     203             : 
     204         906 :     bool                IsInBroadcastIteration() const { return mbInBroadcastIteration; }
     205             : 
     206             :     /** Erase an area from set and delete it if last reference, or if
     207             :         mbInBroadcastIteration is set push it to the vector of to-be-erased
     208             :         areas instead.
     209             : 
     210             :         Meant to be used internally and from ScBroadcastAreaSlotMachine only.
     211             :      */
     212             :     void                EraseArea( ScBroadcastAreas::iterator& rIter );
     213             : };
     214             : 
     215             : 
     216             : /**
     217             :     BroadcastAreaSlots and their management, once per document.
     218             :  */
     219             : 
     220             : class  ScBroadcastAreaSlotMachine
     221             : {
     222             : private:
     223             : 
     224             :     /**
     225             :         Slot offset arrangement of columns and rows, once per sheet.
     226             : 
     227             :         +---+---+
     228             :         | 0 | 3 |
     229             :         +---+---+
     230             :         | 1 | 4 |
     231             :         +---+---+
     232             :         | 2 | 5 |
     233             :         +---+---+
     234             :      */
     235             : 
     236             :     class TableSlots
     237             :     {
     238             :         public:
     239             :                                             TableSlots();
     240             :                                             ~TableSlots();
     241        5582 :             inline ScBroadcastAreaSlot**    getSlots() { return ppSlots; }
     242             : 
     243             :             /**
     244             :                 Obtain slot pointer, no check on validity! It is assumed that
     245             :                 all calls are made with the results of ComputeSlotOffset(),
     246             :                 ComputeAreaPoints() and ComputeNextSlot()
     247             :               */
     248        4004 :             inline ScBroadcastAreaSlot*     getAreaSlot( SCSIZE nOff ) { return *(ppSlots + nOff); }
     249             : 
     250             :         private:
     251             :             ScBroadcastAreaSlot**   ppSlots;
     252             : 
     253             :             // prevent usage
     254             :             TableSlots( const TableSlots& );
     255             :             TableSlots& operator=( const TableSlots& );
     256             :     };
     257             : 
     258             :     typedef ::std::map< SCTAB, TableSlots* > TableSlotsMap;
     259             : 
     260             :     typedef ::std::vector< ::std::pair< ScBroadcastAreaSlot*, ScBroadcastAreas::iterator > > AreasToBeErased;
     261             : 
     262             : private:
     263             :     ScBroadcastAreasBulk  aBulkBroadcastAreas;
     264             :     TableSlotsMap         aTableSlotsMap;
     265             :     AreasToBeErased       maAreasToBeErased;
     266             :     SvtBroadcaster       *pBCAlways;             // for the RC_ALWAYS special range
     267             :     ScDocument           *pDoc;
     268             :     ScBroadcastArea      *pUpdateChain;
     269             :     ScBroadcastArea      *pEOUpdateChain;
     270             :     sal_uLong             nInBulkBroadcast;
     271             : 
     272             :     inline SCSIZE       ComputeSlotOffset( const ScAddress& rAddress ) const;
     273             :     void                ComputeAreaPoints( const ScRange& rRange,
     274             :                                             SCSIZE& nStart, SCSIZE& nEnd,
     275             :                                             SCSIZE& nRowBreak ) const;
     276             : 
     277             : public:
     278             :                         ScBroadcastAreaSlotMachine( ScDocument* pDoc );
     279             :                         ~ScBroadcastAreaSlotMachine();
     280             :     void                StartListeningArea( const ScRange& rRange,
     281             :                                             SvtListener* pListener );
     282             :     void                EndListeningArea( const ScRange& rRange,
     283             :                                             SvtListener* pListener );
     284             :     sal_Bool                AreaBroadcast( const ScHint& rHint ) const;
     285             :         // return: at least one broadcast occurred
     286             :     sal_Bool                AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHint ) const;
     287             :     void                DelBroadcastAreasInRange( const ScRange& rRange );
     288             :     void                UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
     289             :                                             const ScRange& rRange,
     290             :                                             SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
     291             :     void                EnterBulkBroadcast();
     292             :     void                LeaveBulkBroadcast();
     293             :     bool                InsertBulkArea( const ScBroadcastArea* p );
     294             :     /// @return: how many removed
     295             :     size_t              RemoveBulkArea( const ScBroadcastArea* p );
     296             :     inline ScBroadcastArea* GetUpdateChain() const { return pUpdateChain; }
     297           0 :     inline void SetUpdateChain( ScBroadcastArea* p ) { pUpdateChain = p; }
     298           0 :     inline ScBroadcastArea* GetEOUpdateChain() const { return pEOUpdateChain; }
     299           0 :     inline void SetEOUpdateChain( ScBroadcastArea* p ) { pEOUpdateChain = p; }
     300         223 :     inline bool IsInBulkBroadcast() const { return nInBulkBroadcast > 0; }
     301             : 
     302             :     // only for ScBroadcastAreaSlot
     303             :     void                PushAreaToBeErased( ScBroadcastAreaSlot* pSlot,
     304             :                                             ScBroadcastAreas::iterator& rIter );
     305             :     // only for ScBroadcastAreaSlot
     306             :     void                FinallyEraseAreas( ScBroadcastAreaSlot* pSlot );
     307             : };
     308             : 
     309             : 
     310             : class ScBulkBroadcast
     311             : {
     312             :     ScBroadcastAreaSlotMachine* pBASM;
     313             : public:
     314       45924 :     explicit ScBulkBroadcast( ScBroadcastAreaSlotMachine* p ) : pBASM(p)
     315             :     {
     316       45924 :         if (pBASM)
     317       45879 :             pBASM->EnterBulkBroadcast();
     318       45924 :     }
     319       45924 :     ~ScBulkBroadcast()
     320             :     {
     321       45924 :         if (pBASM)
     322       45879 :             pBASM->LeaveBulkBroadcast();
     323       45924 :     }
     324             :     void LeaveBulkBroadcast()
     325             :     {
     326             :         if (pBASM)
     327             :         {
     328             :             pBASM->LeaveBulkBroadcast();
     329             :             pBASM = NULL;
     330             :         }
     331             :     }
     332             : };
     333             : 
     334             : #endif
     335             : 
     336             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10