Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


Hi,

This patch converts a SvStringsISortDtor to a vector and maintains equivalent functionality.

Instead of sorting strings upon each insertion all strings are now added and then a single sort and "unique" are applied (SvStringsISortDtor behaves like a SET with regards to insertion, which is why "unique" is applied). SwEditWin::ShowAutoTextCorrectQuickHelp() is the only place where strings are added to the vector.

The change in behaviour from keeping the first inserted version of a string to keeping the first version post-sort (case-insensitive ASCII comparison) should have no material impact as the strings retrieved from SwAutoCompleteWord are already unique (case-insensitive ASCII comparison) and the capitalization of the string is generally changed anyway to match the capitalization of the word to be auto-completed. Also, there appears to be no logical reason to store the first inserted version of a string over the first version post-sort.

* In previous patches that I've seen on the list it appears ok to convert a vector of String pointers to simply a vector of String values so I've done the same. * I used a pointer to the vector as the move() function previously copied and cleared all elements whereas a pointer swap would suffice. * I've put a TODO in the code to replace the ASCII only case-insensitive sort (existing limitation).

- make + make dev-install successful
- functionality tested ok
- licence statement on file

Cheers,
Brad

From ddf05af3c0614c9565c42cf87b43722523703eac Mon Sep 17 00:00:00 2001
From: Brad Sowden <code@sowden.org>
Date: Sat, 2 Jun 2012 19:09:43 +1200
Subject: [PATCH 1/2] Replace SvStringsISortDtor in edtwin.cxx and
 gloslst.[ch]xx

Note that the replacement vector stores all strings first and then
sort and "unique" are applied (ASCII treated as case-insensitive).
Previously strings were inserted sequentially and only the first
version of a string would be stored (case-insensitive ASCII
comparision). This should have no material impact as the strings
retreived from SwAutoCompleteWord are already unique (case-
insensitive ASCII comparison) and the capitalization of the string
is generally changed anyway to match the capitalization of the word
to be auto-completed. Also, there appears to be no logical reason
to store the first inserted version of a string over of the first
version post-sort.

Change-Id: I132865bbb9b382d417fb2cff9de351fdb2cbfb13
---
 sw/source/ui/docvw/edtwin.cxx  |  100 +++++++++++++++++++++++++++------------
 sw/source/ui/inc/gloslst.hxx   |    5 +-
 sw/source/ui/utlui/gloslst.cxx |    6 +--
 3 files changed, 73 insertions(+), 38 deletions(-)

diff --git a/sw/source/ui/docvw/edtwin.cxx b/sw/source/ui/docvw/edtwin.cxx
index 6d5cc4f..dca8219 100644
--- a/sw/source/ui/docvw/edtwin.cxx
+++ b/sw/source/ui/docvw/edtwin.cxx
@@ -143,6 +143,7 @@
 #include <PostItMgr.hxx>
 
 #include <algorithm>
+#include <vector>
 
 #include "../../core/inc/rootfrm.hxx"
 
@@ -271,33 +272,39 @@ public:
 
 struct QuickHelpData
 {
-    SvStringsISortDtor aArr;
+    std::vector<String> *pHelpStrings;
     sal_uInt16* pAttrs;
     CommandExtTextInputData* pCETID;
     sal_uLong nTipId;
     sal_uInt16 nLen, nCurArrPos;
     sal_Bool bClear : 1, bChkInsBlank : 1, bIsTip : 1, bIsAutoText : 1;
 
-    QuickHelpData() : pAttrs( 0 ), pCETID( 0 )  { ClearCntnt(); }
+    QuickHelpData() : pAttrs( 0 ), pCETID( 0 )
+    {
+        pHelpStrings = new std::vector<String>;
+        ClearCntnt();
+    }
+    ~QuickHelpData() { delete pHelpStrings; }
 
     void Move( QuickHelpData& rCpy );
     void ClearCntnt();
     void Start( SwWrtShell& rSh, sal_uInt16 nWrdLen );
     void Stop( SwWrtShell& rSh );
 
-    sal_Bool HasCntnt() const       { return aArr.Count() && 0 != nLen; }
+    sal_Bool HasCntnt() const { return !pHelpStrings->empty() && 0 != nLen; }
 
     void Inc( sal_Bool bEndLess )
-        {
-            if( ++nCurArrPos >= aArr.Count() )
-                nCurArrPos = (bEndLess && !bIsAutoText )? 0 : nCurArrPos-1;
-        }
+    {
+        if( ++nCurArrPos >= pHelpStrings->size() )
+            nCurArrPos = (bEndLess && !bIsAutoText ) ? 0 : nCurArrPos-1;
+    }
     void Dec( sal_Bool bEndLess )
-        {
-            if( 0 == nCurArrPos-- )
-                nCurArrPos = (bEndLess && !bIsAutoText ) ? aArr.Count()-1 : 0;
-        }
+    {
+        if( 0 == nCurArrPos-- )
+            nCurArrPos = (bEndLess && !bIsAutoText ) ?  pHelpStrings->size()-1 : 0;
+    }
     void FillStrArr( SwWrtShell& rSh, const String& rWord );
+    void SortAndFilter();
 };
 
 /*--------------------------------------------------------------------
@@ -2468,7 +2475,7 @@ KEYINPUT_CHECKTABLE_INSDEL:
                 // replace the word or abbreviation with the auto text
                 rSh.StartUndo( UNDO_START );
 
-                String sFnd( *aTmpQHD.aArr[ aTmpQHD.nCurArrPos ] );
+                String sFnd( (*aTmpQHD.pHelpStrings)[ aTmpQHD.nCurArrPos ] );
                 if( aTmpQHD.bIsAutoText )
                 {
                     SwGlossaryList* pList = ::GetGlossaryList();
@@ -5464,9 +5471,9 @@ uno::Reference< ::com::sun::star::accessibility::XAccessible > 
SwEditWin::Create
 
 void QuickHelpData::Move( QuickHelpData& rCpy )
 {
-    // move pointer
-    aArr.Insert( &rCpy.aArr );
-    rCpy.aArr.Remove( (sal_uInt16)0, rCpy.aArr.Count() );
+    pHelpStrings->clear();
+    std::swap( pHelpStrings, rCpy.pHelpStrings );
+
     bClear = rCpy.bClear;
     nLen = rCpy.nLen;
     nCurArrPos = rCpy.nCurArrPos;
@@ -5478,8 +5485,7 @@ void QuickHelpData::Move( QuickHelpData& rCpy )
     pCETID = rCpy.pCETID;
     rCpy.pCETID = 0;
 
-    if( pAttrs )
-        delete[] pAttrs;
+    delete[] pAttrs;
     pAttrs = rCpy.pAttrs;
     rCpy.pAttrs = 0;
 }
@@ -5489,7 +5495,7 @@ void QuickHelpData::ClearCntnt()
     nLen = nCurArrPos = 0;
     bClear = bChkInsBlank = sal_False;
     nTipId = 0;
-    aArr.DeleteAndDestroy( 0 , aArr.Count() );
+    pHelpStrings->clear();
     bIsTip = sal_True;
     bIsAutoText = sal_True;
     delete pCETID, pCETID = 0;
@@ -5498,8 +5504,11 @@ void QuickHelpData::ClearCntnt()
 
 void QuickHelpData::Start( SwWrtShell& rSh, sal_uInt16 nWrdLen )
 {
-    if( pCETID ) delete pCETID, pCETID = 0;
-    if( pAttrs ) delete[] pAttrs, pAttrs = 0;
+    delete pCETID;
+    pCETID = 0;
+
+    delete[] pAttrs;
+    pAttrs = 0;
 
     if( USHRT_MAX != nWrdLen )
     {
@@ -5515,12 +5524,12 @@ void QuickHelpData::Start( SwWrtShell& rSh, sal_uInt16 nWrdLen )
                     rSh.GetCharRect().Pos() )));
         aPt.Y() -= 3;
         nTipId = Help::ShowTip( &rWin, Rectangle( aPt, Size( 1, 1 )),
-                        *aArr[ nCurArrPos ],
+                        (*pHelpStrings)[ nCurArrPos ],
                         QUICKHELP_LEFT | QUICKHELP_BOTTOM );
     }
     else
     {
-        String sStr( *aArr[ nCurArrPos ] );
+        String sStr( (*pHelpStrings)[ nCurArrPos ] );
         sStr.Erase( 0, nLen );
         sal_uInt16 nL = sStr.Len();
         pAttrs = new sal_uInt16[ nL ];
@@ -5573,9 +5582,7 @@ void QuickHelpData::FillStrArr( SwWrtShell& rSh, const String& rWord )
                     COMPARE_EQUAL == rWord.CompareIgnoreCaseToAscii(
                                         sStr, rWord.Len() ))
                 {
-                    String* pNew = new String( sStr );
-                    if( !aArr.Insert( pNew ) )
-                        delete pNew;
+                    pHelpStrings->push_back( sStr );
                 }
             }
             if( !n )                    // get data for the second loop
@@ -5616,15 +5623,42 @@ void QuickHelpData::FillStrArr( SwWrtShell& rSh, const String& rWord )
                 else // mixed case - use what we have
                     aMatch = rS;
 
-                String *pNew = new String( aMatch );
-                if (!aArr.Insert( pNew ))
-                    delete pNew;
+                pHelpStrings->push_back( aMatch );
             }
             ++nStt;
         }
     }
 }
 
+// TODO - implement an i18n aware sort
+void QuickHelpData::SortAndFilter()
+{
+    struct CompareIgnoreCaseAscii
+    {
+        bool operator()(const String& s1, const String& s2) const
+        {
+            return s1.CompareIgnoreCaseToAscii(s2) == COMPARE_LESS;
+        }
+    };
+    std::sort( pHelpStrings->begin(),
+               pHelpStrings->end(),
+               CompareIgnoreCaseAscii() );
+
+    struct EqualIgnoreCaseAscii
+    {
+        bool operator()(const String& s1, const String& s2) const
+        {
+            return s1.CompareIgnoreCaseToAscii(s2) == COMPARE_EQUAL;
+        }
+    };
+    std::vector<String>::iterator it = std::unique( pHelpStrings->begin(),
+                                                    pHelpStrings->end(),
+                                                    EqualIgnoreCaseAscii() );
+    pHelpStrings->erase( it, pHelpStrings->end() );
+
+    nCurArrPos = 0;
+}
+
 void SwEditWin::ShowAutoTextCorrectQuickHelp(
         const String& rWord, SvxAutoCorrCfg* pACfg, SvxAutoCorrect* pACorr,
         sal_Bool bFromIME )
@@ -5634,10 +5668,10 @@ void SwEditWin::ShowAutoTextCorrectQuickHelp(
     if( pACfg->IsAutoTextTip() )
     {
         SwGlossaryList* pList = ::GetGlossaryList();
-        pList->HasLongName( rWord, &pQuickHlpData->aArr );
+        pList->HasLongName( rWord, pQuickHlpData->pHelpStrings );
     }
 
-    if( pQuickHlpData->aArr.Count() )
+    if( !pQuickHlpData->pHelpStrings->empty() )
     {
         pQuickHlpData->bIsTip = sal_True;
         pQuickHlpData->bIsAutoText = sal_True;
@@ -5652,8 +5686,12 @@ void SwEditWin::ShowAutoTextCorrectQuickHelp(
         pQuickHlpData->FillStrArr( rSh, rWord );
     }
 
-    if( pQuickHlpData->aArr.Count() )
+
+    if( !pQuickHlpData->pHelpStrings->empty() )
+    {
+        pQuickHlpData->SortAndFilter();
         pQuickHlpData->Start( rSh, rWord.Len() );
+    }
 }
 
 void SwEditWin::ShowHeaderFooterSeparator( bool bShowHeader, bool bShowFooter )
diff --git a/sw/source/ui/inc/gloslst.hxx b/sw/source/ui/inc/gloslst.hxx
index 66ed6d7..f10cb7b 100644
--- a/sw/source/ui/inc/gloslst.hxx
+++ b/sw/source/ui/inc/gloslst.hxx
@@ -33,10 +33,9 @@
 #include <tools/datetime.hxx>
 #include <tools/string.hxx>
 #include <vcl/timer.hxx>
-#include <svl/svarray.hxx>
 
 class SwGlossaries;
-class SvStringsISortDtor;
+class vector;
 
 struct AutoTextGroup
 {
@@ -66,7 +65,7 @@ public:
         SwGlossaryList();
         ~SwGlossaryList();
 
-    sal_Bool            HasLongName(const String& rBegin, SvStringsISortDtor* pLongNames );
+    bool HasLongName(const String& rBegin, std::vector<String> *pLongNames);
     sal_Bool            GetShortName(const String& rLongName,
                                         String& rShortName, String& rGroupName );
 
diff --git a/sw/source/ui/utlui/gloslst.cxx b/sw/source/ui/utlui/gloslst.cxx
index f5be64a..9203000 100644
--- a/sw/source/ui/utlui/gloslst.cxx
+++ b/sw/source/ui/utlui/gloslst.cxx
@@ -26,7 +26,6 @@
  *
  ************************************************************************/
 
-#include <svl/svstdarr.hxx>
 #include <tools/urlobj.hxx>
 #include <vcl/dialog.hxx>
 #include <vcl/msgbox.hxx>
@@ -423,7 +422,7 @@ void SwGlossaryList::FillGroup(AutoTextGroup* pGroup, SwGlossaries* pGlossaries)
     passendem Anfang zurueckgeben
 ********************************************************************/
 
-sal_Bool SwGlossaryList::HasLongName(const String& rBegin, SvStringsISortDtor* pLongNames )
+bool SwGlossaryList::HasLongName(const String& rBegin, std::vector<String> *pLongNames)
 {
     if(!bFilled)
         Update();
@@ -441,8 +440,7 @@ sal_Bool SwGlossaryList::HasLongName(const String& rBegin, SvStringsISortDtor* p
             if( rSCmp.isEqual( sBlock.Copy(0, nBeginLen), rBegin ) &&
                 nBeginLen + 1 < sBlock.Len())
             {
-                String* pBlock = new String(sBlock);
-                pLongNames->Insert(pBlock);
+                pLongNames->push_back( sBlock );
                 nFound++;
                 if(FIND_MAX_GLOS == nFound)
                     break;
-- 
1.7.7.6



Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.