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

Generated by: LCOV version 1.10