LCOV - code coverage report
Current view: top level - sc/source/core/tool - chartlis.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 379 0.0 %
Date: 2014-04-14 Functions: 0 76 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             : #include <vcl/svapp.hxx>
      21             : 
      22             : #include "chartlis.hxx"
      23             : #include "brdcst.hxx"
      24             : #include "document.hxx"
      25             : #include "reftokenhelper.hxx"
      26             : #include "stlalgorithm.hxx"
      27             : 
      28             : using namespace com::sun::star;
      29             : using ::std::vector;
      30             : using ::std::list;
      31             : using ::std::unary_function;
      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             : #define SC_CHARTTIMEOUT 10
      37             : 
      38           0 : class ScChartUnoData
      39             : {
      40             :     uno::Reference< chart::XChartDataChangeEventListener >  xListener;
      41             :     uno::Reference< chart::XChartData >                     xSource;
      42             : 
      43             : public:
      44           0 :             ScChartUnoData( const uno::Reference< chart::XChartDataChangeEventListener >& rL,
      45             :                             const uno::Reference< chart::XChartData >& rS ) :
      46           0 :                     xListener( rL ), xSource( rS ) {}
      47           0 :             ~ScChartUnoData() {}
      48             : 
      49           0 :     const uno::Reference< chart::XChartDataChangeEventListener >& GetListener() const   { return xListener; }
      50           0 :     const uno::Reference< chart::XChartData >& GetSource() const                        { return xSource; }
      51             : };
      52             : 
      53             : // ScChartListener
      54           0 : ScChartListener::ExternalRefListener::ExternalRefListener(ScChartListener& rParent, ScDocument* pDoc) :
      55           0 :     mrParent(rParent), mpDoc(pDoc)
      56             : {
      57           0 : }
      58             : 
      59           0 : ScChartListener::ExternalRefListener::~ExternalRefListener()
      60             : {
      61           0 :     if (!mpDoc || mpDoc->IsInDtorClear())
      62             :         // The document is being destroyed.  Do nothing.
      63           0 :         return;
      64             : 
      65             :     // Make sure to remove all pointers to this object.
      66           0 :     mpDoc->GetExternalRefManager()->removeLinkListener(this);
      67           0 : }
      68             : 
      69           0 : void ScChartListener::ExternalRefListener::notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType)
      70             : {
      71           0 :     switch (eType)
      72             :     {
      73             :         case ScExternalRefManager::LINK_MODIFIED:
      74             :         {
      75           0 :             if (maFileIds.count(nFileId))
      76             :                 // We are listening to this external document.  Send an update
      77             :                 // requst to the chart.
      78           0 :                 mrParent.SetUpdateQueue();
      79             :         }
      80           0 :         break;
      81             :         case ScExternalRefManager::LINK_BROKEN:
      82           0 :             removeFileId(nFileId);
      83           0 :         break;
      84             :     }
      85           0 : }
      86             : 
      87           0 : void ScChartListener::ExternalRefListener::addFileId(sal_uInt16 nFileId)
      88             : {
      89           0 :     maFileIds.insert(nFileId);
      90           0 : }
      91             : 
      92           0 : void ScChartListener::ExternalRefListener::removeFileId(sal_uInt16 nFileId)
      93             : {
      94           0 :     maFileIds.erase(nFileId);
      95           0 : }
      96             : 
      97           0 : boost::unordered_set<sal_uInt16>& ScChartListener::ExternalRefListener::getAllFileIds()
      98             : {
      99           0 :     return maFileIds;
     100             : }
     101             : 
     102           0 : ScChartListener::ScChartListener( const OUString& rName, ScDocument* pDocP,
     103             :         const ScRangeListRef& rRangeList ) :
     104             :     SvtListener(),
     105             :     mpExtRefListener(NULL),
     106           0 :     mpTokens(new vector<ScTokenRef>),
     107             :     maName(rName),
     108             :     pUnoData( NULL ),
     109             :     mpDoc( pDocP ),
     110             :     bUsed( false ),
     111             :     bDirty( false ),
     112           0 :     bSeriesRangesScheduled( false )
     113             : {
     114           0 :     ScRefTokenHelper::getTokensFromRangeList(*mpTokens, *rRangeList);
     115           0 : }
     116             : 
     117           0 : ScChartListener::ScChartListener( const OUString& rName, ScDocument* pDocP, vector<ScTokenRef>* pTokens ) :
     118             :     SvtListener(),
     119             :     mpExtRefListener(NULL),
     120             :     mpTokens(pTokens),
     121             :     maName(rName),
     122             :     pUnoData( NULL ),
     123             :     mpDoc( pDocP ),
     124             :     bUsed( false ),
     125             :     bDirty( false ),
     126           0 :     bSeriesRangesScheduled( false )
     127             : {
     128           0 : }
     129             : 
     130           0 : ScChartListener::ScChartListener( const ScChartListener& r ) :
     131             :     SvtListener(),
     132             :     mpExtRefListener(NULL),
     133           0 :     mpTokens(new vector<ScTokenRef>(*r.mpTokens)),
     134             :     maName(r.maName),
     135             :     pUnoData( NULL ),
     136             :     mpDoc( r.mpDoc ),
     137             :     bUsed( false ),
     138             :     bDirty( r.bDirty ),
     139           0 :     bSeriesRangesScheduled( r.bSeriesRangesScheduled )
     140             : {
     141           0 :     if ( r.pUnoData )
     142           0 :         pUnoData = new ScChartUnoData( *r.pUnoData );
     143             : 
     144           0 :     if (r.mpExtRefListener.get())
     145             :     {
     146             :         // Re-register this new listener for the files that the old listener
     147             :         // was listening to.
     148             : 
     149           0 :         ScExternalRefManager* pRefMgr = mpDoc->GetExternalRefManager();
     150           0 :         const boost::unordered_set<sal_uInt16>& rFileIds = r.mpExtRefListener->getAllFileIds();
     151           0 :         mpExtRefListener.reset(new ExternalRefListener(*this, mpDoc));
     152           0 :         boost::unordered_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
     153           0 :         for (; itr != itrEnd; ++itr)
     154             :         {
     155           0 :             pRefMgr->addLinkListener(*itr, mpExtRefListener.get());
     156           0 :             mpExtRefListener->addFileId(*itr);
     157             :         }
     158             :     }
     159           0 : }
     160             : 
     161           0 : ScChartListener::~ScChartListener()
     162             : {
     163           0 :     if ( HasBroadcaster() )
     164           0 :         EndListeningTo();
     165           0 :     delete pUnoData;
     166             : 
     167           0 :     if (mpExtRefListener.get())
     168             :     {
     169             :         // Stop listening to all external files.
     170           0 :         ScExternalRefManager* pRefMgr = mpDoc->GetExternalRefManager();
     171           0 :         const boost::unordered_set<sal_uInt16>& rFileIds = mpExtRefListener->getAllFileIds();
     172           0 :         boost::unordered_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
     173           0 :         for (; itr != itrEnd; ++itr)
     174           0 :             pRefMgr->removeLinkListener(*itr, mpExtRefListener.get());
     175             :     }
     176           0 : }
     177             : 
     178           0 : const OUString& ScChartListener::GetName() const
     179             : {
     180           0 :     return maName;
     181             : }
     182             : 
     183           0 : void ScChartListener::SetUno(
     184             :         const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
     185             :         const uno::Reference< chart::XChartData >& rSource )
     186             : {
     187           0 :     delete pUnoData;
     188           0 :     pUnoData = new ScChartUnoData( rListener, rSource );
     189           0 : }
     190             : 
     191           0 : uno::Reference< chart::XChartDataChangeEventListener > ScChartListener::GetUnoListener() const
     192             : {
     193           0 :     if ( pUnoData )
     194           0 :         return pUnoData->GetListener();
     195           0 :     return uno::Reference< chart::XChartDataChangeEventListener >();
     196             : }
     197             : 
     198           0 : uno::Reference< chart::XChartData > ScChartListener::GetUnoSource() const
     199             : {
     200           0 :     if ( pUnoData )
     201           0 :         return pUnoData->GetSource();
     202           0 :     return uno::Reference< chart::XChartData >();
     203             : }
     204             : 
     205           0 : void ScChartListener::Notify( const SfxHint& rHint )
     206             : {
     207           0 :     const ScHint* p = dynamic_cast<const ScHint*>(&rHint);
     208           0 :     if (p && (p->GetId() & SC_HINT_DATACHANGED))
     209           0 :         SetUpdateQueue();
     210           0 : }
     211             : 
     212           0 : void ScChartListener::Update()
     213             : {
     214           0 :     if ( mpDoc->IsInInterpreter() )
     215             :     {   // If interpreting do nothing and restart timer so we don't
     216             :         // interfere with interpreter and don't produce an Err522 or similar.
     217             :         // This may happen if we are rescheduled via Basic function.
     218           0 :         mpDoc->GetChartListenerCollection()->StartTimer();
     219           0 :         return ;
     220             :     }
     221           0 :     if ( pUnoData )
     222             :     {
     223           0 :         bDirty = false;
     224             :         // recognize some day what has changed inside the Chart
     225           0 :         chart::ChartDataChangeEvent aEvent( pUnoData->GetSource(),
     226             :                                         chart::ChartDataChangeType_ALL,
     227           0 :                                         0, 0, 0, 0 );
     228           0 :         pUnoData->GetListener()->chartDataChanged( aEvent );
     229             :     }
     230           0 :     else if ( mpDoc->GetAutoCalc() )
     231             :     {
     232           0 :         bDirty = false;
     233           0 :         mpDoc->UpdateChart(GetName());
     234             :     }
     235             : }
     236             : 
     237           0 : ScRangeListRef ScChartListener::GetRangeList() const
     238             : {
     239           0 :     ScRangeListRef aRLRef(new ScRangeList);
     240           0 :     ScRefTokenHelper::getRangeListFromTokens(*aRLRef, *mpTokens, ScAddress());
     241           0 :     return aRLRef;
     242             : }
     243             : 
     244           0 : void ScChartListener::SetRangeList( const ScRangeListRef& rNew )
     245             : {
     246           0 :     vector<ScTokenRef> aTokens;
     247           0 :     ScRefTokenHelper::getTokensFromRangeList(aTokens, *rNew);
     248           0 :     mpTokens->swap(aTokens);
     249           0 : }
     250             : 
     251             : namespace {
     252             : 
     253             : class StartEndListening : public unary_function<ScTokenRef, void>
     254             : {
     255             : public:
     256           0 :     StartEndListening(ScDocument* pDoc, ScChartListener& rParent, bool bStart) :
     257           0 :         mpDoc(pDoc), mrParent(rParent), mbStart(bStart) {}
     258             : 
     259           0 :     void operator() (const ScTokenRef& pToken)
     260             :     {
     261           0 :         if (!ScRefTokenHelper::isRef(pToken))
     262           0 :             return;
     263             : 
     264           0 :         bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
     265           0 :         if (bExternal)
     266             :         {
     267           0 :             sal_uInt16 nFileId = pToken->GetIndex();
     268           0 :             ScExternalRefManager* pRefMgr = mpDoc->GetExternalRefManager();
     269           0 :             ScChartListener::ExternalRefListener* pExtRefListener = mrParent.GetExtRefListener();
     270           0 :             if (mbStart)
     271             :             {
     272           0 :                 pRefMgr->addLinkListener(nFileId, pExtRefListener);
     273           0 :                 pExtRefListener->addFileId(nFileId);
     274             :             }
     275             :             else
     276             :             {
     277           0 :                 pRefMgr->removeLinkListener(nFileId, pExtRefListener);
     278           0 :                 pExtRefListener->removeFileId(nFileId);
     279             :             }
     280             :         }
     281             :         else
     282             :         {
     283           0 :             ScRange aRange;
     284           0 :             ScRefTokenHelper::getRangeFromToken(aRange, pToken, ScAddress(), bExternal);
     285           0 :             if (mbStart)
     286           0 :                 startListening(aRange);
     287             :             else
     288           0 :                 endListening(aRange);
     289             :         }
     290             :     }
     291             : private:
     292           0 :     void startListening(const ScRange& rRange)
     293             :     {
     294           0 :         if (rRange.aStart == rRange.aEnd)
     295           0 :             mpDoc->StartListeningCell(rRange.aStart, &mrParent);
     296             :         else
     297           0 :             mpDoc->StartListeningArea(rRange, &mrParent);
     298           0 :     }
     299             : 
     300           0 :     void endListening(const ScRange& rRange)
     301             :     {
     302           0 :         if (rRange.aStart == rRange.aEnd)
     303           0 :             mpDoc->EndListeningCell(rRange.aStart, &mrParent);
     304             :         else
     305           0 :             mpDoc->EndListeningArea(rRange, &mrParent);
     306           0 :     }
     307             : private:
     308             :     ScDocument* mpDoc;
     309             :     ScChartListener& mrParent;
     310             :     bool mbStart;
     311             : };
     312             : 
     313             : }
     314             : 
     315           0 : void ScChartListener::StartListeningTo()
     316             : {
     317           0 :     if (!mpTokens.get() || mpTokens->empty())
     318             :         // no references to listen to.
     319           0 :         return;
     320             : 
     321           0 :     for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(mpDoc, *this, true));
     322             : }
     323             : 
     324           0 : void ScChartListener::EndListeningTo()
     325             : {
     326           0 :     if (!mpTokens.get() || mpTokens->empty())
     327             :         // no references to listen to.
     328           0 :         return;
     329             : 
     330           0 :     for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(mpDoc, *this, false));
     331             : }
     332             : 
     333           0 : void ScChartListener::ChangeListening( const ScRangeListRef& rRangeListRef,
     334             :                                        bool bDirtyP )
     335             : {
     336           0 :     EndListeningTo();
     337           0 :     SetRangeList( rRangeListRef );
     338           0 :     StartListeningTo();
     339           0 :     if ( bDirtyP )
     340           0 :         SetDirty( true );
     341           0 : }
     342             : 
     343           0 : void ScChartListener::UpdateScheduledSeriesRanges()
     344             : {
     345           0 :     if ( bSeriesRangesScheduled )
     346             :     {
     347           0 :         bSeriesRangesScheduled = false;
     348           0 :         UpdateSeriesRanges();
     349             :     }
     350           0 : }
     351             : 
     352           0 : void ScChartListener::UpdateChartIntersecting( const ScRange& rRange )
     353             : {
     354           0 :     ScTokenRef pToken;
     355           0 :     ScRefTokenHelper::getTokenFromRange(pToken, rRange);
     356             : 
     357           0 :     if (ScRefTokenHelper::intersects(*mpTokens, pToken, ScAddress()))
     358             :     {
     359             :         // force update (chart has to be loaded), don't use ScChartListener::Update
     360           0 :         mpDoc->UpdateChart(GetName());
     361           0 :     }
     362           0 : }
     363             : 
     364           0 : void ScChartListener::UpdateSeriesRanges()
     365             : {
     366           0 :     ScRangeListRef pRangeList(new ScRangeList);
     367           0 :     ScRefTokenHelper::getRangeListFromTokens(*pRangeList, *mpTokens, ScAddress());
     368           0 :     mpDoc->SetChartRangeList(GetName(), pRangeList);
     369           0 : }
     370             : 
     371           0 : ScChartListener::ExternalRefListener* ScChartListener::GetExtRefListener()
     372             : {
     373           0 :     if (!mpExtRefListener.get())
     374           0 :         mpExtRefListener.reset(new ExternalRefListener(*this, mpDoc));
     375             : 
     376           0 :     return mpExtRefListener.get();
     377             : }
     378             : 
     379           0 : void ScChartListener::SetUpdateQueue()
     380             : {
     381           0 :     bDirty = true;
     382           0 :     mpDoc->GetChartListenerCollection()->StartTimer();
     383           0 : }
     384             : 
     385           0 : bool ScChartListener::operator==( const ScChartListener& r ) const
     386             : {
     387           0 :     bool b1 = (mpTokens.get() && !mpTokens->empty());
     388           0 :     bool b2 = (r.mpTokens.get() && !r.mpTokens->empty());
     389             : 
     390           0 :     if (mpDoc != r.mpDoc || bUsed != r.bUsed || bDirty != r.bDirty ||
     391           0 :         bSeriesRangesScheduled != r.bSeriesRangesScheduled ||
     392           0 :         GetName() != r.GetName() || b1 != b2)
     393           0 :         return false;
     394             : 
     395           0 :     if (!b1 && !b2)
     396             :         // both token list instances are empty.
     397           0 :         return true;
     398             : 
     399           0 :     return *mpTokens == *r.mpTokens;
     400             : }
     401             : 
     402           0 : bool ScChartListener::operator!=( const ScChartListener& r ) const
     403             : {
     404           0 :     return !operator==(r);
     405             : }
     406             : 
     407           0 : ScChartHiddenRangeListener::ScChartHiddenRangeListener()
     408             : {
     409           0 : }
     410             : 
     411           0 : ScChartHiddenRangeListener::~ScChartHiddenRangeListener()
     412             : {
     413             :     // empty d'tor
     414           0 : }
     415             : 
     416             : // ScChartListenerCollection
     417           0 : ScChartListenerCollection::RangeListenerItem::RangeListenerItem(const ScRange& rRange, ScChartHiddenRangeListener* p) :
     418           0 :     maRange(rRange), mpListener(p)
     419             : {
     420           0 : }
     421             : 
     422           0 : ScChartListenerCollection::ScChartListenerCollection( ScDocument* pDocP ) :
     423           0 :     pDoc( pDocP )
     424             : {
     425           0 :     aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
     426           0 : }
     427             : 
     428           0 : ScChartListenerCollection::ScChartListenerCollection(
     429             :         const ScChartListenerCollection& rColl ) :
     430           0 :     pDoc( rColl.pDoc )
     431             : {
     432           0 :     aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
     433           0 : }
     434             : 
     435           0 : ScChartListenerCollection::~ScChartListenerCollection()
     436             : {
     437             :     //  remove ChartListener objects before aTimer dtor is called, because
     438             :     //  ScChartListener::EndListeningTo may cause ScChartListenerCollection::StartTimer
     439             :     //  to be called if an empty ScNoteCell is deleted
     440             : 
     441           0 :     maListeners.clear();
     442           0 : }
     443             : 
     444           0 : void ScChartListenerCollection::StartAllListeners()
     445             : {
     446           0 :     ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     447           0 :     for (; it != itEnd; ++it)
     448           0 :         it->second->StartListeningTo();
     449           0 : }
     450             : 
     451           0 : void ScChartListenerCollection::insert(ScChartListener* pListener)
     452             : {
     453           0 :     OUString aName = pListener->GetName();
     454           0 :     maListeners.insert(aName, pListener);
     455           0 : }
     456             : 
     457           0 : void ScChartListenerCollection::removeByName(const OUString& rName)
     458             : {
     459           0 :     maListeners.erase(rName);
     460           0 : }
     461             : 
     462           0 : ScChartListener* ScChartListenerCollection::findByName(const OUString& rName)
     463             : {
     464           0 :     ListenersType::iterator it = maListeners.find(rName);
     465           0 :     return it == maListeners.end() ? NULL : it->second;
     466             : }
     467             : 
     468           0 : const ScChartListener* ScChartListenerCollection::findByName(const OUString& rName) const
     469             : {
     470           0 :     ListenersType::const_iterator it = maListeners.find(rName);
     471           0 :     return it == maListeners.end() ? NULL : it->second;
     472             : }
     473             : 
     474           0 : bool ScChartListenerCollection::hasListeners() const
     475             : {
     476           0 :     return !maListeners.empty();
     477             : }
     478             : 
     479           0 : const ScChartListenerCollection::ListenersType& ScChartListenerCollection::getListeners() const
     480             : {
     481           0 :     return maListeners;
     482             : }
     483             : 
     484           0 : ScChartListenerCollection::ListenersType& ScChartListenerCollection::getListeners()
     485             : {
     486           0 :     return maListeners;
     487             : }
     488             : 
     489           0 : ScChartListenerCollection::StringSetType& ScChartListenerCollection::getNonOleObjectNames()
     490             : {
     491           0 :     return maNonOleObjectNames;
     492             : }
     493             : 
     494           0 : OUString ScChartListenerCollection::getUniqueName(const OUString& rPrefix) const
     495             : {
     496           0 :     for (sal_Int32 nNum = 1; nNum < 10000; ++nNum) // arbitrary limit to prevent infinite loop.
     497             :     {
     498           0 :         OUStringBuffer aBuf(rPrefix);
     499           0 :         aBuf.append(nNum);
     500           0 :         OUString aTestName = aBuf.makeStringAndClear();
     501           0 :         if (maListeners.find(aTestName) == maListeners.end())
     502           0 :             return aTestName;
     503           0 :     }
     504           0 :     return OUString();
     505             : }
     506             : 
     507           0 : void ScChartListenerCollection::ChangeListening( const OUString& rName,
     508             :         const ScRangeListRef& rRangeListRef, bool bDirty )
     509             : {
     510           0 :     ScChartListener* pCL = findByName(rName);
     511           0 :     if (pCL)
     512             :     {
     513           0 :         pCL->EndListeningTo();
     514           0 :         pCL->SetRangeList( rRangeListRef );
     515             :     }
     516             :     else
     517             :     {
     518           0 :         pCL = new ScChartListener(rName, pDoc, rRangeListRef);
     519           0 :         insert(pCL);
     520             :     }
     521           0 :     pCL->StartListeningTo();
     522           0 :     if ( bDirty )
     523           0 :         pCL->SetDirty( true );
     524           0 : }
     525             : 
     526             : namespace {
     527             : 
     528             : class InsertChartListener : public std::unary_function<ScChartListener*, void>
     529             : {
     530             :     ScChartListenerCollection::ListenersType& mrListeners;
     531             : public:
     532           0 :     InsertChartListener(ScChartListenerCollection::ListenersType& rListeners) :
     533           0 :         mrListeners(rListeners) {}
     534             : 
     535           0 :     void operator() (ScChartListener* p)
     536             :     {
     537           0 :         OUString aName = p->GetName();
     538           0 :         mrListeners.insert(aName, p);
     539           0 :     }
     540             : };
     541             : 
     542             : }
     543             : 
     544           0 : void ScChartListenerCollection::FreeUnused()
     545             : {
     546           0 :     std::vector<ScChartListener*> aUsed, aUnused;
     547             : 
     548             :     // First, filter each listener into 'used' and 'unused' categories.
     549             :     {
     550           0 :         ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     551           0 :         for (; it != itEnd; ++it)
     552             :         {
     553           0 :             ScChartListener* p = it->second;
     554           0 :             if (p->IsUno())
     555             :             {
     556             :                 // We don't delete UNO charts; they are to be deleted separately via FreeUno().
     557           0 :                 aUsed.push_back(p);
     558           0 :                 continue;
     559             :             }
     560             : 
     561           0 :             if (p->IsUsed())
     562             :             {
     563           0 :                 p->SetUsed(false);
     564           0 :                 aUsed.push_back(p);
     565             :             }
     566             :             else
     567           0 :                 aUnused.push_back(p);
     568             :         }
     569             :     }
     570             : 
     571             :     // Release all pointers currently managed by the ptr_map container.
     572           0 :     maListeners.release().release();
     573             : 
     574             :     // Re-insert the listeners we need to keep.
     575           0 :     std::for_each(aUsed.begin(), aUsed.end(), InsertChartListener(maListeners));
     576             : 
     577             :     // Now, delete the ones no longer needed.
     578           0 :     std::for_each(aUnused.begin(), aUnused.end(), ScDeleteObjectByPtr<ScChartListener>());
     579           0 : }
     580             : 
     581           0 : void ScChartListenerCollection::FreeUno( const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
     582             :                                          const uno::Reference< chart::XChartData >& rSource )
     583             : {
     584           0 :     std::vector<ScChartListener*> aUsed, aUnused;
     585             : 
     586             :     // First, filter each listener into 'used' and 'unused' categories.
     587             :     {
     588           0 :         ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     589           0 :         for (; it != itEnd; ++it)
     590             :         {
     591           0 :             ScChartListener* p = it->second;
     592           0 :             if (p->IsUno() && p->GetUnoListener() == rListener && p->GetUnoSource() == rSource)
     593           0 :                 aUnused.push_back(p);
     594             :             else
     595           0 :                 aUsed.push_back(p);
     596             :         }
     597             :     }
     598             : 
     599             :     // Release all pointers currently managed by the ptr_map container.
     600           0 :     maListeners.release().release();
     601             : 
     602             :     // Re-insert the listeners we need to keep.
     603           0 :     std::for_each(aUsed.begin(), aUsed.end(), InsertChartListener(maListeners));
     604             : 
     605             :     // Now, delete the ones no longer needed.
     606           0 :     std::for_each(aUnused.begin(), aUnused.end(), ScDeleteObjectByPtr<ScChartListener>());
     607           0 : }
     608             : 
     609           0 : void ScChartListenerCollection::StartTimer()
     610             : {
     611           0 :     aTimer.SetTimeout( SC_CHARTTIMEOUT );
     612           0 :     aTimer.Start();
     613           0 : }
     614             : 
     615           0 : IMPL_LINK_NOARG(ScChartListenerCollection, TimerHdl)
     616             : {
     617           0 :     if ( Application::AnyInput( VCL_INPUT_KEYBOARD ) )
     618             :     {
     619           0 :         aTimer.Start();
     620           0 :         return 0;
     621             :     }
     622           0 :     UpdateDirtyCharts();
     623           0 :     return 0;
     624             : }
     625             : 
     626           0 : void ScChartListenerCollection::UpdateDirtyCharts()
     627             : {
     628           0 :     ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     629           0 :     for (; it != itEnd; ++it)
     630             :     {
     631           0 :         ScChartListener* p = it->second;
     632           0 :         if (p->IsDirty())
     633           0 :             p->Update();
     634             : 
     635           0 :         if (aTimer.IsActive() && !pDoc->IsImportingXML())
     636           0 :             break;                      // one interfered
     637             :     }
     638           0 : }
     639             : 
     640           0 : void ScChartListenerCollection::SetDirty()
     641             : {
     642           0 :     ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     643           0 :     for (; it != itEnd; ++it)
     644           0 :         it->second->SetDirty(true);
     645             : 
     646           0 :     StartTimer();
     647           0 : }
     648             : 
     649           0 : void ScChartListenerCollection::SetDiffDirty(
     650             :             const ScChartListenerCollection& rCmp, bool bSetChartRangeLists )
     651             : {
     652           0 :     bool bDirty = false;
     653           0 :     ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     654           0 :     for (; it != itEnd; ++it)
     655             :     {
     656           0 :         ScChartListener* pCL = it->second;
     657             :         OSL_ASSERT(pCL);
     658           0 :         const ScChartListener* pCLCmp = rCmp.findByName(pCL->GetName());
     659           0 :         if (!pCLCmp || *pCL != *pCLCmp)
     660             :         {
     661           0 :             if ( bSetChartRangeLists )
     662             :             {
     663           0 :                 if (pCLCmp)
     664             :                 {
     665           0 :                     const ScRangeListRef& rList1 = pCL->GetRangeList();
     666           0 :                     const ScRangeListRef& rList2 = pCLCmp->GetRangeList();
     667           0 :                     bool b1 = rList1.Is();
     668           0 :                     bool b2 = rList2.Is();
     669           0 :                     if ( b1 != b2 || (b1 && b2 && (*rList1 != *rList2)) )
     670           0 :                         pDoc->SetChartRangeList( pCL->GetName(), rList1 );
     671             :                 }
     672             :                 else
     673           0 :                     pDoc->SetChartRangeList( pCL->GetName(), pCL->GetRangeList() );
     674             :             }
     675           0 :             bDirty = true;
     676           0 :             pCL->SetDirty( true );
     677             :         }
     678             :     }
     679           0 :     if ( bDirty )
     680           0 :         StartTimer();
     681           0 : }
     682             : 
     683           0 : void ScChartListenerCollection::SetRangeDirty( const ScRange& rRange )
     684             : {
     685           0 :     bool bDirty = false;
     686           0 :     ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     687           0 :     for (; it != itEnd; ++it)
     688             :     {
     689           0 :         ScChartListener* pCL = it->second;
     690           0 :         const ScRangeListRef& rList = pCL->GetRangeList();
     691           0 :         if ( rList.Is() && rList->Intersects( rRange ) )
     692             :         {
     693           0 :             bDirty = true;
     694           0 :             pCL->SetDirty( true );
     695             :         }
     696           0 :     }
     697           0 :     if ( bDirty )
     698           0 :         StartTimer();
     699             : 
     700             :     // New hidden range listener implementation
     701           0 :     for (list<RangeListenerItem>::iterator itr = maHiddenListeners.begin(), itrEnd = maHiddenListeners.end();
     702             :           itr != itrEnd; ++itr)
     703             :     {
     704           0 :         if (itr->maRange.Intersects(rRange))
     705           0 :             itr->mpListener->notify();
     706             :     }
     707           0 : }
     708             : 
     709           0 : void ScChartListenerCollection::UpdateScheduledSeriesRanges()
     710             : {
     711           0 :     ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     712           0 :     for (; it != itEnd; ++it)
     713           0 :         it->second->UpdateScheduledSeriesRanges();
     714           0 : }
     715             : 
     716           0 : void ScChartListenerCollection::UpdateChartsContainingTab( SCTAB nTab )
     717             : {
     718           0 :     ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
     719           0 :     ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
     720           0 :     for (; it != itEnd; ++it)
     721           0 :         it->second->UpdateChartIntersecting(aRange);
     722           0 : }
     723             : 
     724           0 : bool ScChartListenerCollection::operator==( const ScChartListenerCollection& r ) const
     725             : {
     726             :     // Do not use ScStrCollection::operator==() here that uses IsEqual und Compare.
     727             :     // Use ScChartListener::operator==() instead.
     728           0 :     if (pDoc != r.pDoc || maListeners.size() != r.maListeners.size())
     729           0 :         return false;
     730             : 
     731           0 :     ListenersType::const_iterator it = maListeners.begin(), itEnd = maListeners.end();
     732           0 :     ListenersType::const_iterator it2 = r.maListeners.begin();
     733           0 :     for (; it != itEnd; ++it, ++it2)
     734             :     {
     735           0 :         if (*it != *it2)
     736           0 :             return false;
     737             :     }
     738           0 :     return true;
     739             : }
     740             : 
     741           0 : bool ScChartListenerCollection::operator!=( const ScChartListenerCollection& r ) const
     742             : {
     743           0 :     return !operator==(r);
     744             : }
     745             : 
     746           0 : void ScChartListenerCollection::StartListeningHiddenRange( const ScRange& rRange, ScChartHiddenRangeListener* pListener )
     747             : {
     748           0 :     RangeListenerItem aItem(rRange, pListener);
     749           0 :     maHiddenListeners.push_back(aItem);
     750           0 : }
     751             : 
     752             : namespace {
     753             : 
     754             : struct MatchListener : public ::std::unary_function<
     755             :         ScChartListenerCollection::RangeListenerItem, bool>
     756             : {
     757           0 :     MatchListener(const ScChartHiddenRangeListener* pMatch) :
     758           0 :         mpMatch(pMatch)
     759             :     {
     760           0 :     }
     761             : 
     762           0 :     bool operator() (const ScChartListenerCollection::RangeListenerItem& rItem) const
     763             :     {
     764           0 :         return mpMatch == rItem.mpListener;
     765             :     }
     766             : 
     767             : private:
     768             :     const ScChartHiddenRangeListener* mpMatch;
     769             : };
     770             : 
     771             : }
     772           0 : void ScChartListenerCollection::EndListeningHiddenRange( ScChartHiddenRangeListener* pListener )
     773             : {
     774           0 :     maHiddenListeners.remove_if(MatchListener(pListener));
     775           0 : }
     776             : 
     777             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10