editeng/source/editeng/editobj.cxx | 58 ++++++++++++++++++++++++++ editeng/source/editeng/editobj2.hxx | 4 + include/editeng/editobj.hxx | 3 + include/svl/stringpool.hxx | 5 -- sc/inc/column.hxx | 3 + sc/inc/document.hxx | 8 ++- sc/inc/table.hxx | 3 + sc/qa/unit/ucalc.cxx | 80 ++++++++++++++++++++++++++++++++++++ sc/qa/unit/ucalc.hxx | 2 sc/source/core/data/column3.cxx | 58 ++++++++++++++++++++++++++ sc/source/core/data/documen2.cxx | 5 ++ sc/source/core/data/document.cxx | 16 +++++++ sc/source/core/data/table2.cxx | 16 +++++++ svl/qa/unit/svl.cxx | 4 - svl/source/misc/stringpool.cxx | 8 +-- 15 files changed, 261 insertions(+), 12 deletions(-)
New commits: commit 927a907e17dd58c393e6bb6f54aa8a234d5d4223 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu Oct 3 14:24:28 2013 -0400 Add methods to turn cell strings into numeric IDs for comparison. Both in case sensitive and case insensitive comparisons. Change-Id: I356a655273f0f37157810c86e1cf3f87ea2afa09 diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 6d09ad1..2f4d697 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -280,6 +280,9 @@ public: ScFormulaCell* SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell ); bool SetGroupFormulaCell( SCROW nRow, ScFormulaCell* pCell ); + sal_uIntPtr GetCellStringID( SCROW nRow ) const; + sal_uIntPtr GetCellStringIDIgnoreCase( SCROW nRow ) const; + void SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast = true ); void SetRawString( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const OUString& rStr, bool bBroadcast = true ); void SetValue( SCROW nRow, double fVal ); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 6828d4d..2ef6073 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -436,7 +436,6 @@ public: sal_uLong GetCodeCount() const; // RPN-Code in formulas DECL_LINK( GetUserDefinedColor, sal_uInt16 * ); // number formatter - public: SC_DLLPUBLIC ScDocument( ScDocumentMode eMode = SCDOCMODE_DOCUMENT, SfxObjectShell* pDocShell = NULL ); @@ -860,6 +859,11 @@ public: */ double* GetValueCell( const ScAddress& rPos ); + svl::StringPool& GetCellStringPool(); + const svl::StringPool& GetCellStringPool() const; + sal_uIntPtr GetCellStringID( const ScAddress& rPos ) const; + sal_uIntPtr GetCellStringIDIgnoreCase( const ScAddress& rPos ) const; + SC_DLLPUBLIC void GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString ); SC_DLLPUBLIC void GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString ); sal_uInt16 GetStringForFormula( const ScAddress& rPos, OUString& rString ); @@ -2066,8 +2070,6 @@ private: // CLOOK-Impl-methods ScRefCellValue GetRefCellValue( const ScAddress& rPos ); - svl::StringPool& GetCellStringPool(); - std::map< SCTAB, ScSortParam > mSheetSortParams; }; diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index fc8ae3a..ce7c5da 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -343,6 +343,9 @@ public: ScFormulaCell* SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell ); bool SetGroupFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell ); + sal_uIntPtr GetCellStringID( SCCOL nCol, SCROW nRow ) const; + sal_uIntPtr GetCellStringIDIgnoreCase( SCCOL nCol, SCROW nRow ) const; + void SetValue( SCCOL nCol, SCROW nRow, const double& rVal ); void SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 8d2266e..ba9a78e 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -63,6 +63,7 @@ #include <svx/svdocirc.hxx> #include <svx/svdopath.hxx> #include "svl/srchitem.hxx" +#include "svl/stringpool.hxx" #include <sfx2/docfile.hxx> @@ -458,6 +459,85 @@ void Test::testCollator() CPPUNIT_ASSERT_MESSAGE("these strings are supposed to be different!", nRes != 0); } +void Test::testCellStringPool() +{ + m_pDoc->InsertTab(0, "foo"); + + // Strings that are identical. + m_pDoc->SetString(ScAddress(0,0,0), "Andy"); // A1 + m_pDoc->SetString(ScAddress(0,1,0), "Andy"); // A2 + m_pDoc->SetString(ScAddress(0,2,0), "Bruce"); // A3 + m_pDoc->SetString(ScAddress(0,3,0), "andy"); // A4 + m_pDoc->SetString(ScAddress(0,4,0), "BRUCE"); // A5 + + sal_uIntPtr nId1 = m_pDoc->GetCellStringID(ScAddress(0,0,0)); + sal_uIntPtr nId2 = m_pDoc->GetCellStringID(ScAddress(0,1,0)); + CPPUNIT_ASSERT_MESSAGE("Failed to get a valid string ID.", nId1); + CPPUNIT_ASSERT_MESSAGE("Failed to get a valid string ID.", nId2); + CPPUNIT_ASSERT_EQUAL(nId1, nId2); + + nId2 = m_pDoc->GetCellStringID(ScAddress(0,2,0)); + CPPUNIT_ASSERT_MESSAGE("They must differ", nId1 != nId2); + + nId2 = m_pDoc->GetCellStringID(ScAddress(0,3,0)); + CPPUNIT_ASSERT_MESSAGE("They must differ", nId1 != nId2); + + nId2 = m_pDoc->GetCellStringID(ScAddress(0,4,0)); + CPPUNIT_ASSERT_MESSAGE("They must differ", nId1 != nId2); + + // A3 and A5 should differ but should be equal case-insensitively. + nId1 = m_pDoc->GetCellStringID(ScAddress(0,2,0)); + nId2 = m_pDoc->GetCellStringID(ScAddress(0,4,0)); + CPPUNIT_ASSERT_MESSAGE("They must differ", nId1 != nId2); + + nId1 = m_pDoc->GetCellStringIDIgnoreCase(ScAddress(0,2,0)); + nId2 = m_pDoc->GetCellStringIDIgnoreCase(ScAddress(0,4,0)); + CPPUNIT_ASSERT_MESSAGE("They must be equal when cases are ignored.", nId1 == nId2); + + // A2 and A4 should be equal when ignoring cases. + nId1 = m_pDoc->GetCellStringIDIgnoreCase(ScAddress(0,1,0)); + nId2 = m_pDoc->GetCellStringIDIgnoreCase(ScAddress(0,3,0)); + CPPUNIT_ASSERT_MESSAGE("They must be equal when cases are ignored.", nId1 == nId2); + + // Check the string counts after purging. Purging shouldn't remove any strings in this case. + svl::StringPool& rPool = m_pDoc->GetCellStringPool(); + rPool.purge(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rPool.getCount()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPool.getCountIgnoreCase()); + + // Clear A1 and purge again. + clearRange(m_pDoc, ScAddress(0,0,0)); + rPool.purge(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rPool.getCount()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPool.getCountIgnoreCase()); + + // Clear A2 and purge again. + clearRange(m_pDoc, ScAddress(0,1,0)); + rPool.purge(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), rPool.getCount()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPool.getCountIgnoreCase()); + + // Clear A3 and purge again. + clearRange(m_pDoc, ScAddress(0,2,0)); + rPool.purge(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPool.getCount()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rPool.getCountIgnoreCase()); + + // Clear A4 and purge again. + clearRange(m_pDoc, ScAddress(0,3,0)); + rPool.purge(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPool.getCount()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPool.getCountIgnoreCase()); + + // Clear A5 and the pool should be completely empty. + clearRange(m_pDoc, ScAddress(0,4,0)); + rPool.purge(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rPool.getCount()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rPool.getCountIgnoreCase()); + + m_pDoc->DeleteTab(0); +} + void Test::testRangeList() { m_pDoc->InsertTab(0, "foo"); diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index d01714e..d1ba668 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -80,6 +80,7 @@ public: */ void testPerf(); void testCollator(); + void testCellStringPool(); void testRangeList(); void testInput(); @@ -284,6 +285,7 @@ public: CPPUNIT_TEST(testPerf); #endif CPPUNIT_TEST(testCollator); + CPPUNIT_TEST(testCellStringPool); CPPUNIT_TEST(testRangeList); CPPUNIT_TEST(testInput); CPPUNIT_TEST(testFormulaHashAndTag); diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index f5eccae..6c964ca 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -1732,6 +1732,64 @@ bool ScColumn::SetGroupFormulaCell( SCROW nRow, ScFormulaCell* pCell ) return true; } +sal_uIntPtr ScColumn::GetCellStringID( SCROW nRow ) const +{ + sc::CellStoreType::const_position_type aPos = maCells.position(nRow); + switch (aPos.first->type) + { + case sc::element_type_string: + { + const OUString& rStr = sc::string_block::at(*aPos.first->data, aPos.second); + return pDocument->GetCellStringPool().getIdentifier(rStr); + } + break; + case sc::element_type_edittext: + { + std::vector<sal_uIntPtr> aIDs; + const EditTextObject* pObj = sc::edittext_block::at(*aPos.first->data, aPos.second); + pObj->GetStringIDs(pDocument->GetCellStringPool(), aIDs); + if (aIDs.size() != 1) + // We don't handle multiline content for now. + return 0; + + return aIDs[0]; + } + break; + default: + ; + } + return 0; +} + +sal_uIntPtr ScColumn::GetCellStringIDIgnoreCase( SCROW nRow ) const +{ + sc::CellStoreType::const_position_type aPos = maCells.position(nRow); + switch (aPos.first->type) + { + case sc::element_type_string: + { + const OUString& rStr = sc::string_block::at(*aPos.first->data, aPos.second); + return pDocument->GetCellStringPool().getIdentifierIgnoreCase(rStr); + } + break; + case sc::element_type_edittext: + { + std::vector<sal_uIntPtr> aIDs; + const EditTextObject* pObj = sc::edittext_block::at(*aPos.first->data, aPos.second); + pObj->GetStringIDsIgnoreCase(pDocument->GetCellStringPool(), aIDs); + if (aIDs.size() != 1) + // We don't handle multiline content for now. + return 0; + + return aIDs[0]; + } + break; + default: + ; + } + return 0; +} + namespace { class FilterEntriesHandler diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index deec664..8946c93 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -605,6 +605,11 @@ svl::StringPool& ScDocument::GetCellStringPool() return *mpCellStringPool; } +const svl::StringPool& ScDocument::GetCellStringPool() const +{ + return *mpCellStringPool; +} + bool ScDocument::GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow, bool bNotes ) const { diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index dc7db44..9b91290 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -3221,6 +3221,22 @@ double* ScDocument::GetValueCell( const ScAddress& rPos ) return maTabs[rPos.Tab()]->GetValueCell(rPos.Col(), rPos.Row()); } +sal_uIntPtr ScDocument::GetCellStringID( const ScAddress& rPos ) const +{ + if (!TableExists(rPos.Tab())) + return 0; + + return maTabs[rPos.Tab()]->GetCellStringID(rPos.Col(), rPos.Row()); +} + +sal_uIntPtr ScDocument::GetCellStringIDIgnoreCase( const ScAddress& rPos ) const +{ + if (!TableExists(rPos.Tab())) + return 0; + + return maTabs[rPos.Tab()]->GetCellStringIDIgnoreCase(rPos.Col(), rPos.Row()); +} + void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString ) { if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] ) diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 7bd7ac6..4e2ae2a 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1505,6 +1505,22 @@ bool ScTable::SetGroupFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell return aCol[nCol].SetGroupFormulaCell(nRow, pCell); } +sal_uIntPtr ScTable::GetCellStringID( SCCOL nCol, SCROW nRow ) const +{ + if (!ValidColRow(nCol, nRow)) + return 0; + + return aCol[nCol].GetCellStringID(nRow); +} + +sal_uIntPtr ScTable::GetCellStringIDIgnoreCase( SCCOL nCol, SCROW nRow ) const +{ + if (!ValidColRow(nCol, nRow)) + return 0; + + return aCol[nCol].GetCellStringIDIgnoreCase(nRow); +} + void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal ) { if (ValidColRow(nCol, nRow)) commit 5f972ca0bd5b275637f7fd71e4301fe91de377ef Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu Oct 3 12:16:22 2013 -0400 Add methods to extract string IDs from edit text object. Note that a single edit text object may have multiple string ID's in case it consists of multiple paragraphs. Change-Id: Ie90541de38a639c30a010817dada389e9445d08c diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx index aaf5e5f..4e6af47 100644 --- a/editeng/source/editeng/editobj.cxx +++ b/editeng/source/editeng/editobj.cxx @@ -154,6 +154,16 @@ void ContentInfo::NormalizeString( svl::StringPool& rPool ) aText = OUString(rPool.intern(aText)); } +sal_uIntPtr ContentInfo::GetStringID( const svl::StringPool& rPool ) const +{ + return rPool.getIdentifier(aText); +} + +sal_uIntPtr ContentInfo::GetStringIDIgnoreCase( const svl::StringPool& rPool ) const +{ + return rPool.getIdentifierIgnoreCase(aText); +} + const WrongList* ContentInfo::GetWrongList() const { return mpWrongs.get(); @@ -327,6 +337,16 @@ void EditTextObject::NormalizeString( svl::StringPool& rPool ) mpImpl->NormalizeString(rPool); } +bool EditTextObject::GetStringIDs( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const +{ + return mpImpl->GetStringIDs(rPool, rIDs); +} + +bool EditTextObject::GetStringIDsIgnoreCase( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const +{ + return mpImpl->GetStringIDsIgnoreCase(rPool, rIDs); +} + const SfxItemPool* EditTextObject::GetPool() const { return mpImpl->GetPool(); @@ -623,6 +643,44 @@ void EditTextObjectImpl::NormalizeString( svl::StringPool& rPool ) } } +bool EditTextObjectImpl::GetStringIDs( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const +{ + std::vector<sal_uIntPtr> aIDs; + aIDs.reserve(aContents.size()); + ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end(); + for (; it != itEnd; ++it) + { + const ContentInfo& rInfo = *it; + sal_uIntPtr nID = rInfo.GetStringID(rPool); + if (!nID) + return false; + + aIDs.push_back(nID); + } + + rIDs.swap(aIDs); + return true; +} + +bool EditTextObjectImpl::GetStringIDsIgnoreCase( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const +{ + std::vector<sal_uIntPtr> aIDs; + aIDs.reserve(aContents.size()); + ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end(); + for (; it != itEnd; ++it) + { + const ContentInfo& rInfo = *it; + sal_uIntPtr nID = rInfo.GetStringIDIgnoreCase(rPool); + if (!nID) + return false; + + aIDs.push_back(nID); + } + + rIDs.swap(aIDs); + return true; +} + bool EditTextObjectImpl::IsVertical() const { return bVertical; diff --git a/editeng/source/editeng/editobj2.hxx b/editeng/source/editeng/editobj2.hxx index c331134..d2118d7 100644 --- a/editeng/source/editeng/editobj2.hxx +++ b/editeng/source/editeng/editobj2.hxx @@ -143,6 +143,8 @@ public: ~ContentInfo(); void NormalizeString( svl::StringPool& rPool ); + sal_uIntPtr GetStringID( const svl::StringPool& rPool ) const; + sal_uIntPtr GetStringIDIgnoreCase( const svl::StringPool& rPool ) const; const XEditAttributesType& GetAttribs() const { return aAttribs; } XEditAttributesType& GetAttribs() { return aAttribs; } @@ -207,6 +209,8 @@ public: void SetUserType( sal_uInt16 n ); void NormalizeString( svl::StringPool& rPool ); + bool GetStringIDs( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const; + bool GetStringIDsIgnoreCase( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const; bool IsVertical() const; void SetVertical( bool b ); diff --git a/include/editeng/editobj.hxx b/include/editeng/editobj.hxx index 36392e2..4751469 100644 --- a/include/editeng/editobj.hxx +++ b/include/editeng/editobj.hxx @@ -85,6 +85,9 @@ public: */ void NormalizeString( svl::StringPool& rPool ); + bool GetStringIDs( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const; + bool GetStringIDsIgnoreCase( const svl::StringPool& rPool, std::vector<sal_uIntPtr>& rIDs ) const; + const SfxItemPool* GetPool() const; sal_uInt16 GetUserType() const; // For OutlinerMode, it can however not save in compatible format void SetUserType( sal_uInt16 n ); commit e73c580538bc6fe83441e2db94a4ec2708fbca84 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu Oct 3 11:34:24 2013 -0400 Let's just use sal_uIntPtr straight. So that the user of this class won't have to include the header just to get the string ID type. Change-Id: I0ccbc18fe02644f69701f57b0b1b9c30fd141d83 diff --git a/include/svl/stringpool.hxx b/include/svl/stringpool.hxx index cac7637..fbcff1e 100644 --- a/include/svl/stringpool.hxx +++ b/include/svl/stringpool.hxx @@ -37,7 +37,6 @@ class SVL_DLLPUBLIC StringPool const CharClass* mpCharClass; public: - typedef sal_uIntPtr StrIdType; StringPool(); StringPool( const CharClass* pCharClass ); @@ -61,7 +60,7 @@ public: * * @return unique ID of the string object. */ - StrIdType getIdentifier( const OUString& rStr ) const; + sal_uIntPtr getIdentifier( const OUString& rStr ) const; /** * Get a unique ID of string object for case insensitive comparison. The @@ -72,7 +71,7 @@ public: * @return unique ID of the string object usable for case insensitive * comparison. */ - StrIdType getIdentifierIgnoreCase( const OUString& rStr ) const; + sal_uIntPtr getIdentifierIgnoreCase( const OUString& rStr ) const; /** * Go through all string objects in the pool, and clear those that are no diff --git a/svl/qa/unit/svl.cxx b/svl/qa/unit/svl.cxx index 11a52e6..a34bb47 100644 --- a/svl/qa/unit/svl.cxx +++ b/svl/qa/unit/svl.cxx @@ -309,8 +309,8 @@ void Test::testStringPool() CPPUNIT_ASSERT_MESSAGE("They must differ.", p1 != p2); OUString aAndy("Andy"); - svl::StringPool::StrIdType si1 = aPool.getIdentifier("Andy"); - svl::StringPool::StrIdType si2 = aPool.getIdentifier(aAndy); + sal_uIntPtr si1 = aPool.getIdentifier("Andy"); + sal_uIntPtr si2 = aPool.getIdentifier(aAndy); CPPUNIT_ASSERT_MESSAGE("Identifier shouldn't be 0.", si1); CPPUNIT_ASSERT_MESSAGE("Identifier shouldn't be 0.", si2); CPPUNIT_ASSERT_EQUAL(si1, si2); diff --git a/svl/source/misc/stringpool.cxx b/svl/source/misc/stringpool.cxx index 4760348..7ebc207 100644 --- a/svl/source/misc/stringpool.cxx +++ b/svl/source/misc/stringpool.cxx @@ -45,13 +45,13 @@ rtl_uString* StringPool::intern( const OUString& rStr ) return pOrig; } -StringPool::StrIdType StringPool::getIdentifier( const OUString& rStr ) const +sal_uIntPtr StringPool::getIdentifier( const OUString& rStr ) const { StrHashType::const_iterator it = maStrPool.find(rStr); - return (it == maStrPool.end()) ? 0 : reinterpret_cast<StrIdType>(it->pData); + return (it == maStrPool.end()) ? 0 : reinterpret_cast<sal_uIntPtr>(it->pData); } -StringPool::StrIdType StringPool::getIdentifierIgnoreCase( const OUString& rStr ) const +sal_uIntPtr StringPool::getIdentifierIgnoreCase( const OUString& rStr ) const { StrHashType::const_iterator itOrig = maStrPool.find(rStr); if (itOrig == maStrPool.end()) @@ -64,7 +64,7 @@ StringPool::StrIdType StringPool::getIdentifierIgnoreCase( const OUString& rStr return 0; const rtl_uString* pUpper = itUpper->second.pData; - return reinterpret_cast<StrIdType>(pUpper); + return reinterpret_cast<sal_uIntPtr>(pUpper); } namespace { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits