ScChartListenerCollection is no longer a child of ScStrCollection.
This commit is contained in:
parent
47de5f1c09
commit
1f290abba0
9 changed files with 323 additions and 211 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue