xref: /aoo41x/main/sc/source/core/inc/bcaslot.hxx (revision 6d3b264b)
138d50f7bSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
338d50f7bSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
438d50f7bSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
538d50f7bSAndrew Rist  * distributed with this work for additional information
638d50f7bSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
738d50f7bSAndrew Rist  * to you under the Apache License, Version 2.0 (the
838d50f7bSAndrew Rist  * "License"); you may not use this file except in compliance
938d50f7bSAndrew Rist  * with the License.  You may obtain a copy of the License at
1038d50f7bSAndrew Rist  *
1138d50f7bSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1238d50f7bSAndrew Rist  *
1338d50f7bSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1438d50f7bSAndrew Rist  * software distributed under the License is distributed on an
1538d50f7bSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1638d50f7bSAndrew Rist  * KIND, either express or implied.  See the License for the
1738d50f7bSAndrew Rist  * specific language governing permissions and limitations
1838d50f7bSAndrew Rist  * under the License.
1938d50f7bSAndrew Rist  *
2038d50f7bSAndrew Rist  *************************************************************/
2138d50f7bSAndrew Rist 
2238d50f7bSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef SC_BCASLOT_HXX
25cdf0e10cSrcweir #define SC_BCASLOT_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <set>
28cdf0e10cSrcweir #include <hash_set>
29cdf0e10cSrcweir #include <functional>
30cdf0e10cSrcweir #include <svl/broadcast.hxx>
31cdf0e10cSrcweir #include <svl/svarray.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include "global.hxx"
34cdf0e10cSrcweir #include "brdcst.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir /**
37cdf0e10cSrcweir     Used in a Unique Associative Container.
38cdf0e10cSrcweir  */
39cdf0e10cSrcweir 
40cdf0e10cSrcweir class ScBroadcastArea
41cdf0e10cSrcweir {
42cdf0e10cSrcweir private:
43cdf0e10cSrcweir 	ScBroadcastArea*	pUpdateChainNext;
44cdf0e10cSrcweir     SvtBroadcaster      aBroadcaster;
45cdf0e10cSrcweir     ScRange             aRange;
46cdf0e10cSrcweir 	sal_uLong				nRefCount;
47cdf0e10cSrcweir 	sal_Bool				bInUpdateChain;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir public:
ScBroadcastArea(const ScRange & rRange)50cdf0e10cSrcweir 			ScBroadcastArea( const ScRange& rRange )
51cdf0e10cSrcweir 				: pUpdateChainNext( NULL ), aRange( rRange ),
52cdf0e10cSrcweir 				nRefCount( 0 ), bInUpdateChain( sal_False ) {}
GetBroadcaster()53cdf0e10cSrcweir     inline SvtBroadcaster&       GetBroadcaster()       { return aBroadcaster; }
GetBroadcaster() const54cdf0e10cSrcweir     inline const SvtBroadcaster& GetBroadcaster() const { return aBroadcaster; }
UpdateRange(const ScRange & rNewRange)55cdf0e10cSrcweir 	inline void			UpdateRange( const ScRange& rNewRange )
56cdf0e10cSrcweir 			                { aRange = rNewRange; }
GetRange() const57cdf0e10cSrcweir     inline const ScRange&   GetRange() const { return aRange; }
GetStart() const58cdf0e10cSrcweir 	inline const ScAddress& GetStart() const { return aRange.aStart; }
GetEnd() const59cdf0e10cSrcweir 	inline const ScAddress& GetEnd() const { return aRange.aEnd; }
IncRef()60cdf0e10cSrcweir 	inline void			IncRef() { ++nRefCount; }
DecRef()61cdf0e10cSrcweir 	inline sal_uLong		DecRef() { return nRefCount ? --nRefCount : 0; }
GetRef()62cdf0e10cSrcweir 	inline sal_uLong		GetRef() { return nRefCount; }
GetUpdateChainNext() const63cdf0e10cSrcweir 	inline ScBroadcastArea* GetUpdateChainNext() const { return pUpdateChainNext; }
SetUpdateChainNext(ScBroadcastArea * p)64cdf0e10cSrcweir 	inline void			SetUpdateChainNext( ScBroadcastArea* p ) { pUpdateChainNext = p; }
IsInUpdateChain() const65cdf0e10cSrcweir 	inline sal_Bool			IsInUpdateChain() const { return bInUpdateChain; }
SetInUpdateChain(sal_Bool b)66cdf0e10cSrcweir 	inline void			SetInUpdateChain( sal_Bool b ) { bInUpdateChain = b; }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     /** Equalness of this or range. */
69cdf0e10cSrcweir     inline  bool        operator==( const ScBroadcastArea & rArea ) const;
70cdf0e10cSrcweir };
71cdf0e10cSrcweir 
operator ==(const ScBroadcastArea & rArea) const72cdf0e10cSrcweir inline bool ScBroadcastArea::operator==( const ScBroadcastArea & rArea ) const
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     return aRange == rArea.aRange;
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
77cdf0e10cSrcweir //=============================================================================
78cdf0e10cSrcweir 
79cdf0e10cSrcweir struct ScBroadcastAreaHash
80cdf0e10cSrcweir {
operator ()ScBroadcastAreaHash81cdf0e10cSrcweir     size_t operator()( const ScBroadcastArea* p ) const
82cdf0e10cSrcweir     {
83cdf0e10cSrcweir         return p->GetRange().hashArea();
84cdf0e10cSrcweir     }
85cdf0e10cSrcweir };
86cdf0e10cSrcweir 
87cdf0e10cSrcweir struct ScBroadcastAreaEqual
88cdf0e10cSrcweir {
operator ()ScBroadcastAreaEqual89cdf0e10cSrcweir     bool operator()( const ScBroadcastArea* p1, const ScBroadcastArea* p2) const
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         return *p1 == *p2;
92cdf0e10cSrcweir     }
93cdf0e10cSrcweir };
94cdf0e10cSrcweir 
95cdf0e10cSrcweir typedef ::std::hash_set< ScBroadcastArea*, ScBroadcastAreaHash, ScBroadcastAreaEqual > ScBroadcastAreas;
96cdf0e10cSrcweir 
97cdf0e10cSrcweir //=============================================================================
98cdf0e10cSrcweir 
99cdf0e10cSrcweir struct ScBroadcastAreaBulkHash
100cdf0e10cSrcweir {
operator ()ScBroadcastAreaBulkHash101cdf0e10cSrcweir     size_t operator()( const ScBroadcastArea* p ) const
102cdf0e10cSrcweir     {
103cdf0e10cSrcweir         return reinterpret_cast<size_t>(p);
104cdf0e10cSrcweir     }
105cdf0e10cSrcweir };
106cdf0e10cSrcweir 
107cdf0e10cSrcweir struct ScBroadcastAreaBulkEqual
108cdf0e10cSrcweir {
operator ()ScBroadcastAreaBulkEqual109cdf0e10cSrcweir     bool operator()( const ScBroadcastArea* p1, const ScBroadcastArea* p2) const
110cdf0e10cSrcweir     {
111cdf0e10cSrcweir         return p1 == p2;
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir };
114cdf0e10cSrcweir 
115cdf0e10cSrcweir typedef ::std::hash_set< const ScBroadcastArea*, ScBroadcastAreaBulkHash,
116cdf0e10cSrcweir         ScBroadcastAreaBulkEqual > ScBroadcastAreasBulk;
117cdf0e10cSrcweir 
118cdf0e10cSrcweir //=============================================================================
119cdf0e10cSrcweir 
120cdf0e10cSrcweir class ScBroadcastAreaSlotMachine;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir /// Collection of BroadcastAreas
123cdf0e10cSrcweir class ScBroadcastAreaSlot
124cdf0e10cSrcweir {
125cdf0e10cSrcweir private:
126cdf0e10cSrcweir     ScBroadcastAreas	aBroadcastAreaTbl;
127cdf0e10cSrcweir     mutable ScBroadcastArea aTmpSeekBroadcastArea;      // for FindBroadcastArea()
128cdf0e10cSrcweir 	ScDocument*			pDoc;
129cdf0e10cSrcweir 	ScBroadcastAreaSlotMachine* pBASM;
130cdf0e10cSrcweir 
131*6d3b264bSHerbert Dürr     ScBroadcastAreas::const_iterator  FindBroadcastArea( const ScRange& rRange ) const;
132cdf0e10cSrcweir 
133cdf0e10cSrcweir     /**
134cdf0e10cSrcweir         More hypothetical (memory would probably be doomed anyway) check
135cdf0e10cSrcweir         whether there would be an overflow when adding an area, setting the
136cdf0e10cSrcweir         proper state if so.
137cdf0e10cSrcweir 
138cdf0e10cSrcweir         @return sal_True if a HardRecalcState is effective and area is not to be
139cdf0e10cSrcweir         added.
140cdf0e10cSrcweir       */
141cdf0e10cSrcweir     bool                CheckHardRecalcStateCondition() const;
142cdf0e10cSrcweir 
143cdf0e10cSrcweir public:
144cdf0e10cSrcweir 						ScBroadcastAreaSlot( ScDocument* pDoc,
145cdf0e10cSrcweir 										ScBroadcastAreaSlotMachine* pBASM );
146cdf0e10cSrcweir 						~ScBroadcastAreaSlot();
GetBroadcastAreas() const147cdf0e10cSrcweir 	const ScBroadcastAreas&	GetBroadcastAreas() const
148cdf0e10cSrcweir 											{ return aBroadcastAreaTbl; }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     /**
151cdf0e10cSrcweir         Only here new ScBroadcastArea objects are created, prevention of dupes.
152cdf0e10cSrcweir 
153cdf0e10cSrcweir         @param rpArea
154cdf0e10cSrcweir             If NULL, a new ScBroadcastArea is created and assigned ton the
155cdf0e10cSrcweir             reference if a matching area wasn't found. If a matching area was
156cdf0e10cSrcweir             found, that is assigned. In any case, the SvtListener is added to
157cdf0e10cSrcweir             the broadcaster.
158cdf0e10cSrcweir 
159cdf0e10cSrcweir             If not NULL then no listeners are startet, only the area is
160cdf0e10cSrcweir             inserted and the reference count incremented. Effectively the same
161cdf0e10cSrcweir             as InsertListeningArea(), so use that instead.
162cdf0e10cSrcweir 
163cdf0e10cSrcweir         @return
164cdf0e10cSrcweir             sal_True if rpArea passed was NULL and ScBroadcastArea is newly
165cdf0e10cSrcweir             created.
166cdf0e10cSrcweir      */
167cdf0e10cSrcweir 	bool				StartListeningArea( const ScRange& rRange,
168cdf0e10cSrcweir 											SvtListener* pListener,
169cdf0e10cSrcweir 											ScBroadcastArea*& rpArea );
170cdf0e10cSrcweir 
171cdf0e10cSrcweir     /**
172cdf0e10cSrcweir         Insert a ScBroadcastArea obtained via StartListeningArea() to
173cdf0e10cSrcweir         subsequent slots.
174cdf0e10cSrcweir      */
175cdf0e10cSrcweir     void                InsertListeningArea( ScBroadcastArea* pArea );
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 	void				EndListeningArea( const ScRange& rRange,
178cdf0e10cSrcweir 											SvtListener* pListener,
179cdf0e10cSrcweir 											ScBroadcastArea*& rpArea );
180cdf0e10cSrcweir 	sal_Bool				AreaBroadcast( const ScHint& rHint ) const;
181cdf0e10cSrcweir     /// @return sal_True if at least one broadcast occurred.
182cdf0e10cSrcweir     sal_Bool				AreaBroadcastInRange( const ScRange& rRange,
183cdf0e10cSrcweir                                               const ScHint& rHint ) const;
184cdf0e10cSrcweir 	void				DelBroadcastAreasInRange( const ScRange& rRange );
185cdf0e10cSrcweir 	void				UpdateRemove( UpdateRefMode eUpdateRefMode,
186cdf0e10cSrcweir 										const ScRange& rRange,
187cdf0e10cSrcweir 										SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
188cdf0e10cSrcweir     void                UpdateRemoveArea( ScBroadcastArea* pArea );
189cdf0e10cSrcweir 	void				UpdateInsert( ScBroadcastArea* pArea );
190cdf0e10cSrcweir };
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 
193cdf0e10cSrcweir /**
194cdf0e10cSrcweir 	BroadcastAreaSlots and their management, once per document.
195cdf0e10cSrcweir  */
196cdf0e10cSrcweir 
197cdf0e10cSrcweir class  ScBroadcastAreaSlotMachine
198cdf0e10cSrcweir {
199cdf0e10cSrcweir private:
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     /**
202cdf0e10cSrcweir         Slot offset arrangement of columns and rows, once per sheet.
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         +---+---+
205cdf0e10cSrcweir         | 0 | 3 |
206cdf0e10cSrcweir         +---+---+
207cdf0e10cSrcweir         | 1 | 4 |
208cdf0e10cSrcweir         +---+---+
209cdf0e10cSrcweir         | 2 | 5 |
210cdf0e10cSrcweir         +---+---+
211cdf0e10cSrcweir      */
212cdf0e10cSrcweir 
213cdf0e10cSrcweir     class TableSlots
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         public:
216cdf0e10cSrcweir                                             TableSlots();
217cdf0e10cSrcweir                                             ~TableSlots();
getSlots()218cdf0e10cSrcweir             inline ScBroadcastAreaSlot**    getSlots() { return ppSlots; }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir             /**
221cdf0e10cSrcweir                 Obtain slot pointer, no check on validity! It is assumed that
222cdf0e10cSrcweir                 all calls are made with the results of ComputeSlotOffset(),
223cdf0e10cSrcweir                 ComputeAreaPoints() and ComputeNextSlot()
224cdf0e10cSrcweir               */
getAreaSlot(SCSIZE nOff)225cdf0e10cSrcweir             inline ScBroadcastAreaSlot*     getAreaSlot( SCSIZE nOff ) { return *(ppSlots + nOff); }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         private:
228cdf0e10cSrcweir             ScBroadcastAreaSlot**	ppSlots;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir             // prevent usage
231cdf0e10cSrcweir             TableSlots( const TableSlots& );
232cdf0e10cSrcweir             TableSlots& operator=( const TableSlots& );
233cdf0e10cSrcweir     };
234cdf0e10cSrcweir 
235cdf0e10cSrcweir     typedef ::std::map< SCTAB, TableSlots* > TableSlotsMap;
236cdf0e10cSrcweir 
237cdf0e10cSrcweir private:
238cdf0e10cSrcweir     ScBroadcastAreasBulk  aBulkBroadcastAreas;
239cdf0e10cSrcweir     TableSlotsMap         aTableSlotsMap;
240cdf0e10cSrcweir     SvtBroadcaster       *pBCAlways;             // for the RC_ALWAYS special range
241cdf0e10cSrcweir     ScDocument           *pDoc;
242cdf0e10cSrcweir     ScBroadcastArea      *pUpdateChain;
243cdf0e10cSrcweir     ScBroadcastArea      *pEOUpdateChain;
244cdf0e10cSrcweir     sal_uLong                 nInBulkBroadcast;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	inline SCSIZE		ComputeSlotOffset( const ScAddress& rAddress ) const;
247cdf0e10cSrcweir 	void				ComputeAreaPoints( const ScRange& rRange,
248cdf0e10cSrcweir 											SCSIZE& nStart, SCSIZE& nEnd,
249cdf0e10cSrcweir 											SCSIZE& nRowBreak ) const;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir public:
252cdf0e10cSrcweir 						ScBroadcastAreaSlotMachine( ScDocument* pDoc );
253cdf0e10cSrcweir 						~ScBroadcastAreaSlotMachine();
254cdf0e10cSrcweir 	void				StartListeningArea( const ScRange& rRange,
255cdf0e10cSrcweir 											SvtListener* pListener );
256cdf0e10cSrcweir 	void				EndListeningArea( const ScRange& rRange,
257cdf0e10cSrcweir 											SvtListener* pListener );
258cdf0e10cSrcweir 	sal_Bool				AreaBroadcast( const ScHint& rHint ) const;
259cdf0e10cSrcweir         // return: at least one broadcast occurred
260cdf0e10cSrcweir     sal_Bool                AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHint ) const;
261cdf0e10cSrcweir 	void				DelBroadcastAreasInRange( const ScRange& rRange );
262cdf0e10cSrcweir 	void				UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
263cdf0e10cSrcweir 											const ScRange& rRange,
264cdf0e10cSrcweir 											SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
265cdf0e10cSrcweir     void                EnterBulkBroadcast();
266cdf0e10cSrcweir     void                LeaveBulkBroadcast();
267cdf0e10cSrcweir     bool                InsertBulkArea( const ScBroadcastArea* p );
268cdf0e10cSrcweir     /// @return: how many removed
269cdf0e10cSrcweir     size_t              RemoveBulkArea( const ScBroadcastArea* p );
GetUpdateChain() const270cdf0e10cSrcweir 	inline ScBroadcastArea* GetUpdateChain() const { return pUpdateChain; }
SetUpdateChain(ScBroadcastArea * p)271cdf0e10cSrcweir 	inline void SetUpdateChain( ScBroadcastArea* p ) { pUpdateChain = p; }
GetEOUpdateChain() const272cdf0e10cSrcweir 	inline ScBroadcastArea* GetEOUpdateChain() const { return pEOUpdateChain; }
SetEOUpdateChain(ScBroadcastArea * p)273cdf0e10cSrcweir 	inline void SetEOUpdateChain( ScBroadcastArea* p ) { pEOUpdateChain = p; }
IsInBulkBroadcast() const274cdf0e10cSrcweir     inline bool IsInBulkBroadcast() const { return nInBulkBroadcast > 0; }
275cdf0e10cSrcweir };
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 
278cdf0e10cSrcweir class ScBulkBroadcast
279cdf0e10cSrcweir {
280cdf0e10cSrcweir     ScBroadcastAreaSlotMachine* pBASM;
281cdf0e10cSrcweir public:
ScBulkBroadcast(ScBroadcastAreaSlotMachine * p)282cdf0e10cSrcweir     explicit ScBulkBroadcast( ScBroadcastAreaSlotMachine* p ) : pBASM(p)
283cdf0e10cSrcweir     {
284cdf0e10cSrcweir         if (pBASM)
285cdf0e10cSrcweir             pBASM->EnterBulkBroadcast();
286cdf0e10cSrcweir     }
~ScBulkBroadcast()287cdf0e10cSrcweir     ~ScBulkBroadcast()
288cdf0e10cSrcweir     {
289cdf0e10cSrcweir         if (pBASM)
290cdf0e10cSrcweir             pBASM->LeaveBulkBroadcast();
291cdf0e10cSrcweir     }
LeaveBulkBroadcast()292cdf0e10cSrcweir     void LeaveBulkBroadcast()
293cdf0e10cSrcweir     {
294cdf0e10cSrcweir         if (pBASM)
295cdf0e10cSrcweir         {
296cdf0e10cSrcweir             pBASM->LeaveBulkBroadcast();
297cdf0e10cSrcweir             pBASM = NULL;
298cdf0e10cSrcweir         }
299cdf0e10cSrcweir     }
300cdf0e10cSrcweir };
301cdf0e10cSrcweir 
302cdf0e10cSrcweir #endif
303