ScChartListenerCollection is no longer a child of ScStrCollection.

This commit is contained in:
Kohei Yoshida 2012-02-01 15:13:50 -05:00
parent 47de5f1c09
commit 1f290abba0
9 changed files with 323 additions and 211 deletions

View file

@ -43,13 +43,14 @@
#include <boost/unordered_set.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/ptr_container/ptr_map.hpp>
class ScDocument;
class ScChartUnoData;
#include <com/sun/star/chart/XChartData.hpp>
#include <com/sun/star/chart/XChartDataChangeEventListener.hpp>
class SC_DLLPUBLIC ScChartListener : public StrData, public SvtListener
class SC_DLLPUBLIC ScChartListener : public SvtListener
{
public:
class ExternalRefListener : public ScExternalRefManager::LinkListener
@ -76,6 +77,7 @@ private:
boost::scoped_ptr<ExternalRefListener> mpExtRefListener;
boost::scoped_ptr<std::vector<ScTokenRef> > mpTokens;
rtl::OUString maName;
ScChartUnoData* pUnoData;
ScDocument* pDoc;
bool bUsed:1; // for ScChartListenerCollection::FreeUnused
@ -86,15 +88,17 @@ private:
ScChartListener& operator=( const ScChartListener& );
public:
ScChartListener( const String& rName, ScDocument* pDoc,
const ScRange& rRange );
ScChartListener( const String& rName, ScDocument* pDoc,
const ScRangeListRef& rRangeListRef );
ScChartListener( const String& rName, ScDocument* pDoc,
::std::vector<ScTokenRef>* pTokens );
ScChartListener( const ScChartListener& );
virtual ~ScChartListener();
virtual ScDataObject* Clone() const;
ScChartListener( const rtl::OUString& rName, ScDocument* pDoc,
const ScRange& rRange );
ScChartListener( const rtl::OUString& rName, ScDocument* pDoc,
const ScRangeListRef& rRangeListRef );
ScChartListener( const rtl::OUString& rName, ScDocument* pDoc,
::std::vector<ScTokenRef>* pTokens );
ScChartListener( const ScChartListener& );
~ScChartListener();
const rtl::OUString& GetName() const;
void SetName(const rtl::OUString& rName);
void SetUno( const com::sun::star::uno::Reference< com::sun::star::chart::XChartDataChangeEventListener >& rListener,
const com::sun::star::uno::Reference< com::sun::star::chart::XChartData >& rSource );
@ -127,9 +131,8 @@ public:
ExternalRefListener* GetExtRefListener();
void SetUpdateQueue();
bool operator==( const ScChartListener& );
bool operator!=( const ScChartListener& r )
{ return !operator==( r ); }
bool operator==( const ScChartListener& ) const;
bool operator!=( const ScChartListener& r ) const;
};
// ============================================================================
@ -144,7 +147,7 @@ public:
// ============================================================================
class ScChartListenerCollection : public ScStrCollection
class ScChartListenerCollection
{
public:
struct RangeListenerItem
@ -154,7 +157,10 @@ public:
explicit RangeListenerItem(const ScRange& rRange, ScChartHiddenRangeListener* p);
};
typedef boost::ptr_map<rtl::OUString, ScChartListener> ListenersType;
private:
ListenersType maListeners;
::std::list<RangeListenerItem> maHiddenListeners;
Timer aTimer;
@ -165,18 +171,25 @@ private:
// not implemented
ScChartListenerCollection& operator=( const ScChartListenerCollection& );
using ScStrCollection::operator==;
public:
ScChartListenerCollection( ScDocument* pDoc );
ScChartListenerCollection( const ScChartListenerCollection& );
virtual ScDataObject* Clone() const;
virtual ~ScChartListenerCollection();
ScChartListenerCollection( ScDocument* pDoc );
ScChartListenerCollection( const ScChartListenerCollection& );
~ScChartListenerCollection();
// only needed after copy-ctor, if newly added to doc
void StartAllListeners();
SC_DLLPUBLIC void Insert(ScChartListener* pListener);
ScChartListener* Find(const ScChartListener& rListener);
const ScChartListener* Find(const ScChartListener& rListener) const;
bool HasListeners() const;
const ListenersType& GetListeners() const;
ListenersType& GetListeners();
size_t GetCount() const;
rtl::OUString GetUniqueName(const rtl::OUString& rPrefix) const;
void ChangeListening( const String& rName,
const ScRangeListRef& rRangeListRef,
bool bDirty = false );
@ -186,7 +199,7 @@ public:
const com::sun::star::uno::Reference< com::sun::star::chart::XChartData >& rSource );
void StartTimer();
void UpdateDirtyCharts();
void SC_DLLPUBLIC SetDirty();
SC_DLLPUBLIC void SetDirty();
void SetDiffDirty( const ScChartListenerCollection&,
bool bSetChartRangeLists = false );
@ -195,7 +208,8 @@ public:
void UpdateScheduledSeriesRanges();
void UpdateChartsContainingTab( SCTAB nTab );
bool operator==( const ScChartListenerCollection& );
bool operator==( const ScChartListenerCollection& r ) const;
bool operator!=( const ScChartListenerCollection& r ) const;
/**
* Start listening on hide/show change within specified cell range. A

View file

@ -503,11 +503,11 @@ void ScDocument::UpdateChartRef( UpdateRefMode eUpdateRefMode,
if (!pDrawLayer)
return;
sal_uInt16 nChartCount = pChartListenerCollection->GetCount();
for ( sal_uInt16 nIndex = 0; nIndex < nChartCount; nIndex++ )
ScChartListenerCollection::ListenersType& rListeners = pChartListenerCollection->GetListeners();
ScChartListenerCollection::ListenersType::iterator it = rListeners.begin(), itEnd = rListeners.end();
for (; it != itEnd; ++it)
{
ScChartListener* pChartListener =
(ScChartListener*) (pChartListenerCollection->At(nIndex));
ScChartListener* pChartListener = it->second;
ScRangeListRef aRLR( pChartListener->GetRangeList() );
ScRangeListRef aNewRLR( new ScRangeList );
bool bChanged = false;
@ -556,7 +556,9 @@ void ScDocument::UpdateChartRef( UpdateRefMode eUpdateRefMode,
// UNO broadcasts are done after UpdateChartRef, so the chart will get this
// reference change.
uno::Reference< embed::XEmbeddedObject > xIPObj = FindOleObjectByName( pChartListener->GetString() );
uno::Reference<embed::XEmbeddedObject> xIPObj =
FindOleObjectByName(pChartListener->GetName());
svt::EmbeddedObjectRef::TryRunningState( xIPObj );
// After the change, chart keeps track of its own data source ranges,
@ -715,13 +717,10 @@ void ScDocument::UpdateChartListenerCollection()
continue;
rtl::OUString aObjName = ((SdrOle2Obj*)pObject)->GetPersistName();
aCLSearcher.SetString( aObjName );
sal_uInt16 nIndex;
if ( pChartListenerCollection->Search( &aCLSearcher, nIndex ) )
{
((ScChartListener*) (pChartListenerCollection->
At( nIndex )))->SetUsed( true );
}
aCLSearcher.SetName(aObjName);
ScChartListener* pListener = pChartListenerCollection->Find(aCLSearcher);
if (pListener)
pListener->SetUsed(true);
else if ( lcl_StringInCollection( pOtherObjects, aObjName ) )
{
// non-chart OLE object -> don't touch

View file

@ -1464,7 +1464,7 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode,
// TimerDelays etc.
void ScDocument::KeyInput( const KeyEvent& )
{
if ( pChartListenerCollection->GetCount() )
if ( pChartListenerCollection->HasListeners() )
pChartListenerCollection->StartTimer();
if( apTemporaryChartLock.get() )
apTemporaryChartLock->StartOrContinueLocking();

View file

@ -3467,13 +3467,15 @@ void ScDocument::CalcAfterLoad()
return; // dann wird erst beim Einfuegen in das richtige Doc berechnet
bCalcingAfterLoad = true;
TableContainer::iterator it = maTabs.begin();
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->CalcAfterLoad();
for (it = maTabs.begin(); it != maTabs.end(); ++it)
if (*it)
(*it)->SetDirtyAfterLoad();
{
TableContainer::iterator it = maTabs.begin();
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->CalcAfterLoad();
for (it = maTabs.begin(); it != maTabs.end(); ++it)
if (*it)
(*it)->SetDirtyAfterLoad();
}
bCalcingAfterLoad = false;
SetDetectiveDirty(false); // noch keine wirklichen Aenderungen
@ -3483,11 +3485,12 @@ void ScDocument::CalcAfterLoad()
// similar to ScMyShapeResizer::CreateChartListener for loading own files (i104899).
if (pChartListenerCollection)
{
sal_uInt16 nChartCount = pChartListenerCollection->GetCount();
for ( sal_uInt16 nIndex = 0; nIndex < nChartCount; nIndex++ )
const ScChartListenerCollection::ListenersType& rListeners = pChartListenerCollection->GetListeners();
ScChartListenerCollection::ListenersType::const_iterator it = rListeners.begin(), itEnd = rListeners.end();
for (; it != itEnd; ++it)
{
ScChartListener* pChartListener = static_cast<ScChartListener*>(pChartListenerCollection->At(nIndex));
InterpretDirtyCells(*pChartListener->GetRangeList());
const ScChartListener* p = it->second;
InterpretDirtyCells(*p->GetRangeList());
}
}
}

View file

@ -301,15 +301,14 @@ void ScChartHelper::AddRangesIfProtectedChart( ScRangeListVector& rRangesVector,
( xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ) ) >>= bDisableDataTableDialog ) &&
bDisableDataTableDialog )
{
::rtl::OUString aChartName = pSdrOle2Obj->GetPersistName();
ScRange aEmptyRange;
ScChartListener aSearcher( aChartName, pDocument, aEmptyRange );
sal_uInt16 nIndex = 0;
ScChartListenerCollection* pCollection = pDocument->GetChartListenerCollection();
if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
if (pCollection)
{
ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
if ( pListener )
::rtl::OUString aChartName = pSdrOle2Obj->GetPersistName();
ScRange aEmptyRange;
ScChartListener aSearcher( aChartName, pDocument, aEmptyRange );
const ScChartListener* pListener = pCollection->Find(aSearcher);
if (pListener)
{
const ScRangeListRef& rRangeList = pListener->GetRangeList();
if ( rRangeList.Is() )
@ -398,9 +397,8 @@ void ScChartHelper::CreateProtectedChartListenersAndNotify( ScDocument* pDoc, Sd
{
ScRange aEmptyRange;
ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
sal_uInt16 nIndex = 0;
ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
if ( pCollection && !pCollection->Search( &aSearcher, nIndex ) )
if (pCollection && !pCollection->Find(aSearcher))
{
ScRangeList aRangeList( rRangesVector[ nRangeList++ ] );
ScRangeListRef rRangeList( new ScRangeList( aRangeList ) );

View file

@ -35,6 +35,7 @@
#include "brdcst.hxx"
#include "document.hxx"
#include "reftokenhelper.hxx"
#include "stlalgorithm.hxx"
using namespace com::sun::star;
using ::std::vector;
@ -118,12 +119,12 @@ boost::unordered_set<sal_uInt16>& ScChartListener::ExternalRefListener::getAllFi
// ----------------------------------------------------------------------------
ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
ScChartListener::ScChartListener( const rtl::OUString& rName, ScDocument* pDocP,
const ScRange& rRange ) :
StrData( rName ),
SvtListener(),
mpExtRefListener(NULL),
mpTokens(new vector<ScTokenRef>),
maName(rName),
pUnoData( NULL ),
pDoc( pDocP ),
bUsed( false ),
@ -133,12 +134,12 @@ ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
SetRangeList( rRange );
}
ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
ScChartListener::ScChartListener( const rtl::OUString& rName, ScDocument* pDocP,
const ScRangeListRef& rRangeList ) :
StrData( rName ),
SvtListener(),
mpExtRefListener(NULL),
mpTokens(new vector<ScTokenRef>),
maName(rName),
pUnoData( NULL ),
pDoc( pDocP ),
bUsed( false ),
@ -148,11 +149,11 @@ ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
ScRefTokenHelper::getTokensFromRangeList(*mpTokens, *rRangeList);
}
ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP, vector<ScTokenRef>* pTokens ) :
StrData( rName ),
ScChartListener::ScChartListener( const rtl::OUString& rName, ScDocument* pDocP, vector<ScTokenRef>* pTokens ) :
SvtListener(),
mpExtRefListener(NULL),
mpTokens(pTokens),
maName(rName),
pUnoData( NULL ),
pDoc( pDocP ),
bUsed( false ),
@ -162,10 +163,10 @@ ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP, vector
}
ScChartListener::ScChartListener( const ScChartListener& r ) :
StrData( r ),
SvtListener(),
mpExtRefListener(NULL),
mpTokens(new vector<ScTokenRef>(*r.mpTokens)),
maName(r.maName),
pUnoData( NULL ),
pDoc( r.pDoc ),
bUsed( false ),
@ -209,9 +210,14 @@ ScChartListener::~ScChartListener()
}
}
ScDataObject* ScChartListener::Clone() const
const rtl::OUString& ScChartListener::GetName() const
{
return new ScChartListener( *this );
return maName;
}
void ScChartListener::SetName(const rtl::OUString& rName)
{
maName = rName;
}
void ScChartListener::SetUno(
@ -264,7 +270,7 @@ void ScChartListener::Update()
else if ( pDoc->GetAutoCalc() )
{
bDirty = false;
pDoc->UpdateChart( GetString());
pDoc->UpdateChart(GetName());
}
}
@ -401,7 +407,7 @@ void ScChartListener::UpdateChartIntersecting( const ScRange& rRange )
if (ScRefTokenHelper::intersects(*mpTokens, pToken))
{
// force update (chart has to be loaded), don't use ScChartListener::Update
pDoc->UpdateChart( GetString());
pDoc->UpdateChart(GetName());
}
}
@ -410,7 +416,7 @@ void ScChartListener::UpdateSeriesRanges()
{
ScRangeListRef pRangeList(new ScRangeList);
ScRefTokenHelper::getRangeListFromTokens(*pRangeList, *mpTokens);
pDoc->SetChartRangeList(GetString(), pRangeList);
pDoc->SetChartRangeList(GetName(), pRangeList);
}
ScChartListener::ExternalRefListener* ScChartListener::GetExtRefListener()
@ -427,14 +433,14 @@ void ScChartListener::SetUpdateQueue()
pDoc->GetChartListenerCollection()->StartTimer();
}
bool ScChartListener::operator==( const ScChartListener& r )
bool ScChartListener::operator==( const ScChartListener& r ) const
{
bool b1 = (mpTokens.get() && !mpTokens->empty());
bool b2 = (r.mpTokens.get() && !r.mpTokens->empty());
if (pDoc != r.pDoc || bUsed != r.bUsed || bDirty != r.bDirty ||
bSeriesRangesScheduled != r.bSeriesRangesScheduled ||
GetString() != r.GetString() || b1 != b2)
GetName() != r.GetName() || b1 != b2)
return false;
if (!b1 && !b2)
@ -444,6 +450,11 @@ bool ScChartListener::operator==( const ScChartListener& r )
return *mpTokens == *r.mpTokens;
}
bool ScChartListener::operator!=( const ScChartListener& r ) const
{
return !operator==(r);
}
// ============================================================================
ScChartHiddenRangeListener::ScChartHiddenRangeListener()
@ -463,7 +474,6 @@ ScChartListenerCollection::RangeListenerItem::RangeListenerItem(const ScRange& r
}
ScChartListenerCollection::ScChartListenerCollection( ScDocument* pDocP ) :
ScStrCollection( 4, 4, false ),
pDoc( pDocP )
{
aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
@ -471,7 +481,6 @@ ScChartListenerCollection::ScChartListenerCollection( ScDocument* pDocP ) :
ScChartListenerCollection::ScChartListenerCollection(
const ScChartListenerCollection& rColl ) :
ScStrCollection( rColl ),
pDoc( rColl.pDoc )
{
aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
@ -483,32 +492,88 @@ ScChartListenerCollection::~ScChartListenerCollection()
// ScChartListener::EndListeningTo may cause ScChartListenerCollection::StartTimer
// to be called if an empty ScNoteCell is deleted
if (GetCount())
FreeAll();
}
ScDataObject* ScChartListenerCollection::Clone() const
{
return new ScChartListenerCollection( *this );
maListeners.clear();
}
void ScChartListenerCollection::StartAllListeners()
{
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
it->second->StartListeningTo();
}
void ScChartListenerCollection::Insert(ScChartListener* pListener)
{
rtl::OUString aName = pListener->GetName();
maListeners.insert(aName, pListener);
}
ScChartListener* ScChartListenerCollection::Find(const ScChartListener& rListener)
{
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
{
((ScChartListener*) pItems[ nIndex ])->StartListeningTo();
ScChartListener* p = it->second;
OSL_ASSERT(p);
if (*p == rListener)
return p;
}
return NULL;
}
const ScChartListener* ScChartListenerCollection::Find(const ScChartListener& rListener) const
{
ListenersType::const_iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
{
const ScChartListener* p = it->second;
OSL_ASSERT(p);
if (*p == rListener)
return p;
}
return NULL;
}
bool ScChartListenerCollection::HasListeners() const
{
return !maListeners.empty();
}
const ScChartListenerCollection::ListenersType& ScChartListenerCollection::GetListeners() const
{
return maListeners;
}
ScChartListenerCollection::ListenersType& ScChartListenerCollection::GetListeners()
{
return maListeners;
}
size_t ScChartListenerCollection::GetCount() const
{
return maListeners.size();
}
rtl::OUString ScChartListenerCollection::GetUniqueName(const rtl::OUString& rPrefix) const
{
for (sal_Int32 nNum = 1; nNum < 10000; ++nNum) // arbitrary limit to prevent infinite loop.
{
rtl::OUStringBuffer aBuf(rPrefix);
aBuf.append(nNum);
rtl::OUString aTestName = aBuf.makeStringAndClear();
if (maListeners.find(aTestName) == maListeners.end())
return aTestName;
}
return rtl::OUString();
}
void ScChartListenerCollection::ChangeListening( const String& rName,
const ScRangeListRef& rRangeListRef, bool bDirty )
{
ScChartListener aCLSearcher( rName, pDoc, rRangeListRef );
ScChartListener* pCL;
sal_uInt16 nIndex;
if ( Search( &aCLSearcher, nIndex ) )
ScChartListener* pCL = Find(aCLSearcher);
if (pCL)
{
pCL = (ScChartListener*) pItems[ nIndex ];
pCL->EndListeningTo();
pCL->SetRangeList( rRangeListRef );
}
@ -522,39 +587,87 @@ void ScChartListenerCollection::ChangeListening( const String& rName,
pCL->SetDirty( true );
}
namespace {
class InsertChartListener : public std::unary_function<ScChartListener*, void>
{
ScChartListenerCollection::ListenersType& mrListeners;
public:
InsertChartListener(ScChartListenerCollection::ListenersType& rListeners) :
mrListeners(rListeners) {}
void operator() (ScChartListener* p)
{
rtl::OUString aName = p->GetName();
mrListeners.insert(aName, p);
}
};
}
void ScChartListenerCollection::FreeUnused()
{
// rueckwaerts wg. Pointer-Aufrueckerei im Array
for ( sal_uInt16 nIndex = nCount; nIndex-- >0; )
std::vector<ScChartListener*> aUsed, aUnused;
// First, filter each listener into 'used' and 'unused' categories.
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
// Uno-Charts nicht rauskicken
// (werden per FreeUno von aussen geloescht)
if ( !pCL->IsUno() )
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
{
if ( pCL->IsUsed() )
pCL->SetUsed( false );
ScChartListener* p = it->second;
if (p->IsUno())
{
// We don't delete UNO charts; they are to be deleted separately via FreeUno().
aUsed.push_back(p);
continue;
}
if (p->IsUsed())
{
p->SetUsed(false);
aUsed.push_back(p);
}
else
Free( pCL );
aUnused.push_back(p);
}
}
// Release all pointers currently managed by the ptr_map container.
maListeners.release().release();
// Re-insert the listeners we need to keep.
std::for_each(aUsed.begin(), aUsed.end(), InsertChartListener(maListeners));
// Now, delete the ones no longer needed.
std::for_each(aUnused.begin(), aUnused.end(), ScDeleteObjectByPtr<ScChartListener>());
}
void ScChartListenerCollection::FreeUno( const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
const uno::Reference< chart::XChartData >& rSource )
{
// rueckwaerts wg. Pointer-Aufrueckerei im Array
for ( sal_uInt16 nIndex = nCount; nIndex-- >0; )
std::vector<ScChartListener*> aUsed, aUnused;
// First, filter each listener into 'used' and 'unused' categories.
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
if ( pCL->IsUno() &&
pCL->GetUnoListener() == rListener &&
pCL->GetUnoSource() == rSource )
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
{
Free( pCL );
ScChartListener* p = it->second;
if (p->IsUno() && p->GetUnoListener() == rListener && p->GetUnoSource() == rSource)
aUnused.push_back(p);
else
aUsed.push_back(p);
}
//! sollte nur einmal vorkommen?
}
// Release all pointers currently managed by the ptr_map container.
maListeners.release().release();
// Re-insert the listeners we need to keep.
std::for_each(aUsed.begin(), aUsed.end(), InsertChartListener(maListeners));
// Now, delete the ones no longer needed.
std::for_each(aUnused.begin(), aUnused.end(), ScDeleteObjectByPtr<ScChartListener>());
}
void ScChartListenerCollection::StartTimer()
@ -576,12 +689,14 @@ IMPL_LINK( ScChartListenerCollection, TimerHdl, Timer*, EMPTYARG )
void ScChartListenerCollection::UpdateDirtyCharts()
{
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
if ( pCL->IsDirty() )
pCL->Update();
if ( aTimer.IsActive() && !pDoc->IsImportingXML())
ScChartListener* p = it->second;
if (p->IsDirty())
p->Update();
if (aTimer.IsActive() && !pDoc->IsImportingXML())
break; // da kam einer dazwischen
}
}
@ -589,11 +704,10 @@ void ScChartListenerCollection::UpdateDirtyCharts()
void ScChartListenerCollection::SetDirty()
{
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
pCL->SetDirty( true );
}
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
it->second->SetDirty(true);
StartTimer();
}
@ -602,27 +716,27 @@ void ScChartListenerCollection::SetDiffDirty(
const ScChartListenerCollection& rCmp, bool bSetChartRangeLists )
{
bool bDirty = false;
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
sal_uInt16 nFound;
bool bFound = rCmp.Search( pCL, nFound );
if ( !bFound || (*pCL != *((const ScChartListener*) rCmp.pItems[ nFound ])) )
ScChartListener* pCL = it->second;
OSL_ASSERT(pCL);
const ScChartListener* pCLCmp = rCmp.Find(*pCL);
if (!pCLCmp || *pCL != *pCLCmp)
{
if ( bSetChartRangeLists )
{
if ( bFound )
if (pCLCmp)
{
const ScRangeListRef& rList1 = pCL->GetRangeList();
const ScRangeListRef& rList2 =
((const ScChartListener*) rCmp.pItems[ nFound ])->GetRangeList();
const ScRangeListRef& rList2 = pCLCmp->GetRangeList();
bool b1 = rList1.Is();
bool b2 = rList2.Is();
if ( b1 != b2 || (b1 && b2 && (*rList1 != *rList2)) )
pDoc->SetChartRangeList( pCL->GetString(), rList1 );
pDoc->SetChartRangeList( pCL->GetName(), rList1 );
}
else
pDoc->SetChartRangeList( pCL->GetString(), pCL->GetRangeList() );
pDoc->SetChartRangeList( pCL->GetName(), pCL->GetRangeList() );
}
bDirty = true;
pCL->SetDirty( true );
@ -636,9 +750,10 @@ void ScChartListenerCollection::SetDiffDirty(
void ScChartListenerCollection::SetRangeDirty( const ScRange& rRange )
{
bool bDirty = false;
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
ScChartListener* pCL = it->second;
const ScRangeListRef& rList = pCL->GetRangeList();
if ( rList.Is() && rList->Intersects( rRange ) )
{
@ -661,40 +776,43 @@ void ScChartListenerCollection::SetRangeDirty( const ScRange& rRange )
void ScChartListenerCollection::UpdateScheduledSeriesRanges()
{
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
pCL->UpdateScheduledSeriesRanges();
}
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
it->second->UpdateScheduledSeriesRanges();
}
void ScChartListenerCollection::UpdateChartsContainingTab( SCTAB nTab )
{
ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
{
ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
pCL->UpdateChartIntersecting( aRange );
}
ListenersType::iterator it = maListeners.begin(), itEnd = maListeners.end();
for (; it != itEnd; ++it)
it->second->UpdateChartIntersecting(aRange);
}
bool ScChartListenerCollection::operator==( const ScChartListenerCollection& r )
bool ScChartListenerCollection::operator==( const ScChartListenerCollection& r ) const
{
// hier nicht ScStrCollection::operator==() verwenden, der umstaendlich via
// IsEqual und Compare laeuft, stattdessen ScChartListener::operator==()
if ( pDoc != r.pDoc || nCount != r.nCount )
if (pDoc != r.pDoc || maListeners.size() != r.maListeners.size())
return false;
for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
ListenersType::const_iterator it = maListeners.begin(), itEnd = maListeners.end();
ListenersType::const_iterator it2 = r.maListeners.begin();
for (; it != itEnd; ++it, ++it2)
{
if ( *((ScChartListener*) pItems[ nIndex ]) !=
*((ScChartListener*) r.pItems[ nIndex ]) )
if (*it != *it2)
return false;
}
return true;
}
bool ScChartListenerCollection::operator!=( const ScChartListenerCollection& r ) const
{
return !operator==(r);
}
void ScChartListenerCollection::StartListeningHiddenRange( const ScRange& rRange, ScChartHiddenRangeListener* pListener )
{
RangeListenerItem aItem(rRange, pListener);

View file

@ -3062,12 +3062,11 @@ void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape,
xShapeProps->getPropertyValue( sPersistName ) >>= aChartName;
ScRange aEmptyRange;
ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
sal_uInt16 nIndex = 0;
ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
if (pCollection)
{
ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
if ( pListener )
ScChartListener* pListener = pCollection->Find(aSearcher);
if (pListener)
{
const ScRangeListRef& rRangeList = pListener->GetRangeList();
if ( rRangeList.Is() )

View file

@ -3246,42 +3246,21 @@ void ScCellRangesBase::ForceChartListener_Impl()
// call Update immediately so the caller to setData etc. can
// regognize the listener call
if ( pDocShell )
{
ScChartListenerCollection* pColl = pDocShell->GetDocument()->GetChartListenerCollection();
if ( pColl )
{
sal_uInt16 nCollCount = pColl->GetCount();
for ( sal_uInt16 nIndex = 0; nIndex < nCollCount; nIndex++ )
{
ScChartListener* pChartListener = (ScChartListener*)pColl->At(nIndex);
if ( pChartListener &&
pChartListener->GetUnoSource() == static_cast<chart::XChartData*>(this) &&
pChartListener->IsDirty() )
pChartListener->Update();
}
}
}
}
if (!pDocShell)
return;
String lcl_UniqueName( ScStrCollection& rColl, const String& rPrefix )
{
long nNumber = 1;
sal_uInt16 nCollCount = rColl.GetCount();
while (sal_True)
ScChartListenerCollection* pColl = pDocShell->GetDocument()->GetChartListenerCollection();
if (!pColl)
return;
ScChartListenerCollection::ListenersType& rListeners = pColl->GetListeners();
ScChartListenerCollection::ListenersType::iterator it = rListeners.begin(), itEnd = rListeners.end();
for (; it != itEnd; ++it)
{
String aName(rPrefix);
aName += String::CreateFromInt32( nNumber );
sal_Bool bFound = false;
for (sal_uInt16 i=0; i<nCollCount; i++)
if ( rColl[i]->GetString() == aName )
{
bFound = sal_True;
break;
}
if (!bFound)
return aName;
++nNumber;
ScChartListener* p = it->second;
OSL_ASSERT(p);
if (p->GetUnoSource() == static_cast<chart::XChartData*>(this) && p->IsDirty())
p->Update();
}
}
@ -3297,8 +3276,11 @@ void SAL_CALL ScCellRangesBase::addChartDataChangeEventListener( const uno::Refe
ScDocument* pDoc = pDocShell->GetDocument();
ScRangeListRef aRangesRef( new ScRangeList(aRanges) );
ScChartListenerCollection* pColl = pDoc->GetChartListenerCollection();
String aName(lcl_UniqueName( *pColl,
String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("__Uno")) ));
rtl::OUString aName = pColl->GetUniqueName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("__Uno")));
if (aName.isEmpty())
// failed to create unique name.
return;
ScChartListener* pListener = new ScChartListener( aName, pDoc, aRangesRef );
pListener->SetUno( aListener, this );
pColl->Insert( pListener );

View file

@ -602,41 +602,40 @@ void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) con
switch ( nHandle )
{
case PROP_HANDLE_RELATED_CELLRANGES:
{
ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL );
if (!pDoc)
break;
ScRange aEmptyRange;
ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
if (!pCollection)
break;
ScChartListener aSearcher(aChartName, pDoc, aEmptyRange);
ScChartListener* pListener = pCollection->Find(aSearcher);
if (!pListener)
break;
const ScRangeListRef& rRangeList = pListener->GetRangeList();
if (!rRangeList.Is())
break;
size_t nCount = rRangeList->size();
uno::Sequence<table::CellRangeAddress> aCellRanges(nCount);
table::CellRangeAddress* pCellRanges = aCellRanges.getArray();
for (size_t i = 0; i < nCount; ++i)
{
ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL );
if ( pDoc )
{
ScRange aEmptyRange;
sal_uInt16 nIndex = 0;
ScChartListener aSearcher( aChartName, pDoc, aEmptyRange );
ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection();
if ( pCollection && pCollection->Search( &aSearcher, nIndex ) )
{
ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) );
if ( pListener )
{
const ScRangeListRef& rRangeList = pListener->GetRangeList();
if ( rRangeList.Is() )
{
size_t nCount = rRangeList->size();
uno::Sequence< table::CellRangeAddress > aCellRanges( nCount );
table::CellRangeAddress* pCellRanges = aCellRanges.getArray();
for ( size_t i = 0; i < nCount; ++i )
{
ScRange aRange( *(*rRangeList)[i] );
table::CellRangeAddress aCellRange;
ScUnoConversion::FillApiRange( aCellRange, aRange );
pCellRanges[ i ] = aCellRange;
}
rValue <<= aCellRanges;
}
}
}
}
ScRange aRange(*(*rRangeList)[i]);
table::CellRangeAddress aCellRange;
ScUnoConversion::FillApiRange(aCellRange, aRange);
pCellRanges[i] = aCellRange;
}
break;
rValue <<= aCellRanges;
}
break;
default:
break;
;
}
}