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