diff options
author | Kohei Yoshida <kohei.yoshida@suse.com> | 2012-02-08 15:08:29 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.com> | 2012-02-08 18:33:19 -0500 |
commit | 8ff0331bff9db9206e27558aca3958b65afb044b (patch) | |
tree | 6e4a9bbd5bfdf10bdedc1d3f109b80692108391f | |
parent | 7ffdf6a0dbe23ba9b561ccac71f0b41384e93ac1 (diff) |
Move away from TypedScStrCollection in favor of STL's.
-rw-r--r-- | sc/inc/collect.hxx | 59 | ||||
-rw-r--r-- | sc/inc/column.hxx | 6 | ||||
-rw-r--r-- | sc/inc/document.hxx | 25 | ||||
-rw-r--r-- | sc/inc/dpobject.hxx | 4 | ||||
-rw-r--r-- | sc/inc/table.hxx | 6 | ||||
-rw-r--r-- | sc/inc/types.hxx | 4 | ||||
-rw-r--r-- | sc/inc/validat.hxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 97 | ||||
-rw-r--r-- | sc/source/core/data/documen3.cxx | 94 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/validat.cxx | 32 | ||||
-rw-r--r-- | sc/source/core/tool/collect.cxx | 230 | ||||
-rw-r--r-- | sc/source/ui/app/inputhdl.cxx | 422 | ||||
-rw-r--r-- | sc/source/ui/dbgui/filtdlg.cxx | 66 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pfiltdlg.cxx | 22 | ||||
-rw-r--r-- | sc/source/ui/formdlg/dwfunctr.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/inc/filtdlg.hxx | 3 | ||||
-rw-r--r-- | sc/source/ui/inc/inputhdl.hxx | 21 | ||||
-rw-r--r-- | sc/source/ui/inc/pfiltdlg.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin.cxx | 100 |
21 files changed, 645 insertions, 578 deletions
diff --git a/sc/inc/collect.hxx b/sc/inc/collect.hxx index 08aa75630f55..2eb223b94455 100644 --- a/sc/inc/collect.hxx +++ b/sc/inc/collect.hxx @@ -42,8 +42,7 @@ #define MAXDELTA 1024 #define SCPOS_INVALID USHRT_MAX -#define SC_STRTYPE_VALUE 0 -#define SC_STRTYPE_STANDARD 1 +#include <boost/ptr_container/ptr_set.hpp> class ScDocument; @@ -113,9 +112,8 @@ public: // TypedScStrCollection: wie ScStrCollection, nur, dass Zahlen vor Strings // sortiert werden -class TypedStrData : public ScDataObject +class TypedStrData { - friend class TypedScStrCollection; public: enum StringType { Value = 0, @@ -130,39 +128,48 @@ public: TypedStrData( const TypedStrData& rCpy ); - virtual ScDataObject* Clone() const; - bool IsStrData() const; SC_DLLPUBLIC const rtl::OUString& GetString() const; double GetValue() const; + StringType GetStringType() const; -private: - rtl::OUString maStrValue; - double mfValue; - StringType meStrType; // 0 = Value -}; + struct LessCaseSensitive : std::binary_function<TypedStrData, TypedStrData, bool> + { + bool operator() (const TypedStrData& left, const TypedStrData& right) const; + }; -class SC_DLLPUBLIC TypedScStrCollection : public ScSortedCollection -{ -private: - sal_Bool bCaseSensitive; + struct LessCaseInsensitive : std::binary_function<TypedStrData, TypedStrData, bool> + { + bool operator() (const TypedStrData& left, const TypedStrData& right) const; + }; -public: - TypedScStrCollection( sal_uInt16 nLim = 4, sal_uInt16 nDel = 4, sal_Bool bDup = false ); + struct EqualCaseSensitive : std::binary_function<TypedStrData, TypedStrData, bool> + { + bool operator() (const TypedStrData& left, const TypedStrData& right) const; + }; - TypedScStrCollection( const TypedScStrCollection& rCpy ) - : ScSortedCollection( rCpy ) { bCaseSensitive = rCpy.bCaseSensitive; } - ~TypedScStrCollection(); + struct EqualCaseInsensitive : std::binary_function<TypedStrData, TypedStrData, bool> + { + bool operator() (const TypedStrData& left, const TypedStrData& right) const; + }; - virtual ScDataObject* Clone() const; - virtual short Compare( ScDataObject* pKey1, ScDataObject* pKey2 ) const; + bool operator== (const TypedStrData& r) const; + bool operator< (const TypedStrData& r) const; - TypedStrData* operator[]( const sal_uInt16 nIndex) const; - void SetCaseSensitive( sal_Bool bSet ); +private: + rtl::OUString maStrValue; + double mfValue; + StringType meStrType; +}; - sal_Bool FindText( const String& rStart, String& rResult, sal_uInt16& rPos, sal_Bool bBack ) const; - sal_Bool GetExactMatch( String& rString ) const; +class FindTypedStrData : std::unary_function<TypedStrData, bool> +{ + TypedStrData maVal; + bool mbCaseSens; +public: + FindTypedStrData(const TypedStrData& rVal, bool bCaseSens); + bool operator() (const TypedStrData& r) const; }; #endif diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 2f58a92630d8..e5e78f39a95a 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -62,7 +62,7 @@ class ScMarkData; class ScPatternAttr; class ScStyleSheet; class SvtBroadcaster; -class TypedScStrCollection; +class TypedStrData; class ScProgress; class ScPostIt; struct ScFunctionData; @@ -379,8 +379,8 @@ public: /// Including current, may return -1 SCsROW GetNextUnprotected( SCROW nRow, bool bUp ) const; - void GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollection& rStrings, bool& rHasDates); - bool GetDataEntries(SCROW nRow, TypedScStrCollection& rStrings, bool bLimit); + void GetFilterEntries(SCROW nStartRow, SCROW nEndRow, std::vector<TypedStrData>& rStrings, bool& rHasDates); + bool GetDataEntries(SCROW nRow, std::set<TypedStrData>& rStrings, bool bLimit); void UpdateInsertTabAbs(SCTAB nNewPos); bool TestTabRefAbs(SCTAB nTable); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index b402ac83d7e8..004d8e90295f 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -118,7 +118,6 @@ class ScTokenArray; class ScValidationData; class ScValidationDataList; class ScViewOptions; -class TypedScStrCollection; class ScChangeTrack; class ScEditEngineDefaulter; class ScFieldEditEngine; @@ -1479,13 +1478,23 @@ public: SCTAB nTab, ScQueryParam& rQueryParam ); void GetUpperCellString(SCCOL nCol, SCROW nRow, SCTAB nTab, rtl::OUString& rStr); - bool GetFilterEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, - bool bFilter, TypedScStrCollection& rStrings, bool& rHasDates); - SC_DLLPUBLIC bool GetFilterEntriesArea( SCCOL nCol, SCROW nStartRow, SCROW nEndRow, - SCTAB nTab, TypedScStrCollection& rStrings, bool& rHasDates ); - bool GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, - TypedScStrCollection& rStrings, bool bLimit = false ); - bool GetFormulaEntries( TypedScStrCollection& rStrings ); + /** + * Get a list of unique strings to use in filtering criteria. The string + * values are sorted, and there are no duplicate values in the list. The + * data range to use to populate the filter entries is inferred from the + * database range that contains the specified cell position. + */ + bool GetFilterEntries( + SCCOL nCol, SCROW nRow, SCTAB nTab, bool bFilter, std::vector<TypedStrData>& rStrings, bool& rHasDates); + + SC_DLLPUBLIC bool GetFilterEntriesArea( + SCCOL nCol, SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bCaseSens, + std::vector<TypedStrData>& rStrings, bool& rHasDates); + + bool GetDataEntries( + SCCOL nCol, SCROW nRow, SCTAB nTab, bool bCaseSens, + std::vector<TypedStrData>& rStrings, bool bLimit = false ); + bool GetFormulaEntries( ScTypedCaseStrSet& rStrings ); bool HasAutoFilter( SCCOL nCol, SCROW nRow, SCTAB nTab ); diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 79b5a67a0345..121b6149a4d1 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -38,6 +38,7 @@ #include <com/sun/star/sheet/XDimensionsSupplier.hpp> #include <set> +#include <vector> #include <boost/ptr_container/ptr_list.hpp> #include <boost/ptr_container/ptr_vector.hpp> @@ -64,7 +65,6 @@ class ScPivotCollection; struct ScPivotParam; struct ScImportSourceDesc; class ScSheetSourceDesc; -class TypedScStrCollection; struct PivotField; class ScDPCacheTable; class ScDPTableData; @@ -192,7 +192,7 @@ public: void GetMemberResultNames(ScDPUniqueStringSet& rNames, long nDimension); - void FillPageList( TypedScStrCollection& rStrings, long nField ); + void FillPageList( std::vector<rtl::OUString>& rStrings, long nField ); void ToggleDetails(const ::com::sun::star::sheet::DataPilotTableHeaderData& rElemDesc, ScDPObject* pDestObj); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 4f1fe38abe9c..2bae9938d79d 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -761,9 +761,9 @@ public: SCSIZE Query(ScQueryParam& rQueryParam, bool bKeepSub); bool CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam); - void GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, TypedScStrCollection& rStrings, bool& rHasDates); - void GetFilteredFilterEntries( SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, TypedScStrCollection& rStrings, bool& rHasDates ); - bool GetDataEntries(SCCOL nCol, SCROW nRow, TypedScStrCollection& rStrings, bool bLimit); + void GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, std::vector<TypedStrData>& rStrings, bool& rHasDates); + void GetFilteredFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, std::vector<TypedStrData>& rStrings, bool& rHasDates ); + bool GetDataEntries(SCCOL nCol, SCROW nRow, std::set<TypedStrData>& rStrings, bool bLimit); bool HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ); bool HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ); diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx index bb454a9e0854..25fe66b99f58 100644 --- a/sc/inc/types.hxx +++ b/sc/inc/types.hxx @@ -29,6 +29,8 @@ #ifndef __SC_TYPES_HXX__ #define __SC_TYPES_HXX__ +#include "collect.hxx" + #include <boost/intrusive_ptr.hpp> class ScMatrix; @@ -36,6 +38,8 @@ class ScMatrix; typedef ::boost::intrusive_ptr<ScMatrix> ScMatrixRef; typedef ::boost::intrusive_ptr<const ScMatrix> ScConstMatrixRef; +typedef std::set<TypedStrData, TypedStrData::LessCaseSensitive> ScTypedCaseStrSet; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx index 13e4aedd8e82..44bc37a290b8 100644 --- a/sc/inc/validat.hxx +++ b/sc/inc/validat.hxx @@ -37,7 +37,7 @@ namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility; class ScPatternAttr; class ScTokenArray; -class TypedScStrCollection; +class TypedStrData; enum ScValidationMode { @@ -131,7 +131,7 @@ public: @descr Fills the list only, if this is a list validation and IsShowList() is enabled. @param rStrings (out-param) The string list to fill with list validation entires. @return true = rStrings has been filled with at least one entry. */ - bool FillSelectionList( TypedScStrCollection& rStrings, const ScAddress& rPos ) const; + bool FillSelectionList(std::vector<TypedStrData>& rStrings, const ScAddress& rPos) const; // with string: during input, with cell: for detective / RC_FORCED sal_Bool IsDataValid( const String& rTest, const ScPatternAttr& rPattern, @@ -165,9 +165,9 @@ private: @param rTokArr Formula token array. @param rMatch (out-param) the index of the first item that matched, -1 if nothing matched. @return true = Cell range found, rRange is valid, or an error entry stuffed into the list if pCell==NULL. */ - bool GetSelectionFromFormula( TypedScStrCollection* pStrings, - ScBaseCell* pCell, const ScAddress& rPos, - const ScTokenArray& rTokArr, int& rMatch ) const; + bool GetSelectionFromFormula( + std::vector<TypedStrData>* pStrings, ScBaseCell* pCell, const ScAddress& rPos, + const ScTokenArray& rTokArr, int& rMatch) const; /** Tests, if pCell is equal to what the passed token array represents. */ bool IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const; diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 113b8ae37584..c62f9f249392 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -1516,77 +1516,76 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, } -void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollection& rStrings, bool& rHasDates) +void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, std::vector<TypedStrData>& rStrings, bool& rHasDates) { bool bHasDates = false; SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); rtl::OUString aString; - SCROW nRow = 0; SCSIZE nIndex; Search( nStartRow, nIndex ); - while ( (nIndex < maItems.size()) ? ((nRow=maItems[nIndex].nRow) <= nEndRow) : false ) + for (; nIndex < maItems.size(); ++nIndex) { + SCROW nRow = maItems[nIndex].nRow; + if (nRow > nEndRow) + break; + ScBaseCell* pCell = maItems[nIndex].pCell; - TypedStrData* pData = NULL; sal_uLong nFormat = GetNumberFormat( nRow ); ScCellFormat::GetInputString( pCell, nFormat, aString, *pFormatter ); if ( pDocument->HasStringData( nCol, nRow, nTab ) ) - pData = new TypedStrData( aString ); - else { - double nValue = 0.0; + rStrings.push_back(TypedStrData(aString)); + continue; + } - switch ( pCell->GetCellType() ) - { - case CELLTYPE_VALUE: - nValue = ((ScValueCell*)pCell)->GetValue(); - break; + double nValue = 0.0; - case CELLTYPE_FORMULA: - { - ScFormulaCell* pFC = static_cast<ScFormulaCell*>(pCell); - sal_uInt16 nErr = pFC->GetErrCode(); - if (nErr) - { - // Error cell is evaluated as string (for now). - String aErr = ScGlobal::GetErrorString(nErr); - if (aErr.Len()) - pData = new TypedStrData(aErr); - } - else - nValue = pFC->GetValue(); - } + switch ( pCell->GetCellType() ) + { + case CELLTYPE_VALUE: + nValue = ((ScValueCell*)pCell)->GetValue(); break; - default: - ; - } - - if (!pData) + case CELLTYPE_FORMULA: { - if (pFormatter) + ScFormulaCell* pFC = static_cast<ScFormulaCell*>(pCell); + sal_uInt16 nErr = pFC->GetErrCode(); + if (nErr) { - short nType = pFormatter->GetType(nFormat); - if ((nType & NUMBERFORMAT_DATE) && !(nType & NUMBERFORMAT_TIME)) + // Error cell is evaluated as string (for now). + String aErr = ScGlobal::GetErrorString(nErr); + if (aErr.Len()) { - // special case for date values. Disregard the time - // element if the number format is of date type. - nValue = ::rtl::math::approxFloor(nValue); - bHasDates = true; + rStrings.push_back(TypedStrData(aErr)); + continue; } } - pData = new TypedStrData(aString, nValue, TypedStrData::Value); + else + nValue = pFC->GetValue(); } + break; + + default: + ; } - if ( !rStrings.Insert( pData ) ) - delete pData; // doppelt + if (pFormatter) + { + short nType = pFormatter->GetType(nFormat); + if ((nType & NUMBERFORMAT_DATE) && !(nType & NUMBERFORMAT_TIME)) + { + // special case for date values. Disregard the time + // element if the number format is of date type. + nValue = ::rtl::math::approxFloor(nValue); + bHasDates = true; + } + } - ++nIndex; + rStrings.push_back(TypedStrData(aString, nValue, TypedStrData::Value)); } rHasDates = bHasDates; @@ -1602,7 +1601,7 @@ void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollec #define DATENT_SEARCH 2000 -bool ScColumn::GetDataEntries(SCROW nStartRow, TypedScStrCollection& rStrings, bool bLimit) +bool ScColumn::GetDataEntries(SCROW nStartRow, std::set<TypedStrData>& rStrings, bool bLimit) { sal_Bool bFound = false; SCSIZE nThisIndex; @@ -1633,10 +1632,8 @@ bool ScColumn::GetDataEntries(SCROW nStartRow, TypedScStrCollection& rStrings, b else ((ScEditCell*)pCell)->GetString(aString); - TypedStrData* pData = new TypedStrData(aString); - if ( !rStrings.Insert( pData ) ) - delete pData; // doppelt - else if ( bLimit && rStrings.GetCount() >= DATENT_MAX ) + bool bInserted = rStrings.insert(TypedStrData(aString)).second; + if (bInserted && bLimit && rStrings.size() >= DATENT_MAX) break; // Maximum erreicht bFound = true; @@ -1658,10 +1655,8 @@ bool ScColumn::GetDataEntries(SCROW nStartRow, TypedScStrCollection& rStrings, b else ((ScEditCell*)pCell)->GetString(aString); - TypedStrData* pData = new TypedStrData(aString); - if ( !rStrings.Insert( pData ) ) - delete pData; // doppelt - else if ( bLimit && rStrings.GetCount() >= DATENT_MAX ) + bool bInserted = rStrings.insert(TypedStrData(aString)).second; + if (bInserted && bLimit && rStrings.size() >= DATENT_MAX) break; // Maximum erreicht bFound = true; diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 631d7210cac2..3b8be7ae6948 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -1425,7 +1425,7 @@ bool ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, // bool ScDocument::GetFilterEntries( - SCCOL nCol, SCROW nRow, SCTAB nTab, bool bFilter, TypedScStrCollection& rStrings, bool& rHasDates) + SCCOL nCol, SCROW nRow, SCTAB nTab, bool bFilter, std::vector<TypedStrData>& rStrings, bool& rHasDates) { if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && pDBCollection ) { @@ -1445,7 +1445,6 @@ bool ScDocument::GetFilterEntries( ScQueryParam aParam; pDBData->GetQueryParam( aParam ); - rStrings.SetCaseSensitive( aParam.bCaseSens ); // return all filter entries, if a filter condition is connected with a boolean OR if ( bFilter ) @@ -1471,6 +1470,17 @@ bool ScDocument::GetFilterEntries( maTabs[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates ); } + if (aParam.bCaseSens) + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseSensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseSensitive()); + } + else + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseInsensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseInsensitive()); + } + return true; } } @@ -1482,12 +1492,23 @@ bool ScDocument::GetFilterEntries( // GetFilterEntriesArea - Eintraege fuer Filter-Dialog // -bool ScDocument::GetFilterEntriesArea( SCCOL nCol, SCROW nStartRow, SCROW nEndRow, - SCTAB nTab, TypedScStrCollection& rStrings, bool& rHasDates ) +bool ScDocument::GetFilterEntriesArea( + SCCOL nCol, SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bCaseSens, + std::vector<TypedStrData>& rStrings, bool& rHasDates) { if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] ) { maTabs[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates ); + if (bCaseSens) + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseSensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseSensitive()); + } + else + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseInsensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseInsensitive()); + } return true; } @@ -1498,8 +1519,9 @@ bool ScDocument::GetFilterEntriesArea( SCCOL nCol, SCROW nStartRow, SCROW nEndRo // GetDataEntries - Eintraege fuer Auswahlliste-Listbox (keine Zahlen / Formeln) // -bool ScDocument::GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, - TypedScStrCollection& rStrings, bool bLimit ) +bool ScDocument::GetDataEntries( + SCCOL nCol, SCROW nRow, SCTAB nTab, bool bCaseSens, + std::vector<TypedStrData>& rStrings, bool bLimit ) { if( !bLimit ) { @@ -1511,23 +1533,53 @@ bool ScDocument::GetDataEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, { const ScValidationData* pData = GetValidationEntry( nValidation ); if( pData && pData->FillSelectionList( rStrings, ScAddress( nCol, nRow, nTab ) ) ) + { + if (pData->GetListType() == ValidListType::SORTEDASCENDING) + { + if (bCaseSens) + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseSensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseSensitive()); + } + else + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseInsensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseInsensitive()); + } + } return true; + } } } - return ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->GetDataEntries( nCol, nRow, rStrings, bLimit ); + if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size())) + return false; + + if (!maTabs[nTab]) + return false; + + std::set<TypedStrData> aStrings; + bool bRet = maTabs[nTab]->GetDataEntries(nCol, nRow, aStrings, bLimit); + rStrings.insert(rStrings.end(), aStrings.begin(), aStrings.end()); + if (bCaseSens) + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseSensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseSensitive()); + } + else + { + std::sort(rStrings.begin(), rStrings.end(), TypedStrData::LessCaseInsensitive()); + std::unique(rStrings.begin(), rStrings.end(), TypedStrData::EqualCaseInsensitive()); + } + + return bRet; } // // GetFormulaEntries - Eintraege fuer Formel-AutoEingabe // -// Funktionen werden als 1 schon vom InputHandler eingefuegt -#define SC_STRTYPE_NAMES 2 -#define SC_STRTYPE_DBNAMES 3 -#define SC_STRTYPE_HEADERS 4 - -bool ScDocument::GetFormulaEntries( TypedScStrCollection& rStrings ) +bool ScDocument::GetFormulaEntries( ScTypedCaseStrSet& rStrings ) { // // Bereichsnamen @@ -1537,11 +1589,7 @@ bool ScDocument::GetFormulaEntries( TypedScStrCollection& rStrings ) { ScRangeName::const_iterator itr = pRangeName->begin(), itrEnd = pRangeName->end(); for (; itr != itrEnd; ++itr) - { - TypedStrData* pNew = new TypedStrData(itr->second->GetName(), 0.0, TypedStrData::Name); - if (!rStrings.Insert(pNew)) - delete pNew; - } + rStrings.insert(TypedStrData(itr->second->GetName(), 0.0, TypedStrData::Name)); } // @@ -1553,11 +1601,7 @@ bool ScDocument::GetFormulaEntries( TypedScStrCollection& rStrings ) const ScDBCollection::NamedDBs& rDBs = pDBCollection->getNamedDBs(); ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end(); for (; itr != itrEnd; ++itr) - { - TypedStrData* pNew = new TypedStrData(itr->GetName(), 0.0, TypedStrData::DbName); - if ( !rStrings.Insert(pNew) ) - delete pNew; - } + rStrings.insert(TypedStrData(itr->GetName(), 0.0, TypedStrData::DbName)); } // @@ -1580,9 +1624,7 @@ bool ScDocument::GetFormulaEntries( TypedScStrCollection& rStrings ) if ( pCell->HasStringData() ) { rtl::OUString aStr = pCell->GetStringData(); - TypedStrData* pNew = new TypedStrData(aStr, 0.0, TypedStrData::Header); - if ( !rStrings.Insert(pNew) ) - delete pNew; + rStrings.insert(TypedStrData(aStr, 0.0, TypedStrData::Header)); } } } diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 7458fca8e2ba..828f58e2b37c 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -979,7 +979,7 @@ long ScDPObject::GetDimCount() return nRet; } -void ScDPObject::FillPageList( TypedScStrCollection& rStrings, long nField ) +void ScDPObject::FillPageList( std::vector<rtl::OUString>& rStrings, long nField ) { //! merge members access with ToggleDetails? @@ -1060,16 +1060,12 @@ void ScDPObject::FillPageList( TypedScStrCollection& rStrings, long nField ) if (bVisible) { // use the order from getElementNames - TypedStrData* pData = new TypedStrData( pNameArr[nPos] ); - if ( !rStrings.AtInsert( rStrings.GetCount(), pData ) ) - delete pData; + rStrings.push_back(pNameArr[nPos]); } } // add "-all-" entry to the top (unsorted) - TypedStrData* pAllData = new TypedStrData( String( ScResId( SCSTR_ALL ) ) ); //! separate string? (also output) - if ( !rStrings.AtInsert( 0, pAllData ) ) - delete pAllData; + rStrings.insert(rStrings.begin(), ScResId::toString(ScResId(SCSTR_ALL))); } void ScDPObject::GetHeaderPositionData(const ScAddress& rPos, DataPilotTableHeaderData& rData) diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index a1ed9b97a852..11aed0c79f7c 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -2108,13 +2108,13 @@ bool ScTable::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL /* nEndCol * return true; } -void ScTable::GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, TypedScStrCollection& rStrings, bool& rHasDates) +void ScTable::GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, std::vector<TypedStrData>& rStrings, bool& rHasDates) { aCol[nCol].GetFilterEntries( nRow1, nRow2, rStrings, rHasDates ); } void ScTable::GetFilteredFilterEntries( - SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, TypedScStrCollection& rStrings, bool& rHasDates ) + SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, std::vector<TypedStrData>& rStrings, bool& rHasDates) { // remove the entry for this column from the query parameter ScQueryParam aParam( rParam ); @@ -2135,7 +2135,7 @@ void ScTable::GetFilteredFilterEntries( rHasDates = bHasDates; } -bool ScTable::GetDataEntries(SCCOL nCol, SCROW nRow, TypedScStrCollection& rStrings, bool bLimit) +bool ScTable::GetDataEntries(SCCOL nCol, SCROW nRow, std::set<TypedStrData>& rStrings, bool bLimit) { return aCol[nCol].GetDataEntries( nRow, rStrings, bLimit ); } diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx index c19ea192a31a..ec1da2488719 100644 --- a/sc/source/core/data/validat.cxx +++ b/sc/source/core/data/validat.cxx @@ -601,13 +601,6 @@ sal_uLong lclGetCellFormat( ScDocument& rDoc, const ScAddress& rPos ) return pPattern->GetNumberFormat( rDoc.GetFormatTable() ); } -/** Inserts the passed string object. Always takes ownership. pData is invalid after this call! */ -void lclInsertStringToCollection( TypedScStrCollection& rStrColl, TypedStrData* pData, bool bSorted ) -{ - if( !(bSorted ? rStrColl.Insert( pData ) : rStrColl.AtInsert( rStrColl.GetCount(), pData )) ) - delete pData; -} - } // namespace // ---------------------------------------------------------------------------- @@ -617,11 +610,9 @@ bool ScValidationData::HasSelectionList() const return (eDataMode == SC_VALID_LIST) && (mnListType != ValidListType::INVISIBLE); } -bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings, - ScBaseCell* pCell, - const ScAddress& rPos, - const ScTokenArray& rTokArr, - int& rMatch ) const +bool ScValidationData::GetSelectionFromFormula( + std::vector<TypedStrData>* pStrings, ScBaseCell* pCell, const ScAddress& rPos, + const ScTokenArray& rTokArr, int& rMatch) const { bool bOk = true; @@ -676,7 +667,6 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings, SvNumberFormatter* pFormatter = GetDocument()->GetFormatTable(); - bool bSortList = (mnListType == ValidListType::SORTEDASCENDING); SCSIZE nCol, nRow, nCols, nRows, n = 0; pValues->GetDimensions( nCols, nRows ); @@ -783,7 +773,8 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings, if( NULL != pEntry ) { - lclInsertStringToCollection( *pStrings, pEntry, bSortList ); + pStrings->push_back(*pEntry); + delete pEntry; n++; } } @@ -794,28 +785,25 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings, return bOk || NULL == pCell; } -bool ScValidationData::FillSelectionList( TypedScStrCollection& rStrColl, const ScAddress& rPos ) const +bool ScValidationData::FillSelectionList(std::vector<TypedStrData>& rStrColl, const ScAddress& rPos) const { bool bOk = false; if( HasSelectionList() ) { - SAL_WNODEPRECATED_DECLARATIONS_PUSH - ::std::auto_ptr< ScTokenArray > pTokArr( CreateTokenArry( 0 ) ); - SAL_WNODEPRECATED_DECLARATIONS_POP + boost::scoped_ptr<ScTokenArray> pTokArr( CreateTokenArry(0) ); // *** try if formula is a string list *** - bool bSortList = (mnListType == ValidListType::SORTEDASCENDING); sal_uInt32 nFormat = lclGetCellFormat( *GetDocument(), rPos ); ScStringTokenIterator aIt( *pTokArr ); for( const String* pString = aIt.First(); pString && aIt.Ok(); pString = aIt.Next() ) { double fValue; bool bIsValue = GetDocument()->GetFormatTable()->IsNumberFormat( *pString, nFormat, fValue ); - TypedStrData* pData = new TypedStrData( - *pString, fValue, bIsValue ? TypedStrData::Value : TypedStrData::Standard); - lclInsertStringToCollection( rStrColl, pData, bSortList ); + rStrColl.push_back( + TypedStrData( + *pString, fValue, bIsValue ? TypedStrData::Value : TypedStrData::Standard)); } bOk = aIt.Ok(); diff --git a/sc/source/core/tool/collect.cxx b/sc/source/core/tool/collect.cxx index ca4805aac43e..2bbf24412470 100644 --- a/sc/source/core/tool/collect.cxx +++ b/sc/source/core/tool/collect.cxx @@ -306,198 +306,114 @@ sal_Bool ScSortedCollection::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) c // TypedScStrCollection //------------------------------------------------------------------------ -TypedStrData::TypedStrData( - const rtl::OUString& rStr, double nVal, StringType nType ) : - maStrValue(rStr), - mfValue(nVal), - meStrType(nType) {} +bool TypedStrData::LessCaseSensitive::operator() (const TypedStrData& left, const TypedStrData& right) const +{ + if (left.meStrType != right.meStrType) + return left.meStrType < right.meStrType; -TypedStrData::TypedStrData( const TypedStrData& rCpy ) : - ScDataObject(), - maStrValue(rCpy.maStrValue), - mfValue(rCpy.mfValue), - meStrType(rCpy.meStrType) {} + if (left.meStrType == Value) + return left.mfValue < right.mfValue; -ScDataObject* TypedStrData::Clone() const -{ - return new TypedStrData(*this); + return ScGlobal::GetCaseTransliteration()->compareString( + left.maStrValue, right.maStrValue) < 0; } -bool TypedStrData::IsStrData() const +bool TypedStrData::LessCaseInsensitive::operator() (const TypedStrData& left, const TypedStrData& right) const { - return meStrType != Value; + if (left.meStrType != right.meStrType) + return left.meStrType < right.meStrType; + + if (left.meStrType == Value) + return left.mfValue < right.mfValue; + + return ScGlobal::GetpTransliteration()->compareString( + left.maStrValue, right.maStrValue) < 0; } -const rtl::OUString& TypedStrData::GetString() const +bool TypedStrData::EqualCaseSensitive::operator() (const TypedStrData& left, const TypedStrData& right) const { - return maStrValue; + if (left.meStrType != right.meStrType) + return false; + + if (left.meStrType == Value && left.mfValue != right.mfValue) + return false; + + return ScGlobal::GetCaseTransliteration()->compareString( + left.maStrValue, right.maStrValue) == 0; } -double TypedStrData::GetValue () const +bool TypedStrData::EqualCaseInsensitive::operator() (const TypedStrData& left, const TypedStrData& right) const { - return mfValue; + if (left.meStrType != right.meStrType) + return false; + + if (left.meStrType == Value && left.mfValue != right.mfValue) + return false; + + return ScGlobal::GetpTransliteration()->compareString( + left.maStrValue, right.maStrValue) == 0; } -TypedScStrCollection::TypedScStrCollection( sal_uInt16 nLim , sal_uInt16 nDel , sal_Bool bDup ) - : ScSortedCollection( nLim, nDel, bDup ) +bool TypedStrData::operator== (const TypedStrData& r) const { - bCaseSensitive = false; + // Case insensitive comparison by default. + EqualCaseInsensitive aHdl; + return aHdl(*this, r); } -TypedScStrCollection::~TypedScStrCollection() -{} -ScDataObject* TypedScStrCollection::Clone() const +bool TypedStrData::operator< (const TypedStrData& r) const { - return new TypedScStrCollection(*this); + // Case insensitive comparison by default. + LessCaseInsensitive aHdl; + return aHdl(*this, r); } -TypedStrData* TypedScStrCollection::operator[]( const sal_uInt16 nIndex) const +TypedStrData::TypedStrData( + const rtl::OUString& rStr, double nVal, StringType nType ) : + maStrValue(rStr), + mfValue(nVal), + meStrType(nType) {} + +TypedStrData::TypedStrData( const TypedStrData& rCpy ) : + maStrValue(rCpy.maStrValue), + mfValue(rCpy.mfValue), + meStrType(rCpy.meStrType) {} + +bool TypedStrData::IsStrData() const { - return (TypedStrData*)At(nIndex); + return meStrType != Value; } -void TypedScStrCollection::SetCaseSensitive( sal_Bool bSet ) +const rtl::OUString& TypedStrData::GetString() const { - bCaseSensitive = bSet; + return maStrValue; } -short TypedScStrCollection::Compare( ScDataObject* pKey1, ScDataObject* pKey2 ) const +double TypedStrData::GetValue() const { - short nResult = 0; - - if ( pKey1 && pKey2 ) - { - TypedStrData& rData1 = (TypedStrData&)*pKey1; - TypedStrData& rData2 = (TypedStrData&)*pKey2; - - if ( rData1.meStrType > rData2.meStrType ) - nResult = 1; - else if ( rData1.meStrType < rData2.meStrType ) - nResult = -1; - else if ( !rData1.meStrType /* && !rData2.nStrType */ ) - { - //-------------------- - // Zahlen vergleichen: - //-------------------- - if ( rData1.mfValue == rData2.mfValue ) - nResult = 0; - else if ( rData1.mfValue < rData2.mfValue ) - nResult = -1; - else - nResult = 1; - } - else /* if ( rData1.nStrType && rData2.nStrType ) */ - { - //--------------------- - // Strings vergleichen: - //--------------------- - if ( bCaseSensitive ) - nResult = (short) ScGlobal::GetCaseTransliteration()->compareString( - rData1.maStrValue, rData2.maStrValue ); - else - nResult = (short) ScGlobal::GetpTransliteration()->compareString( - rData1.maStrValue, rData2.maStrValue ); - } - } - - return nResult; + return mfValue; } -sal_Bool TypedScStrCollection::FindText( const String& rStart, String& rResult, - sal_uInt16& rPos, sal_Bool bBack ) const +TypedStrData::StringType TypedStrData::GetStringType() const { - // Die Collection ist nach String-Vergleichen sortiert, darum muss hier - // alles durchsucht werden - - sal_Bool bFound = false; - - String aOldResult; - if ( rPos != SCPOS_INVALID && rPos < nCount ) - { - TypedStrData* pData = (TypedStrData*) pItems[rPos]; - if (pData->meStrType) - aOldResult = pData->maStrValue; - } - - if ( bBack ) // rueckwaerts - { - sal_uInt16 nStartPos = nCount; - if ( rPos != SCPOS_INVALID ) - nStartPos = rPos; // weitersuchen... - - for ( sal_uInt16 i=nStartPos; i>0; ) - { - --i; - TypedStrData* pData = (TypedStrData*) pItems[i]; - if (pData->meStrType) - { - if ( ScGlobal::GetpTransliteration()->isMatch( rStart, pData->maStrValue ) ) - { - // If the collection is case sensitive, it may contain several entries - // that are equal when compared case-insensitive. They are skipped here. - if ( !bCaseSensitive || !aOldResult.Len() || - !ScGlobal::GetpTransliteration()->isEqual( - pData->maStrValue, aOldResult ) ) - { - rResult = pData->maStrValue; - rPos = i; - bFound = sal_True; - break; - } - } - } - } - } - else // vorwaerts - { - sal_uInt16 nStartPos = 0; - if ( rPos != SCPOS_INVALID ) - nStartPos = rPos + 1; // weitersuchen... - - for ( sal_uInt16 i=nStartPos; i<nCount; i++ ) - { - TypedStrData* pData = (TypedStrData*) pItems[i]; - if (pData->meStrType) - { - if ( ScGlobal::GetpTransliteration()->isMatch( rStart, pData->maStrValue ) ) - { - // If the collection is case sensitive, it may contain several entries - // that are equal when compared case-insensitive. They are skipped here. - if ( !bCaseSensitive || !aOldResult.Len() || - !ScGlobal::GetpTransliteration()->isEqual( - pData->maStrValue, aOldResult ) ) - { - rResult = pData->maStrValue; - rPos = i; - bFound = sal_True; - break; - } - } - } - } - } - - return bFound; + return meStrType; } - // Gross-/Kleinschreibung anpassen +FindTypedStrData::FindTypedStrData(const TypedStrData& rVal, bool bCaseSens) : + maVal(rVal), mbCaseSens(bCaseSens) {} -sal_Bool TypedScStrCollection::GetExactMatch( String& rString ) const +bool FindTypedStrData::operator() (const TypedStrData& r) const { - for (sal_uInt16 i=0; i<nCount; i++) + if (mbCaseSens) { - TypedStrData* pData = (TypedStrData*) pItems[i]; - if ( pData->meStrType && ScGlobal::GetpTransliteration()->isEqual( - pData->maStrValue, rString ) ) - { - rString = pData->maStrValue; // String anpassen - return sal_True; - } + TypedStrData::EqualCaseSensitive aHdl; + return aHdl(maVal, r); + } + else + { + TypedStrData::EqualCaseInsensitive aHdl; + return aHdl(maVal, r); } - - return false; } - - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index 38cbee81ff02..af0982001201 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -102,23 +102,114 @@ using namespace formula; sal_Bool ScInputHandler::bOptLoaded = false; // App-Optionen ausgewertet sal_Bool ScInputHandler::bAutoComplete = false; // wird in KeyInput gesetzt +extern sal_uInt16 nEditAdjust; //! Member an ViewData + +namespace { + // delimiters (in addition to ScEditUtil) needed for range finder: // only characters that are allowed in formulas next to references // and the quotation mark (so string constants can be skipped) +const sal_Char pMinDelimiters[] = " !\""; -static const sal_Char pMinDelimiters[] = " !\""; - -extern sal_uInt16 nEditAdjust; //! Member an ViewData - -//================================================================== - -static sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc) +sal_Unicode lcl_getSheetSeparator(ScDocument* pDoc) { ScCompiler aComp(pDoc, ScAddress()); aComp.SetGrammar(pDoc->GetGrammar()); return aComp.GetNativeAddressSymbol(ScCompiler::Convention::SHEET_SEPARATOR); } +ScTypedCaseStrSet::const_iterator findText( + const ScTypedCaseStrSet& rDataSet, ScTypedCaseStrSet::const_iterator itPos, + const rtl::OUString& rStart, rtl::OUString& rResult, bool bBack) +{ + rtl::OUString aOldResult; + if (itPos != rDataSet.end()) + { + const TypedStrData& rData = *itPos; + if (rData.GetStringType()) + aOldResult = rData.GetString(); + } + + if (bBack) // rueckwaerts + { + ScTypedCaseStrSet::const_reverse_iterator it = rDataSet.rbegin(), itEnd = rDataSet.rend(); + if (itPos != rDataSet.end()) + { + size_t nPos = std::distance(rDataSet.begin(), itPos); + size_t nRPos = rDataSet.size() - 1 - nPos; + std::advance(it, nRPos); + } + + for (; it != itEnd; ++it) + { + const TypedStrData& rData = *it; + if (rData.GetStringType() == TypedStrData::Value) + // skip values. + continue; + + if (!ScGlobal::GetpTransliteration()->isMatch(rStart, rData.GetString())) + // not a match. + continue; + + rResult = rData.GetString(); + return (++it).base(); // convert the reverse iterator back to iterator. + } + } + else // vorwaerts + { + ScTypedCaseStrSet::const_iterator it = rDataSet.begin(), itEnd = rDataSet.end(); + if (itPos != rDataSet.end()) + it = itPos; + + for (; it != itEnd; ++it) + { + const TypedStrData& rData = *it; + if (rData.GetStringType() == TypedStrData::Value) + // skip values. + continue; + + if (!ScGlobal::GetpTransliteration()->isMatch(rStart, rData.GetString())) + // not a match. + continue; + + rResult = rData.GetString(); + return it; + } + } + + return rDataSet.end(); // no matching text found. +} + +rtl::OUString getExactMatch(const ScTypedCaseStrSet& rDataSet, const rtl::OUString& rString) +{ + ScTypedCaseStrSet::const_iterator it = rDataSet.begin(), itEnd = rDataSet.end(); + for (; it != itEnd; ++it) + { + const TypedStrData& rData = *it; + if (rData.GetStringType() == TypedStrData::Value) + continue; + + if (!ScGlobal::GetpTransliteration()->isEqual(rData.GetString(), rString)) + continue; + + return rData.GetString(); + } + return rtl::OUString(); +} + +void removeChars(rtl::OUString& rStr, sal_Unicode c) +{ + rtl::OUStringBuffer aBuf(rStr); + for (sal_Int32 i = 0, n = aBuf.getLength(); i < n; ++i) + { + if (aBuf.charAt(i) == c) + aBuf.setCharAt(i, sal_Unicode(' ')); + } + rStr = aBuf.makeStringAndClear(); +} + +} + void ScInputHandler::InitRangeFinder( const String& rFormula ) { DeleteRangeFinder(); @@ -312,19 +403,15 @@ inline String GetEditText(EditEngine* pEng) return ScEditUtil::GetSpaceDelimitedString(*pEng); } -void lcl_RemoveTabs(String& rStr) +void lcl_RemoveTabs(rtl::OUString& rStr) { - xub_StrLen nPos; - while ( (nPos=rStr.Search('\t')) != STRING_NOTFOUND ) - rStr.SetChar( nPos, ' ' ); + removeChars(rStr, sal_Unicode('\t')); } -void lcl_RemoveLineEnd(String& rStr) +void lcl_RemoveLineEnd(rtl::OUString& rStr) { rStr = convertLineEnd(rStr, LINEEND_LF); - xub_StrLen nPos; - while ( (nPos=rStr.Search('\n')) != STRING_NOTFOUND ) - rStr.SetChar( nPos, ' ' ); + removeChars(rStr, sal_Unicode('\n')); } xub_StrLen lcl_MatchParenthesis( const String& rStr, xub_StrLen nPos ) @@ -433,7 +520,6 @@ ScInputHandler::ScInputHandler() nTipVisible( 0 ), pTipVisibleSecParent( NULL ), nTipVisibleSec( 0 ), - nAutoPos( SCPOS_INVALID ), bUseTab( false ), bTextValid( sal_True ), nFormSelStart( 0 ), @@ -634,7 +720,6 @@ void ScInputHandler::UpdateSpellSettings( sal_Bool bFromStartTab ) // Funktionen/Bereichsnamen etc. als Tip-Hilfe // -#define SC_STRTYPE_FUNCTIONS 1 // die anderen Typen sind in ScDocument::GetFormulaEntries festgelegt void ScInputHandler::GetFormulaData() @@ -644,14 +729,14 @@ void ScInputHandler::GetFormulaData() ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); if ( pFormulaData ) - pFormulaData->FreeAll(); + pFormulaData->clear(); else - pFormulaData = new TypedScStrCollection; + pFormulaData = new ScTypedCaseStrSet; if( pFormulaDataPara ) - pFormulaDataPara->FreeAll(); + pFormulaDataPara->clear(); else - pFormulaDataPara = new TypedScStrCollection; + pFormulaDataPara = new ScTypedCaseStrSet; // MRU-Funktionen aus dem Funktions-Autopiloten // wie in ScPosWnd::FillFunctions (inputwin.cxx) @@ -673,9 +758,7 @@ void ScInputHandler::GetFormulaData() { String aEntry = *pDesc->pFuncName; aEntry.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "()" )); - TypedStrData* pData = new TypedStrData(aEntry, 0.0, TypedStrData::Standard); - if (!pFormulaData->Insert(pData)) - delete pData; + pFormulaData->insert(TypedStrData(aEntry, 0.0, TypedStrData::Standard)); break; // nicht weitersuchen } } @@ -688,9 +771,7 @@ void ScInputHandler::GetFormulaData() { pDesc->initArgumentInfo(); String aEntry = pDesc->getSignature(); - TypedStrData* pData = new TypedStrData(aEntry, 0.0, TypedStrData::Standard); - if (!pFormulaDataPara->Insert(pData)) - delete pData; + pFormulaDataPara->insert(TypedStrData(aEntry, 0.0, TypedStrData::Standard)); } } pDoc->GetFormulaEntries( *pFormulaData ); @@ -783,10 +864,11 @@ void ScInputHandler::ShowTipCursor() nArgPos = aHelper.GetArgStart( aSelText, nNextFStart, 0 ); nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount()); - sal_Bool bFlag = false; - String aNew; - sal_uInt16 nParAutoPos = SCPOS_INVALID; - if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, false ) ) + bool bFlag = false; + rtl::OUString aNew; + ScTypedCaseStrSet::const_iterator it = + findText(*pFormulaDataPara, pFormulaDataPara->end(), ppFDesc->getFunctionName(), aNew, false); + if (it != pFormulaDataPara->end()) { sal_uInt16 nActive = 0; for( sal_uInt16 i=0; i < nArgs; i++ ) @@ -801,16 +883,16 @@ void ScInputHandler::ShowTipCursor() } if( bFlag ) { - sal_uInt16 nCountSemicolon = comphelper::string::getTokenCount(aNew, cSep) - 1; - sal_uInt16 nCountDot = comphelper::string::getTokenCount(aNew, cSheetSep) - 1; - sal_uInt16 nStartPosition = 0; - sal_uInt16 nEndPosition = 0; + sal_Int32 nCountSemicolon = comphelper::string::getTokenCount(aNew, cSep) - 1; + sal_Int32 nCountDot = comphelper::string::getTokenCount(aNew, cSheetSep) - 1; + sal_Int32 nStartPosition = 0; + sal_Int32 nEndPosition = 0; if( !nCountSemicolon ) { - for( sal_uInt16 i = 0; i < aNew.Len(); i++ ) + for (sal_Int32 i = 0; i < aNew.getLength(); ++i) { - sal_Unicode cNext = aNew.GetChar( i ); + sal_Unicode cNext = aNew.getStr()[i]; if( cNext == '(' ) { nStartPosition = i+1; @@ -820,9 +902,9 @@ void ScInputHandler::ShowTipCursor() else if( !nCountDot ) { sal_uInt16 nCount = 0; - for( sal_uInt16 i = 0; i < aNew.Len(); i++ ) + for (sal_Int32 i = 0; i < aNew.getLength(); ++i) { - sal_Unicode cNext = aNew.GetChar( i ); + sal_Unicode cNext = aNew.getStr()[i]; if( cNext == '(' ) { nStartPosition = i+1; @@ -842,9 +924,9 @@ void ScInputHandler::ShowTipCursor() else { sal_uInt16 nCount = 0; - for( sal_uInt16 i = 0; i < aNew.Len(); i++ ) + for (sal_Int32 i = 0; i < aNew.getLength(); ++i) { - sal_Unicode cNext = aNew.GetChar( i ); + sal_Unicode cNext = aNew.getStr()[i]; if( cNext == '(' ) { nStartPosition = i+1; @@ -866,9 +948,13 @@ void ScInputHandler::ShowTipCursor() } } - if( nStartPosition ) + if (nStartPosition > 0) { - aNew.Insert( 0x25BA, nStartPosition ); + rtl::OUStringBuffer aBuf; + aBuf.append(aNew.copy(0, nStartPosition)); + aBuf.append(static_cast<sal_Unicode>(0x25BA)); + aBuf.append(aNew.copy(nStartPosition)); + aNew = aBuf.makeStringAndClear(); ShowTipBelow( aNew ); bFound = sal_True; } @@ -890,10 +976,11 @@ void ScInputHandler::ShowTipCursor() { break; } - String aNew; - sal_uInt16 nParAutoPos = SCPOS_INVALID; + rtl::OUString aNew; nPosition = aText.Len()+1; - if( pFormulaDataPara->FindText( aText, aNew, nParAutoPos, false ) ) + ScTypedCaseStrSet::const_iterator it = + findText(*pFormulaDataPara, pFormulaDataPara->end(), aText, aNew, false); + if (it != pFormulaDataPara->end()) { if( aFormula.GetChar( nPosition ) =='(' ) { @@ -995,12 +1082,13 @@ void ScInputHandler::UseFormulaData() sal_uInt16 nArgs; sal_Bool bFound = false; - String aText = pEngine->GetWord( 0, aSel.nEndPos-1 ); - if ( aText.Len() ) + rtl::OUString aText = pEngine->GetWord( 0, aSel.nEndPos-1 ); + if (!aText.isEmpty()) { - String aNew; - nAutoPos = SCPOS_INVALID; - if ( pFormulaData->FindText( aText, aNew, nAutoPos, false ) ) + rtl::OUString aNew; + miAutoPos = pFormulaData->end(); + miAutoPos = findText(*pFormulaData, miAutoPos, aText, aNew, false); + if (miAutoPos != pFormulaData->end()) { ShowTip( aNew ); aAutoSearch = aText; @@ -1027,10 +1115,11 @@ void ScInputHandler::UseFormulaData() nArgPos = aHelper.GetArgStart( aFormula, nNextFStart, 0 ); nArgs = static_cast<sal_uInt16>(ppFDesc->getParameterCount()); - sal_Bool bFlag = false; - String aNew; - sal_uInt16 nParAutoPos = SCPOS_INVALID; - if( pFormulaDataPara->FindText( ppFDesc->getFunctionName(), aNew, nParAutoPos, false ) ) + bool bFlag = false; + rtl::OUString aNew; + ScTypedCaseStrSet::const_iterator it = + findText(*pFormulaDataPara, pFormulaDataPara->end(), ppFDesc->getFunctionName(), aNew, false); + if (it != pFormulaDataPara->end()) { sal_uInt16 nActive = 0; for( sal_uInt16 i=0; i < nArgs; i++ ) @@ -1045,16 +1134,16 @@ void ScInputHandler::UseFormulaData() } if( bFlag ) { - sal_uInt16 nCountSemicolon = comphelper::string::getTokenCount(aNew, cSep) - 1; - sal_uInt16 nCountDot = comphelper::string::getTokenCount(aNew, cSheetSep) - 1; - sal_uInt16 nStartPosition = 0; - sal_uInt16 nEndPosition = 0; + sal_Int32 nCountSemicolon = comphelper::string::getTokenCount(aNew, cSep) - 1; + sal_Int32 nCountDot = comphelper::string::getTokenCount(aNew, cSheetSep) - 1; + sal_Int32 nStartPosition = 0; + sal_Int32 nEndPosition = 0; if( !nCountSemicolon ) { - for( sal_uInt16 i = 0; i < aNew.Len(); i++ ) + for (sal_Int32 i = 0; i < aNew.getLength(); ++i) { - sal_Unicode cNext = aNew.GetChar( i ); + sal_Unicode cNext = aNew.getStr()[i]; if( cNext == '(' ) { nStartPosition = i+1; @@ -1064,9 +1153,9 @@ void ScInputHandler::UseFormulaData() else if( !nCountDot ) { sal_uInt16 nCount = 0; - for( sal_uInt16 i = 0; i < aNew.Len(); i++ ) + for (sal_Int32 i = 0; i < aNew.getLength(); ++i) { - sal_Unicode cNext = aNew.GetChar( i ); + sal_Unicode cNext = aNew.getStr()[i]; if( cNext == '(' ) { nStartPosition = i+1; @@ -1086,9 +1175,9 @@ void ScInputHandler::UseFormulaData() else { sal_uInt16 nCount = 0; - for( sal_uInt16 i = 0; i < aNew.Len(); i++ ) + for (sal_Int32 i = 0; i < aNew.getLength(); ++i) { - sal_Unicode cNext = aNew.GetChar( i ); + sal_Unicode cNext = aNew.getStr()[i]; if( cNext == '(' ) { nStartPosition = i+1; @@ -1110,9 +1199,13 @@ void ScInputHandler::UseFormulaData() } } - if( nStartPosition ) + if (nStartPosition > 0) { - aNew.Insert( 0x25BA, nStartPosition ); + rtl::OUStringBuffer aBuf; + aBuf.append(aNew.copy(0, nStartPosition)); + aBuf.append(static_cast<sal_Unicode>(0x25BA)); + aBuf.append(aNew.copy(nStartPosition)); + aNew = aBuf.makeStringAndClear(); ShowTipBelow( aNew ); bFound = sal_True; } @@ -1135,8 +1228,9 @@ void ScInputHandler::NextFormulaEntry( sal_Bool bBack ) EditView* pActiveView = pTopView ? pTopView : pTableView; if ( pActiveView && pFormulaData ) { - String aNew; - if ( pFormulaData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) ) + rtl::OUString aNew; + miAutoPos = findText(*pFormulaData, miAutoPos, aAutoSearch, aNew, bBack); + if (miAutoPos != pFormulaData->end()) ShowTip( aNew ); // als QuickHelp anzeigen } @@ -1146,7 +1240,7 @@ void ScInputHandler::NextFormulaEntry( sal_Bool bBack ) pActiveView->ShowCursor(); } -void lcl_CompleteFunction( EditView* pView, const String& rInsert, sal_Bool& rParInserted ) +void lcl_CompleteFunction( EditView* pView, const String& rInsert, bool& rParInserted ) { if (pView) { @@ -1191,23 +1285,20 @@ void lcl_CompleteFunction( EditView* pView, const String& rInsert, sal_Bool& rPa void ScInputHandler::PasteFunctionData() { - if ( pFormulaData && nAutoPos != SCPOS_INVALID ) + if (pFormulaData && miAutoPos != pFormulaData->end()) { - TypedStrData* pData = (*pFormulaData)[nAutoPos]; - if (pData) - { - String aInsert = pData->GetString(); - sal_Bool bParInserted = false; + const TypedStrData& rData = *miAutoPos; + const rtl::OUString& aInsert = rData.GetString(); + bool bParInserted = false; - DataChanging(); // kann nicht neu sein - lcl_CompleteFunction( pTopView, aInsert, bParInserted ); - lcl_CompleteFunction( pTableView, aInsert, bParInserted ); - DataChanged(); - ShowTipCursor(); + DataChanging(); // kann nicht neu sein + lcl_CompleteFunction( pTopView, aInsert, bParInserted ); + lcl_CompleteFunction( pTableView, aInsert, bParInserted ); + DataChanged(); + ShowTipCursor(); - if (bParInserted) - AutoParAdded(); - } + if (bParInserted) + AutoParAdded(); } HideTip(); @@ -1310,7 +1401,10 @@ void ScInputHandler::FormulaPreview() { ShowTip( aValue ); // als QuickHelp anzeigen aManualTip = aValue; // nach ShowTip setzen - nAutoPos = SCPOS_INVALID; // Formel-Autocomplete aufheben + if (pFormulaData) + miAutoPos = pFormulaData->end(); + else if (pColumnData) + miAutoPos = pColumnData->end(); } } @@ -1437,15 +1531,17 @@ void ScInputHandler::GetColData() ScDocument* pDoc = pActiveViewSh->GetViewData()->GetDocShell()->GetDocument(); if ( pColumnData ) - pColumnData->FreeAll(); + pColumnData->clear(); else { - pColumnData = new TypedScStrCollection; - pColumnData->SetCaseSensitive( sal_True ); // equal strings are handled in FindText + pColumnData = new ScTypedCaseStrSet; } - pDoc->GetDataEntries( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), - *pColumnData, sal_True ); + std::vector<TypedStrData> aEntries; + pDoc->GetDataEntries( + aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), true, aEntries, true); + if (!aEntries.empty()) + pColumnData->insert(aEntries.begin(), aEntries.end()); } } @@ -1465,12 +1561,13 @@ void ScInputHandler::UseColData() // beim Tippen xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara ); if ( aSel.nEndPos == nParLen ) { - String aText = GetEditText(pEngine); - if (aText.Len()) + rtl::OUString aText = GetEditText(pEngine); + if (!aText.isEmpty()) { - String aNew; - nAutoPos = SCPOS_INVALID; // nix - if ( pColumnData->FindText( aText, aNew, nAutoPos, false ) ) + rtl::OUString aNew; + miAutoPos = pColumnData->end(); + miAutoPos = findText(*pColumnData, miAutoPos, aText, aNew, false); + if (miAutoPos != pColumnData->end()) { // durch dBase Import etc. koennen Umbrueche im String sein, // das wuerde hier mehrere Absaetze ergeben -> nicht gut @@ -1481,12 +1578,12 @@ void ScInputHandler::UseColData() // beim Tippen //! genaue Ersetzung im EnterHandler !!! // ein Space zwischen Absaetzen: - sal_uLong nEdLen = pEngine->GetTextLen() + nParCnt - 1; - String aIns = aNew.Copy( (xub_StrLen)nEdLen ); + sal_Int32 nEdLen = pEngine->GetTextLen() + nParCnt - 1; + rtl::OUString aIns = aNew.copy(nEdLen); // selection must be "backwards", so the cursor stays behind the last // typed character - ESelection aSelection( aSel.nEndPara, aSel.nEndPos + aIns.Len(), + ESelection aSelection( aSel.nEndPara, aSel.nEndPos + aIns.getLength(), aSel.nEndPara, aSel.nEndPos ); // when editing in input line, apply to both edit views @@ -1503,17 +1600,18 @@ void ScInputHandler::UseColData() // beim Tippen aAutoSearch = aText; // zum Weitersuchen - nAutoPos ist gesetzt - if ( aText.Len() == aNew.Len() ) + if (aText.getLength() == aNew.getLength()) { // Wenn der eingegebene Text gefunden wurde, TAB nur dann // verschlucken, wenn noch etwas kommt - String aDummy; - sal_uInt16 nNextPos = nAutoPos; - bUseTab = pColumnData->FindText( aText, aDummy, nNextPos, false ); + rtl::OUString aDummy; + ScTypedCaseStrSet::const_iterator itNextPos = + findText(*pColumnData, miAutoPos, aText, aDummy, false); + bUseTab = itNextPos != pColumnData->end(); } else - bUseTab = sal_True; + bUseTab = true; } } } @@ -1526,7 +1624,7 @@ void ScInputHandler::NextAutoEntry( sal_Bool bBack ) EditView* pActiveView = pTopView ? pTopView : pTableView; if ( pActiveView && pColumnData ) { - if ( nAutoPos != SCPOS_INVALID && aAutoSearch.Len() ) + if (miAutoPos != pColumnData->end() && !aAutoSearch.isEmpty()) { // stimmt die Selektion noch? (kann per Maus geaendert sein) @@ -1535,18 +1633,19 @@ void ScInputHandler::NextAutoEntry( sal_Bool bBack ) sal_uInt16 nParCnt = pEngine->GetParagraphCount(); if ( aSel.nEndPara+1 == nParCnt && aSel.nStartPara == aSel.nEndPara ) { - String aText = GetEditText(pEngine); + rtl::OUString aText = GetEditText(pEngine); xub_StrLen nSelLen = aSel.nEndPos - aSel.nStartPos; xub_StrLen nParLen = pEngine->GetTextLen( aSel.nEndPara ); - if ( aSel.nEndPos == nParLen && aText.Len() == aAutoSearch.Len() + nSelLen ) + if ( aSel.nEndPos == nParLen && aText.getLength() == aAutoSearch.getLength() + nSelLen ) { - String aNew; - if ( pColumnData->FindText( aAutoSearch, aNew, nAutoPos, bBack ) ) + rtl::OUString aNew; + miAutoPos = findText(*pColumnData, miAutoPos, aAutoSearch, aNew, bBack); + if (miAutoPos != pColumnData->end()) { - bInOwnChange = sal_True; // disable ModifyHdl (reset below) + bInOwnChange = true; // disable ModifyHdl (reset below) lcl_RemoveLineEnd( aNew ); - String aIns = aNew.Copy( aAutoSearch.Len() ); + rtl::OUString aIns = aNew.copy(aAutoSearch.getLength()); // when editing in input line, apply to both edit views if ( pTableView ) @@ -1554,7 +1653,7 @@ void ScInputHandler::NextAutoEntry( sal_Bool bBack ) pTableView->DeleteSelected(); pTableView->InsertText( aIns, false ); pTableView->SetSelection( ESelection( - aSel.nEndPara, aSel.nStartPos + aIns.Len(), + aSel.nEndPara, aSel.nStartPos + aIns.getLength(), aSel.nEndPara, aSel.nStartPos ) ); } if ( pTopView ) @@ -1562,7 +1661,7 @@ void ScInputHandler::NextAutoEntry( sal_Bool bBack ) pTopView->DeleteSelected(); pTopView->InsertText( aIns, false ); pTopView->SetSelection( ESelection( - aSel.nEndPara, aSel.nStartPos + aIns.Len(), + aSel.nEndPara, aSel.nStartPos + aIns.getLength(), aSel.nEndPara, aSel.nStartPos ) ); } @@ -1968,7 +2067,7 @@ bool ScInputHandler::StartTable( sal_Unicode cTyped, bool bFromCommand, bool bIn pEngine->SetText(aCurrentText); aStr = aCurrentText; bTextValid = false; - aCurrentText.Erase(); + aCurrentText = rtl::OUString(); } else aStr = GetEditText(pEngine); @@ -2062,7 +2161,7 @@ IMPL_LINK( ScInputHandler, ModifyHdl, void *, EMPTYARG ) // update input line from ModifyHdl for changes that are not // wrapped by DataChanging/DataChanged calls (like Drag&Drop) - String aText; + rtl::OUString aText; if ( pInputWin->IsMultiLineInput() ) aText = ScEditUtil::GetMultilineString(*pEngine); else @@ -2114,7 +2213,7 @@ void ScInputHandler::DataChanged( sal_Bool bFromTopNotify ) if (eMode==SC_INPUT_TYPE || eMode==SC_INPUT_TABLE) { - String aText; + rtl::OUString aText; if ( pInputWin && pInputWin->IsMultiLineInput() ) aText = ScEditUtil::GetMultilineString(*pEngine); else @@ -2404,11 +2503,11 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode ) sal_Bool bAttrib = false; // Formatierung vorhanden ? sal_Bool bForget = false; // wegen Gueltigkeit streichen ? - String aString = GetEditText(pEngine); + rtl::OUString aString = GetEditText(pEngine); EditView* pActiveView = pTopView ? pTopView : pTableView; - if (bModified && pActiveView && aString.Len() && !lcl_IsNumber(aString)) + if (bModified && pActiveView && !aString.isEmpty() && !lcl_IsNumber(aString)) { - if ( pColumnData && nAutoPos != SCPOS_INVALID ) + if (pColumnData && miAutoPos != pColumnData->end()) { // #i47125# If AutoInput appended something, do the final AutoCorrect // with the cursor at the end of the input. @@ -2609,8 +2708,8 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode ) else if (bAutoComplete) // Gross-/Kleinschreibung anpassen { // Perform case-matching only when the typed text is partial. - if (pColumnData && aAutoSearch.Len() < aString.Len()) - pColumnData->GetExactMatch(aString); + if (pColumnData && aAutoSearch.getLength() < aString.getLength()) + aString = getExactMatch(*pColumnData, aString); } } @@ -2640,12 +2739,12 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode ) DeleteRangeFinder(); ResetAutoPar(); - sal_Bool bOldMod = bModified; + bool bOldMod = bModified; bModified = false; bSelIsRef = false; eMode = SC_INPUT_NONE; - StopInputWinEngine( sal_True ); + StopInputWinEngine(true); // Text input (through number formats) or ApplySelectionPattern modify // the cell's attributes, so pLastPattern is no longer valid @@ -2655,34 +2754,34 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode ) { // keine typographische Anfuehrungszeichen in Formeln - if ( aString.GetChar(0) == '=' ) + if (aString.getStr()[0] == '=') { SvxAutoCorrect* pAuto = SvxAutoCorrCfg::Get().GetAutoCorrect(); if ( pAuto ) { - sal_Unicode cReplace = pAuto->GetStartDoubleQuote(); - if( !cReplace ) - cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkStart().GetChar(0); - if ( cReplace != '"' ) - aString.SearchAndReplaceAll( cReplace, '"' ); - - cReplace = pAuto->GetEndDoubleQuote(); - if( !cReplace ) - cReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkEnd().GetChar(0); - if ( cReplace != '"' ) - aString.SearchAndReplaceAll( cReplace, '"' ); - - cReplace = pAuto->GetStartSingleQuote(); - if( !cReplace ) - cReplace = ScGlobal::pLocaleData->getQuotationMarkStart().GetChar(0); - if ( cReplace != '\'' ) - aString.SearchAndReplaceAll( cReplace, '\'' ); - - cReplace = pAuto->GetEndSingleQuote(); - if( !cReplace ) - cReplace = ScGlobal::pLocaleData->getQuotationMarkEnd().GetChar(0); - if ( cReplace != '\'' ) - aString.SearchAndReplaceAll( cReplace, '\'' ); + rtl::OUString aReplace(pAuto->GetStartDoubleQuote()); + if (aReplace.isEmpty()) + aReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkStart(); + if (!aReplace.equalsAsciiL("\"", 1)) + aString = comphelper::string::replace(aString, aReplace, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\""))); + + aReplace = rtl::OUString(pAuto->GetEndDoubleQuote()); + if (aReplace.isEmpty()) + aReplace = ScGlobal::pLocaleData->getDoubleQuotationMarkEnd(); + if (!aReplace.equalsAsciiL("\"", 1)) + aString = comphelper::string::replace(aString, aReplace, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\""))); + + aReplace = rtl::OUString(pAuto->GetStartSingleQuote()); + if (aReplace.isEmpty()) + aReplace = ScGlobal::pLocaleData->getQuotationMarkStart(); + if (!aReplace.equalsAsciiL("'", 1)) + aString = comphelper::string::replace(aString, aReplace, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("'"))); + + aReplace = rtl::OUString(pAuto->GetEndSingleQuote()); + if (aReplace.isEmpty()) + aReplace = ScGlobal::pLocaleData->getQuotationMarkEnd(); + if (!aReplace.equalsAsciiL("'", 1)) + aString = comphelper::string::replace(aString, aReplace, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("'"))); } } @@ -3021,7 +3120,7 @@ sal_Bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, sal_Bool bStartEdit /* case KEY_RETURN: if (bControl && !bShift && ( !bInputLine || ( pInputWin && pInputWin->IsMultiLineInput() ) ) ) bDoEnter = sal_True; - else if ( nModi == 0 && nTipVisible && pFormulaData && nAutoPos != SCPOS_INVALID ) + else if (nModi == 0 && nTipVisible && pFormulaData && miAutoPos != pFormulaData->end()) { PasteFunctionData(); bUsed = sal_True; @@ -3049,14 +3148,14 @@ sal_Bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, sal_Bool bStartEdit /* case KEY_TAB: if (bControl && !bAlt) { - if ( pFormulaData && nTipVisible && nAutoPos != SCPOS_INVALID ) + if (pFormulaData && nTipVisible && miAutoPos != pFormulaData->end()) { // blaettern NextFormulaEntry( bShift ); bUsed = true; } - else if ( pColumnData && bUseTab && nAutoPos != SCPOS_INVALID ) + else if (pColumnData && bUseTab && miAutoPos != pColumnData->end()) { // in den Eintraegen der AutoEingabe blaettern @@ -3183,7 +3282,10 @@ sal_Bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, sal_Bool bStartEdit /* if ( bUsed && bAutoComplete ) { bUseTab = false; - nAutoPos = SCPOS_INVALID; // do not search further + if (pFormulaData) + miAutoPos = pFormulaData->end(); // do not search further + else if (pColumnData) + miAutoPos = pColumnData->end(); KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction(); if ( nChar && nChar != 8 && nChar != 127 && // no 'backspace', no 'delete' @@ -3307,7 +3409,11 @@ sal_Bool ScInputHandler::InputCommand( const CommandEvent& rCEvt, sal_Bool bForc { // AutoInput after ext text input - nAutoPos = SCPOS_INVALID; + if (pFormulaData) + miAutoPos = pFormulaData->end(); + else if (pColumnData) + miAutoPos = pColumnData->end(); + if (bFormulaMode) UseFormulaData(); else @@ -3392,7 +3498,7 @@ void ScInputHandler::NotifyChange( const ScInputHdlState* pState, const ScAddress& rSPos = pState->GetStartPos(); const ScAddress& rEPos = pState->GetEndPos(); const EditTextObject* pData = pState->GetEditData(); - String aString = pState->GetString(); + rtl::OUString aString = pState->GetString(); sal_Bool bTxtMod = false; ScDocShell* pDocSh = pActiveViewSh->GetViewData()->GetDocShell(); ScDocument* pDoc = pDocSh->GetDocument(); @@ -3404,9 +3510,9 @@ void ScInputHandler::NotifyChange( const ScInputHdlState* pState, else if ( bHadObject ) bTxtMod = sal_True; else if ( bTextValid ) - bTxtMod = ( aString != aCurrentText ); + bTxtMod = ( !aString.equals(aCurrentText) ); else - bTxtMod = ( aString != GetEditText(pEngine) ); + bTxtMod = ( !aString.equals(GetEditText(pEngine)) ); if ( bTxtMod || bForce ) { @@ -3419,12 +3525,12 @@ void ScInputHandler::NotifyChange( const ScInputHdlState* pState, aString = GetEditText(pEngine); lcl_RemoveTabs(aString); bTextValid = false; - aCurrentText.Erase(); + aCurrentText = rtl::OUString(); } else { aCurrentText = aString; - bTextValid = sal_True; //! erst nur als String merken + bTextValid = true; //! erst nur als String merken } if ( pInputWin ) @@ -3621,12 +3727,12 @@ void ScInputHandler::InputChanged( EditView* pView, sal_Bool bFromNotify ) SyncViews( pView ); } -const String& ScInputHandler::GetEditString() +const rtl::OUString& ScInputHandler::GetEditString() { if (pEngine) { aCurrentText = pEngine->GetText(); // immer neu aus Engine - bTextValid = sal_True; + bTextValid = true; } return aCurrentText; diff --git a/sc/source/ui/dbgui/filtdlg.cxx b/sc/source/ui/dbgui/filtdlg.cxx index 2bb76ea98aaa..8cfa8986f4e3 100644 --- a/sc/source/ui/dbgui/filtdlg.cxx +++ b/sc/source/ui/dbgui/filtdlg.cxx @@ -67,7 +67,6 @@ using ::rtl::OUStringBuffer; #define INVALID_HEADER_POS std::numeric_limits<size_t>::max() ScFilterDlg::EntryList::EntryList() : - maList(128, 128), mnHeaderPos(INVALID_HEADER_POS) {} ScFilterDlg::ScFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, @@ -500,11 +499,10 @@ void ScFilterDlg::FillFieldLists() } } - -//---------------------------------------------------------------------------- - void ScFilterDlg::UpdateValueList( size_t nList ) { + bool bCaseSens = aBtnCase.IsChecked(); + if (pDoc && nList > 0 && nList <= QUERY_ENTRY_COUNT) { ComboBox* pValList = maValueEdArr[nList-1]; @@ -541,44 +539,51 @@ void ScFilterDlg::UpdateValueList( size_t nList ) return; pList = r.first->second; - pList->maList.SetCaseSensitive(aBtnCase.IsChecked()); - pDoc->GetFilterEntriesArea( nColumn, nFirstRow+1, nLastRow, - nTab, pList->maList, maHasDates[nOffset+nList-1] ); + pDoc->GetFilterEntriesArea( + nColumn, nFirstRow+1, nLastRow, + nTab, bCaseSens, pList->maList, maHasDates[nOffset+nList-1] ); // Entry for the first line //! Entry (pHdrEntry) doesn't generate collection? pList->mnHeaderPos = INVALID_HEADER_POS; - TypedScStrCollection aHdrColl( 1, 1 ); + std::vector<TypedStrData> aHdrColl; bool bDummy = false; - pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nFirstRow, - nTab, aHdrColl, bDummy ); - TypedStrData* pHdrEntry = aHdrColl[0]; - if ( pHdrEntry ) + pDoc->GetFilterEntriesArea( + nColumn, nFirstRow, nFirstRow, nTab, true, aHdrColl, bDummy ); + if (!aHdrColl.empty()) { - TypedStrData* pNewEntry = new TypedStrData(*pHdrEntry); - if ( pList->maList.Insert(pNewEntry) ) + // See if the header value is already in the list. + std::vector<TypedStrData>::iterator itBeg = pList->maList.begin(), itEnd = pList->maList.end(); + std::vector<TypedStrData>::iterator it = std::find_if( + itBeg, itEnd, FindTypedStrData(aHdrColl.front(), bCaseSens)); + if (it == itEnd) { - pList->mnHeaderPos = pList->maList.IndexOf(pNewEntry); - OSL_ENSURE( pList->mnHeaderPos != INVALID_HEADER_POS, - "Header-Eintrag nicht wiedergefunden" ); + // Not in the list. Insert it. + pList->maList.push_back(aHdrColl.front()); + if (bCaseSens) + std::sort(pList->maList.begin(), pList->maList.end(), TypedStrData::LessCaseSensitive()); + else + std::sort(pList->maList.begin(), pList->maList.end(), TypedStrData::LessCaseInsensitive()); + + // Record its position. + itBeg = pList->maList.begin(); + itEnd = pList->maList.end(); + it = std::find_if(itBeg, itEnd, FindTypedStrData(aHdrColl.front(), bCaseSens)); + pList->mnHeaderPos = std::distance(itBeg, it); } - else - delete pNewEntry; // was already there } } else pList = &maEntryLists[nColumn]; OSL_ASSERT(pList); - sal_uInt16 nValueCount = pList->maList.GetCount(); - if ( nValueCount > 0 ) + + std::vector<TypedStrData>::const_iterator it = pList->maList.begin(), itEnd = pList->maList.end(); + for (; it != itEnd; ++it) { - for ( sal_uInt16 i=0; i<nValueCount; i++ ) - { - pValList->InsertEntry(pList->maList[i]->GetString(), nListPos); - nListPos++; - } + pValList->InsertEntry(it->GetString(), nListPos); + nListPos++; } } pValList->SetText( aCurValue ); @@ -616,14 +621,9 @@ void ScFilterDlg::UpdateHdrInValueList( size_t nList ) ComboBox* pValList = maValueEdArr[nList-1]; size_t nListPos = nPos + 2; // for "empty" and "non-empty" - TypedStrData* pHdrEntry = maEntryLists[nColumn].maList[nPos]; - if (!pHdrEntry) - { - OSL_FAIL("Eintag in Liste nicht gefunden"); - return; - } + const TypedStrData& rHdrEntry = maEntryLists[nColumn].maList[nPos]; - rtl::OUString aHdrStr = pHdrEntry->GetString(); + const rtl::OUString& aHdrStr = rHdrEntry.GetString(); bool bWasThere = aHdrStr.equals(pValList->GetEntry(nListPos)); bool bInclude = !aBtnHeader.IsChecked(); diff --git a/sc/source/ui/dbgui/pfiltdlg.cxx b/sc/source/ui/dbgui/pfiltdlg.cxx index 14f1cf29f499..fdfc7f273657 100644 --- a/sc/source/ui/dbgui/pfiltdlg.cxx +++ b/sc/source/ui/dbgui/pfiltdlg.cxx @@ -346,22 +346,18 @@ void ScPivotFilterDlg::UpdateValueList( sal_uInt16 nList ) SCROW nLastRow = theQueryData.nRow2; nFirstRow++; bool bHasDates = false; - - pEntryLists[nColumn] = new TypedScStrCollection( 128, 128 ); - pEntryLists[nColumn]->SetCaseSensitive( aBtnCase.IsChecked() ); - pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nLastRow, - nTab, *pEntryLists[nColumn], bHasDates ); + bool bCaseSens = aBtnCase.IsChecked(); + pEntryLists[nColumn] = new std::vector<TypedStrData>; + pDoc->GetFilterEntriesArea( + nColumn, nFirstRow, nLastRow, nTab, bCaseSens, *pEntryLists[nColumn], bHasDates); } - TypedScStrCollection* pColl = pEntryLists[nColumn]; - sal_uInt16 nValueCount = pColl->GetCount(); - if ( nValueCount > 0 ) + std::vector<TypedStrData>* pColl = pEntryLists[nColumn]; + std::vector<TypedStrData>::const_iterator it = pColl->begin(), itEnd = pColl->end(); + for (; it != itEnd; ++it) { - for ( sal_uInt16 i=0; i<nValueCount; i++ ) - { - pValList->InsertEntry( (*pColl)[i]->GetString(), nListPos ); - nListPos++; - } + pValList->InsertEntry(it->GetString(), nListPos); + nListPos++; } } pValList->SetText( aCurValue ); diff --git a/sc/source/ui/formdlg/dwfunctr.cxx b/sc/source/ui/formdlg/dwfunctr.cxx index 45ec35ad9057..357bdc037f9c 100644 --- a/sc/source/ui/formdlg/dwfunctr.cxx +++ b/sc/source/ui/formdlg/dwfunctr.cxx @@ -899,7 +899,7 @@ void ScFunctionDockWin::DoEnter(sal_Bool /* bOk */) //@@ ??? } if (pHdl) { - if(pHdl->GetEditString().Len()==0) + if (pHdl->GetEditString().isEmpty()) { aString = '='; aString += pAllFuncList->GetSelectEntry(); diff --git a/sc/source/ui/inc/filtdlg.hxx b/sc/source/ui/inc/filtdlg.hxx index e62ca411614a..71dcee4e4155 100644 --- a/sc/source/ui/inc/filtdlg.hxx +++ b/sc/source/ui/inc/filtdlg.hxx @@ -44,6 +44,7 @@ #include <map> #include <boost/ptr_container/ptr_map.hpp> #include <boost/noncopyable.hpp> +#include <boost/scoped_ptr.hpp> //---------------------------------------------------------------------------- @@ -57,7 +58,7 @@ class ScFilterDlg : public ScAnyRefDlg { struct EntryList : boost::noncopyable { - TypedScStrCollection maList; + std::vector<TypedStrData> maList; size_t mnHeaderPos; EntryList(); }; diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx index 76c4daca74cc..e27891a515da 100644 --- a/sc/source/ui/inc/inputhdl.hxx +++ b/sc/source/ui/inc/inputhdl.hxx @@ -31,10 +31,14 @@ #include "global.hxx" #include "address.hxx" +#include "types.hxx" + #include <tools/fract.hxx> #include <tools/gen.hxx> #include <editeng/svxenum.hxx> +#include <set> + class ScDocument; class ScTabView; class ScTabViewShell; @@ -45,7 +49,7 @@ class ScEditEngineDefaulter; class EditView; class EditTextObject; class ScInputHdlState; -class TypedScStrCollection; +class TypedStrData; class ScRangeFindList; class Timer; class KeyEvent; @@ -66,20 +70,21 @@ private: EditView* pTableView; // aktive EditView dazu EditView* pTopView; // EditView in der Eingabezeile - TypedScStrCollection* pColumnData; - TypedScStrCollection* pFormulaData; - TypedScStrCollection* pFormulaDataPara; + ScTypedCaseStrSet* pColumnData; + ScTypedCaseStrSet* pFormulaData; + ScTypedCaseStrSet* pFormulaDataPara; + ScTypedCaseStrSet::const_iterator miAutoPos; + Window* pTipVisibleParent; sal_uLong nTipVisible; Window* pTipVisibleSecParent; sal_uLong nTipVisibleSec; String aManualTip; - String aAutoSearch; - sal_uInt16 nAutoPos; + rtl::OUString aAutoSearch; sal_Bool bUseTab; // Blaettern moeglich sal_Bool bTextValid; // Text noch nicht in Edit-Engine - String aCurrentText; + rtl::OUString aCurrentText; String aFormText; // fuer Funktions-Autopilot xub_StrLen nFormSelStart; // Selektion fuer Funktions-Autopilot @@ -173,7 +178,7 @@ public: eMode != SC_INPUT_TYPE); } sal_Bool IsTopMode() const { return (eMode == SC_INPUT_TOP); } - const String& GetEditString(); + const rtl::OUString& GetEditString(); const String& GetFormString() const { return aFormText; } const ScAddress& GetCursorPos() const { return aCursorPos; } diff --git a/sc/source/ui/inc/pfiltdlg.hxx b/sc/source/ui/inc/pfiltdlg.hxx index 7953cab4b0f9..b9cd841d3d47 100644 --- a/sc/source/ui/inc/pfiltdlg.hxx +++ b/sc/source/ui/inc/pfiltdlg.hxx @@ -44,7 +44,7 @@ class ScViewData; class ScDocument; class ScQueryItem; -class TypedScStrCollection; +class TypedStrData; //================================================================== @@ -108,7 +108,7 @@ private: ListBox* aFieldLbArr[3]; ListBox* aCondLbArr[3]; - TypedScStrCollection* pEntryLists[MAXCOLCOUNT]; + std::vector<TypedStrData>* pEntryLists[MAXCOLCOUNT]; #ifdef _PFILTDLG_CXX private: diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 51569dcafa19..e5405b9eef3f 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -137,6 +137,8 @@ #include <vcl/svapp.hxx> #include <svx/sdr/overlay/overlayselection.hxx> +#include <vector> + using namespace com::sun::star; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; @@ -688,14 +690,14 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow) // Populate the check box list. bool bHasDates = false; - TypedScStrCollection aStrings(128, 128); + std::vector<TypedStrData> aStrings; pDoc->GetFilterEntries(nCol, nRow, nTab, true, aStrings, bHasDates); - sal_uInt16 nCount = aStrings.GetCount(); - mpAutoFilterPopup->setMemberSize(nCount); - for (sal_uInt16 i = 0; i < nCount; ++i) + mpAutoFilterPopup->setMemberSize(aStrings.size()); + std::vector<TypedStrData>::const_iterator it = aStrings.begin(), itEnd = aStrings.end(); + for (; it != itEnd; ++it) { - rtl::OUString aVal = aStrings[i]->GetString(); + const rtl::OUString& aVal = it->GetString(); bool bSelected = true; if (!aSelected.empty()) bSelected = aSelected.count(aVal) > 0; @@ -825,7 +827,6 @@ void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) delete pFilterBox; delete pFilterFloat; - sal_uInt16 i; ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); @@ -864,7 +865,7 @@ void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) // SetSize comes later - TypedScStrCollection aStrings( 128, 128 ); + std::vector<rtl::OUString> aStrings; // get list box entries and selection sal_Bool bHasCurrentPage = false; @@ -898,18 +899,19 @@ void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) // include all entry widths for the size of the drop-down long nMaxText = 0; - sal_uInt16 nCount = aStrings.GetCount(); - for (i=0; i<nCount; i++) { - TypedStrData* pData = aStrings[i]; - long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() ); - if ( nTextWidth > nMaxText ) - nMaxText = nTextWidth; + std::vector<rtl::OUString>::const_iterator it = aStrings.begin(), itEnd = aStrings.end(); + for (; it != itEnd; ++it) + { + long nTextWidth = pFilterBox->GetTextWidth(*it); + if ( nTextWidth > nMaxText ) + nMaxText = nTextWidth; + } } // add scrollbar width if needed (string entries are counted here) // (scrollbar is shown if the box is exactly full?) - if ( nCount >= SC_FILTERLISTBOX_LINES ) + if (aStrings.size() >= SC_FILTERLISTBOX_LINES) nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); nMaxText += 4; // for borders @@ -935,20 +937,23 @@ void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS); // fill the list box - sal_Bool bWait = ( nCount > 100 ); + bool bWait = aStrings.size() > 100; if (bWait) EnterWait(); - for (i=0; i<nCount; i++) - pFilterBox->InsertEntry( aStrings[i]->GetString() ); + { + std::vector<rtl::OUString>::const_iterator it = aStrings.begin(), itEnd = aStrings.end(); + for (; it != itEnd; ++it) + pFilterBox->InsertEntry(*it); + } pFilterBox->SetSeparatorPos( 0 ); if (bWait) LeaveWait(); - pFilterBox->SetUpdateMode(sal_True); + pFilterBox->SetUpdateMode(true); sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND; if (bHasCurrentPage) @@ -1114,12 +1119,6 @@ void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange ) CaptureMouse(); } -namespace { - - - -} - void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelect ) { delete pFilterBox; @@ -1165,15 +1164,14 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelec // SetSize spaeter - sal_Bool bEmpty = false; - TypedScStrCollection aStrings( 128, 128 ); + bool bEmpty = false; + std::vector<TypedStrData> aStrings; // case sensitive if ( bDataSelect ) // Auswahl-Liste { // Liste fuellen - aStrings.SetCaseSensitive( sal_True ); - pDoc->GetDataEntries( nCol, nRow, nTab, aStrings ); - if ( aStrings.GetCount() == 0 ) - bEmpty = sal_True; + pDoc->GetDataEntries(nCol, nRow, nTab, true, aStrings); + if (aStrings.empty()) + bEmpty = true; } else // AutoFilter { @@ -1186,7 +1184,7 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelec // default entries static const sal_uInt16 nDefIDs[] = { SCSTR_ALLFILTER, SCSTR_TOP10FILTER, SCSTR_STDFILTER, SCSTR_EMPTY, SCSTR_NOTEMPTY }; - const sal_uInt16 nDefCount = SAL_N_ELEMENTS(nDefIDs); + const size_t nDefCount = SAL_N_ELEMENTS(nDefIDs); for (i=0; i<nDefCount; i++) { String aEntry( (ScResId) nDefIDs[i] ); @@ -1204,13 +1202,12 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelec // check widths of numerical entries (string entries are not included) // so all numbers are completely visible - sal_uInt16 nCount = aStrings.GetCount(); - for (i=0; i<nCount; i++) + std::vector<TypedStrData>::const_iterator it = aStrings.begin(), itEnd = aStrings.end(); + for (; it != itEnd; ++it) { - TypedStrData* pData = aStrings[i]; - if ( !pData->IsStrData() ) // only numerical entries + if (!it->IsStrData()) // only numerical entries { - long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() ); + long nTextWidth = pFilterBox->GetTextWidth(it->GetString()); if ( nTextWidth > nMaxText ) nMaxText = nTextWidth; } @@ -1218,7 +1215,7 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelec // add scrollbar width if needed (string entries are counted here) // (scrollbar is shown if the box is exactly full?) - if ( nCount + nDefCount >= SC_FILTERLISTBOX_LINES ) + if (aStrings.size() + nDefCount >= SC_FILTERLISTBOX_LINES) nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize(); nMaxText += 4; // for borders @@ -1248,19 +1245,19 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelec pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS); // Listbox fuellen - sal_uInt16 nCount = aStrings.GetCount(); - sal_Bool bWait = ( nCount > 100 ); + bool bWait = aStrings.size() > 100; if (bWait) EnterWait(); - for (i=0; i<nCount; i++) - pFilterBox->InsertEntry( aStrings[i]->GetString() ); + std::vector<TypedStrData>::const_iterator it = aStrings.begin(), itEnd = aStrings.end(); + for (; it != itEnd; ++it) + pFilterBox->InsertEntry(it->GetString()); if (bWait) LeaveWait(); - pFilterBox->SetUpdateMode(sal_True); + pFilterBox->SetUpdateMode(true); } sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND; @@ -1329,17 +1326,22 @@ void ScGridWindow::LaunchDataSelectMenu( SCCOL nCol, SCROW nRow, bool bDataSelec bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING); if ( bSortList ) { - sal_uInt16 nStrIndex; - if (aStrings.Search(pNew,nStrIndex)) - nSelPos = nStrIndex; + std::vector<TypedStrData>::const_iterator itBeg = aStrings.begin(), itEnd = aStrings.end(); + std::vector<TypedStrData>::const_iterator it = + std::find_if(itBeg, itEnd, FindTypedStrData(*pNew, true)); + if (it != itEnd) + // Found! + nSelPos = std::distance(itBeg, it); } else { - sal_uInt16 nCount = aStrings.GetCount(); - for (i = 0; ((i < nCount) && ( LISTBOX_ENTRY_NOTFOUND == nSelPos)); i++) + TypedStrData::EqualCaseSensitive aHdl; + std::vector<TypedStrData>::const_iterator itBeg = aStrings.begin(), itEnd = aStrings.end(); + std::vector<TypedStrData>::const_iterator it = itBeg; + for (; it != itEnd && LISTBOX_ENTRY_NOTFOUND == nSelPos; ++it) { - if ( aStrings.Compare(aStrings[i], pNew)==0 ) - nSelPos = i; + if (aHdl(*it, *pNew)) + nSelPos = std::distance(itBeg, it); } } delete pNew; |