LCOV - code coverage report
Current view: top level - sc/source/core/tool - chartlis.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 223 374 59.6 %
Date: 2012-08-25 Functions: 53 75 70.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 171 613 27.9 %

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

Generated by: LCOV version 1.10