summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kyoshida@novell.com>2011-05-12 00:16:20 -0400
committerKohei Yoshida <kyoshida@novell.com>2011-05-13 22:54:10 -0400
commitf66c82ef0e1b6c76fa7b6f6b4cdd404de87dd62e (patch)
tree193c3c5f3d3971bc95f9e78f822cee9bd6c7c4e5
parenta8384828566b864e226f8c8897a6b0861571d910 (diff)
Refactored ScDBCollection to not derive from ScSortedCollection.
It's much cleaner this way.
-rw-r--r--sc/inc/dbcolect.hxx48
-rw-r--r--sc/source/core/tool/dbcolect.cxx269
2 files changed, 157 insertions, 160 deletions
diff --git a/sc/inc/dbcolect.hxx b/sc/inc/dbcolect.hxx
index 3586ca9ab..750c0542a 100644
--- a/sc/inc/dbcolect.hxx
+++ b/sc/inc/dbcolect.hxx
@@ -40,11 +40,12 @@
#include "queryparam.hxx"
#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/ptr_container/ptr_set.hpp>
#include <boost/scoped_ptr.hpp>
class ScDocument;
-class ScDBData : public ScDataObject, public ScRefreshTimer
+class ScDBData : public ScRefreshTimer
{
private:
ScSortParam maSortParam;
@@ -78,6 +79,11 @@ private:
using ScRefreshTimer::operator==;
public:
+ struct less : public ::std::binary_function<ScDBData, ScDBData, bool>
+ {
+ bool operator() (const ScDBData& left, const ScDBData& right) const;
+ };
+
SC_DLLPUBLIC ScDBData(const ::rtl::OUString& rName,
SCTAB nTab,
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
@@ -85,8 +91,6 @@ public:
ScDBData(const ScDBData& rData);
~ScDBData();
- virtual ScDataObject* Clone() const;
-
ScDBData& operator= (const ScDBData& rData);
bool operator== (const ScDBData& rData) const;
@@ -154,39 +158,27 @@ public:
void ExtendDataArea(ScDocument* pDoc);
};
-
-//------------------------------------------------------------------------
-class SC_DLLPUBLIC ScDBCollection : public ScSortedCollection
+class SC_DLLPUBLIC ScDBCollection
{
- typedef ::boost::ptr_vector<ScDBData> DBRangesType;
+ typedef ::boost::ptr_set<ScDBData, ScDBData::less> NamedDBsType;
public:
- typedef DBRangesType AnonDBsType;
+ typedef ::boost::ptr_vector<ScDBData> AnonDBsType;
private:
Link aRefreshHandler;
ScDocument* pDoc;
sal_uInt16 nEntryIndex; // counter for unique indices
+ NamedDBsType maNamedDBs;
AnonDBsType maAnonDBs;
public:
- ScDBCollection(sal_uInt16 nLim = 4, sal_uInt16 nDel = 4, sal_Bool bDup = false, ScDocument* pDocument = NULL) :
- ScSortedCollection ( nLim, nDel, bDup ),
- pDoc ( pDocument ),
- nEntryIndex ( SC_START_INDEX_DB_COLL ) // see above for the names
- {}
-
+ ScDBCollection(ScDocument* pDocument);
ScDBCollection(const ScDBCollection& r);
- virtual ScDataObject* Clone() const { return new ScDBCollection(*this); }
- ScDBData* operator[]( const sal_uInt16 nIndex) const {return (ScDBData*)At(nIndex);}
- virtual short Compare(ScDataObject* pKey1, ScDataObject* pKey2) const;
- virtual sal_Bool IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const;
- ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const;
- ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
- ScDBData* GetFilterDBAtTable(SCTAB nTab) const;
- ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab );
-
- sal_Bool SearchName( const String& rName, sal_uInt16& rIndex ) const;
+ const ScDBData* GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const;
+ const ScDBData* GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const;
+ const ScDBData* GetFilterDBAtTable(SCTAB nTab) const;
+ ScDBData* GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab );
void DeleteOnTab( SCTAB nTab );
void UpdateReference(UpdateRefMode eUpdateRefMode,
@@ -195,15 +187,19 @@ public:
SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
void UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
- ScDBData* FindIndex(sal_uInt16 nIndex);
sal_uInt16 GetEntryIndex() { return nEntryIndex; }
void SetEntryIndex(sal_uInt16 nInd) { nEntryIndex = nInd; }
- virtual sal_Bool Insert(ScDataObject* pScDataObject);
void SetRefreshHandler( const Link& rLink )
{ aRefreshHandler = rLink; }
const Link& GetRefreshHandler() const { return aRefreshHandler; }
+ ScDBData* findByIndex(sal_uInt16 nIndex);
+ ScDBData* findByName(const ::rtl::OUString& rName);
+ bool insert(ScDBData* p);
+ bool empty() const;
+ size_t size() const;
+
const ScDBData* findAnonAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const;
const ScDBData* findAnonByRange(const ScRange& rRange) const;
ScDBData* getAnonByRange(const ScRange& rRange);
diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx
index d0bd04755..7b01672a5 100644
--- a/sc/source/core/tool/dbcolect.cxx
+++ b/sc/source/core/tool/dbcolect.cxx
@@ -45,13 +45,20 @@
#include <memory>
+using ::std::auto_ptr;
using ::std::unary_function;
using ::std::for_each;
using ::std::find_if;
using ::std::remove_if;
+using ::std::pair;
//---------------------------------------------------------------------------------------
+bool ScDBData::less::operator() (const ScDBData& left, const ScDBData& right) const
+{
+ return ScGlobal::GetpTransliteration()->compareString(left.GetName(), right.GetName()) < 0;
+}
+
ScDBData::ScDBData( const ::rtl::OUString& rName,
SCTAB nTab,
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
@@ -83,7 +90,6 @@ ScDBData::ScDBData( const ::rtl::OUString& rName,
}
ScDBData::ScDBData( const ScDBData& rData ) :
- ScDataObject(),
ScRefreshTimer ( rData ),
maSortParam (rData.maSortParam),
maQueryParam (rData.maQueryParam),
@@ -423,11 +429,6 @@ bool ScDBData::HasQueryParam() const
return maQueryParam.GetEntry(0).bDoQuery;
}
-ScDataObject* ScDBData::Clone() const
-{
- return new ScDBData(*this);
-}
-
void ScDBData::UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos)
{
ScRange aRange;
@@ -512,7 +513,7 @@ void ScDBData::ExtendDataArea(ScDocument* pDoc)
namespace {
-class FindByTable : public ::std::unary_function<ScDBData, bool>
+class FindByTable : public unary_function<ScDBData, bool>
{
SCTAB mnTab;
public:
@@ -597,70 +598,88 @@ public:
}
};
-}
+class FindByIndex : public unary_function<ScDBData, bool>
+{
+ sal_uInt16 mnIndex;
+public:
+ FindByIndex(sal_uInt16 nIndex) : mnIndex(nIndex) {}
+ bool operator() (const ScDBData& r) const
+ {
+ return r.GetIndex() == mnIndex;
+ }
+};
-ScDBCollection::ScDBCollection(const ScDBCollection& r) :
- ScSortedCollection(r), pDoc(r.pDoc), nEntryIndex(r.nEntryIndex), maAnonDBs(r.maAnonDBs)
-{}
+class FindByName : public unary_function<ScDBData, bool>
+{
+ const ::rtl::OUString& mrName;
+public:
+ FindByName(const ::rtl::OUString& rName) : mrName(rName) {}
+ bool operator() (const ScDBData& r) const
+ {
+ return r.GetName() == mrName;
+ }
+};
-short ScDBCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
+class FindFilterDBByTable : public unary_function<ScDBData, bool>
{
- const String& rStr1 = ((ScDBData*)pKey1)->GetName();
- const String& rStr2 = ((ScDBData*)pKey2)->GetName();
- return (short) ScGlobal::GetpTransliteration()->compareString( rStr1, rStr2 );
-}
+ SCTAB mnTab;
+public:
+ FindFilterDBByTable(SCTAB nTab) : mnTab(nTab) {}
+ bool operator() (const ScDBData& r) const
+ {
+ if (r.GetTable() != mnTab)
+ return false;
-// IsEqual - alles gleich
+ return (r.HasAutoFilter() || r.HasQueryParam());
+ }
+};
-sal_Bool ScDBCollection::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
-{
- return *(ScDBData*)pKey1 == *(ScDBData*)pKey2;
}
-ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const
+ScDBCollection::ScDBCollection(ScDocument* pDocument) :
+ pDoc(pDocument), nEntryIndex(SC_START_INDEX_DB_COLL) {}
+
+ScDBCollection::ScDBCollection(const ScDBCollection& r) :
+ pDoc(r.pDoc), nEntryIndex(r.nEntryIndex), maAnonDBs(r.maAnonDBs) {}
+
+const ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const
{
- ScDBData* pNoNameData = pDoc->GetAnonymousDBData(nTab);
- if (pItems)
- {
- for (sal_uInt16 i = 0; i < nCount; i++)
- {
- if (((ScDBData*)pItems[i])->IsDBAtCursor(nCol, nRow, nTab, bStartOnly))
- {
- ScDBData* pDB = (ScDBData*)pItems[i];
- return pDB; //return AnonymousDBData only if nothing else was found
- }
- }
- }
+ // First, search the global named db ranges.
+ NamedDBsType::const_iterator itr = find_if(
+ maNamedDBs.begin(), maNamedDBs.end(), FindByCursor(nCol, nRow, nTab, bStartOnly));
+ if (itr != maNamedDBs.end())
+ return &(*itr);
+
+ // Check for the sheet-local anonymous db range.
+ const ScDBData* pNoNameData = pDoc->GetAnonymousDBData(nTab);
if (pNoNameData)
if (pNoNameData->IsDBAtCursor(nCol,nRow,nTab,bStartOnly))
return pNoNameData;
- // Check the anonymous db ranges.
+ // Check the global anonymous db ranges.
const ScDBData* pData = findAnonAtCursor(nCol, nRow, nTab, bStartOnly);
if (pData)
- return const_cast<ScDBData*>(pData);
+ return pData;
return NULL;
}
-ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
+const ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
{
+ // First, search the global named db ranges.
+ ScRange aRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
+ NamedDBsType::const_iterator itr = find_if(
+ maNamedDBs.begin(), maNamedDBs.end(), FindByRange(aRange));
+ if (itr != maNamedDBs.end())
+ return &(*itr);
+
+ // Check for the sheet-local anonymous db range.
ScDBData* pNoNameData = pDoc->GetAnonymousDBData(nTab);
- if (pItems)
- {
- for (sal_uInt16 i = 0; i < nCount; i++)
- if (((ScDBData*)pItems[i])->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2))
- {
- ScDBData* pDB = (ScDBData*)pItems[i];
- return pDB; //return AnonymousDBData only if nothing else was found
- }
- }
if (pNoNameData)
if (pNoNameData->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2))
return pNoNameData;
- // Check the anonymous db ranges.
- ScRange aRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
+ // Lastly, check the global anonymous db ranges.
const ScDBData* pData = findAnonByRange(aRange);
if (pData)
return const_cast<ScDBData*>(pData);
@@ -668,53 +687,34 @@ ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCO
return NULL;
}
-ScDBData* ScDBCollection::GetFilterDBAtTable(SCTAB nTab) const
+const ScDBData* ScDBCollection::GetFilterDBAtTable(SCTAB nTab) const
{
- ScDBData* pDataEmpty = NULL;
- if (pItems)
- {
- for (sal_uInt16 i = 0; i < nCount; i++)
- {
- ScDBData* pDBTemp = (ScDBData*)pItems[i];
- if ( pDBTemp->GetTable() == nTab )
- {
- sal_Bool bFilter = pDBTemp->HasAutoFilter() || pDBTemp->HasQueryParam();
+ NamedDBsType::const_iterator itr = find_if(
+ maNamedDBs.begin(), maNamedDBs.end(), FindFilterDBByTable(nTab));
- if ( bFilter )
- return pDBTemp;
- }
- }
- }
-
- return pDataEmpty;
-}
-
-sal_Bool ScDBCollection::SearchName( const String& rName, sal_uInt16& rIndex ) const
-{
- if (rtl::OUString(rName)==rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME)))
- DBG_ASSERT(false,"search for noname string");
- ScDBData aDataObj( rName, 0,0,0,0,0 );
- return Search( &aDataObj, rIndex );
+ return itr == maNamedDBs.end() ? NULL : &(*itr);
}
void ScDBCollection::DeleteOnTab( SCTAB nTab )
{
- sal_uInt16 nPos = 0;
- while ( nPos < nCount )
+ FindByTable func(nTab);
+ // First, collect the positions of all items that need to be deleted.
+ ::std::vector<NamedDBsType::iterator> v;
{
- // look for output positions on the deleted sheet
-
- SCCOL nEntryCol1, nEntryCol2;
- SCROW nEntryRow1, nEntryRow2;
- SCTAB nEntryTab;
- static_cast<const ScDBData*>(At(nPos))->GetArea( nEntryTab, nEntryCol1, nEntryRow1, nEntryCol2, nEntryRow2 );
- if ( nEntryTab == nTab )
- AtFree(nPos);
- else
- ++nPos;
+ NamedDBsType::iterator itr = maNamedDBs.begin(), itrEnd = maNamedDBs.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ if (func(*itr))
+ v.push_back(itr);
+ }
}
- remove_if(maAnonDBs.begin(), maAnonDBs.end(), FindByTable(nTab));
+ // Delete them all.
+ ::std::vector<NamedDBsType::iterator>::iterator itr = v.begin(), itrEnd = v.end();
+ for (; itr != itrEnd; ++itr)
+ maNamedDBs.erase(*itr);
+
+ remove_if(maAnonDBs.begin(), maAnonDBs.end(), func);
}
void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
@@ -722,12 +722,6 @@ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
{
- for (sal_uInt16 i=0; i<nCount; i++)
- {
- ((ScDBData*)pItems[i])->UpdateReference(
- pDoc, eUpdateRefMode,
- nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
- }
ScDBData* pData = pDoc->GetAnonymousDBData(nTab1);
if (pData)
{
@@ -744,71 +738,38 @@ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
}
UpdateRefFunc func(pDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
+ for_each(maNamedDBs.begin(), maNamedDBs.end(), func);
for_each(maAnonDBs.begin(), maAnonDBs.end(), func);
}
void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
{
- // wenn nOldPos vor nNewPos liegt, ist nNewPos schon angepasst
-
- for (sal_uInt16 i=0; i<nCount; i++)
- {
- ScDBData* pData = (ScDBData*)pItems[i];
- pData->UpdateMoveTab(nOldPos, nNewPos);
- }
-
UpdateMoveTabFunc func(nOldPos, nNewPos);
+ for_each(maNamedDBs.begin(), maNamedDBs.end(), func);
for_each(maAnonDBs.begin(), maAnonDBs.end(), func);
}
-
-ScDBData* ScDBCollection::FindIndex(sal_uInt16 nIndex)
-{
- sal_uInt16 i = 0;
- while (i < nCount)
- {
- if ((*this)[i]->GetIndex() == nIndex)
- return (*this)[i];
- i++;
- }
- return NULL;
-}
-
-sal_Bool ScDBCollection::Insert(ScDataObject* pScDataObject)
-{
- ScDBData* pData = (ScDBData*) pScDataObject;
- if (!pData->GetIndex()) // schon gesetzt?
- pData->SetIndex(nEntryIndex++);
- sal_Bool bInserted = ScSortedCollection::Insert(pScDataObject);
- if ( bInserted && pData->HasImportParam() && !pData->HasImportSelection() )
- {
- pData->SetRefreshHandler( GetRefreshHandler() );
- pData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() );
- }
- return bInserted;
-}
-
ScDBData* ScDBCollection::GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab )
{
ScDBData* pNearData = NULL;
- SCTAB nAreaTab;
- SCCOL nStartCol, nEndCol;
- SCROW nStartRow, nEndRow;
- for (sal_uInt16 i = 0; i < nCount; i++)
+ NamedDBsType::iterator itr = maNamedDBs.begin(), itrEnd = maNamedDBs.end();
+ for (; itr != itrEnd; ++itr)
{
- ScDBData* pDB = (ScDBData*)pItems[i];
- pDB->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ SCTAB nAreaTab;
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ itr->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
if ( nTab == nAreaTab && nCol+1 >= nStartCol && nCol <= nEndCol+1 &&
nRow+1 >= nStartRow && nRow <= nEndRow+1 )
{
if ( nCol < nStartCol || nCol > nEndCol || nRow < nStartRow || nRow > nEndRow )
{
if (!pNearData)
- pNearData = pDB; // ersten angrenzenden Bereich merken
+ pNearData = &(*itr); // ersten angrenzenden Bereich merken
}
else
- return pDB; // nicht "unbenannt" und Cursor steht wirklich drin
+ return &(*itr); // nicht "unbenannt" und Cursor steht wirklich drin
}
}
if (pNearData)
@@ -816,6 +777,46 @@ ScDBData* ScDBCollection::GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab )
return pDoc->GetAnonymousDBData(nTab); // "unbenannt" nur zurueck, wenn sonst nichts gefunden
}
+ScDBData* ScDBCollection::findByIndex(sal_uInt16 nIndex)
+{
+ NamedDBsType::iterator itr = find_if(
+ maNamedDBs.begin(), maNamedDBs.end(), FindByIndex(nIndex));
+ return itr == maNamedDBs.end() ? NULL : &(*itr);
+}
+
+ScDBData* ScDBCollection::findByName(const ::rtl::OUString& rName)
+{
+ NamedDBsType::iterator itr = find_if(
+ maNamedDBs.begin(), maNamedDBs.end(), FindByName(rName));
+ return itr == maNamedDBs.end() ? NULL : &(*itr);
+}
+
+bool ScDBCollection::insert(ScDBData* p)
+{
+ auto_ptr<ScDBData> pData(p);
+ if (!pData->GetIndex())
+ pData->SetIndex(nEntryIndex++);
+
+ pair<NamedDBsType::iterator, bool> r = maNamedDBs.insert(pData);
+
+ if (r.second && pData->HasImportParam() && !pData->HasImportSelection())
+ {
+ pData->SetRefreshHandler(GetRefreshHandler());
+ pData->SetRefreshControl(pDoc->GetRefreshTimerControlAddress());
+ }
+ return r.second;
+}
+
+bool ScDBCollection::empty() const
+{
+ return maNamedDBs.empty();
+}
+
+size_t ScDBCollection::size() const
+{
+ return maNamedDBs.size();
+}
+
const ScDBData* ScDBCollection::findAnonAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const
{
AnonDBsType::const_iterator itr = find_if(