LibreOffice Module sc (master)  1
chartlis.cxx
Go to the documentation of this file.
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 #include <memory>
21 #include <vcl/svapp.hxx>
22 
23 #include <chartlis.hxx>
24 #include <brdcst.hxx>
25 #include <document.hxx>
26 #include <reftokenhelper.hxx>
27 #include <formula/token.hxx>
28 #include <com/sun/star/chart/XChartDataChangeEventListener.hpp>
29 
30 using namespace com::sun::star;
31 using ::std::vector;
32 using ::std::for_each;
33 
34 // Update chart listeners quickly, to get a similar behavior to loaded charts
35 // which register UNO listeners.
36 
38 {
39  uno::Reference< chart::XChartDataChangeEventListener > xListener;
40  uno::Reference< chart::XChartData > xSource;
41 
42 public:
43  ScChartUnoData( const uno::Reference< chart::XChartDataChangeEventListener >& rL,
44  const uno::Reference< chart::XChartData >& rS ) :
45  xListener( rL ), xSource( rS ) {}
46 
47  const uno::Reference< chart::XChartDataChangeEventListener >& GetListener() const { return xListener; }
48  const uno::Reference< chart::XChartData >& GetSource() const { return xSource; }
49 };
50 
51 // ScChartListener
53  mrParent(rParent), m_pDoc(&rDoc)
54 {
55 }
56 
58 {
59  if (!m_pDoc || m_pDoc->IsInDtorClear())
60  // The document is being destroyed. Do nothing.
61  return;
62 
63  // Make sure to remove all pointers to this object.
64  m_pDoc->GetExternalRefManager()->removeLinkListener(this);
65 }
66 
68 {
69  switch (eType)
70  {
72  {
73  if (maFileIds.count(nFileId))
74  // We are listening to this external document. Send an update
75  // request to the chart.
76  mrParent.SetUpdateQueue();
77  }
78  break;
80  removeFileId(nFileId);
81  break;
83  m_pDoc = nullptr;
84  break;
85  }
86 }
87 
89 {
90  maFileIds.insert(nFileId);
91 }
92 
94 {
95  maFileIds.erase(nFileId);
96 }
97 
98 ScChartListener::ScChartListener( const OUString& rName, ScDocument& rDocP,
99  const ScRangeListRef& rRangeList ) :
100  mpTokens(new vector<ScTokenRef>),
101  maName(rName),
102  mrDoc( rDocP ),
103  bUsed( false ),
104  bDirty( false )
105 {
106  ScRefTokenHelper::getTokensFromRangeList(&rDocP, *mpTokens, *rRangeList);
107 }
108 
109 ScChartListener::ScChartListener( const OUString& rName, ScDocument& rDocP, std::unique_ptr<vector<ScTokenRef>> pTokens ) :
110  mpTokens(std::move(pTokens)),
111  maName(rName),
112  mrDoc( rDocP ),
113  bUsed( false ),
114  bDirty( false )
115 {
116 }
117 
119 {
120  if ( HasBroadcaster() )
121  EndListeningTo();
122  pUnoData.reset();
123 
124  if (mpExtRefListener)
125  {
126  // Stop listening to all external files.
128  const std::unordered_set<sal_uInt16>& rFileIds = mpExtRefListener->getAllFileIds();
129  for (const auto& rFileId : rFileIds)
130  pRefMgr->removeLinkListener(rFileId, mpExtRefListener.get());
131  }
132 }
133 
135  const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
136  const uno::Reference< chart::XChartData >& rSource )
137 {
138  pUnoData.reset( new ScChartUnoData( rListener, rSource ) );
139 }
140 
141 uno::Reference< chart::XChartDataChangeEventListener > ScChartListener::GetUnoListener() const
142 {
143  if ( pUnoData )
144  return pUnoData->GetListener();
145  return uno::Reference< chart::XChartDataChangeEventListener >();
146 }
147 
148 uno::Reference< chart::XChartData > ScChartListener::GetUnoSource() const
149 {
150  if ( pUnoData )
151  return pUnoData->GetSource();
152  return uno::Reference< chart::XChartData >();
153 }
154 
155 void ScChartListener::Notify( const SfxHint& rHint )
156 {
157  const ScHint* p = dynamic_cast<const ScHint*>(&rHint);
158  if (p && (p->GetId() == SfxHintId::ScDataChanged))
159  SetUpdateQueue();
160 }
161 
163 {
164  if ( mrDoc.IsInInterpreter() )
165  { // If interpreting do nothing and restart timer so we don't
166  // interfere with interpreter and don't produce an Err522 or similar.
167  // This may happen if we are rescheduled via Basic function.
169  return ;
170  }
171  if ( pUnoData )
172  {
173  bDirty = false;
174  // recognize some day what has changed inside the Chart
175  chart::ChartDataChangeEvent aEvent( pUnoData->GetSource(),
176  chart::ChartDataChangeType_ALL,
177  0, 0, 0, 0 );
178  pUnoData->GetListener()->chartDataChanged( aEvent );
179  }
180  else if ( mrDoc.GetAutoCalc() )
181  {
182  bDirty = false;
184  }
185 }
186 
188 {
189  ScRangeListRef aRLRef(new ScRangeList);
191  return aRLRef;
192 }
193 
195 {
196  vector<ScTokenRef> aTokens;
198  mpTokens->swap(aTokens);
199 }
200 
201 namespace {
202 
203 class StartEndListening
204 {
205 public:
206  StartEndListening(ScDocument& rDoc, ScChartListener& rParent, bool bStart) :
207  mrDoc(rDoc), mrParent(rParent), mbStart(bStart) {}
208 
209  void operator() (const ScTokenRef& pToken)
210  {
211  if (!ScRefTokenHelper::isRef(pToken))
212  return;
213 
214  bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
215  if (bExternal)
216  {
217  sal_uInt16 nFileId = pToken->GetIndex();
218  ScExternalRefManager* pRefMgr = mrDoc.GetExternalRefManager();
219  ScChartListener::ExternalRefListener* pExtRefListener = mrParent.GetExtRefListener();
220  if (mbStart)
221  {
222  pRefMgr->addLinkListener(nFileId, pExtRefListener);
223  pExtRefListener->addFileId(nFileId);
224  }
225  else
226  {
227  pRefMgr->removeLinkListener(nFileId, pExtRefListener);
228  pExtRefListener->removeFileId(nFileId);
229  }
230  }
231  else
232  {
233  ScRange aRange;
234  ScRefTokenHelper::getRangeFromToken(&mrDoc, aRange, pToken, ScAddress(), bExternal);
235  if (mbStart)
236  startListening(aRange);
237  else
238  endListening(aRange);
239  }
240  }
241 private:
242  void startListening(const ScRange& rRange)
243  {
244  if (rRange.aStart == rRange.aEnd)
245  mrDoc.StartListeningCell(rRange.aStart, &mrParent);
246  else
247  mrDoc.StartListeningArea(rRange, false, &mrParent);
248  }
249 
250  void endListening(const ScRange& rRange)
251  {
252  if (rRange.aStart == rRange.aEnd)
253  mrDoc.EndListeningCell(rRange.aStart, &mrParent);
254  else
255  mrDoc.EndListeningArea(rRange, false, &mrParent);
256  }
257 private:
258  ScDocument& mrDoc;
260  bool mbStart;
261 };
262 
263 }
264 
266 {
267  if (!mpTokens || mpTokens->empty())
268  // no references to listen to.
269  return;
270 
271  for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(mrDoc, *this, true));
272 }
273 
275 {
276  if (!mpTokens || mpTokens->empty())
277  // no references to listen to.
278  return;
279 
280  for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(mrDoc, *this, false));
281 }
282 
284  bool bDirtyP )
285 {
286  EndListeningTo();
287  SetRangeList( rRangeListRef );
289  if ( bDirtyP )
290  SetDirty( true );
291 }
292 
294 {
295  ScTokenRef pToken;
296  ScRefTokenHelper::getTokenFromRange(&mrDoc, pToken, rRange);
297 
299  {
300  // force update (chart has to be loaded), don't use ScChartListener::Update
302  }
303 }
304 
306 {
307  if (!mpExtRefListener)
308  mpExtRefListener.reset(new ExternalRefListener(*this, mrDoc));
309 
310  return mpExtRefListener.get();
311 }
312 
314 {
315  bDirty = true;
317 }
318 
320 {
321  bool b1 = (mpTokens && !mpTokens->empty());
322  bool b2 = (r.mpTokens && !r.mpTokens->empty());
323 
324  if (&mrDoc != &r.mrDoc || bUsed != r.bUsed || bDirty != r.bDirty ||
325  GetName() != r.GetName() || b1 != b2)
326  return false;
327 
328  if (!b1 && !b2)
329  // both token list instances are empty.
330  return true;
331 
332  return *mpTokens == *r.mpTokens;
333 }
334 
336 {
337  return !operator==(r);
338 }
339 
341 {
342 }
343 
345 {
346  // empty d'tor
347 }
348 
350 {
352  aIdle.SetPriority( TaskPriority::REPAINT );
353 }
354 
356  meModifiedDuringUpdate( SC_CLCUPDATE_NONE ),
357  aIdle( "sc::ScChartListenerCollection aIdle" ),
358  rDoc( rDocP )
359 {
360  Init();
361 }
362 
364  const ScChartListenerCollection& rColl ) :
365  meModifiedDuringUpdate( SC_CLCUPDATE_NONE ),
366  aIdle( "sc::ScChartListenerCollection aIdle" ),
367  rDoc( rColl.rDoc )
368 {
369  Init();
370 }
371 
373 {
374  // remove ChartListener objects before aIdle dtor is called, because
375  // ScChartListener::EndListeningTo may cause ScChartListenerCollection::StartTimer
376  // to be called if an empty ScNoteCell is deleted
377 
378  m_Listeners.clear();
379 }
380 
382 {
383  for (auto const& it : m_Listeners)
384  {
385  it.second->StartListeningTo();
386  }
387 }
388 
390 {
393  OUString aName = pListener->GetName();
394  return m_Listeners.insert(std::make_pair(aName, std::unique_ptr<ScChartListener>(pListener))).second;
395 }
396 
397 void ScChartListenerCollection::removeByName(const OUString& rName)
398 {
401  m_Listeners.erase(rName);
402 }
403 
405 {
406  ListenersType::iterator const it = m_Listeners.find(rName);
407  return it == m_Listeners.end() ? nullptr : it->second.get();
408 }
409 
410 const ScChartListener* ScChartListenerCollection::findByName(const OUString& rName) const
411 {
412  ListenersType::const_iterator const it = m_Listeners.find(rName);
413  return it == m_Listeners.end() ? nullptr : it->second.get();
414 }
415 
417 {
418  return !m_Listeners.empty();
419 }
420 
421 OUString ScChartListenerCollection::getUniqueName(std::u16string_view rPrefix) const
422 {
423  for (sal_Int32 nNum = 1; nNum < 10000; ++nNum) // arbitrary limit to prevent infinite loop.
424  {
425  OUString aTestName = rPrefix + OUString::number(nNum);
426  if (m_Listeners.find(aTestName) == m_Listeners.end())
427  return aTestName;
428  }
429  return OUString();
430 }
431 
432 void ScChartListenerCollection::ChangeListening( const OUString& rName,
433  const ScRangeListRef& rRangeListRef )
434 {
435  ScChartListener* pCL = findByName(rName);
436  if (pCL)
437  {
438  pCL->EndListeningTo();
439  pCL->SetRangeList( rRangeListRef );
440  }
441  else
442  {
443  pCL = new ScChartListener(rName, rDoc, rRangeListRef);
444  insert(pCL);
445  }
446  pCL->StartListeningTo();
447 }
448 
450 {
453 
454  ListenersType aUsed;
455 
456  for (auto & pair : m_Listeners)
457  {
458  ScChartListener* p = pair.second.get();
459  if (p->IsUno())
460  {
461  // We don't delete UNO charts; they are to be deleted separately via FreeUno().
462  aUsed.insert(std::make_pair(pair.first, std::move(pair.second)));
463  continue;
464  }
465 
466  if (p->IsUsed())
467  {
468  p->SetUsed(false);
469  aUsed.insert(std::make_pair(pair.first, std::move(pair.second)));
470  }
471  }
472 
473  m_Listeners = std::move(aUsed);
474 }
475 
476 void ScChartListenerCollection::FreeUno( const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
477  const uno::Reference< chart::XChartData >& rSource )
478 {
481 
482  for (auto it = m_Listeners.begin(); it != m_Listeners.end(); )
483  {
484  ScChartListener *const p = it->second.get();
485  if (p->IsUno() && p->GetUnoListener() == rListener && p->GetUnoSource() == rSource)
486  it = m_Listeners.erase(it);
487  else
488  ++it;
489  }
490 }
491 
493 {
494  aIdle.Start();
495 }
496 
498 {
499  if ( Application::AnyInput( VclInputFlags::KEYBOARD ) )
500  {
501  aIdle.Start();
502  return;
503  }
504  UpdateDirtyCharts();
505 }
506 
508 {
509  // During ScChartListener::Update() the most nasty things can happen due to
510  // UNO listeners, e.g. reentrant calls via BASIC to insert() and FreeUno()
511  // and similar that modify m_Listeners and invalidate iterators.
513 
514  for (auto const& it : m_Listeners)
515  {
516  ScChartListener *const p = it.second.get();
517  if (p->IsDirty())
518  p->Update();
519 
521  break; // iterator is invalid
522 
523  if (aIdle.IsActive() && !rDoc.IsImportingXML())
524  break; // one interfered
525  }
527 }
528 
530 {
531  for (auto const& it : m_Listeners)
532  {
533  it.second->SetDirty(true);
534  }
535 
536  StartTimer();
537 }
538 
540  const ScChartListenerCollection& rCmp, bool bSetChartRangeLists )
541 {
542  bool bDirty = false;
543  for (auto const& it : m_Listeners)
544  {
545  ScChartListener *const pCL = it.second.get();
546  assert(pCL);
547  const ScChartListener* pCLCmp = rCmp.findByName(pCL->GetName());
548  if (!pCLCmp || *pCL != *pCLCmp)
549  {
550  if ( bSetChartRangeLists )
551  {
552  if (pCLCmp)
553  {
554  const ScRangeListRef& rList1 = pCL->GetRangeList();
555  const ScRangeListRef& rList2 = pCLCmp->GetRangeList();
556  bool b1 = rList1.is();
557  bool b2 = rList2.is();
558  if ( b1 != b2 || (b1 && b2 && (*rList1 != *rList2)) )
559  rDoc.SetChartRangeList( pCL->GetName(), rList1 );
560  }
561  else
562  rDoc.SetChartRangeList( pCL->GetName(), pCL->GetRangeList() );
563  }
564  bDirty = true;
565  pCL->SetDirty( true );
566  }
567  }
568  if ( bDirty )
569  StartTimer();
570 }
571 
573 {
574  bool bDirty = false;
575  for (auto const& it : m_Listeners)
576  {
577  ScChartListener *const pCL = it.second.get();
578  const ScRangeListRef& rList = pCL->GetRangeList();
579  if ( rList.is() && rList->Intersects( rRange ) )
580  {
581  bDirty = true;
582  pCL->SetDirty( true );
583  }
584  }
585  if ( bDirty )
586  StartTimer();
587 
588  // New hidden range listener implementation
589  for (auto& [pListener, rHiddenRange] : maHiddenListeners)
590  {
591  if (rHiddenRange.Intersects(rRange))
592  {
593  pListener->notify();
594  }
595  }
596 }
597 
599 {
600  ScRange aRange( 0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab );
601  for (auto const& it : m_Listeners)
602  {
603  it.second->UpdateChartIntersecting(aRange);
604  }
605 }
606 
608 {
609  // Do not use ScStrCollection::operator==() here that uses IsEqual and Compare.
610  // Use ScChartListener::operator==() instead.
611  if (&rDoc != &r.rDoc)
612  return false;
613 
614  return std::equal(m_Listeners.begin(), m_Listeners.end(), r.m_Listeners.begin(), r.m_Listeners.end(),
615  [](const ListenersType::value_type& lhs, const ListenersType::value_type& rhs) {
616  return (lhs.first == rhs.first) && (*lhs.second == *rhs.second);
617  });
618 }
619 
621 {
622  maHiddenListeners.insert(std::make_pair<>(pListener, rRange));
623 }
624 
626 {
627  auto range = maHiddenListeners.equal_range(pListener);
628  maHiddenListeners.erase(range.first, range.second);
629 }
630 
631 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool is() const
OUString maName
Definition: chartlis.hxx:67
enum ScChartListenerCollection::UpdateStatus meModifiedDuringUpdate
void UpdateChartIntersecting(const ScRange &rRange)
Definition: chartlis.cxx:293
bool Intersects(const ScRange &) const
Definition: rangelst.cxx:1077
css::uno::Reference< css::chart::XChartData > GetUnoSource() const
Definition: chartlis.cxx:148
ScAddress aStart
Definition: address.hxx:497
bool operator!=(const ScChartListener &r) const
Definition: chartlis.cxx:335
void ChangeListening(const OUString &rName, const ScRangeListRef &rRangeListRef)
Definition: chartlis.cxx:432
bool IsInInterpreter() const
Definition: document.hxx:2403
void EndListeningTo()
Definition: chartlis.cxx:274
ScChartListenerCollection(ScDocument &rDoc)
Definition: chartlis.cxx:355
bool SC_DLLPUBLIC isExternalRef(const ScTokenRef &pToken)
uno::Reference< chart::XChartDataChangeEventListener > xListener
Definition: chartlis.cxx:39
void getTokenFromRange(const ScDocument *pDoc, ScTokenRef &pToken, const ScRange &rRange)
Create a double reference token from a range object.
void UpdateChartsContainingTab(SCTAB nTab)
Definition: chartlis.cxx:598
bool insert(ScChartListener *pListener)
Definition: chartlis.cxx:389
void getRangeListFromTokens(const ScDocument *pDoc, ScRangeList &rRangeList, const ::std::vector< ScTokenRef > &pTokens, const ScAddress &rPos)
void SetUno(const css::uno::Reference< css::chart::XChartDataChangeEventListener > &rListener, const css::uno::Reference< css::chart::XChartData > &rSource)
Definition: chartlis.cxx:134
ScRangeListRef GetRangeList() const
Definition: chartlis.cxx:187
ScDocument & mrDoc
Definition: chartlis.hxx:69
ScAddress aEnd
Definition: address.hxx:498
ListenersType m_Listeners
Definition: chartlis.hxx:128
bool SC_DLLPUBLIC isRef(const ScTokenRef &pToken)
bool IsUno() const
Definition: chartlis.hxx:90
OUString getUniqueName(std::u16string_view rPrefix) const
Create a unique name that's not taken by any existing chart listener objects.
Definition: chartlis.cxx:421
std::unique_ptr< ExternalRefListener > mpExtRefListener
Definition: chartlis.hxx:64
SfxHintId GetId() const
void UpdateChart(const OUString &rName)
Definition: documen5.cxx:335
ExternalRefListener(ScChartListener &rParent, ScDocument &rDoc)
Definition: chartlis.cxx:52
bool IsActive() const
void FreeUno(const css::uno::Reference< css::chart::XChartDataChangeEventListener > &rListener, const css::uno::Reference< css::chart::XChartData > &rSource)
Definition: chartlis.cxx:476
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:891
void StartListeningHiddenRange(const ScRange &rRange, ScChartHiddenRangeListener *pListener)
Start listening on hide/show change within specified cell range.
Definition: chartlis.cxx:620
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:627
std::unordered_multimap< ScChartHiddenRangeListener *, ScRange > maHiddenListeners
Definition: chartlis.hxx:136
void StartListeningTo()
Definition: chartlis.cxx:265
bool IsUsed() const
Definition: chartlis.hxx:100
void removeLinkListener(sal_uInt16 nFileId, LinkListener *pListener)
Remove an existing link listener.
bool operator==(const ScChartListener &) const
Definition: chartlis.cxx:319
std::unique_ptr< ScChartUnoData > pUnoData
Definition: chartlis.hxx:68
virtual ~ScChartListener() override
Definition: chartlis.cxx:118
void addFileId(sal_uInt16 nFileId)
Definition: chartlis.cxx:88
ScChartListener * findByName(const OUString &rName)
Definition: chartlis.cxx:404
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:890
bool IsImportingXML() const
Definition: document.hxx:2220
virtual void Notify(const SfxHint &rHint) override
Definition: chartlis.cxx:155
std::unique_ptr< std::vector< ScTokenRef > > mpTokens
Definition: chartlis.hxx:65
static bool AnyInput(VclInputFlags nType=VCL_INPUT_ANY)
const OUString & GetName() const
Definition: chartlis.hxx:83
virtual ~ScChartHiddenRangeListener()
Definition: chartlis.cxx:344
uno::Reference< chart::XChartData > xSource
Definition: chartlis.cxx:40
void SetUsed(bool bFlg)
Definition: chartlis.hxx:101
ScChartListener(const OUString &rName, ScDocument &rDoc, const ScRangeListRef &rRangeListRef)
Definition: chartlis.cxx:98
IMPL_LINK_NOARG(ScChartListenerCollection, TimerHdl, Timer *, void)
Definition: chartlis.cxx:497
void SetRangeList(const ScRangeListRef &rNew)
Definition: chartlis.cxx:194
void SetRangeDirty(const ScRange &rRange)
Definition: chartlis.cxx:572
void removeByName(const OUString &rName)
Definition: chartlis.cxx:397
void SetUpdateQueue()
Definition: chartlis.cxx:313
bool HasBroadcaster() const
ExternalRefListener * GetExtRefListener()
Definition: chartlis.cxx:305
const uno::Reference< chart::XChartDataChangeEventListener > & GetListener() const
Definition: chartlis.cxx:47
std::map< OUString, std::unique_ptr< ScChartListener > > ListenersType
Definition: chartlis.hxx:125
bool operator==(const ScChartListenerCollection &r) const
Definition: chartlis.cxx:607
virtual ~ExternalRefListener() override
Definition: chartlis.cxx:57
bool IsDirty() const
Definition: chartlis.hxx:102
void EndListeningHiddenRange(ScChartHiddenRangeListener *pListener)
Remove all ranges associated with passed listener instance from the list of hidden range listeners...
Definition: chartlis.cxx:625
OUString maName
OUString aName
void ChangeListening(const ScRangeListRef &rRangeListRef, bool bDirty)
Definition: chartlis.cxx:283
::boost::intrusive_ptr< formula::FormulaToken > ScTokenRef
Definition: types.hxx:29
void * p
SC_DLLPUBLIC ScChartListenerCollection * GetChartListenerCollection() const
Definition: document.hxx:2226
void SetDirty(bool bFlg)
Definition: chartlis.hxx:103
void SetInvokeHandler(const Link< Timer *, void > &rLink)
void SetChartRangeList(std::u16string_view rChartName, const ScRangeListRef &rNewRangeListRef)
only assigns the new RangeList, no ChartListener or the like
Definition: documen5.cxx:485
void SetDiffDirty(const ScChartListenerCollection &, bool bSetChartRangeLists)
Definition: chartlis.cxx:539
virtual void Start(bool bStartTimer=true) override
bool SC_DLLPUBLIC intersects(const ScDocument *pDoc, const ::std::vector< ScTokenRef > &rTokens, const ScTokenRef &pToken, const ScAddress &rPos)
bool hasListeners() const
Definition: chartlis.cxx:416
virtual void notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType) override
Definition: chartlis.cxx:67
void SetPriority(TaskPriority ePriority)
css::uno::Reference< css::chart::XChartDataChangeEventListener > GetUnoListener() const
Definition: chartlis.cxx:141
bool getRangeFromToken(const ScDocument *pDoc, ScRange &rRange, const ScTokenRef &pToken, const ScAddress &rPos, bool bExternal=false)
ScChartUnoData(const uno::Reference< chart::XChartDataChangeEventListener > &rL, const uno::Reference< chart::XChartData > &rS)
Definition: chartlis.cxx:43
void removeFileId(sal_uInt16 nFileId)
Definition: chartlis.cxx:93
BaseContainerNodeSharedPtr & mrParent
void addLinkListener(sal_uInt16 nFileId, LinkListener *pListener)
Register a new link listener to a specified external document.
void getTokensFromRangeList(const ScDocument *pDoc,::std::vector< ScTokenRef > &pTokens, const ScRangeList &rRanges)
AnyEventRef aEvent
sal_Int16 SCTAB
Definition: types.hxx:22
const uno::Reference< chart::XChartData > & GetSource() const
Definition: chartlis.cxx:48
SC_DLLPUBLIC bool GetAutoCalc() const
Definition: document.hxx:1408
bool m_bDetectedRangeSegmentation false