diff options
-rw-r--r-- | sc/inc/userlist.hxx | 75 | ||||
-rw-r--r-- | sc/source/core/tool/userlist.cxx | 164 | ||||
-rw-r--r-- | sc/source/ui/optdlg/tpusrlst.cxx | 2 |
3 files changed, 144 insertions, 97 deletions
diff --git a/sc/inc/userlist.hxx b/sc/inc/userlist.hxx index e88335921eff..acfac1249288 100644 --- a/sc/inc/userlist.hxx +++ b/sc/inc/userlist.hxx @@ -33,34 +33,46 @@ #include "scdllapi.h" #include "collect.hxx" -//------------------------------------------------------------------------ +#include <boost/ptr_container/ptr_vector.hpp> + +/** + * Stores individual user-defined sort list. + */ class SC_DLLPUBLIC ScUserListData : public ScDataObject { -friend class ScUserList; - String aStr; - sal_uInt16 nTokenCount; - String* pSubStrings; - String* pUpperSub; +public: + struct SubStr + { + ::rtl::OUString maReal; + ::rtl::OUString maUpper; + SubStr(const ::rtl::OUString& rReal, const ::rtl::OUString& rUpper); + }; +private: + typedef ::boost::ptr_vector<SubStr> SubStringsType; + SubStringsType maSubStrings; + ::rtl::OUString aStr; SC_DLLPRIVATE void InitTokens(); public: - ScUserListData(const String& rStr); - ScUserListData(const ScUserListData& rData); - virtual ~ScUserListData(); - - virtual ScDataObject* Clone() const { return new ScUserListData(*this); } - - const String& GetString() const { return aStr; } - void SetString( const String& rStr); - sal_uInt16 GetSubCount() const; - sal_Bool GetSubIndex(const String& rSubStr, sal_uInt16& rIndex) const; - String GetSubStr(sal_uInt16 nIndex) const; - StringCompare Compare(const String& rSubStr1, const String& rSubStr2) const; - StringCompare ICompare(const String& rSubStr1, const String& rSubStr2) const; + ScUserListData(const ::rtl::OUString& rStr); + ScUserListData(const ScUserListData& rData); + virtual ~ScUserListData(); + + virtual ScDataObject* Clone() const { return new ScUserListData(*this); } + + const ::rtl::OUString& GetString() const { return aStr; } + void SetString(const ::rtl::OUString& rStr); + size_t GetSubCount() const; + bool GetSubIndex(const ::rtl::OUString& rSubStr, sal_uInt16& rIndex) const; + ::rtl::OUString GetSubStr(sal_uInt16 nIndex) const; + StringCompare Compare(const ::rtl::OUString& rSubStr1, const ::rtl::OUString& rSubStr2) const; + StringCompare ICompare(const ::rtl::OUString& rSubStr1, const ::rtl::OUString& rSubStr2) const; }; -//------------------------------------------------------------------------ +/** + * Collection of user-defined sort lists. + */ class SC_DLLPUBLIC ScUserList : public ScCollection { public: @@ -69,25 +81,16 @@ public: virtual ScDataObject* Clone() const; - ScUserListData* GetData( const String& rSubStr ) const; - /// If the list in rStr is already inserted - sal_Bool HasEntry( const String& rStr ) const; + ScUserListData* GetData( const ::rtl::OUString& rSubStr ) const; + /// If the list in rStr is already inserted + bool HasEntry( const ::rtl::OUString& rStr ) const; - inline ScUserListData* operator[]( const sal_uInt16 nIndex) const; - inline ScUserList& operator= ( const ScUserList& r ); - sal_Bool operator==( const ScUserList& r ) const; - inline sal_Bool operator!=( const ScUserList& r ) const; + ScUserListData* operator[]( const sal_uInt16 nIndex) const; + ScUserList& operator= ( const ScUserList& r ); + bool operator==( const ScUserList& r ) const; + bool operator!=( const ScUserList& r ) const; }; -inline ScUserList& ScUserList::operator=( const ScUserList& r ) - { return (ScUserList&)ScCollection::operator=( r ); } - -inline ScUserListData* ScUserList::operator[]( const sal_uInt16 nIndex) const - { return (ScUserListData*)At(nIndex); } - -inline sal_Bool ScUserList::operator!=( const ScUserList& r ) const - { return !operator==( r ); } - #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/userlist.cxx b/sc/source/core/tool/userlist.cxx index 6e96b85ee00c..d5bf672c84c4 100644 --- a/sc/source/core/tool/userlist.cxx +++ b/sc/source/core/tool/userlist.cxx @@ -34,7 +34,6 @@ //------------------------------------------------------------------------ #include <unotools/charclass.hxx> -#include <string.h> #include "global.hxx" #include "userlist.hxx" @@ -42,30 +41,64 @@ #include <unotools/calendarwrapper.hxx> #include <unotools/transliterationwrapper.hxx> -// STATIC DATA ----------------------------------------------------------- +using ::rtl::OUString; +namespace { -//------------------------------------------------------------------------ +class FindByName : public ::std::unary_function<ScUserListData::SubStr, bool> +{ + const OUString& mrName; + bool mbUpper; +public: + FindByName(const OUString& rName, bool bUpper) : mrName(rName), mbUpper(bUpper) {} + bool operator() (const ScUserListData::SubStr& r) const + { + return mbUpper ? r.maUpper.equals(mrName) : r.maReal.equals(mrName); + } +}; + +} + +ScUserListData::SubStr::SubStr(const OUString& rReal, const OUString& rUpper) : + maReal(rReal), maUpper(rUpper) {} void ScUserListData::InitTokens() { sal_Unicode cSep = ScGlobal::cListDelimiter; - nTokenCount = (sal_uInt16) aStr.GetTokenCount(cSep); - if (nTokenCount) + maSubStrings.clear(); + const sal_Unicode* p = aStr.getStr(); + const sal_Unicode* p0 = p; + sal_Int32 nLen = 0; + bool bFirst = true; + for (sal_Int32 i = 0, n = aStr.getLength(); i < n; ++i, ++p, ++nLen) { - pSubStrings = new String[nTokenCount]; - pUpperSub = new String[nTokenCount]; - for (sal_uInt16 i=0; i<nTokenCount; i++) + if (bFirst) + { + // very first character, or the first character after a separator. + p0 = p; + nLen = 0; + bFirst = false; + } + if (*p == cSep && nLen) { - pUpperSub[i] = pSubStrings[i] = aStr.GetToken((xub_StrLen)i,cSep); - ScGlobal::pCharClass->toUpper(pUpperSub[i]); + OUString aSub(p0, nLen); + String aUpStr = aSub; + ScGlobal::pCharClass->toUpper(aUpStr); + maSubStrings.push_back(new SubStr(aSub, aUpStr)); + bFirst = true; } } - else - pSubStrings = pUpperSub = NULL; + + if (nLen) + { + OUString aSub(p0, nLen); + String aUpStr = aSub; + ScGlobal::pCharClass->toUpper(aUpStr); + maSubStrings.push_back(new SubStr(aSub, aUpStr)); + } } -ScUserListData::ScUserListData(const String& rStr) : +ScUserListData::ScUserListData(const OUString& rStr) : aStr(rStr) { InitTokens(); @@ -80,60 +113,57 @@ ScUserListData::ScUserListData(const ScUserListData& rData) : ScUserListData::~ScUserListData() { - delete[] pSubStrings; - delete[] pUpperSub; } -void ScUserListData::SetString( const String& rStr ) +void ScUserListData::SetString( const OUString& rStr ) { - delete[] pSubStrings; - delete[] pUpperSub; - aStr = rStr; InitTokens(); } -sal_uInt16 ScUserListData::GetSubCount() const +size_t ScUserListData::GetSubCount() const { - return nTokenCount; + return maSubStrings.size(); } -sal_Bool ScUserListData::GetSubIndex(const String& rSubStr, sal_uInt16& rIndex) const +bool ScUserListData::GetSubIndex(const OUString& rSubStr, sal_uInt16& rIndex) const { - sal_uInt16 i; - for (i=0; i<nTokenCount; i++) - if (rSubStr == pSubStrings[i]) - { - rIndex = i; - return sal_True; - } - - String aUpStr = rSubStr; - ScGlobal::pCharClass->toUpper(aUpStr); - for (i=0; i<nTokenCount; i++) - if (aUpStr == pUpperSub[i]) - { - rIndex = i; - return sal_True; - } + // First, case sensitive search. + SubStringsType::const_iterator itr = ::std::find_if( + maSubStrings.begin(), maSubStrings.end(), FindByName(rSubStr, false)); + if (itr != maSubStrings.end()) + { + rIndex = ::std::distance(maSubStrings.begin(), itr); + return true; + } + // When that fails, do a case insensitive search. + String aTmp = rSubStr; + ScGlobal::pCharClass->toUpper(aTmp); + OUString aUpStr = aTmp; + itr = ::std::find_if( + maSubStrings.begin(), maSubStrings.end(), FindByName(aUpStr, true)); + if (itr != maSubStrings.end()) + { + rIndex = ::std::distance(maSubStrings.begin(), itr); + return true; + } return false; } -String ScUserListData::GetSubStr(sal_uInt16 nIndex) const +OUString ScUserListData::GetSubStr(sal_uInt16 nIndex) const { - if (nIndex < nTokenCount) - return pSubStrings[nIndex]; + if (nIndex < maSubStrings.size()) + return maSubStrings[nIndex].maReal; else - return EMPTY_STRING; + return OUString(); } -StringCompare ScUserListData::Compare(const String& rSubStr1, const String& rSubStr2) const +StringCompare ScUserListData::Compare(const OUString& rSubStr1, const OUString& rSubStr2) const { - sal_uInt16 nIndex1; - sal_uInt16 nIndex2; - sal_Bool bFound1 = GetSubIndex(rSubStr1, nIndex1); - sal_Bool bFound2 = GetSubIndex(rSubStr2, nIndex2); + sal_uInt16 nIndex1, nIndex2; + bool bFound1 = GetSubIndex(rSubStr1, nIndex1); + bool bFound2 = GetSubIndex(rSubStr2, nIndex2); if (bFound1) { if (bFound2) @@ -154,12 +184,11 @@ StringCompare ScUserListData::Compare(const String& rSubStr1, const String& rSub return (StringCompare) ScGlobal::GetCaseTransliteration()->compareString( rSubStr1, rSubStr2 ); } -StringCompare ScUserListData::ICompare(const String& rSubStr1, const String& rSubStr2) const +StringCompare ScUserListData::ICompare(const OUString& rSubStr1, const OUString& rSubStr2) const { - sal_uInt16 nIndex1; - sal_uInt16 nIndex2; - sal_Bool bFound1 = GetSubIndex(rSubStr1, nIndex1); - sal_Bool bFound2 = GetSubIndex(rSubStr2, nIndex2); + sal_uInt16 nIndex1, nIndex2; + bool bFound1 = GetSubIndex(rSubStr1, nIndex1); + bool bFound2 = GetSubIndex(rSubStr2, nIndex2); if (bFound1) { if (bFound2) @@ -252,7 +281,7 @@ ScDataObject* ScUserList::Clone() const return ( new ScUserList( *this ) ); } -ScUserListData* ScUserList::GetData(const String& rSubStr) const +ScUserListData* ScUserList::GetData(const OUString& rSubStr) const { sal_uInt16 nIndex; sal_uInt16 i = 0; @@ -262,9 +291,19 @@ ScUserListData* ScUserList::GetData(const String& rSubStr) const return NULL; } -sal_Bool ScUserList::operator==( const ScUserList& r ) const +ScUserListData* ScUserList::operator[]( const sal_uInt16 nIndex) const +{ + return (ScUserListData*)At(nIndex); +} + +ScUserList& ScUserList::operator=( const ScUserList& r ) +{ + return (ScUserList&)ScCollection::operator=( r ); +} + +bool ScUserList::operator==( const ScUserList& r ) const { - sal_Bool bEqual = (nCount == r.nCount); + bool bEqual = (nCount == r.nCount); if ( bEqual ) { @@ -276,22 +315,27 @@ sal_Bool ScUserList::operator==( const ScUserList& r ) const pMyData = (ScUserListData*)At(i); pOtherData = (ScUserListData*)r.At(i); - bEqual =( (pMyData->nTokenCount == pOtherData->nTokenCount) - && (pMyData->aStr == pOtherData->aStr) ); + bEqual = ((pMyData->GetSubCount() == pOtherData->GetSubCount()) + && (pMyData->GetString() == pOtherData->GetString()) ); } } return bEqual; } +bool ScUserList::operator!=( const ScUserList& r ) const +{ + return !operator==( r ); +} + -sal_Bool ScUserList::HasEntry( const String& rStr ) const +bool ScUserList::HasEntry( const OUString& rStr ) const { for ( sal_uInt16 i=0; i<nCount; i++) { const ScUserListData* pMyData = (ScUserListData*) At(i); - if ( pMyData->aStr == rStr ) - return sal_True; + if ( pMyData->GetString() == rStr ) + return true; } return false; } diff --git a/sc/source/ui/optdlg/tpusrlst.cxx b/sc/source/ui/optdlg/tpusrlst.cxx index 2fcc726efbad..c67561b9193f 100644 --- a/sc/source/ui/optdlg/tpusrlst.cxx +++ b/sc/source/ui/optdlg/tpusrlst.cxx @@ -323,7 +323,7 @@ void ScTpUserLists::UpdateEntries( sal_uInt16 nList ) { if ( i!=0 ) aEntryListStr += CR; - aEntryListStr += pList->GetSubStr( i ); + aEntryListStr += String(pList->GetSubStr(i)); } aEntryListStr.ConvertLineEnd(); |