LCOV - code coverage report
Current view: top level - sc/source/core/inc - bcaslot.hxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 43 0.0 %
Date: 2014-04-14 Functions: 0 30 0.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_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             : namespace sc {
      32             : 
      33           0 : struct AreaListener
      34             : {
      35             :     ScRange maArea;
      36             :     SvtListener* mpListener;
      37             : };
      38             : 
      39             : }
      40             : 
      41             : /**
      42             :     Used in a Unique Associative Container.
      43             :  */
      44             : 
      45           0 : 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           0 :             ScBroadcastArea( const ScRange& rRange )
      56             :                 : pUpdateChainNext( NULL ), aRange( rRange ),
      57           0 :                 nRefCount( 0 ), bInUpdateChain( false ) {}
      58           0 :     inline SvtBroadcaster&       GetBroadcaster()       { return aBroadcaster; }
      59             :     inline const SvtBroadcaster& GetBroadcaster() const { return aBroadcaster; }
      60           0 :     inline void         UpdateRange( const ScRange& rNewRange )
      61           0 :                             { aRange = rNewRange; }
      62           0 :     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           0 :     inline void         IncRef() { ++nRefCount; }
      66           0 :     inline sal_uLong        DecRef() { return nRefCount ? --nRefCount : 0; }
      67           0 :     inline sal_uLong        GetRef() { return nRefCount; }
      68           0 :     inline ScBroadcastArea* GetUpdateChainNext() const { return pUpdateChainNext; }
      69           0 :     inline void         SetUpdateChainNext( ScBroadcastArea* p ) { pUpdateChainNext = p; }
      70           0 :     inline bool         IsInUpdateChain() const { return bInUpdateChain; }
      71           0 :     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           0 : inline bool ScBroadcastArea::operator==( const ScBroadcastArea & rArea ) const
      78             : {
      79           0 :     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           0 :     ScBroadcastAreaEntry( ScBroadcastArea* p ) : mpArea( p), mbErasure( false) {}
      88             : };
      89             : 
      90             : struct ScBroadcastAreaHash
      91             : {
      92           0 :     size_t operator()( const ScBroadcastAreaEntry& rEntry ) const
      93             :     {
      94           0 :         return rEntry.mpArea->GetRange().hashArea();
      95             :     }
      96             : };
      97             : 
      98             : struct ScBroadcastAreaEqual
      99             : {
     100           0 :     bool operator()( const ScBroadcastAreaEntry& rEntry1, const ScBroadcastAreaEntry& rEntry2) const
     101             :     {
     102           0 :         return *rEntry1.mpArea == *rEntry2.mpArea;
     103             :     }
     104             : };
     105             : 
     106             : typedef ::boost::unordered_set< ScBroadcastAreaEntry, ScBroadcastAreaHash, ScBroadcastAreaEqual > ScBroadcastAreas;
     107             : 
     108             : struct ScBroadcastAreaBulkHash
     109             : {
     110           0 :     size_t operator()( const ScBroadcastArea* p ) const
     111             :     {
     112           0 :         return reinterpret_cast<size_t>(p);
     113             :     }
     114             : };
     115             : 
     116             : struct ScBroadcastAreaBulkEqual
     117             : {
     118           0 :     bool operator()( const ScBroadcastArea* p1, const ScBroadcastArea* p2) const
     119             :     {
     120           0 :         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           0 :     bool                isMarkedErased( const ScBroadcastAreas::iterator& rIter )
     155             :                             {
     156           0 :                                 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             : 
     208           0 :     bool                IsInBroadcastIteration() const { return mbInBroadcastIteration; }
     209             : 
     210             :     /** Erase an area from set and delete it if last reference, or if
     211             :         mbInBroadcastIteration is set push it to the vector of to-be-erased
     212             :         areas instead.
     213             : 
     214             :         Meant to be used internally and from ScBroadcastAreaSlotMachine only.
     215             :      */
     216             :     void                EraseArea( ScBroadcastAreas::iterator& rIter );
     217             : 
     218             :     void GetAllListeners( const ScRange& rRange, std::vector<sc::AreaListener>& rListeners );
     219             : };
     220             : 
     221             : 
     222             : /**
     223             :     BroadcastAreaSlots and their management, once per document.
     224             :  */
     225             : 
     226             : class  ScBroadcastAreaSlotMachine
     227             : {
     228             : private:
     229             : 
     230             :     /**
     231             :         Slot offset arrangement of columns and rows, once per sheet.
     232             : 
     233             :         +---+---+
     234             :         | 0 | 3 |
     235             :         +---+---+
     236             :         | 1 | 4 |
     237             :         +---+---+
     238             :         | 2 | 5 |
     239             :         +---+---+
     240             :      */
     241             : 
     242             :     class TableSlots
     243             :     {
     244             :         public:
     245             :                                             TableSlots();
     246             :                                             ~TableSlots();
     247           0 :             inline ScBroadcastAreaSlot**    getSlots() { return ppSlots; }
     248             : 
     249             :             /**
     250             :                 Obtain slot pointer, no check on validity! It is assumed that
     251             :                 all calls are made with the results of ComputeSlotOffset(),
     252             :                 ComputeAreaPoints() and ComputeNextSlot()
     253             :               */
     254           0 :             inline ScBroadcastAreaSlot*     getAreaSlot( SCSIZE nOff ) { return *(ppSlots + nOff); }
     255             : 
     256             :         private:
     257             :             ScBroadcastAreaSlot**   ppSlots;
     258             : 
     259             :             // prevent usage
     260             :             TableSlots( const TableSlots& );
     261             :             TableSlots& operator=( const TableSlots& );
     262             :     };
     263             : 
     264             :     typedef ::std::map< SCTAB, TableSlots* > TableSlotsMap;
     265             : 
     266             :     typedef ::std::vector< ::std::pair< ScBroadcastAreaSlot*, ScBroadcastAreas::iterator > > AreasToBeErased;
     267             : 
     268             : private:
     269             :     ScBroadcastAreasBulk  aBulkBroadcastAreas;
     270             :     TableSlotsMap         aTableSlotsMap;
     271             :     AreasToBeErased       maAreasToBeErased;
     272             :     SvtBroadcaster       *pBCAlways;             // for the RC_ALWAYS special range
     273             :     ScDocument           *pDoc;
     274             :     ScBroadcastArea      *pUpdateChain;
     275             :     ScBroadcastArea      *pEOUpdateChain;
     276             :     sal_uLong             nInBulkBroadcast;
     277             : 
     278             :     inline SCSIZE       ComputeSlotOffset( const ScAddress& rAddress ) const;
     279             :     void                ComputeAreaPoints( const ScRange& rRange,
     280             :                                             SCSIZE& nStart, SCSIZE& nEnd,
     281             :                                             SCSIZE& nRowBreak ) const;
     282             : 
     283             : public:
     284             :                         ScBroadcastAreaSlotMachine( ScDocument* pDoc );
     285             :                         ~ScBroadcastAreaSlotMachine();
     286             :     void                StartListeningArea( const ScRange& rRange,
     287             :                                             SvtListener* pListener );
     288             :     void                EndListeningArea( const ScRange& rRange,
     289             :                                             SvtListener* pListener );
     290             :     bool                AreaBroadcast( const ScHint& rHint ) const;
     291             :         // return: at least one broadcast occurred
     292             :     bool                AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHint ) const;
     293             :     void                DelBroadcastAreasInRange( const ScRange& rRange );
     294             :     void                UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
     295             :                                             const ScRange& rRange,
     296             :                                             SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
     297             :     void                EnterBulkBroadcast();
     298             :     void                LeaveBulkBroadcast();
     299             :     bool                InsertBulkArea( const ScBroadcastArea* p );
     300             :     /// @return: how many removed
     301             :     size_t              RemoveBulkArea( const ScBroadcastArea* p );
     302             :     inline ScBroadcastArea* GetUpdateChain() const { return pUpdateChain; }
     303           0 :     inline void SetUpdateChain( ScBroadcastArea* p ) { pUpdateChain = p; }
     304           0 :     inline ScBroadcastArea* GetEOUpdateChain() const { return pEOUpdateChain; }
     305           0 :     inline void SetEOUpdateChain( ScBroadcastArea* p ) { pEOUpdateChain = p; }
     306           0 :     inline bool IsInBulkBroadcast() const { return nInBulkBroadcast > 0; }
     307             : 
     308             :     // only for ScBroadcastAreaSlot
     309             :     void                PushAreaToBeErased( ScBroadcastAreaSlot* pSlot,
     310             :                                             ScBroadcastAreas::iterator& rIter );
     311             :     // only for ScBroadcastAreaSlot
     312             :     void                FinallyEraseAreas( ScBroadcastAreaSlot* pSlot );
     313             : 
     314             :     std::vector<sc::AreaListener> GetAllListeners( const ScRange& rRange );
     315             : };
     316             : 
     317             : 
     318             : class ScBulkBroadcast
     319             : {
     320             :     ScBroadcastAreaSlotMachine* pBASM;
     321             : public:
     322           0 :     explicit ScBulkBroadcast( ScBroadcastAreaSlotMachine* p ) : pBASM(p)
     323             :     {
     324           0 :         if (pBASM)
     325           0 :             pBASM->EnterBulkBroadcast();
     326           0 :     }
     327           0 :     ~ScBulkBroadcast()
     328             :     {
     329           0 :         if (pBASM)
     330           0 :             pBASM->LeaveBulkBroadcast();
     331           0 :     }
     332             :     void LeaveBulkBroadcast()
     333             :     {
     334             :         if (pBASM)
     335             :         {
     336             :             pBASM->LeaveBulkBroadcast();
     337             :             pBASM = NULL;
     338             :         }
     339             :     }
     340             : };
     341             : 
     342             : #endif
     343             : 
     344             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10