diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2011-05-12 00:16:20 -0400 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2011-05-13 22:54:10 -0400 |
commit | f66c82ef0e1b6c76fa7b6f6b4cdd404de87dd62e (patch) | |
tree | 193c3c5f3d3971bc95f9e78f822cee9bd6c7c4e5 | |
parent | a8384828566b864e226f8c8897a6b0861571d910 (diff) |
Refactored ScDBCollection to not derive from ScSortedCollection.
It's much cleaner this way.
-rw-r--r-- | sc/inc/dbcolect.hxx | 48 | ||||
-rw-r--r-- | sc/source/core/tool/dbcolect.cxx | 269 |
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( |