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