[Libreoffice-commits] core.git: Branch 'private/jmux/sorted-pagedesc+spzfrmfmts' - 2665 commits - accessibility/inc accessibility/source android/Bootstrap android/default-document android/experimental animations/source apple_remote/source avmedia/Library_avmediagst.mk avmedia/Library_avmedia.mk avmedia/Library_avmediaogl.mk avmedia/Module_avmedia.mk avmedia/source basctl/Module_basctl.mk basctl/source basebmp/source basegfx/CppunitTest_basegfx.mk basegfx/source basegfx/test basic/inc basic/Library_sb.mk basic/Module_basic.mk basic/qa basic/source bean/com bean/README binaryurp/source bin/find-german-comments bin/findunusedcode bin/gbuild-to-ide bin/lo-all-static-libs bin/lolcat bin/parse-perfcheck.py bin/refcount_leak.py bin/run bin/unpack-sources bridges/source bridges/test canvas/Library_oglcanvas.mk canvas/Package_opengl.mk canvas/source chart2/CppunitTest_chart2_export.mk chart2/CppunitTest_chart2_import.mk chart2/CppunitTest_chart2_xshape.mk chart2/inc chart2/Library_chartcontroller.mk chart 2/Library_chartcore.mk chart2/Library_chartopengl.mk chart2/opengl chart2/Package_opengl.mk chart2/qa chart2/source chart2/uiconfig cli_ure/source codemaker/source comphelper/Library_comphelper.mk comphelper/qa comphelper/source compilerplugins/clang config_host/config_features.h.in config_host/config_global.h.in config_host.mk.in configmgr/CppunitTest_configmgr_unit.mk configmgr/qa configmgr/source configure.ac connectivity/com connectivity/qa connectivity/source connectivity/workben cppcanvas/qa cppcanvas/source cppuhelper/qa cppuhelper/source cppuhelper/test cppu/qa cppu/source cpputools/source cppu/util crashrep/source cui/Library_cui.mk cui/source cui/uiconfig dbaccess/CppunitTest_dbaccess_embeddeddb_performancetest.mk dbaccess/CppunitTest_dbaccess_hsqldb_test.mk dbaccess/Module_dbaccess.mk dbaccess/PythonTest_dbaccess_python.mk dbaccess/qa dbaccess/source dbaccess/uiconfig desktop/Module_desktop.mk desktop/Package_sbase_sh.mk desktop/Package_scalc_sh.mk desktop/Package_scripts .mk desktop/Package_sdraw_sh.mk desktop/Package_simpress_sh.mk desktop/Package_smath_sh.mk desktop/Package_swriter_sh.mk desktop/source desktop/test desktop/uiconfig desktop/unx desktop/win32 dictionaries distro-configs/LibreOfficeAndroidAarch64.conf distro-configs/LibreOfficeAndroid.conf distro-configs/LibreOfficeAndroidX86.conf distro-configs/LibreOfficeLinux.conf distro-configs/LibreOfficeMacOSX64.conf distro-configs/LibreOfficeMacOSX.conf distro-configs/LibreOfficeWin32.conf download.lst drawinglayer/source dtrans/source dtrans/test editeng/CppunitTest_editeng_core.mk editeng/CustomTarget_generated.mk editeng/Library_editeng.mk editeng/Module_editeng.mk editeng/qa editeng/source embeddedobj/source extensions/Executable_pluginapp.bin.mk extensions/qa extensions/source extensions/test extensions/uiconfig extensions/workben external/apache-commons external/boost external/clucene external/coinmp external/cppunit external/curl external/freetype external/glew external/glm external/icu external/jfreereport external/lcms2 external/libabw external/libcdr external/libebook external/libetonyek external/libgltf external/libmspub external/libmwaw external/libodfgen external/liborcus external/libpagemaker external/librevenge external/libvisio external/libwps external/libxml2 external/libxmlsec external/libxslt external/lpsolve external/Module_external.mk external/nss external/python3 external/unixODBC filter/Configuration_filter.mk filter/CppunitTest_filter_eps_test.mk filter/CppunitTest_filter_met_test.mk filter/CppunitTest_filter_pcd_test.mk filter/Module_filter.mk filter/qa filter/source filter/uiconfig forms/qa forms/source formula/source fpicker/source framework/inc framework/qa framework/source .gitignore helpcompiler/source helpcontent2 hwpfilter/source i18nlangtag/source i18npool/inc i18npool/Library_localedata_euro.mk i18npool/source icon-themes/crystal icon-themes/galaxy icon-themes/hicontrast icon-themes/human icon-themes/industrial icon-themes/oxygen icon-th emes/sifr icon-themes/tango icon-themes/tango_testing idlc/source idl/inc idl/source include/avmedia include/basebmp include/basic include/canvas include/com include/comphelper include/cppuhelper include/drawinglayer include/editeng include/filter include/formula include/helpcompiler include/jvmfwk include/LibreOfficeKit include/o3tl include/oox include/osl include/package include/postwin.h include/rsc include/rtl include/sal include/salhelper include/sax include/sfx2 include/svl include/svtools include/svx include/test include/toolkit include/tools include/tubes include/ucbhelper include/uno include/unotools include/vbahelper include/vcl include/xmloff include/xmlreader instsetoo_native/inc_openoffice instsetoo_native/util io/source ios/shared io/test javaunohelper/com javaunohelper/source javaunohelper/test jurt/com jurt/test jvmfwk/distributions jvmfwk/inc jvmfwk/Library_jvmfwk.mk jvmfwk/Library_sunjavaplugin.mk jvmfwk/Module_jvmfwk.mk jvmfwk/plugins jvmfwk/README jvmfwk/source l 10ntools/source librelogo/CustomTarget_librelogo.mk librelogo/Module_librelogo.mk libreofficekit/Module_libreofficekit.mk libreofficekit/qa lingucomponent/source linguistic/source linguistic/workben logerrit lotuswordpro/source Makefile.fetch Makefile.in mysqlc/source nlpsolver/src nlpsolver/ThirdParty o3tl/CppunitTest_o3tl_tests.mk o3tl/qa o3tl/README odk/docs odk/examples odk/index.html odk/index_online.html odk/qa odk/source offapi/com offapi/UnoApi_offapi.mk officecfg/Configuration_officecfg.mk officecfg/registry oox/CustomTarget_generated.mk oox/inc oox/source package/inc package/Library_package2.mk package/source postprocess/CustomTarget_registry.mk postprocess/Rdb_services.mk pyuno/CustomTarget_python_shell.mk pyuno/demo pyuno/source pyuno/zipcore qadevOOo/runner qadevOOo/testdocs qadevOOo/tests readlicense_oo/docs readlicense_oo/license README.Android README.cross registry/source registry/tools remotebridges/examples reportbuilder/java reportdesign/source reportdesign/uiconf ig RepositoryExternal.mk Repository.mk RepositoryModule_host.mk rsc/inc rsc/source sal/cppunittester sal/CppunitTest_sal_osl_process.mk sal/Library_sal.mk sal/osl sal/qa sal/rtl sal/test sal/workben sax/source sax/test scaddins/idl scaddins/source sc/CppunitTest_sc_annotationobj.mk sc/CppunitTest_sc_annotationshapeobj.mk sc/CppunitTest_sc_annotationsobj.mk sc/CppunitTest_sc_cellrangeobj.mk sc/CppunitTest_sc_chart_regression_test.mk sc/CppunitTest_sc_datapilotfieldobj.mk sc/CppunitTest_sc_datapilottableobj.mk sc/CppunitTest_sc_editfieldobj_cell.mk sc/CppunitTest_sc_editfieldobj_header.mk sc/CppunitTest_sc_html_export_test.mk sc/CppunitTest_sc_macros_test.mk sc/CppunitTest_sc_modelobj.mk sc/CppunitTest_sc_namedrangeobj.mk sc/CppunitTest_sc_namedrangesobj.mk sc/CppunitTest_sc_opencl_test.mk sc/CppunitTest_sc_outlineobj.mk sc/CppunitTest_sc_rangelst_test.mk sc/CppunitTest_sc_styleloaderobj.mk sc/CppunitTest_sc_subsequent_export_test.mk sc/CppunitTest_sc_tablesheetobj.mk sc/CppunitTest_s c_tablesheetsobj.mk sc/CppunitTest_sc_ucalc.mk sc/inc sc/Library_scfilt.mk sc/Library_sc.mk sc/Library_scopencl.mk sc/Library_scqahelper.mk sc/Module_sc.mk scp2/AutoInstall.mk scp2/inc scp2/InstallModule_base.mk scp2/InstallModule_calc.mk scp2/InstallModule_crashrep.mk scp2/InstallModule_draw.mk scp2/InstallModule_impress.mk scp2/InstallModule_math.mk scp2/InstallModule_ooo.mk scp2/InstallModule_quickstart.mk scp2/InstallModule_writer.mk scp2/source sc/qa scripting/examples scripting/java scripting/Module_scripting.mk scripting/source scripting/workben sc/sdi sc/source sc/uiconfig sc/workben sd/CppunitTest_sd_export_tests.mk sd/CppunitTest_sd_filters_test.mk sd/CppunitTest_sd_uimpress.mk sdext/source sd/inc sd/qa sd/source sd/uiconfig setup_native/scripts setup_native/source sfx2/inc sfx2/sdi sfx2/source sfx2/uiconfig sfx2/util shell/inc shell/Module_shell.mk shell/source slideshow/Library_OGLTrans.mk slideshow/Library_slideshow.mk slideshow/Package_opengl.mk slideshow/source slides how/test smoketest/data smoketest/libtest.cxx solenv/bin solenv/doc solenv/gbuild solenv/gcc-wrappers solenv/gdb solenv/inc soltools/cpp soltools/mkdepend sot/qa sot/source starmath/inc starmath/qa starmath/source starmath/uiconfig stoc/source stoc/test store/source svgio/CppunitTest_svgio.mk svgio/inc svgio/source svl/Library_svl.mk svl/source svtools/inc svtools/langsupport svtools/README svtools/source svtools/uiconfig svx/inc svx/Library_svxcore.mk svx/Library_svx.mk svx/sdi svx/source svx/uiconfig svx/UIConfig_svx.mk svx/util svx/workben sw/AllLangResTarget_sw.mk sw/CppunitTest_sw_filters_test.mk sw/CppunitTest_sw_globalfilter.mk sw/CppunitTest_sw_htmlexport.mk sw/CppunitTest_sw_odfimport.mk sw/CppunitTest_sw_ooxmlimport.mk sw/CppunitTest_sw_rtfexport.mk sw/CppunitTest_sw_tox.mk sw/CppunitTest_sw_uiwriter.mk sw/CppunitTest_sw_uwriter.mk swext/mediawiki sw/inc sw/Library_sw.mk sw/Module_sw.mk sw/qa sw/README sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk sysui/CustomTarget_ solaris.mk sysui/desktop test/Library_test.mk test/source testtools/com toolkit/qa toolkit/source toolkit/test tools/CppunitTest_tools_test.mk tools/Library_tl.mk tools/qa tools/source tools/test touch/Library_libotouch.mk touch/source translations tubes/source ucbhelper/source ucb/qa ucb/source udkapi/com UnoControls/source unodevtools/source unoidl/source unotest/source unotools/CppunitTest_unotools_fontdefs.mk unotools/qa unotools/source unoxml/Library_unoxml.mk unoxml/source unusedcode.easy ure/source uui/source vbahelper/Module_vbahelper.mk vbahelper/source vcl/android vcl/CppunitTest_vcl_filters_test.mk vcl/CppunitTest_vcl_fontcharmap.mk vcl/Executable_icontest.mk vcl/Executable_outdevgrind.mk vcl/Executable_vcldemo.mk vcl/generic vcl/headless vcl/inc vcl/ios vcl/Library_vcl.mk vcl/Library_vclopengl.mk vcl/Library_vclplug_gen.mk vcl/Library_vclplug_gtk.mk vcl/Module_vcl.mk vcl/opengl vcl/osx vcl/Package_fontunxppds.mk vcl/Package_opengl.mk vcl/qa vcl/quartz vcl/source vcl/unx vcl/win vcl/workben winaccessibility/source wizards/com wizards/Package_access2base.mk wizards/source writerfilter/inc writerfilter/Library_writerfilter.mk writerfilter/qa writerfilter/README writerfilter/source writerperfect/Library_wpftdraw.mk writerperfect/Library_wpftimpress.mk writerperfect/Library_wpftwriter.mk writerperfect/qa writerperfect/source xmerge/source xmlhelp/source xmloff/dtd xmloff/inc xmloff/source xmlscript/source xmlscript/test xmlsecurity/source

Jan-Marek Glogowski glogow at fbihome.de
Wed Nov 12 03:30:29 PST 2014


Rebased ref, commits from common ancestor:
commit 86c0ae3e028f0da50e7aedb992678810c33dadcb
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Oct 29 16:04:47 2014 +0100

    MM: don't read column content twice to fill SwCalc
    
    Currently we fill the SwCalc dict twice via lcl_GetColumnCnt and
    GetMergeColumnCnt.
    
    This also drops the unused nFmt argument from GetMergeColumnCnt.
    
    Change-Id: I2f7fd1578353e919209002c0c3040adc14b08528

diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx
index b79cda0..aa6117b 100644
--- a/sw/inc/dbmgr.hxx
+++ b/sw/inc/dbmgr.hxx
@@ -311,7 +311,7 @@ public:
     void            CloseAll(bool bIncludingMerge = true);
 
     bool            GetMergeColumnCnt(const OUString& rColumnName, sal_uInt16 nLanguage,
-                                      OUString &rResult, double *pNumber, sal_uInt32 *pFormat);
+                                      OUString &rResult, double *pNumber);
     bool            FillCalcWithMergeData(SvNumberFormatter *pDocFormatter,
                                           sal_uInt16 nLanguage, bool asString, SwCalc &aCalc);
     bool            ToNextMergeRecord();
diff --git a/sw/source/core/fields/dbfld.cxx b/sw/source/core/fields/dbfld.cxx
index 0247008..101808b 100644
--- a/sw/source/core/fields/dbfld.cxx
+++ b/sw/source/core/fields/dbfld.cxx
@@ -322,13 +322,13 @@ void SwDBField::Evaluate()
     if(!pMgr || !pMgr->IsDataSourceOpen(aTmpData.sDataSource, aTmpData.sCommand, true))
         return ;
 
-    sal_uInt32 nFmt;
+    sal_uInt32 nFmt = 0;
 
     // search corresponding column name
     OUString aColNm( ((SwDBFieldType*)GetTyp())->GetColumnName() );
 
     SvNumberFormatter* pDocFormatter = GetDoc()->GetNumberFormatter();
-    pMgr->GetMergeColumnCnt(aColNm, GetLanguage(), aContent, &nValue, &nFmt);
+    pMgr->GetMergeColumnCnt(aColNm, GetLanguage(), aContent, &nValue);
     if( !( nSubType & nsSwExtendedSubType::SUB_OWN_FMT ) )
         SetFormat( nFmt = pMgr->GetColumnFmt( aTmpData.sDataSource, aTmpData.sCommand,
                                         aColNm, pDocFormatter, GetLanguage() ));
diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx
index 23f00f8..a2c361d 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -1392,9 +1392,8 @@ void SwHiddenTxtField::Evaluate(SwDoc* pDoc)
                                                 sDataTableOrQuery, false))
                 {
                     double fNumber;
-                    sal_uInt32 nTmpFormat;
                     pMgr->GetMergeColumnCnt(GetColumnName( sTmpName ),
-                        GetLanguage(), aContent, &fNumber, &nTmpFormat );
+                        GetLanguage(), aContent, &fNumber );
                     bValid = true;
                 }
                 else if( !sDBName.isEmpty() && !sDataSource.isEmpty() &&
diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx
index 142faf4..da2eb7a 100644
--- a/sw/source/uibase/dbui/dbmgr.cxx
+++ b/sw/source/uibase/dbui/dbmgr.cxx
@@ -267,8 +267,27 @@ static bool lcl_MoveAbsolute(SwDSParam* pParam, long nAbsPos)
     return bRet;
 }
 
-static bool lcl_GetColumnCnt(SwDSParam* pParam,
-    const OUString& rColumnName, long nLanguage, OUString& rResult, double* pNumber)
+static void lcl_GetColumnCnt(SwDSParam *pParam,
+                             const uno::Reference< XPropertySet > &rColumnProps,
+                             long nLanguage, OUString &rResult, double* pNumber)
+{
+    SwDBFormatData aFormatData;
+    if(!pParam->xFormatter.is())
+    {
+        uno::Reference<XDataSource> xSource = SwDBManager::getDataSourceAsParent(
+                                    pParam->xConnection,pParam->sDataSource);
+        lcl_InitNumberFormatter(*pParam, xSource );
+    }
+    aFormatData.aNullDate = pParam->aNullDate;
+    aFormatData.xFormatter = pParam->xFormatter;
+
+    aFormatData.aLocale = LanguageTag( (LanguageType)nLanguage ).getLocale();
+
+    rResult = SwDBManager::GetDBField( rColumnProps, aFormatData, pNumber);
+}
+
+static bool lcl_GetColumnCnt(SwDSParam* pParam, const OUString& rColumnName,
+                             long nLanguage, OUString& rResult, double* pNumber)
 {
     uno::Reference< XColumnsSupplier > xColsSupp( pParam->xResultSet, UNO_QUERY );
     uno::Reference<XNameAccess> xCols;
@@ -284,20 +303,7 @@ static bool lcl_GetColumnCnt(SwDSParam* pParam,
     Any aCol = xCols->getByName(rColumnName);
     uno::Reference< XPropertySet > xColumnProps;
     aCol >>= xColumnProps;
-
-    SwDBFormatData aFormatData;
-    if(!pParam->xFormatter.is())
-    {
-        uno::Reference<XDataSource> xSource = SwDBManager::getDataSourceAsParent(
-                                    pParam->xConnection,pParam->sDataSource);
-        lcl_InitNumberFormatter(*pParam, xSource );
-    }
-    aFormatData.aNullDate = pParam->aNullDate;
-    aFormatData.xFormatter = pParam->xFormatter;
-
-    aFormatData.aLocale = LanguageTag( (LanguageType)nLanguage ).getLocale();
-
-    rResult = SwDBManager::GetDBField( xColumnProps, aFormatData, pNumber);
+    lcl_GetColumnCnt( pParam, xColumnProps, nLanguage, rResult, pNumber );
     return true;
 };
 
@@ -1859,7 +1865,7 @@ bool SwDBManager::GetColumnCnt(const OUString& rSourceName, const OUString& rTab
 
 // reads the column data at the current position
 bool    SwDBManager::GetMergeColumnCnt(const OUString& rColumnName, sal_uInt16 nLanguage,
-                                   OUString &rResult, double *pNumber, sal_uInt32 * /*pFormat*/)
+                                   OUString &rResult, double *pNumber)
 {
     if(!pImpl->pMergeData || !pImpl->pMergeData->xResultSet.is() || pImpl->pMergeData->bAfterSelection )
     {
@@ -1904,46 +1910,44 @@ bool SwDBManager::FillCalcWithMergeData( SvNumberFormatter *pDocFormatter,
                 continue;
             }
 
+            // get the column type
+            sal_Int32 nColumnType = DataType::SQLNULL;
+            Any aCol = xCols->getByName( pColNames[nCol] );
+            uno::Reference<XPropertySet> xColumnProps;
+            aCol >>= xColumnProps;
+            Any aType = xColumnProps->getPropertyValue( "Type" );
+            aType >>= nColumnType;
             double aNumber = DBL_MAX;
-            if( lcl_GetColumnCnt(pImpl->pMergeData, rColName, nLanguage, aString, &aNumber) )
+
+            lcl_GetColumnCnt( pImpl->pMergeData, xColumnProps, nLanguage, aString, &aNumber );
+
+            sal_uInt32 nFmt = GetColumnFmt( pImpl->pMergeData->sDataSource,
+                                            pImpl->pMergeData->sCommand,
+                                            pColNames[nCol], pDocFormatter, nLanguage );
+            // aNumber is overwritten by SwDBField::FormatValue, so store initial status
+            bool colIsNumber = aNumber != DBL_MAX;
+            bool bValidValue = SwDBField::FormatValue( pDocFormatter, aString, nFmt,
+                                                       aNumber, nColumnType, NULL );
+            if( colIsNumber )
             {
-                // get the column type
-                sal_Int32 nColumnType = DataType::SQLNULL;
-                Any aCol = xCols->getByName( pColNames[nCol] );
-                uno::Reference<XPropertySet> xCol;
-                aCol >>= xCol;
-                Any aType = xCol->getPropertyValue( "Type" );
-                aType >>= nColumnType;
-
-                sal_uInt32 nFmt;
-                if( !GetMergeColumnCnt(pColNames[nCol], nLanguage, aString, &aNumber, &nFmt) )
-                    continue;
-
-                // aNumber is overwritten by SwDBField::FormatValue, so store initial status
-                bool colIsNumber = aNumber != DBL_MAX;
-                bool bValidValue = SwDBField::FormatValue( pDocFormatter, aString, nFmt,
-                                                           aNumber, nColumnType, NULL );
-                if( colIsNumber )
-                {
-                    if( bValidValue )
-                    {
-                        SwSbxValue aValue;
-                        if( !asString )
-                            aValue.PutDouble( aNumber );
-                        else
-                            aValue.PutString( aString );
-                        SAL_INFO( "sw.dbmgr", "'" << pColNames[nCol] << "': " << aNumber << " / " << aString );
-                        rCalc.VarChange( pColNames[nCol], aValue );
-                    }
-                }
-                else
+                if( bValidValue )
                 {
                     SwSbxValue aValue;
-                    aValue.PutString( aString );
-                    SAL_INFO( "sw.dbmgr", "'" << pColNames[nCol] << "': " << aString );
+                    if( !asString )
+                        aValue.PutDouble( aNumber );
+                    else
+                        aValue.PutString( aString );
+                    SAL_INFO( "sw.dbmgr", "'" << pColNames[nCol] << "': " << aNumber << " / " << aString );
                     rCalc.VarChange( pColNames[nCol], aValue );
                 }
             }
+            else
+            {
+                SwSbxValue aValue;
+                aValue.PutString( aString );
+                SAL_INFO( "sw.dbmgr", "'" << pColNames[nCol] << "': " << aString );
+                rCalc.VarChange( pColNames[nCol], aValue );
+            }
         }
         return bExistsNextRecord;
     }
commit ad3e1d25a0ff025bda1eb69b25925fb3a95a7bcd
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jun 10 12:32:32 2014 +0200

    Optimize lcl_GetUniqueFlyName
    
    Change-Id: Ic894ee471982496ac82dc426c803aba92b8554c2

diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index c7ab83f..89c9ad4 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -124,9 +124,11 @@ struct SwFrmFmtSearch
 {
     sal_uInt16 type;
     const OUString& name;
+    sal_Int32 length;
 
-    SwFrmFmtSearch( sal_uInt16 _type, const OUString& _name )
-        :type( _type ), name( _name ) {}
+    SwFrmFmtSearch( sal_uInt16 _type,
+                    const OUString& _name, sal_Int32 _length )
+        :type( _type ), name( _name ), length( _length ) {}
 };
 
 struct CompareSwFrmFmts
@@ -136,6 +138,12 @@ struct CompareSwFrmFmts
     bool operator()(SwFrmFmtSearch const& lhs, SwFrmFmt* const& rhs) const;
 };
 
+struct PrefixCompareSwFrmFmts
+{
+    bool operator()(SwFrmFmt* const& lhs, SwFrmFmtSearch const& rhs) const;
+    bool operator()(SwFrmFmtSearch const& lhs, SwFrmFmt* const& rhs) const;
+};
+
 typedef o3tl::sorted_vector<SwFrmFmt*, CompareSwFrmFmts,
                             o3tl::find_partialorder_ptrequals> SwFrmFmtsBase;
 
@@ -163,9 +171,11 @@ public:
 
     const_iterator find( const value_type& x ) const;
     std::pair<const_iterator,const_iterator>
-        findRange( const value_type& x, bool& root ) const;
+        findRange( const value_type& x,
+                   bool& root, sal_Int32 length=-1 ) const;
     std::pair<const_iterator,const_iterator>
-        findRange( sal_uInt16 type, const OUString& name, bool& root ) const;
+        findRange( sal_uInt16 type, const OUString& name,
+                   bool& root, sal_Int32 length=-1 ) const;
 
     bool Contains( const value_type& x ) const;
     inline bool Contains(const SwFmt *p) const
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 73fa005..8935bc8 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -2022,14 +2022,21 @@ SwFrmFmts::const_iterator SwFrmFmts::find( const value_type& x ) const
 }
 
 std::pair<SwFrmFmts::const_iterator,SwFrmFmts::const_iterator>
-SwFrmFmts::findRange( sal_uInt16 type, const OUString& name, bool& root ) const
+SwFrmFmts::findRange( sal_uInt16 type, const OUString& name, bool& root, sal_Int32 length ) const
 {
     SwFrmFmtSearch x( type, name, length );
     std::pair<const_iterator, const_iterator> ret(end(), end());
     if ( !empty() ) {
-        ret = std::equal_range(begin() + GetOffset(), end(), x, CompareSwFrmFmts());
-        root = (front()->Which() == type
-             && front()->GetName().compareTo( name ) == 0);
+        if ( length >= 0 ) {
+            ret = std::equal_range(begin() + GetOffset(), end(), x, PrefixCompareSwFrmFmts());
+            root = (front()->Which() == type
+                 && front()->GetName().compareTo( name, length ) == 0);
+        }
+        else {
+            ret = std::equal_range(begin() + GetOffset(), end(), x, CompareSwFrmFmts());
+            root = (front()->Which() == type
+                 && front()->GetName().compareTo( name ) == 0);
+        }
     }
     else
         root = false;
@@ -2037,9 +2044,9 @@ SwFrmFmts::findRange( sal_uInt16 type, const OUString& name, bool& root ) const
 }
 
 std::pair<SwFrmFmts::const_iterator,SwFrmFmts::const_iterator>
-SwFrmFmts::findRange( const value_type& x, bool& root ) const
+SwFrmFmts::findRange( const value_type& x, bool& root, sal_Int32 length ) const
 {
-    return findRange( x->Which(), x->GetName(), root );
+    return findRange( x->Which(), x->GetName(), root, length );
 }
 
 bool CompareSwFrmFmts::operator()(SwFrmFmt* const& lhs, SwFrmFmt* const& rhs) const
@@ -2069,6 +2076,24 @@ bool CompareSwFrmFmts::operator()(SwFrmFmtSearch const& lhs, SwFrmFmt* const& rh
     return (lhs.name.compareTo( rhs->GetName() ) < 0);
 }
 
+bool PrefixCompareSwFrmFmts::operator()(SwFrmFmt* const& lhs, SwFrmFmtSearch const& rhs) const
+{
+    if (lhs->Which() < rhs.type)
+        return true;
+    if (lhs->Which() > rhs.type)
+        return false;
+    return (lhs->GetName().compareTo( rhs.name, rhs.length ) < 0);
+}
+
+bool PrefixCompareSwFrmFmts::operator()(SwFrmFmtSearch const& lhs, SwFrmFmt* const& rhs) const
+{
+    if (lhs.type < rhs->Which())
+        return true;
+    if (lhs.type > rhs->Which())
+        return false;
+    return (lhs.name.compareTo( rhs->GetName(), lhs.length ) < 0);
+}
+
 SwFrmFmts::find_insert_type SwFrmFmts::insert( const value_type& x, bool isNewRoot )
 {
     find_insert_type ret = SwFrmFmtsBase::insert( x );
diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index 1ed487f..a20fa0a 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -1302,36 +1302,72 @@ static OUString lcl_GetUniqueFlyName( const SwDoc* pDoc, sal_uInt16 nDefStrId )
 
     const SwFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
 
+    // prepare the bitfield to flag found numbers
     sal_uInt16 nNum, nTmp, nFlagSize = ( rFmts.size() / 8 ) +2;
     sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
-    sal_uInt16 n;
-
     memset( pSetFlags, 0, nFlagSize );
 
-    for( n = 0; n < rFmts.size(); ++n )
-    {
-        const SwFrmFmt* pFlyFmt = rFmts[ n ];
-        if( RES_FLYFRMFMT == pFlyFmt->Which() &&
-            pFlyFmt->GetName().startsWith( aName ) )
-        {
-            // Only get and set the Flag
-            nNum = static_cast< sal_uInt16 >( rtl_ustr_toInt32( pFlyFmt->GetName().getStr() + nNmLen, 10 ) );
-            if( nNum-- && nNum < rFmts.size() )
-                pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
+    // find the range of fly names with common prefix
+    bool root;
+    const std::pair<SwFrmFmts::const_iterator,SwFrmFmts::const_iterator>
+        range = rFmts.findRange( RES_FLYFRMFMT, aName, root, nNmLen );
+    SwFrmFmts::const_iterator it = range.first;
+    sal_uInt16 n = 0;
+    bool found = false;
+
+    // check all number postfixes to find the first free number
+    while ( root || (it != range.second) ) {
+        const SwFrmFmt* pFlyFmt;
+        if ( root )
+            pFlyFmt = rFmts[ 0 ];
+        else {
+            pFlyFmt = *it;
+            it++;
+        }
+
+        // get / set the flag for the number
+        nNum = static_cast< sal_uInt16 >( rtl_ustr_toInt32( pFlyFmt->GetName().getStr() + nNmLen, 10 ) );
+        if( nNum-- && nNum < rFmts.size() ) {
+            pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
+            if ( root ) {
+                // don't inc n for root; number can be everywhere
+                root = false;
+                continue;
+            }
+            else
+                n++;
+        }
+        else {
+            if ( root )
+                root = false;
+            continue;
+        }
+
+        // after 8 conversions, we can check for a hole, because the list is sorted
+        if( 0 == n % 8 ) {
+            if( 0xff != ( nTmp = pSetFlags[ n / 8 - 1 ] ))
+            {
+                // so determine the number
+                nNum = n - 8;
+                while( nTmp & 1 )
+                    ++nNum, nTmp >>= 1;
+                found = true;
+                break;
+            }
         }
     }
 
-    // All numbers are flagged accordingly, so determine the right one
-    nNum = rFmts.size();
-    for( n = 0; n < nFlagSize; ++n )
-        if( 0xff != ( nTmp = pSetFlags[ n ] ))
+    if ( !found ) {
+        if( 0xff != ( nTmp = pSetFlags[ n / 8 ] ))
         {
             // so determine the number
-            nNum = n * 8;
+            nNum = n - n % 8;
             while( nTmp & 1 )
                 ++nNum, nTmp >>= 1;
-            break;
         }
+        else
+            nNum = n;
+    }
 
     delete [] pSetFlags;
     return aName += OUString::number( ++nNum );
commit 5709921628dff7446edeef220ec172d11bb95bf0
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jun 10 11:40:43 2014 +0200

    Optimize FindFlyByName
    
    Change-Id: I004226f8aded4e7909a104ec0ba405223f2d7e0e

diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index 48ccb64..c7ab83f 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -120,9 +120,20 @@ public:
     SwGrfFmtColls() : SwFmtsBaseModify( false ) {}
 };
 
+struct SwFrmFmtSearch
+{
+    sal_uInt16 type;
+    const OUString& name;
+
+    SwFrmFmtSearch( sal_uInt16 _type, const OUString& _name )
+        :type( _type ), name( _name ) {}
+};
+
 struct CompareSwFrmFmts
 {
     bool operator()(SwFrmFmt* const& lhs, SwFrmFmt* const& rhs) const;
+    bool operator()(SwFrmFmt* const& lhs, SwFrmFmtSearch const& rhs) const;
+    bool operator()(SwFrmFmtSearch const& lhs, SwFrmFmt* const& rhs) const;
 };
 
 typedef o3tl::sorted_vector<SwFrmFmt*, CompareSwFrmFmts,
@@ -151,6 +162,10 @@ public:
     void erase( const_iterator const& position );
 
     const_iterator find( const value_type& x ) const;
+    std::pair<const_iterator,const_iterator>
+        findRange( const value_type& x, bool& root ) const;
+    std::pair<const_iterator,const_iterator>
+        findRange( sal_uInt16 type, const OUString& name, bool& root ) const;
 
     bool Contains( const value_type& x ) const;
     inline bool Contains(const SwFmt *p) const
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 08fd95f..73fa005 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -2021,6 +2021,27 @@ SwFrmFmts::const_iterator SwFrmFmts::find( const value_type& x ) const
     return SwFrmFmtsBase::find( x );
 }
 
+std::pair<SwFrmFmts::const_iterator,SwFrmFmts::const_iterator>
+SwFrmFmts::findRange( sal_uInt16 type, const OUString& name, bool& root ) const
+{
+    SwFrmFmtSearch x( type, name, length );
+    std::pair<const_iterator, const_iterator> ret(end(), end());
+    if ( !empty() ) {
+        ret = std::equal_range(begin() + GetOffset(), end(), x, CompareSwFrmFmts());
+        root = (front()->Which() == type
+             && front()->GetName().compareTo( name ) == 0);
+    }
+    else
+        root = false;
+    return ret;
+}
+
+std::pair<SwFrmFmts::const_iterator,SwFrmFmts::const_iterator>
+SwFrmFmts::findRange( const value_type& x, bool& root ) const
+{
+    return findRange( x->Which(), x->GetName(), root );
+}
+
 bool CompareSwFrmFmts::operator()(SwFrmFmt* const& lhs, SwFrmFmt* const& rhs) const
 {
     if (lhs->Which() < rhs->Which())
@@ -2030,6 +2051,24 @@ bool CompareSwFrmFmts::operator()(SwFrmFmt* const& lhs, SwFrmFmt* const& rhs) co
     return (lhs->GetName().compareTo( rhs->GetName() ) < 0);
 }
 
+bool CompareSwFrmFmts::operator()(SwFrmFmt* const& lhs, SwFrmFmtSearch const& rhs) const
+{
+    if (lhs->Which() < rhs.type)
+        return true;
+    if (lhs->Which() > rhs.type)
+        return false;
+    return (lhs->GetName().compareTo( rhs.name ) < 0);
+}
+
+bool CompareSwFrmFmts::operator()(SwFrmFmtSearch const& lhs, SwFrmFmt* const& rhs) const
+{
+    if (lhs.type < rhs->Which())
+        return true;
+    if (lhs.type > rhs->Which())
+        return false;
+    return (lhs.name.compareTo( rhs->GetName() ) < 0);
+}
+
 SwFrmFmts::find_insert_type SwFrmFmts::insert( const value_type& x, bool isNewRoot )
 {
     find_insert_type ret = SwFrmFmtsBase::insert( x );
diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index f0f5864..1ed487f 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -1355,12 +1355,24 @@ OUString SwDoc::GetUniqueFrameName() const
 const SwFlyFrmFmt* SwDoc::FindFlyByName( const OUString& rName, sal_Int8 nNdTyp ) const
 {
     const SwFrmFmts& rFmts = *GetSpzFrmFmts();
-    for( sal_uInt16 n = rFmts.size(); n; )
-    {
-        const SwFrmFmt* pFlyFmt = rFmts[ --n ];
+    bool root;
+    const std::pair<SwFrmFmts::const_iterator,SwFrmFmts::const_iterator>
+        range = rFmts.findRange( RES_FLYFRMFMT, rName, root );
+
+    SwFrmFmts::const_iterator it = range.first;
+    while ( root || (it != range.second) ) {
+        const SwFrmFmt* pFlyFmt;
+        if ( root ) {
+            root = false;
+            pFlyFmt = rFmts[ 0 ];
+        }
+        else {
+            pFlyFmt = *it;
+            it++;
+        }
+
         const SwNodeIndex* pIdx = 0;
-        if( RES_FLYFRMFMT == pFlyFmt->Which() && pFlyFmt->GetName() == rName &&
-            0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) &&
+        if( 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) &&
             pIdx->GetNode().GetNodes().IsDocNodes() )
         {
             if( nNdTyp )
commit 7eaf857aa943d348acfb29a49a1ac570ad259157
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Jun 8 19:41:53 2014 +0200

    Convert SwFrmFmts to a o3tl::sorted_vector
    
    Change-Id: I6ca87d3dd9a3b7067380bb7ebaef306b87516dfb

diff --git a/include/o3tl/sorted_vector.hxx b/include/o3tl/sorted_vector.hxx
index 11eb85d..e154880 100644
--- a/include/o3tl/sorted_vector.hxx
+++ b/include/o3tl/sorted_vector.hxx
@@ -78,6 +78,7 @@ public:
     using base_t::clear;
     using base_t::empty;
     using base_t::size;
+    using base_t::reserve;
 
     sorted_vector( bool FirstDefault=false )
     {
@@ -222,6 +223,16 @@ public:
         std::stable_sort(begin_nonconst() + mOffset, end_nonconst(), Compare());
     }
 
+    void newDefault( const_iterator const& position )
+    {
+        if ( !mOffset || position == begin() || position == end() )
+            return;
+        value_type tmp = front();
+        base_t::operator[]( 0 ) = *position;
+        erase( position );
+        insert( tmp );
+    }
+
 private:
 
     typename base_t::iterator begin_nonconst() { return base_t::begin(); }
diff --git a/sw/inc/calbck.hxx b/sw/inc/calbck.hxx
index 3f6ca20..4b0313e 100644
--- a/sw/inc/calbck.hxx
+++ b/sw/inc/calbck.hxx
@@ -98,7 +98,7 @@ public:
     // controlled access to Modify method
     // mba: this is still considered a hack and it should be fixed; the name makes grep-ing easier
     void ModifyNotification( const SfxPoolItem *pOldValue, const SfxPoolItem *pNewValue ) { Modify ( pOldValue, pNewValue ); }
-   void SwClientNotifyCall( const SwModify& rModify, const SfxHint& rHint ) { SwClientNotify( rModify, rHint ); }
+    void SwClientNotifyCall( const SwModify& rModify, const SfxHint& rHint ) { SwClientNotify( rModify, rHint ); }
 
     const SwModify* GetRegisteredIn() const { return pRegisteredIn; }
     SwModify* GetRegisteredIn() { return pRegisteredIn; }
diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index 8205629..48ccb64 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -120,42 +120,38 @@ public:
     SwGrfFmtColls() : SwFmtsBaseModify( false ) {}
 };
 
-typedef std::vector<SwFrmFmt*> SwFrmFmtsBase;
+struct CompareSwFrmFmts
+{
+    bool operator()(SwFrmFmt* const& lhs, SwFrmFmt* const& rhs) const;
+};
+
+typedef o3tl::sorted_vector<SwFrmFmt*, CompareSwFrmFmts,
+                            o3tl::find_partialorder_ptrequals> SwFrmFmtsBase;
 
 /// Specific frame formats (frames, DrawObjects).
 /// Mimics o3tl::sorted_vector interface
-class SW_DLLPUBLIC SwFrmFmts : private SwFrmFmtsBase, public SwFmtsBase
+class SW_DLLPUBLIC SwFrmFmts : public SwFrmFmtsBase, public SwFmtsBase
 {
 public:
     typedef typename SwFrmFmtsBase::const_iterator const_iterator;
     typedef typename SwFrmFmtsBase::size_type size_type;
     typedef typename SwFrmFmtsBase::value_type value_type;
-    typedef typename std::pair<const_iterator,bool> find_insert_type;
+    typedef typename SwFrmFmtsBase::find_insert_type find_insert_type;
 
-    virtual ~SwFrmFmts();
-
-    void DeleteAndDestroyAll( bool offset = false );
+private:
+    find_insert_type insert( const value_type& x, bool isNewRoot );
 
-    using SwFrmFmtsBase::clear;
-    using SwFrmFmtsBase::empty;
-    using SwFrmFmtsBase::reserve;
-    using SwFrmFmtsBase::size;
+public:
+    SwFrmFmts();
+    virtual ~SwFrmFmts();
 
     find_insert_type insert( const value_type& x );
     size_type erase( const value_type& x );
     void erase( size_type index );
     void erase( const_iterator const& position );
 
-    const value_type& front() const { return SwFrmFmtsBase::front(); }
-    const value_type& back() const { return SwFrmFmtsBase::back(); }
-    const value_type& operator[]( size_t index ) const
-        { return SwFrmFmtsBase::operator[]( index ); }
-
     const_iterator find( const value_type& x ) const;
 
-    const_iterator begin() const { return SwFrmFmtsBase::begin(); }
-    const_iterator end() const { return SwFrmFmtsBase::end(); }
-
     bool Contains( const value_type& x ) const;
     inline bool Contains(const SwFmt *p) const
         { return Contains( static_cast<SwFrmFmt*>( const_cast<SwFmt*>( p ) ) ); }
@@ -168,12 +164,6 @@ public:
     void dumpAsXml(xmlTextWriterPtr w, const char* pName) const;
 
     bool newDefault( const value_type& x );
-
-private:
-    typedef typename SwFrmFmtsBase::iterator iterator;
-    iterator begin_nonconst() { return SwFrmFmtsBase::begin(); }
-    iterator end_nonconst() { return SwFrmFmtsBase::end(); }
-    void newDefault( const_iterator const& position );
 };
 
 /// Unsorted, undeleting SwFrmFmt vector
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
index dcace77..fe3f453 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx
@@ -700,53 +700,21 @@ DECLARE_OOXMLEXPORT_TEST(testTextBoxGradientAngle, "fdo65295.docx")
     uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(8), xIndexAccess->getCount());
 
-    // Angle of frame#1 is 135 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame1(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame1, "FillStyle"));
-    awt::Gradient aGradient1 = getProperty<awt::Gradient>(xFrame1, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16(135 * 10), aGradient1.Angle);
-
-    // Angle of frame#2 is 180 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame2(xIndexAccess->getByIndex(1), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame2, "FillStyle"));
-    awt::Gradient aGradient2 = getProperty<awt::Gradient>(xFrame2, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16(180 * 10), aGradient2.Angle);
-
-    // Angle of frame#3 is  90 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame3(xIndexAccess->getByIndex(2), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame3, "FillStyle"));
-    awt::Gradient aGradient3 = getProperty<awt::Gradient>(xFrame3, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16( 90 * 10), aGradient3.Angle);
-
-    // Angle of frame#4 is 225 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame4(xIndexAccess->getByIndex(3), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame4, "FillStyle"));
-    awt::Gradient aGradient4 = getProperty<awt::Gradient>(xFrame4, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16(225 * 10), aGradient4.Angle);
-
-    // Angle of frame#5 is 270 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame5(xIndexAccess->getByIndex(4), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame5, "FillStyle"));
-    awt::Gradient aGradient5 = getProperty<awt::Gradient>(xFrame5, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16(270 * 10), aGradient5.Angle);
-
-    // Angle of frame#6 is 315 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame6(xIndexAccess->getByIndex(5), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame6, "FillStyle"));
-    awt::Gradient aGradient6 = getProperty<awt::Gradient>(xFrame6, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16(315 * 10), aGradient6.Angle);
-
-    // Angle of frame#7 is   0 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame7(xIndexAccess->getByIndex(6), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame7, "FillStyle"));
-    awt::Gradient aGradient7 = getProperty<awt::Gradient>(xFrame7, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16(  0 * 10), aGradient7.Angle);
-
-    // Angle of frame#8 is  45 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
-    uno::Reference<beans::XPropertySet> xFrame8(xIndexAccess->getByIndex(7), uno::UNO_QUERY);
-    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame8, "FillStyle"));
-    awt::Gradient aGradient8 = getProperty<awt::Gradient>(xFrame8, "FillGradient");
-    CPPUNIT_ASSERT_EQUAL(sal_Int16( 45 * 10), aGradient8.Angle);
+    // Angles in degree based on frame name "Rectangle <n>"
+    sal_Int16 angles[] = { -1, 90, 45, 0, 180, -1, 315, 270, 225, 135 };
+
+    for (int i = 1; i < 10; i++) {
+        sal_Int16 angle = angles[ i ];
+        if (angle < 0)
+            continue;
+        OUString shapename( "Rectangle " );
+        shapename += OUString::number( i );
+        uno::Reference<beans::XPropertySet> xFrame(getShapeByName( shapename ), uno::UNO_QUERY);
+        CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
+        awt::Gradient aGradient = getProperty<awt::Gradient>(xFrame, "FillGradient");
+        // 'aGradient.Angle' holds value in 1/10 of a degree
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(angle * 10), aGradient.Angle);
+    }
 }
 
 DECLARE_OOXMLEXPORT_TEST(testCellGridSpan, "cell-grid-span.docx")
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index c6566f2..08fd95f 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -2007,87 +2007,88 @@ namespace docfunc
     }
 }
 
+SwFrmFmts::SwFrmFmts() : SwFrmFmtsBase( true )
+{
+}
+
 SwFrmFmts::~SwFrmFmts()
 {
     DeleteAndDestroyAll();
 }
 
-void SwFrmFmts::DeleteAndDestroyAll( bool keepDefault )
+SwFrmFmts::const_iterator SwFrmFmts::find( const value_type& x ) const
 {
-    if ( empty() )
-        return;
-    const int _offset = keepDefault ? 1 : 0;
-    for( const_iterator it = begin() + _offset; it != end(); ++it )
-        delete *it;
-    if ( _offset )
-        SwFrmFmtsBase::erase( begin_nonconst() + _offset, end_nonconst() );
-    else
-        clear();
+    return SwFrmFmtsBase::find( x );
 }
 
-SwFrmFmts::find_insert_type SwFrmFmts::insert( const value_type& x )
+bool CompareSwFrmFmts::operator()(SwFrmFmt* const& lhs, SwFrmFmt* const& rhs) const
 {
-    SwFrmFmtsBase::push_back( x );
-    SAL_WARN_IF(x->list != 0, "sw", "Inserting already assigned item");
+    if (lhs->Which() < rhs->Which())
+        return true;
+    if (lhs->Which() > rhs->Which())
+        return false;
+    return (lhs->GetName().compareTo( rhs->GetName() ) < 0);
+}
+
+SwFrmFmts::find_insert_type SwFrmFmts::insert( const value_type& x, bool isNewRoot )
+{
+    find_insert_type ret = SwFrmFmtsBase::insert( x );
+    SAL_WARN_IF(x->list != 0, "sw", "Inserting already assigned SwFrmFmt");
+    SAL_WARN_IF(isNewRoot == ret.second, "sw", "Error condition in insert SwFrmFmt");
     x->list = this;
-    return std::make_pair(end() - 1 , true);
+    return ret;
+}
+
+std::pair<SwFrmFmts::const_iterator,bool> SwFrmFmts::insert( const value_type& x )
+{
+    return insert( x, false );
 }
 
 SwFrmFmts::size_type SwFrmFmts::erase( const value_type& x )
 {
-    const_iterator const ret = find( x );
-    SAL_WARN_IF(x->list != this, "sw", "Removing invalid / unassigned item");
-    if (ret != end()) {
-        SwFrmFmtsBase::erase( begin_nonconst() + (ret - begin()) );
+    size_type ret = SwFrmFmtsBase::erase( x );
+    if (ret) {
+        SAL_WARN_IF(x->list != this, "sw", "Removed invalid / unassigned SwFrmFmt");
         x->list = 0;
-        return 1;
     }
-    return 0;
+    return ret;
 }
 
 void SwFrmFmts::erase( size_type index )
 {
-    erase( begin_nonconst() + index );
+    erase( begin() + index );
 }
 
 void SwFrmFmts::erase( const_iterator const& position )
 {
+    SAL_WARN_IF((*position)->list != this, "sw", "Removing invalid / unassigned SwFrmFmt");
     (*position)->list = 0;
-    SwFrmFmtsBase::erase( begin_nonconst() + (position - begin()) );
+    SwFrmFmtsBase::erase( position );
 }
-
-SwFrmFmts::const_iterator SwFrmFmts::find( const value_type& x ) const
+/*
+std::pair<SwFrmFmts::const_iterator, SwFrmFmts::const_iterator>
+    SwFrmFmts::find( const value_type& x, bool &root ) const
 {
-    return std::find( begin(), end(), x );
+    if ( emptry() ) {
+        root = false;
+        return std::pair<const_iterator, const_iterator>( end(), end() );
+    }
+    std::pair<const_iterator, const_iterator> const its =
+            std::equal_range(begin(), end(), x, CompareSwFrmFmts());
+    root = CompareSwPageDescs()(x, front());
+    return its;
 }
-
-bool SwFrmFmts::Contains( const SwFrmFmts::value_type& x ) const
+*/
+bool SwFrmFmts::Contains( const value_type& x ) const
 {
     return (x->list == this);
 }
 
 bool SwFrmFmts::newDefault( const value_type& x )
 {
-    bool inserted = false;
-    const_iterator it = find( x );
-    if (it == end()) {
-        push_back( x );
-        it = end() - 1;
-        inserted = true;
-    }
-    newDefault( it );
-    return inserted;
-}
-
-void SwFrmFmts::newDefault( const_iterator const& position )
-{
-    if (position == begin())
-        return;
-    SwFrmFmt *tmp;
-    tmp = front();
-    erase( position );
-    SwFrmFmtsBase::operator[]( 0 ) = *position;
-    insert( tmp );
+    find_insert_type ret = insert( x, true );
+    SwFrmFmtsBase::newDefault( ret.first );
+    return ret.second;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 0b030dd..a94cad3 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -2441,10 +2441,10 @@ void SwFrmFmt::SetName( const OUString& rNewName, bool bBroadcast )
     SwFrmFmts::const_iterator it;
     bool move_entry = false;
 
-    if (list) {
-        it = list->find( this );
-        SAL_WARN_IF( list->end() == it, "sw", "SwFrmFmt not found in expected list" );
-//        move_entry = (it != list->begin());
+    if (_list) {
+        it = _list->find( this );
+        SAL_WARN_IF( _list->end() == it, "sw", "SwFrmFmt not found in expected list" );
+        move_entry = (it != list->begin());
         if (move_entry)
             // Clears list
             list->erase( it );
commit e4984d9a844413d7a2af80d12e39f7a6f15e506c
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Jun 8 01:59:29 2014 +0200

    Change SwFrmFmts to o3tl::sorted_vector like API
    
    This changes the SwFrmFmts class std::vector inheritance to private
    and extends the class to a o3tl::sorted_vector compatible API.
    
    This should just be a cleanup patch and is a preparation for the
    change of SwFrmFmts from vector to o3tl::sorted_vector.
    
    For simple list cases, this also adds a SwFrmFmtsV, a std::vector
    version of SwFrmFmts.
    
    Change-Id: I2e91cb4d650b1c46c531885869d201edba84e5a6

diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index a813f38..8205629 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -120,16 +120,67 @@ public:
     SwGrfFmtColls() : SwFmtsBaseModify( false ) {}
 };
 
+typedef std::vector<SwFrmFmt*> SwFrmFmtsBase;
+
 /// Specific frame formats (frames, DrawObjects).
-class SW_DLLPUBLIC SwFrmFmts : public SwFmtsBaseModify<SwFrmFmt*>
+/// Mimics o3tl::sorted_vector interface
+class SW_DLLPUBLIC SwFrmFmts : private SwFrmFmtsBase, public SwFmtsBase
 {
 public:
+    typedef typename SwFrmFmtsBase::const_iterator const_iterator;
+    typedef typename SwFrmFmtsBase::size_type size_type;
+    typedef typename SwFrmFmtsBase::value_type value_type;
+    typedef typename std::pair<const_iterator,bool> find_insert_type;
+
+    virtual ~SwFrmFmts();
+
+    void DeleteAndDestroyAll( bool offset = false );
+
+    using SwFrmFmtsBase::clear;
+    using SwFrmFmtsBase::empty;
+    using SwFrmFmtsBase::reserve;
+    using SwFrmFmtsBase::size;
+
+    find_insert_type insert( const value_type& x );
+    size_type erase( const value_type& x );
+    void erase( size_type index );
+    void erase( const_iterator const& position );
+
+    const value_type& front() const { return SwFrmFmtsBase::front(); }
+    const value_type& back() const { return SwFrmFmtsBase::back(); }
+    const value_type& operator[]( size_t index ) const
+        { return SwFrmFmtsBase::operator[]( index ); }
+
+    const_iterator find( const value_type& x ) const;
+
+    const_iterator begin() const { return SwFrmFmtsBase::begin(); }
+    const_iterator end() const { return SwFrmFmtsBase::end(); }
+
+    bool Contains( const value_type& x ) const;
+    inline bool Contains(const SwFmt *p) const
+        { return Contains( static_cast<SwFrmFmt*>( const_cast<SwFmt*>( p ) ) ); }
+
+    virtual size_t GetFmtCount() const SAL_OVERRIDE
+        { return SwFrmFmtsBase::size(); }
+    virtual SwFrmFmt* GetFmt(size_t idx) const SAL_OVERRIDE
+        { return SwFrmFmtsBase::operator[](idx); }
+
     void dumpAsXml(xmlTextWriterPtr w, const char* pName) const;
 
-    using SwFmtsBaseModify<SwFrmFmt*>::Contains;
+    bool newDefault( const value_type& x );
 
-    inline bool Contains(const SwFrmFmt *p) const
-        { return Contains(const_cast<SwFrmFmt*>( p )); }
+private:
+    typedef typename SwFrmFmtsBase::iterator iterator;
+    iterator begin_nonconst() { return SwFrmFmtsBase::begin(); }
+    iterator end_nonconst() { return SwFrmFmtsBase::end(); }
+    void newDefault( const_iterator const& position );
+};
+
+/// Unsorted, undeleting SwFrmFmt vector
+class SwFrmFmtsV : public SwFmtsBaseModify<SwFrmFmt*>
+{
+public:
+    virtual ~SwFrmFmtsV() {}
 };
 
 class SwCharFmts : public SwFmtsBaseModify<SwCharFmt*>
diff --git a/sw/inc/format.hxx b/sw/inc/format.hxx
index 321bd88..ca522ea 100644
--- a/sw/inc/format.hxx
+++ b/sw/inc/format.hxx
@@ -112,7 +112,7 @@ public:
     inline bool IsDefault() const { return DerivedFrom() == 0; }
 
     inline OUString GetName() const   { return aFmtName; }
-    void SetName( const OUString& rNewName, bool bBroadcast=false );
+    virtual void SetName( const OUString& rNewName, bool bBroadcast=false );
     inline void SetName( const sal_Char* pNewName,
                          bool bBroadcast=false);
 
diff --git a/sw/inc/frmfmt.hxx b/sw/inc/frmfmt.hxx
index e73f6bd..b431859 100644
--- a/sw/inc/frmfmt.hxx
+++ b/sw/inc/frmfmt.hxx
@@ -36,6 +36,7 @@ class SwRect;
 class SwContact;
 class SdrObject;
 namespace sw { class DocumentLayoutManager; }
+class SwFrmFmts;
 
 /// Style of a layout element.
 class SW_DLLPUBLIC SwFrmFmt: public SwFmt
@@ -43,6 +44,7 @@ class SW_DLLPUBLIC SwFrmFmt: public SwFmt
     friend class SwDoc;
     friend class SwPageDesc;    ///< Is allowed to call protected CTor.
     friend class ::sw::DocumentLayoutManager; ///< Is allowed to call protected CTor.
+    friend class SwFrmFmts;     ///< Is allowed to update the list backref.
 
     ::com::sun::star::uno::WeakReference<
         ::com::sun::star::uno::XInterface> m_wXObject;
@@ -50,6 +52,9 @@ class SW_DLLPUBLIC SwFrmFmt: public SwFmt
     //UUUU DrawingLayer FillAttributes in a preprocessed form for primitive usage
     drawinglayer::attribute::SdrAllFillAttributesHelperPtr  maFillAttributes;
 
+    // The assigned list.
+    SwFrmFmts *list;
+
 protected:
     SwFrmFmt(
         SwAttrPool& rPool,
@@ -142,6 +147,7 @@ public:
     //UUUU Access to DrawingLayer FillAttributes in a preprocessed form for primitive usage
     virtual drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const SAL_OVERRIDE;
     virtual bool supportsFullDrawingLayerFillAttributeSet() const SAL_OVERRIDE;
+    virtual void SetName( const OUString& rNewName, bool bBroadcast=false );
 };
 
 // The FlyFrame-Format
diff --git a/sw/source/core/doc/CntntIdxStore.cxx b/sw/source/core/doc/CntntIdxStore.cxx
index 40dcd3e..f38b6f0 100644
--- a/sw/source/core/doc/CntntIdxStore.cxx
+++ b/sw/source/core/doc/CntntIdxStore.cxx
@@ -316,8 +316,11 @@ void CntntIdxStoreImpl::SaveFlys(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt,
             return; // if we have a layout and no DrawObjs, we can skip this
     }
     MarkEntry aSave = { 0, false, 0 };
-    BOOST_FOREACH(const SwFrmFmt* pFrmFmt, *pDoc->GetSpzFrmFmts())
+
+    SwFrmFmts *pSpzFrmFmts = pDoc->GetSpzFrmFmts();
+    for (SwFrmFmts::const_iterator it = pSpzFrmFmts->begin(); it != pSpzFrmFmts->end(); it++)
     {
+        const SwFrmFmt *pFrmFmt = *it;
         if ( RES_FLYFRMFMT == pFrmFmt->Which() || RES_DRAWFRMFMT == pFrmFmt->Which() )
         {
             bool bSkip = false;
diff --git a/sw/source/core/doc/DocumentLinksAdministrationManager.cxx b/sw/source/core/doc/DocumentLinksAdministrationManager.cxx
index 0d2633c..f9b7589 100644
--- a/sw/source/core/doc/DocumentLinksAdministrationManager.cxx
+++ b/sw/source/core/doc/DocumentLinksAdministrationManager.cxx
@@ -266,9 +266,10 @@ bool DocumentLinksAdministrationManager::GetData( const OUString& rItem, const O
     }
 
     _FindItem aPara( GetAppCharClass().lowercase( rItem ));
-    BOOST_FOREACH( const SwFrmFmt* pFmt, *m_rDoc.GetTblFrmFmts() )
+    const SwFrmFmts *mpTblFrmFmtTbl = m_rDoc.GetTblFrmFmts();
+    for (SwFrmFmts::const_iterator it = mpTblFrmFmtTbl->begin(); it != mpTblFrmFmtTbl->end(); it++)
     {
-        if (!(lcl_FindTable(pFmt, &aPara)))
+        if (!(lcl_FindTable(*it, &aPara)))
             break;
     }
     if( aPara.pTblNd )
@@ -310,9 +311,10 @@ bool DocumentLinksAdministrationManager::SetData( const OUString& rItem, const O
 
     OUString sItem(GetAppCharClass().lowercase(rItem));
     _FindItem aPara( sItem );
-    BOOST_FOREACH( const SwFrmFmt* pFmt, *m_rDoc.GetTblFrmFmts() )
+    const SwFrmFmts *mpTblFrmFmtTbl = m_rDoc.GetTblFrmFmts();
+    for (SwFrmFmts::const_iterator it = mpTblFrmFmtTbl->begin(); it != mpTblFrmFmtTbl->end(); it++)
     {
-        if (!(lcl_FindTable(pFmt, &aPara)))
+        if (!(lcl_FindTable(*it, &aPara)))
             break;
     }
     if( aPara.pTblNd )
@@ -368,10 +370,10 @@ bool DocumentLinksAdministrationManager::SetData( const OUString& rItem, const O
     }
 
     _FindItem aPara( GetAppCharClass().lowercase(rItem) );
-    // tables
-    BOOST_FOREACH( const SwFrmFmt* pFmt, *m_rDoc.GetTblFrmFmts() )
+    const SwFrmFmts *mpTblFrmFmtTbl = m_rDoc.GetTblFrmFmts();
+    for (SwFrmFmts::const_iterator it = mpTblFrmFmtTbl->begin(); it != mpTblFrmFmtTbl->end(); it++)
     {
-        if (!(lcl_FindTable(pFmt, &aPara)))
+        if (!(lcl_FindTable(*it, &aPara)))
             break;
     }
     if(aPara.pTblNd
@@ -458,9 +460,10 @@ bool DocumentLinksAdministrationManager::SelectServerObj( const OUString& rStr,
         if( sCmp == "table" )
         {
             sName = rCC.lowercase( sName );
-            BOOST_FOREACH( const SwFrmFmt* pFmt, *m_rDoc.GetTblFrmFmts() )
+            const SwFrmFmts *mpTblFrmFmtTbl = m_rDoc.GetTblFrmFmts();
+            for (SwFrmFmts::const_iterator it = mpTblFrmFmtTbl->begin(); it != mpTblFrmFmtTbl->end(); it++)
             {
-                if (!(lcl_FindTable(pFmt, &aPara)))
+                if (!(lcl_FindTable(*it, &aPara)))
                     break;
             }
             if( aPara.pTblNd )
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index 50e8e2f..c90e562 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -75,7 +75,7 @@ void _RestFlyInRange( _SaveFlyArr & rArr, const SwNodeIndex& rSttIdx,
         aPos.nContent.Assign( 0, 0 );
         SwFmtAnchor aAnchor( pFmt->GetAnchor() );
         aAnchor.SetAnchor( &aPos );
-        pFmt->GetDoc()->GetSpzFrmFmts()->push_back( pFmt );
+        pFmt->GetDoc()->GetSpzFrmFmts()->insert( pFmt );
         pFmt->SetFmtAttr( aAnchor );
         SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode();
         if( pCNd && pCNd->getLayoutFrm( pFmt->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), 0, 0, false ) )
@@ -209,7 +209,7 @@ void DelFlyInRange( const SwNodeIndex& rMkNdIdx,
                     if( i > rTbl.size() )
                         i = rTbl.size();
                     else if( pFmt != rTbl[i] )
-                        i = rTbl.GetPos( pFmt );
+                        i = std::distance(rTbl.begin(), rTbl.find( pFmt ));
                 }
 
                 pDoc->getIDocumentLayoutAccess().DelLayoutFmt( pFmt );
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 5532aed..c6566f2 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -670,8 +670,8 @@ void SwDoc::DelCharFmt(sal_uInt16 nFmt, bool bBroadcast)
         GetIDocumentUndoRedo().AppendUndo(pUndo);
     }
 
-    delete (*mpCharFmtTbl)[nFmt];
     mpCharFmtTbl->erase(mpCharFmtTbl->begin() + nFmt);
+    delete pDel;
 
     getIDocumentState().SetModified();
 }
@@ -693,10 +693,8 @@ void SwDoc::DelFrmFmt( SwFrmFmt *pFmt, bool bBroadcast )
     }
     else
     {
-
         // The format has to be in the one or the other, we'll see in which one.
-        SwFrmFmts::iterator it = std::find( mpFrmFmtTbl->begin(), mpFrmFmtTbl->end(), pFmt );
-        if ( it != mpFrmFmtTbl->end() )
+        if ( mpFrmFmtTbl->Contains( pFmt ) )
         {
             if (bBroadcast)
                 BroadcastStyleOperation(pFmt->GetName(),
@@ -710,17 +708,17 @@ void SwDoc::DelFrmFmt( SwFrmFmt *pFmt, bool bBroadcast )
                 GetIDocumentUndoRedo().AppendUndo(pUndo);
             }
 
-            delete *it;
-            mpFrmFmtTbl->erase(it);
+            mpFrmFmtTbl->erase( pFmt );
+            delete pFmt;
         }
         else
         {
-            SwFrmFmts::iterator it2 = std::find( GetSpzFrmFmts()->begin(), GetSpzFrmFmts()->end(), pFmt );
-            OSL_ENSURE( it2 != GetSpzFrmFmts()->end(), "FrmFmt not found." );
-            if( it2 != GetSpzFrmFmts()->end() )
+            bool contains = GetSpzFrmFmts()->Contains( pFmt );
+            OSL_ENSURE( contains, "FrmFmt not found." );
+            if( contains )
             {
-                delete *it2;
-                GetSpzFrmFmts()->erase( it2 );
+                GetSpzFrmFmts()->erase( pFmt );
+                delete pFmt;
             }
         }
     }
@@ -728,10 +726,10 @@ void SwDoc::DelFrmFmt( SwFrmFmt *pFmt, bool bBroadcast )
 
 void SwDoc::DelTblFrmFmt( SwTableFmt *pFmt )
 {
-    SwFrmFmts::iterator it = std::find( mpTblFrmFmtTbl->begin(), mpTblFrmFmtTbl->end(), pFmt );
+    SwFrmFmts::const_iterator it = mpTblFrmFmtTbl->find( pFmt );
     OSL_ENSURE( it != mpTblFrmFmtTbl->end(), "Fmt not found," );
-    delete *it;
-    mpTblFrmFmtTbl->erase(it);
+    mpTblFrmFmtTbl->erase( it );
+    delete pFmt;
 }
 
 /// Create the formats
@@ -739,7 +737,7 @@ SwFlyFrmFmt *SwDoc::MakeFlyFrmFmt( const OUString &rFmtName,
                                     SwFrmFmt *pDerivedFrom )
 {
     SwFlyFrmFmt *pFmt = new SwFlyFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom );
-    GetSpzFrmFmts()->push_back(pFmt);
+    GetSpzFrmFmts()->insert(pFmt);
     getIDocumentState().SetModified();
     return pFmt;
 }
@@ -748,7 +746,7 @@ SwDrawFrmFmt *SwDoc::MakeDrawFrmFmt( const OUString &rFmtName,
                                      SwFrmFmt *pDerivedFrom )
 {
     SwDrawFrmFmt *pFmt = new SwDrawFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom);
-    GetSpzFrmFmts()->push_back(pFmt);
+    GetSpzFrmFmts()->insert(pFmt);
     getIDocumentState().SetModified();
     return pFmt;
 }
@@ -789,9 +787,8 @@ SwTableFmt* SwDoc::MakeTblFrmFmt( const OUString &rFmtName,
                                     SwFrmFmt *pDerivedFrom )
 {
     SwTableFmt* pFmt = new SwTableFmt( GetAttrPool(), rFmtName, pDerivedFrom );
-    mpTblFrmFmtTbl->push_back( pFmt );
+    mpTblFrmFmtTbl->insert( pFmt );
     getIDocumentState().SetModified();
-
     return pFmt;
 }
 
@@ -802,7 +799,7 @@ SwFrmFmt *SwDoc::MakeFrmFmt(const OUString &rFmtName,
     SwFrmFmt *pFmt = new SwFrmFmt( GetAttrPool(), rFmtName, pDerivedFrom );
 
     pFmt->SetAuto(bAuto);
-    mpFrmFmtTbl->push_back( pFmt );
+    mpFrmFmtTbl->insert( pFmt );
     getIDocumentState().SetModified();
 
     if (GetIDocumentUndoRedo().DoesUndo())
@@ -2010,4 +2007,87 @@ namespace docfunc
     }
 }
 
+SwFrmFmts::~SwFrmFmts()
+{
+    DeleteAndDestroyAll();
+}
+
+void SwFrmFmts::DeleteAndDestroyAll( bool keepDefault )
+{
+    if ( empty() )
+        return;
+    const int _offset = keepDefault ? 1 : 0;
+    for( const_iterator it = begin() + _offset; it != end(); ++it )
+        delete *it;
+    if ( _offset )
+        SwFrmFmtsBase::erase( begin_nonconst() + _offset, end_nonconst() );
+    else
+        clear();
+}
+
+SwFrmFmts::find_insert_type SwFrmFmts::insert( const value_type& x )
+{
+    SwFrmFmtsBase::push_back( x );
+    SAL_WARN_IF(x->list != 0, "sw", "Inserting already assigned item");
+    x->list = this;
+    return std::make_pair(end() - 1 , true);
+}
+
+SwFrmFmts::size_type SwFrmFmts::erase( const value_type& x )
+{
+    const_iterator const ret = find( x );
+    SAL_WARN_IF(x->list != this, "sw", "Removing invalid / unassigned item");
+    if (ret != end()) {
+        SwFrmFmtsBase::erase( begin_nonconst() + (ret - begin()) );
+        x->list = 0;
+        return 1;
+    }
+    return 0;
+}
+
+void SwFrmFmts::erase( size_type index )
+{
+    erase( begin_nonconst() + index );
+}
+
+void SwFrmFmts::erase( const_iterator const& position )
+{
+    (*position)->list = 0;
+    SwFrmFmtsBase::erase( begin_nonconst() + (position - begin()) );
+}
+
+SwFrmFmts::const_iterator SwFrmFmts::find( const value_type& x ) const
+{
+    return std::find( begin(), end(), x );
+}
+
+bool SwFrmFmts::Contains( const SwFrmFmts::value_type& x ) const
+{
+    return (x->list == this);
+}
+
+bool SwFrmFmts::newDefault( const value_type& x )
+{
+    bool inserted = false;
+    const_iterator it = find( x );
+    if (it == end()) {
+        push_back( x );
+        it = end() - 1;
+        inserted = true;
+    }
+    newDefault( it );
+    return inserted;
+}
+
+void SwFrmFmts::newDefault( const_iterator const& position )
+{
+    if (position == begin())
+        return;
+    SwFrmFmt *tmp;
+    tmp = front();
+    erase( position );
+    SwFrmFmtsBase::operator[]( 0 ) = *position;
+    insert( tmp );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index 7704f90..f0f5864 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -1411,7 +1411,7 @@ void SwDoc::SetAllUniqueFlyNames()
 
     if( 255 < ( n = GetSpzFrmFmts()->size() ))
         n = 255;
-    SwFrmFmts aArr;
+    SwFrmFmtsV aArr;
     aArr.reserve( n );
     SwFrmFmt* pFlyFmt;
     bool bContainsAtPageObjWithContentAnchor = false;
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 693dee7..d12321d 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -305,7 +305,7 @@ SwDoc::SwDoc()
      * DefaultFormats and are also in the list.
      */
     /* Formats */
-    mpFrmFmtTbl->push_back(mpDfltFrmFmt);
+    mpFrmFmtTbl->insert(mpDfltFrmFmt);
     mpCharFmtTbl->push_back(mpDfltCharFmt);
 
     /* FmtColls */
@@ -477,10 +477,10 @@ SwDoc::~SwDoc()
 
     // Any of the FrmFormats can still have indices registered.
     // These need to be destroyed now at the latest.
-    BOOST_FOREACH( SwFrmFmt* pFmt, *mpFrmFmtTbl )
-        lcl_DelFmtIndices( pFmt );
-    BOOST_FOREACH( SwFrmFmt* pFmt, *mpSpzFrmFmtTbl )
-        lcl_DelFmtIndices( pFmt );
+    for (SwFrmFmts::const_iterator it = mpFrmFmtTbl->begin(); it != mpFrmFmtTbl->end(); it++)
+        lcl_DelFmtIndices( *it );
+    for (SwFrmFmts::const_iterator it = mpSpzFrmFmtTbl->begin(); it != mpSpzFrmFmtTbl->end(); it++)
+        lcl_DelFmtIndices( *it );
     BOOST_FOREACH( SwSectionFmt* pFmt, *mpSectionFmtTbl )
         lcl_DelFmtIndices( pFmt );
 
@@ -541,7 +541,7 @@ SwDoc::~SwDoc()
     // All Flys need to be destroyed before the Drawing Model,
     // because Flys can still contain DrawContacts, when no
     // Layout could be constructed due to a read error.
-    mpSpzFrmFmtTbl->DeleteAndDestroy( 0, mpSpzFrmFmtTbl->size() );
+    mpSpzFrmFmtTbl->DeleteAndDestroyAll();
 
     // Only now destroy the Model, the drawing objects - which are also
     // contained in the Undo - need to remove their attributes from the
@@ -714,12 +714,12 @@ void SwDoc::ClearDoc()
     if( getIDocumentLayoutAccess().GetCurrentViewShell() )
     {
         // search the FrameFormat of the root frm. This is not allowed to delete
-        mpFrmFmtTbl->erase( std::find( mpFrmFmtTbl->begin(), mpFrmFmtTbl->end(), getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFmt() ) );
-        mpFrmFmtTbl->DeleteAndDestroy(1, mpFrmFmtTbl->size());
-        mpFrmFmtTbl->push_back( getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFmt() );
+        mpFrmFmtTbl->erase( getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFmt() );
+        mpFrmFmtTbl->DeleteAndDestroyAll( true );
+        mpFrmFmtTbl->insert( getIDocumentLayoutAccess().GetCurrentViewShell()->GetLayout()->GetFmt() );
     }
     else
-        mpFrmFmtTbl->DeleteAndDestroy(1, mpFrmFmtTbl->size());
+        mpFrmFmtTbl->DeleteAndDestroyAll( true );
 
     mxForbiddenCharsTable.clear();
 
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 4f10aeb..f9668d6 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -149,11 +149,8 @@ bool SwFEShell::Copy( SwDoc* pClpDoc, const OUString* pNewClpTxt )
         SwFrmFmts& rSpzFrmFmts = *(SwFrmFmts*)pClpDoc->GetSpzFrmFmts();
         if( rSpzFrmFmts[ 0 ] != pFlyFmt )
         {
-            SwFrmFmts::iterator it = std::find( rSpzFrmFmts.begin(), rSpzFrmFmts.end(), pFlyFmt );
-            OSL_ENSURE( it != rSpzFrmFmts.end(), "Fly not contained in Spz-Array" );
-
-            rSpzFrmFmts.erase( it );
-            rSpzFrmFmts.insert( rSpzFrmFmts.begin(), pFlyFmt );
+            bool inserted = rSpzFrmFmts.newDefault( pFlyFmt );
+            OSL_ENSURE( !inserted, "Fly not contained in Spz-Array" );
         }
 
         if ( FLY_AS_CHAR == aAnchor.GetAnchorId() )
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 54e710d..0b030dd 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -2407,7 +2407,8 @@ SwFrmFmt::SwFrmFmt(
     const sal_uInt16* pWhichRange)
 :   SwFmt(rPool, pFmtNm, (pWhichRange ? pWhichRange : aFrmFmtSetRange), pDrvdFrm, nFmtWhich),
     m_wXObject(),
-    maFillAttributes()
+    maFillAttributes(),
+    list(0)
 {
 }
 
@@ -2419,7 +2420,8 @@ SwFrmFmt::SwFrmFmt(
     const sal_uInt16* pWhichRange)
 :   SwFmt(rPool, rFmtNm, (pWhichRange ? pWhichRange : aFrmFmtSetRange), pDrvdFrm, nFmtWhich),
     m_wXObject(),
-    maFillAttributes()
+    maFillAttributes(),
+    list(0)
 {
 }
 
@@ -2433,6 +2435,28 @@ SwFrmFmt::~SwFrmFmt()
     }
 }
 
+void SwFrmFmt::SetName( const OUString& rNewName, bool bBroadcast )
+{
+    SwFrmFmts *_list = list;
+    SwFrmFmts::const_iterator it;
+    bool move_entry = false;
+
+    if (list) {
+        it = list->find( this );
+        SAL_WARN_IF( list->end() == it, "sw", "SwFrmFmt not found in expected list" );
+//        move_entry = (it != list->begin());
+        if (move_entry)
+            // Clears list
+            list->erase( it );
+    }
+
+    SwFmt::SetName( rNewName, bBroadcast );
+
+    if (_list && move_entry)
+        // Sets list
+        _list->insert( this );
+}
+
 bool SwFrmFmt::supportsFullDrawingLayerFillAttributeSet() const
 {
     return true;
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index c545586..d5beddd 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -1151,14 +1151,15 @@ static void lcl_AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
     //because we neither use character bound frames nor objects which
     //are anchored to character bounds.
 
-    SwFrmFmts aCpy( *pTbl );
+    SwFrmFmtsV aCpy;
+    aCpy.insert(aCpy.end(), pTbl->begin(), pTbl->end());
 
     sal_uInt16 nOldCnt = USHRT_MAX;
 
     while ( !aCpy.empty() && aCpy.size() != nOldCnt )
     {
         nOldCnt = aCpy.size();
-        SwFrmFmts::iterator it = aCpy.begin();
+        SwFrmFmtsV::iterator it = aCpy.begin();
         while ( it != aCpy.end() )
         {
             SwFrmFmt *pFmt = *it;
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index 7263545..4d4b157 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -593,8 +593,8 @@ void SwTxtNode::GetMinMaxSize( sal_uLong nIndex, sal_uLong& rMin, sal_uLong &rMa
         if( pTmp )
         {
             aNodeArgs.nIndx = nIndex;
-            BOOST_FOREACH( SwFrmFmt *pFmt, *pTmp )
-                lcl_MinMaxNode( pFmt, &aNodeArgs );
+            for (SwFrmFmts::const_iterator it = pTmp->begin(); it != pTmp->end(); it++ )
+                lcl_MinMaxNode( *it, &aNodeArgs );
         }
     }
     if( aNodeArgs.nLeftRest < 0 )
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
index a8429e8..d9a0d8f 100644
--- a/sw/source/core/undo/rolbck.cxx
+++ b/sw/source/core/undo/rolbck.cxx
@@ -874,8 +874,7 @@ void SwHistoryChangeFlyAnchor::SetInDoc( SwDoc* pDoc, bool )
 {
     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
 
-    const sal_uInt16 nPos = pDoc->GetSpzFrmFmts()->GetPos( &m_rFmt );
-    if ( USHRT_MAX != nPos )    // Format does still exist
+    if ( pDoc->GetSpzFrmFmts()->Contains( &m_rFmt ) )    // Format does still exist
     {
         SwFmtAnchor aTmp( m_rFmt.GetAnchor() );
 
@@ -913,12 +912,12 @@ SwHistoryChangeFlyChain::SwHistoryChangeFlyChain( SwFlyFrmFmt& rFmt,
 
 void SwHistoryChangeFlyChain::SetInDoc( SwDoc* pDoc, bool )
 {
-    if ( USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pFlyFmt ) )
+    if ( pDoc->GetSpzFrmFmts()->Contains( m_pFlyFmt ) )
     {
         SwFmtChain aChain;
 
         if ( m_pPrevFmt &&
-             USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pPrevFmt ) )
+             pDoc->GetSpzFrmFmts()->Contains( m_pPrevFmt ) )
         {
             aChain.SetPrev( m_pPrevFmt );
             SwFmtChain aTmp( m_pPrevFmt->GetChain() );
@@ -927,7 +926,7 @@ void SwHistoryChangeFlyChain::SetInDoc( SwDoc* pDoc, bool )
         }
 
         if ( m_pNextFmt &&
-             USHRT_MAX != pDoc->GetSpzFrmFmts()->GetPos( m_pNextFmt ) )
+             pDoc->GetSpzFrmFmts()->Contains( m_pNextFmt ) )
         {
             aChain.SetNext( m_pNextFmt );
             SwFmtChain aTmp( m_pNextFmt->GetChain() );
diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx
index 43c23ed..cfaf768 100644
--- a/sw/source/core/undo/unattr.cxx
+++ b/sw/source/core/undo/unattr.cxx
@@ -287,11 +287,9 @@ bool SwUndoFmtAttr::IsFmtInDoc( SwDoc* pDoc )
             // no break!
         case RES_DRAWFRMFMT:
         case RES_FLYFRMFMT:
-            nPos = pDoc->GetSpzFrmFmts()->GetPos( m_pFmt );
-            if ( USHRT_MAX == nPos )
-            {
-                nPos = pDoc->GetFrmFmts()->GetPos( m_pFmt );
-            }
+            if (pDoc->GetSpzFrmFmts()->Contains( m_pFmt )
+                    || pDoc->GetFrmFmts()->Contains( m_pFmt ))
+                nPos = 1;
             break;
     }
 
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx
index 085cf31..ff9840e 100644
--- a/sw/source/core/undo/undobj1.cxx
+++ b/sw/source/core/undo/undobj1.cxx
@@ -61,7 +61,7 @@ void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrm)
 
     // add again into array
     SwFrmFmts& rFlyFmts = *(SwFrmFmts*)pDoc->GetSpzFrmFmts();
-    rFlyFmts.push_back( pFrmFmt );
+    rFlyFmts.insert( pFrmFmt );
 
     // OD 26.06.2003 #108784# - insert 'master' drawing object into drawing page
     if ( RES_DRAWFRMFMT == pFrmFmt->Which() )
@@ -220,7 +220,7 @@ void SwUndoFlyBase::DelFly( SwDoc* pDoc )
 
     // delete from array
     SwFrmFmts& rFlyFmts = *(SwFrmFmts*)pDoc->GetSpzFrmFmts();
-    rFlyFmts.erase( std::find( rFlyFmts.begin(), rFlyFmts.end(), pFrmFmt ));
+    rFlyFmts.erase( pFrmFmt );
 }
 
 SwUndoInsLayFmt::SwUndoInsLayFmt( SwFrmFmt* pFormat, sal_uLong nNodeIdx, sal_Int32 nCntIdx )
@@ -537,7 +537,7 @@ void SwUndoSetFlyFmt::UndoImpl(::sw::UndoRedoContext & rContext)
     SwDoc & rDoc = rContext.GetDoc();
 
     // Is the new Format still existent?
-    if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( pOldFmt ) )
+    if( rDoc.GetFrmFmts()->Contains( pOldFmt ) )
     {
         if( bAnchorChgd )
             pFrmFmt->DelFrms();
@@ -610,7 +610,7 @@ void SwUndoSetFlyFmt::RedoImpl(::sw::UndoRedoContext & rContext)
     SwDoc & rDoc = rContext.GetDoc();
 
     // Is the new Format still existent?
-    if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( pNewFmt ) )
+    if( rDoc.GetFrmFmts()->Contains( pNewFmt ) )
     {
 
         if( bAnchorChgd )
diff --git a/sw/source/core/undo/undraw.cxx b/sw/source/core/undo/undraw.cxx
index 570c460..0e93bc5 100644
--- a/sw/source/core/undo/undraw.cxx
+++ b/sw/source/core/undo/undraw.cxx
@@ -234,7 +234,7 @@ void SwUndoDrawGroup::UndoImpl(::sw::UndoRedoContext &)
         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
 
         ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
-        rFlyFmts.push_back( rSave.pFmt );
+        rFlyFmts.insert( rSave.pFmt );
 
         pObj = rSave.pObj;
 
@@ -283,7 +283,7 @@ void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
 
     // re-insert group object
     ::lcl_RestoreAnchor( pObjArr->pFmt, pObjArr->nNodeIdx );
-    rFlyFmts.push_back( pObjArr->pFmt );
+    rFlyFmts.insert( pObjArr->pFmt );
 
     SwDrawContact *pContact = new SwDrawContact( pObjArr->pFmt, pObjArr->pObj );
     // #i26791# - correction: connect object to layout
@@ -382,7 +382,7 @@ void SwUndoDrawUnGroup::UndoImpl(::sw::UndoRedoContext & rContext)
 
     // re-insert group object
     ::lcl_RestoreAnchor( pObjArr->pFmt, pObjArr->nNodeIdx );
-    rFlyFmts.push_back( pObjArr->pFmt );
+    rFlyFmts.insert( pObjArr->pFmt );
 
     SwDrawContact *pContact = new SwDrawContact( pObjArr->pFmt, pObjArr->pObj );
     pContact->ConnectToLayout();
@@ -425,7 +425,7 @@ void SwUndoDrawUnGroup::RedoImpl(::sw::UndoRedoContext &)
         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
 
         ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
-        rFlyFmts.push_back( rSave.pFmt );
+        rFlyFmts.insert( rSave.pFmt );
 
         // #i45952# - notify that position attributes are already set
         OSL_ENSURE( rSave.pFmt->ISA(SwDrawFrmFmt),
@@ -521,7 +521,7 @@ void SwUndoDrawDelete::UndoImpl(::sw::UndoRedoContext & rContext)
     {
         SwUndoGroupObjImpl& rSave = *( pObjArr + n );
         ::lcl_RestoreAnchor( rSave.pFmt, rSave.nNodeIdx );
-        rFlyFmts.push_back( rSave.pFmt );
+        rFlyFmts.insert( rSave.pFmt );
         SdrObject *pObj = rSave.pObj;
         SwDrawContact *pContact = new SwDrawContact( rSave.pFmt, pObj );
         pContact->_Changed( *pObj, SDRUSERCALL_INSERTED, NULL );
diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx
index aafa683..29796ad 100644
--- a/sw/source/core/undo/untbl.cxx
+++ b/sw/source/core/undo/untbl.cxx
@@ -120,7 +120,7 @@ class _SaveTable
     _SaveLine* pLine;
     const SwTable* pSwTable;
     SfxItemSets aSets;
-    SwFrmFmts aFrmFmts;
+    SwFrmFmtsV aFrmFmts;
     sal_uInt16 nLineCount;
     bool bModifyBox : 1;
     bool bSaveFormula : 1;
diff --git a/sw/source/filter/basflt/shellio.cxx b/sw/source/filter/basflt/shellio.cxx
index 497d11c..bcd7a49 100644
--- a/sw/source/filter/basflt/shellio.cxx
+++ b/sw/source/filter/basflt/shellio.cxx
@@ -136,7 +136,7 @@ sal_uLong SwReader::Read( const Reader& rOptions )
     RedlineMode_t ePostReadRedlineMode( nsRedlineMode_t::REDLINE_IGNORE );
 
     // Array of FlyFormats
-    SwFrmFmts aFlyFrmArr;
+    SwFrmFmtsV aFlyFrmArr;
     // only read templates? then ignore multi selection!
     bool bFmtsOnly = po->aOpt.IsFmtsOnly();
 
@@ -158,8 +158,8 @@ sal_uLong SwReader::Read( const Reader& rOptions )
         // store for now all Fly's
         if( pCrsr )
         {
-            std::copy(pDoc->GetSpzFrmFmts()->begin(),
-                pDoc->GetSpzFrmFmts()->end(), std::back_inserter(aFlyFrmArr));
+            aFlyFrmArr.insert(aFlyFrmArr.end(), pDoc->GetSpzFrmFmts()->begin(),
+                pDoc->GetSpzFrmFmts()->end());
         }
 
         const sal_Int32 nSttCntnt = pPam->GetPoint()->nContent.GetIndex();
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx
index a2dd8ee..3895463 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -1000,7 +1000,7 @@ sal_uInt32 WW8Export::GetSdrOrdNum( const SwFrmFmt& rFmt ) const
     {
         // no Layout for this format, then recalc the ordnum
         SwFrmFmt* pFmt = (SwFrmFmt*)&rFmt;
-        nOrdNum = pDoc->GetSpzFrmFmts()->GetPos( pFmt );
+        nOrdNum = std::distance(pDoc->GetSpzFrmFmts()->begin(), pDoc->GetSpzFrmFmts()->find( pFmt ) );
 
         const SwDrawModel* pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
         if( pModel )
commit a3ea52838f3828f41242c9ecf80bd8c4b1b400f2
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Sun Jun 8 01:57:54 2014 +0200

    Add sorted vector special case for delete all
    
    Specializes DeleteAndDestroyAll() to optionally keep the default
    item.
    
    Change-Id: I570fc6614a59fcf08c4569d44873ed79f4af5eda

diff --git a/include/o3tl/sorted_vector.hxx b/include/o3tl/sorted_vector.hxx
index c1f507d..11eb85d 100644
--- a/include/o3tl/sorted_vector.hxx
+++ b/include/o3tl/sorted_vector.hxx
@@ -198,11 +198,18 @@ public:
     }
 
     /* Clear() elements in the vector, and free them one by one. */
-    void DeleteAndDestroyAll()
+    void DeleteAndDestroyAll( bool keepDefault=false )
     {
-        for( const_iterator it = begin(); it != end(); ++it )
+        if ( empty() )
+            return;
+
+        const int _Offset = (keepDefault && mOffset) ? mOffset : 0;
+        for( const_iterator it = begin() + _Offset; it != end(); ++it )
             delete *it;
-        clear();
+        if ( _Offset )
+            base_t::erase( begin_nonconst() + _Offset, end_nonconst() );
+        else
+            clear();
     }
 
     // fdo#58793: some existing code in Writer (SwpHintsArray)
diff --git a/o3tl/qa/test-sorted_vector.cxx b/o3tl/qa/test-sorted_vector.cxx
index 9a89081..dc62c24 100644
--- a/o3tl/qa/test-sorted_vector.cxx
+++ b/o3tl/qa/test-sorted_vector.cxx
@@ -364,6 +364,10 @@ public:
         CPPUNIT_ASSERT( aVec[4] == p3 );
         CPPUNIT_ASSERT( aVec[5] == p4 );
 
+        aVec.DeleteAndDestroyAll( true );
+        CPPUNIT_ASSERT( aVec.size() == 1 );
+        aVec.DeleteAndDestroyAll( true );
+        CPPUNIT_ASSERT( aVec.size() == 1 );
         aVec.DeleteAndDestroyAll();
     }
 
commit b417ce82cc55933418f32ceb657223022d03f13e
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Nov 11 17:01:32 2014 +0100

    Optimize AppendAllObjs for vectors
    
    Removing items from large vectors, especially from the front, is
    very expensive. For a large mail merge job it took most of the time
    to memmove the descending vector items.
    
    Instead of remove, this simply overwrites the current with the last
    element.
    
    Change-Id: I12395388f4e315009602984acb443382fcce9f44

diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index a3dc23f..c545586 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -1143,7 +1143,7 @@ static bool lcl_InHeaderOrFooter( const SwFrmFmt& _rFmt )
     return bRetVal;
 }
 
-void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
+static void lcl_AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
 {
     //Connecting of all Objects, which are described in the SpzTbl with the
     //layout.
@@ -1151,21 +1151,17 @@ void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
     //because we neither use character bound frames nor objects which
     //are anchored to character bounds.
 
-    // Optimization: This code used to make a copy of pTbl and erase() handled items, but using
-    // vector::erase() is a bad idea for performance (especially with large mailmerge documents
-    // it results in extensive repeated copying). Use another vector for marking whether the item
-    // has been handled and operate on the original data without altering them.
-    std::vector< bool > handled( pTbl->size(), false );
-    size_t handledCount = 0;
+    SwFrmFmts aCpy( *pTbl );
 
-    while ( handledCount < pTbl->size())
+    sal_uInt16 nOldCnt = USHRT_MAX;
+
+    while ( !aCpy.empty() && aCpy.size() != nOldCnt )
     {
-        bool changed = false;
-        for ( int i = 0; i < int(pTbl->size()); ++i )
+        nOldCnt = aCpy.size();
+        SwFrmFmts::iterator it = aCpy.begin();
+        while ( it != aCpy.end() )
         {
-            if( handled[ i ] )
-                continue;
-            SwFrmFmt *pFmt = (*pTbl)[ i ];
+            SwFrmFmt *pFmt = *it;
             const SwFmtAnchor &rAnch = pFmt->GetAnchor();
             bool bRemove = false;
             if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
@@ -1189,14 +1185,20 @@ void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
             }
             if ( bRemove )
             {
-                handled[ i ] = true;
-                ++handledCount;
-                changed = true;
+                if ( (*it) != aCpy.back() ) {
+                    (*it) = aCpy.back();
+                    aCpy.pop_back();
+                }
+                else {
+                    aCpy.pop_back();
+                    it = aCpy.end();
+                }
             }
+            else
+                it++;
         }
-        if( !changed )
-            break;
     }
+    aCpy.clear();
 }
 
 /** local method to set 'working' position for newly inserted frames
@@ -1588,7 +1590,7 @@ void _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
     if ( bPages ) // let the Flys connect to each other
     {
         if ( !bDontCreateObjects )
-            AppendAllObjs( pTbl, pLayout );
+            ::lcl_AppendAllObjs( pTbl, pLayout );
         bObjsDirect = true;
     }
 
@@ -1778,7 +1780,7 @@ void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
                 {
                     const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
                     if( !pTbl->empty() )
-                        AppendAllObjs( pTbl, pUpper );
+                        ::lcl_AppendAllObjs( pTbl, pUpper );
                 }
 
                 // If nothing was added (e.g. a hidden section), the split must be reversed.
commit 7d304739f2a04036f4be410cf62e0dc754a168d6
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Jun 6 09:44:34 2014 +0200

    Directly convert frame name tails to Int32
    
    This is a little optimization for large mail merge jobs with many
    frames. The current alorithm doesn't only try to produce unique but
    also reasonable names for the frames.
    
    Per se the algorithm is horrible ineffective for large numbers of
    frames, but this is impossible to fix without changing the
    underlying vector of frames to a sorted one to find and check just
    the correctly prefixed frames.
    
    This patch directly converts the frame names tail instead of
    creating substring of the number tail, which saves billions of
    malloc and free calls seen with my sample document.
    
    Change-Id: Iefdee4053480f40f106c49867bc5a64ec207ba1b

diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index 4bc37a0..7704f90 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -1315,7 +1315,7 @@ static OUString lcl_GetUniqueFlyName( const SwDoc* pDoc, sal_uInt16 nDefStrId )
             pFlyFmt->GetName().startsWith( aName ) )
         {
             // Only get and set the Flag
-            nNum = static_cast< sal_uInt16 >( pFlyFmt->GetName().copy( nNmLen ).toInt32() );
+            nNum = static_cast< sal_uInt16 >( rtl_ustr_toInt32( pFlyFmt->GetName().getStr() + nNmLen, 10 ) );
             if( nNum-- && nNum < rFmts.size() )
                 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
         }
commit a586328ad7593b326817b500f1ce18b9c5fbebba
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri May 16 23:42:32 2014 +0200

    Convert SwPageDescs to a o3tl::sorted_vector
    
    Originally I planned to use a boost::container::flat_map, but there
    seem to be no way to directly access the indexed vector.
    
    And since this already needs the "first item is default" special
    handling, o3tl::sorted_vector is used with the offset.
    
    Change-Id: Idfb79af8ddfd5f5e2e6ca312b46d30e3ddc166d9

diff --git a/sw/inc/pagedesc.hxx b/sw/inc/pagedesc.hxx
index 45ff8b1..a840989 100644
--- a/sw/inc/pagedesc.hxx
+++ b/sw/inc/pagedesc.hxx
@@ -26,6 +26,7 @@
 #include <frmfmt.hxx>
 #include <editeng/numitem.hxx>
 #include <editeng/borderline.hxx>
+#include <o3tl/sorted_vector.hxx>
 #include "poolfmt.hxx"
 
 class SfxPoolItem;
@@ -347,25 +348,43 @@ public:
     operator SwPageDesc() const; // #i7983#
 };
 
-typedef std::vector<SwPageDesc*> SwPageDescsBase;
+struct CompareSwPageDescs
+{
+    bool operator()(OUString const& lhs, SwPageDesc* const& rhs) const;
+    bool operator()(SwPageDesc* const& lhs, OUString const& rhs) const;
+    bool operator()(SwPageDesc* const& lhs, SwPageDesc* const& rhs) const;
+};
+
+typedef o3tl::sorted_vector<SwPageDesc*, CompareSwPageDescs> SwPageDescsBase;
 
 #define RES_POOLPAGE_SIZE (RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)
 
-// Mimics o3tl::sorted_vector interface
-class SwPageDescs : private SwPageDescsBase
+//! A list of SwPageDesc pointers sorted by name.
+/*!
+ * The list of SwPageDesc is implemented as a sorted vector. This results in
+ * fast index access O(1) and fast searches O(log n).
+ *
+ * It currently uses special case version of sorted vector, which keeps the
+ * first item out of the sorted vector, as the first item is
+ *   * non-deletable
+ *   * the default item
+ *
+ * There is some internal friend handling for the name and pool id, so these
+ * can be changed on the object and will correctly be reflected in the list.
+ *
+ * @see SwDoc::DelPageDescP
+ * @see SwPageDesc
+ */
+class SwPageDescs : public SwPageDescsBase
 {
     // to update the poolpages array on PoolFmtId change
     friend void SwPageDesc::SetPoolFmtId( sal_uInt16 nId );
 
-public:
-    typedef typename SwPageDescsBase::const_iterator const_iterator;
-    typedef typename SwPageDescsBase::size_type size_type;
-    typedef typename SwPageDescsBase::value_type value_type;
-
 private:
     // fast index for pool page resources
     value_type poolpages[RES_POOLPAGE_SIZE];
 
+    // updates the poolpages array and the SwPageDesc list member
     void _erase( const value_type& x );
     bool IsIdInPoolRange( sal_uInt16 nId, bool allowDefault ) const;
 
@@ -378,33 +397,16 @@ public:
 
     void DeleteAndDestroyAll();
 
-    using SwPageDescsBase::clear;
-    using SwPageDescsBase::empty;
-    using SwPageDescsBase::size;
-
     std::pair<const_iterator,bool> insert( const value_type& x );
     size_type erase( const value_type& x );
     void erase( size_type index );
     void erase( const_iterator const& position );
 
-    const value_type& front() const { return SwPageDescsBase::front(); }
-    const value_type& back() const { return SwPageDescsBase::back(); }
-    const value_type& operator[]( size_t index ) const
-        { return SwPageDescsBase::operator[]( index ); }
-
     const_iterator find( const OUString &name ) const;
     const_iterator find( const value_type& x ) const;
 
-    const_iterator begin() const { return SwPageDescsBase::begin(); }
-    const_iterator end() const { return SwPageDescsBase::end(); }
-
     bool Contains( const value_type& x ) const;
     value_type GetPoolPageDesc( sal_uInt16 nId ) const;
-
-private:
-    typedef typename SwPageDescsBase::iterator iterator;
-    iterator begin_nonconst() { return SwPageDescsBase::begin(); }
-    iterator end_nonconst() { return SwPageDescsBase::end(); }
 };
 
 #endif // INCLUDED_SW_INC_PAGEDESC_HXX
diff --git a/sw/source/core/layout/pagedesc.cxx b/sw/source/core/layout/pagedesc.cxx
index 0cea710..8f98da8 100644
--- a/sw/source/core/layout/pagedesc.cxx
+++ b/sw/source/core/layout/pagedesc.cxx
@@ -494,7 +494,7 @@ SwPageDescExt::operator SwPageDesc() const
     return aResult;
 }
 
-SwPageDescs::SwPageDescs()
+SwPageDescs::SwPageDescs() : SwPageDescsBase( true )
 {
     memset(poolpages, 0, sizeof(value_type) * RES_POOLPAGE_SIZE);
 }
@@ -506,10 +506,8 @@ SwPageDescs::~SwPageDescs()
 
 void SwPageDescs::DeleteAndDestroyAll()
 {
-    for( const_iterator it = begin(); it != end(); ++it )
-        delete *it;
     memset(poolpages, 0, sizeof(value_type) * RES_POOLPAGE_SIZE);
-    clear();
+    SwPageDescsBase::DeleteAndDestroyAll();
 }
 
 std::pair<SwPageDescs::const_iterator,bool> SwPageDescs::insert( const value_type& x )
@@ -518,9 +516,8 @@ std::pair<SwPageDescs::const_iterator,bool> SwPageDescs::insert( const value_typ
     SAL_WARN_IF(nId != USHRT_MAX && NULL != GetPoolPageDesc( nId ),
                 "sw", "Inserting already assigned pool ID item!");
 
-    const_iterator const ret = find( x );
-    if (ret == end()) {
-        SwPageDescsBase::push_back( x );
+    std::pair<SwPageDescs::const_iterator,bool> ret = SwPageDescsBase::insert( x );
+    if (ret.second) {
         if (x->list != 0) {
             SAL_WARN("sw", "Inserting already assigned item!");
             SAL_WARN_IF(x->list != this, "sw",
@@ -529,9 +526,8 @@ std::pair<SwPageDescs::const_iterator,bool> SwPageDescs::insert( const value_typ
         x->list = this;
         if (nId != USHRT_MAX)
             poolpages[ nId - RES_POOLPAGE_BEGIN ] = x;
-        return std::make_pair(end() - 1 , true);
     }
-    return std::make_pair(ret, false);
+    return ret;
 }
 
 void SwPageDescs::_erase( const value_type& x )
@@ -547,57 +543,60 @@ void SwPageDescs::_erase( const value_type& x )
 
 SwPageDescs::size_type SwPageDescs::erase( const value_type& x )
 {
-    const_iterator const ret = find( x );
-    if (ret != end()) {
-        SwPageDescsBase::erase( begin_nonconst() + (ret - begin()) );
+    size_type ret = SwPageDescsBase::erase( x );
+    if (ret)
         _erase( x );
-        return 1;
-    }
-    return 0;
+    return ret;
 }
 
 void SwPageDescs::erase( size_type index )
 {
-    erase( begin_nonconst() + index );
+    erase( begin() + index );
 }
 
 void SwPageDescs::erase( const_iterator const& position )
 {
     _erase( *position );
-    SwPageDescsBase::erase( begin_nonconst() + (position - begin()) );
+    SwPageDescsBase::erase( position );
+}
+
+bool CompareSwPageDescs::operator()(OUString const& lhs, SwPageDesc* const& rhs) const
+{
+    return (lhs.compareTo( rhs->GetName() ) < 0);
 }
 
-struct spd_oustring_compare : public std::unary_function<SwPageDesc*, bool>
+bool CompareSwPageDescs::operator()(SwPageDesc* const& lhs, OUString const& rhs) const
 {
-    spd_oustring_compare(const OUString &_baseline) : baseline(_baseline) {}
-    bool operator() (SwPageDesc* const &arg)
-        { return (baseline.compareTo( arg->GetName() ) == 0); }
-    const OUString baseline;
-};
+    return (lhs->GetName().compareTo( rhs ) < 0);
+}
 
-struct spd_item_compare : public std::unary_function<SwPageDesc*, bool>
+bool CompareSwPageDescs::operator()(SwPageDesc* const& lhs, SwPageDesc* const& rhs) const
 {
-    spd_item_compare(const SwPageDesc* _baseline) : baseline(_baseline) {}
-    bool operator() (SwPageDesc* const &arg)
-        { return (baseline->GetName().compareTo( arg->GetName() ) == 0); }
-    const SwPageDesc* baseline;
-};
+    return (lhs->GetName().compareTo( rhs->GetName() ) < 0);
+}
 
 SwPageDescs::const_iterator SwPageDescs::find( const OUString &name ) const
 {
-    const_iterator const it = std::find_if(
-        begin(), end(), spd_oustring_compare( name ) );
+    if (empty())
+        return end();
+
+    const_iterator it = end();
+    if (size() > 1) {
+        it = std::lower_bound( begin() + 1, end(), name, CompareSwPageDescs() );
+        if (it != end() && CompareSwPageDescs()(name, *it))
+            it = end();
+    }
+    if (it == end() && !name.compareTo( (*this)[0]->GetName() ))
+        it = begin();
     return it;
 }
 
 SwPageDescs::const_iterator SwPageDescs::find( const value_type& x ) const
 {
-    const_iterator const it = std::find_if(
-        begin(), end(), spd_item_compare( x ) );
-    return it;
+    return find( x->GetName() );
 }
 
-bool SwPageDescs::Contains( const SwPageDescs::value_type& x ) const
+bool SwPageDescs::Contains( const value_type& x ) const
 {
     return (x->list == this);
 }
commit 6e99ff2554403e21cb716d33475b43a46a311a34
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Jul 22 12:45:47 2014 +0200

    Fix broken sorted vector usage
    
    Fixes and optimizes a few places, which will fail in case of the
    sorted_vector conversation.
    
    This drops a simple optimization from the ww8 filter. I'm not
    sure it's worth to memorize and just update the new styles.
    
    Change-Id: I7a444013f59e81c81049cd40b9d9cfa0e29623c0

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index e181e11..b1ceced 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -949,6 +949,8 @@ public:
     SwPageDesc* FindPageDescByName( const OUString& rName, sal_uInt16* pPos = 0 ) const;
     SwPageDesc* FindPageDescByName( const OUString& rName, sal_uInt16* pPos = 0 );
     SwPageDesc* FindPageDescByPoolId( sal_uInt16 nPoolId );
+    bool ContainsPageDesc( const SwPageDesc* ) const;
+    bool ContainsPageDesc( const SwPageDesc& ) const;
 
     /** Copy the complete PageDesc - beyond document and "deep"!
      Optionally copying of PoolFmtId, -HlpId can be prevented. */
diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx
index 4896406..9054cca 100644
--- a/sw/inc/fesh.hxx
+++ b/sw/inc/fesh.hxx
@@ -559,11 +559,11 @@ public:
     sal_uInt16 GetMousePageDesc( const Point &rPt ) const;
     sal_uInt16 GetPageDescCnt() const;
     SwPageDesc* FindPageDescByName( const OUString& rName,
-                                    bool bGetFromPool = false,
-                                    sal_uInt16* pPos = 0 );
+                                    bool bGetFromPool = false );
 
     const SwPageDesc& GetPageDesc( sal_uInt16 i ) const;
     void  ChgPageDesc( sal_uInt16 i, const SwPageDesc& );
+    void  ChgPageDescP( const SwPageDesc&, SwPageDesc* = NULL );
     /** if inside all selection only one PageDesc, @return this.
      Otherwise @return 0 pointer */
     const SwPageDesc* GetSelectedPageDescs() const;
diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index bfdf31f..b1ef59f 100644
--- a/sw/source/core/doc/docdesc.cxx
+++ b/sw/source/core/doc/docdesc.cxx
@@ -851,6 +851,16 @@ void SwDoc::ChgPageDesc( const OUString & rName, const SwPageDesc & rDesc)
         ChgPageDescP(rDesc, pd);
 }
 
+bool SwDoc::ContainsPageDesc( const SwPageDesc *pg ) const
+{
+    return maPageDescs.Contains( const_cast<SwPageDesc*>( pg ) );
+}
+
+bool SwDoc::ContainsPageDesc( const SwPageDesc &pg ) const
+{
+    return maPageDescs.Contains( const_cast<SwPageDesc*>( &pg ) );
+}
+
 /*
  * The HTML import cannot resist changing the page descriptions, I don't
  * know why. This function is meant to check the page descriptors for invalid
diff --git a/sw/source/core/frmedt/fedesc.cxx b/sw/source/core/frmedt/fedesc.cxx
index 154c09b..e335b26 100644
--- a/sw/source/core/frmedt/fedesc.cxx
+++ b/sw/source/core/frmedt/fedesc.cxx
@@ -43,11 +43,7 @@ void SwFEShell::ChgCurPageDesc( const SwPageDesc& rDesc )
 #if OSL_DEBUG_LEVEL > 0
     // SS does not change PageDesc, but only sets the attibute.
     // The Pagedesc should be available in the document
-    bool bFound = false;
-    for ( sal_uInt16 nTst = 0; nTst < GetPageDescCnt(); ++nTst )
-        if ( &rDesc == &GetPageDesc( nTst ) )
-            bFound = true;
-    OSL_ENSURE( bFound, "ChgCurPageDesc with invalid descriptor." );
+    OSL_ENSURE( GetDoc()->ContainsPageDesc( rDesc ), "ChgCurPageDesc with invalid descriptor." );
 #endif
 
     StartAllAction();
@@ -117,24 +113,35 @@ void SwFEShell::ChgPageDesc( sal_uInt16 i, const SwPageDesc &rChged )
     EndAllActionAndCall();
 }
 
+void SwFEShell::ChgPageDescP( const SwPageDesc &rChged, SwPageDesc *pd )
+{
+    StartAllAction();
+    SET_CURR_SHELL( this );
+    //Fix i64842: because Undo has a very special way to handle header/footer content
+    // we have to copy the page descriptor before calling ChgPageDesc.
+    SwPageDesc aDesc( rChged );
+    {
+        ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
+        GetDoc()->CopyPageDesc(rChged, aDesc);
+    }
+    GetDoc()->ChgPageDescP( aDesc, pd );
+    EndAllActionAndCall();
+}
+
 const SwPageDesc& SwFEShell::GetPageDesc( sal_uInt16 i ) const
 {
     return GetDoc()->GetPageDesc( i );
 }
 
 SwPageDesc* SwFEShell::FindPageDescByName( const OUString& rName,
-                                            bool bGetFromPool,
-                                            sal_uInt16* pPos )
+                                            bool bGetFromPool )
 {
-    SwPageDesc* pDesc = GetDoc()->FindPageDescByName(rName, pPos);
+    SwPageDesc* pDesc = GetDoc()->FindPageDescByName( rName );
     if( !pDesc && bGetFromPool )
     {
         sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( rName, nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC );
-        if( USHRT_MAX != nPoolId &&
-            0 != (pDesc = GetDoc()->getIDocumentStylePoolAccess().GetPageDescFromPool( nPoolId ))
-            && pPos )
-                // appended always
-            *pPos = GetDoc()->GetPageDescCnt() - 1 ;
+        if( USHRT_MAX != nPoolId)
+            pDesc = GetDoc()->getIDocumentStylePoolAccess().GetPageDescFromPool( nPoolId );
     }
     return pDesc;
 }
diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx
index 5b94102..e6ec016 100644
--- a/sw/source/filter/basflt/fltshell.cxx
+++ b/sw/source/filter/basflt/fltshell.cxx
@@ -957,19 +957,4 @@ SfxPoolItem* SwFltTOX::Clone(SfxItemPool*) const
     return new SwFltTOX(*this);
 }
 
-// UpdatePageDescs needs to be called at end of parsing to make Writer actually
-// accept Pagedescs contents
-void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset)
-{
-    // Update document page descriptors (only this way also left pages
-    // get adjusted)
-
-    // PageDesc "Standard"
-    rDoc.ChgPageDesc(0, rDoc.GetPageDesc(0));
-
-    // PageDescs "Convert..."
-    for (sal_uInt16 i = nInPageDescOffset; i < rDoc.GetPageDescCnt(); ++i)
-        rDoc.ChgPageDesc(i, rDoc.GetPageDesc(i));
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
index 8b7a039..0a1fbf7 100644
--- a/sw/source/filter/html/htmlcss1.cxx
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -89,9 +89,9 @@ static struct SwCSS1ItemIds
 void SwCSS1Parser::ChgPageDesc( const SwPageDesc *pPageDesc,
                                 const SwPageDesc& rNewPageDesc )
 {
-    const SwPageDesc *spd =  pDoc->FindPageDescByName( pPageDesc->GetName() );
-    OSL_ENSURE( pPageDesc != spd, "Seitenvorlage nicht gefunden" );
-    if (pPageDesc == spd)
+    bool contains = pDoc->ContainsPageDesc( pPageDesc );
+    OSL_ENSURE( contains, "Seitenvorlage nicht gefunden" );
+    if( contains )
         pDoc->ChgPageDescP( rNewPageDesc, const_cast<SwPageDesc*>( pPageDesc ) );
 }
 
diff --git a/sw/source/filter/inc/fltshell.hxx b/sw/source/filter/inc/fltshell.hxx
index 3738c19..df655d5 100644
--- a/sw/source/filter/inc/fltshell.hxx
+++ b/sw/source/filter/inc/fltshell.hxx
@@ -326,8 +326,6 @@ public:
     }
 };
 
-SW_DLLPUBLIC void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset);
-
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index b8b514e..0826735 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -469,12 +469,10 @@ void RtfExport::WritePageDescTable()
         OutPageDescription(rPageDesc, false, false);
 
         // search for the next page description
-        sal_uInt16 i = nSize;
-        while (i)
-            if (rPageDesc.GetFollow() == &pDoc->GetPageDesc(--i))
-                break;
+        sal_uInt16 nPos;
+        pDoc->FindPageDescByName(rPageDesc.GetFollow()->GetName(), &nPos);
         Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PGDSCNXT);
-        OutULong(i).WriteChar(' ');
+        OutULong( nPos ).WriteChar(' ');
         Strm().WriteCharPtr(msfilter::rtfutil::OutString(rPageDesc.GetName(), eDefaultEncoding).getStr()).WriteCharPtr(";}");
     }
     Strm().WriteChar('}').WriteCharPtr(SAL_NEWLINE_STRING);
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index 8104530..5c05079 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -4986,8 +4986,6 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos)
 
     pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags);
 
-    sal_uInt16 nPageDescOffset = rDoc.GetPageDescCnt();
-
     SwNodeIndex aSttNdIdx( rDoc.GetNodes() );
     SwRelNumRuleSpaces aRelNumRule(rDoc, mbNewDoc);
 
@@ -5410,7 +5408,10 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos)
     delete pPaM, pPaM = 0;
     mpLastAnchorPos.reset();//ensure this is deleted before UpdatePageDescs
 
-    UpdatePageDescs(rDoc, nPageDescOffset);
+    // Update document page descriptors (only this way also left pages
+    // get adjusted)
+    for (sal_uInt16 i = 0; i < rDoc.GetPageDescCnt(); ++i)
+        rDoc.ChgPageDescP( rDoc.GetPageDesc(i) );
 
     return nErrRet;
 }
diff --git a/sw/source/uibase/app/appenv.cxx b/sw/source/uibase/app/appenv.cxx
index 8564a2d..1119490 100644
--- a/sw/source/uibase/app/appenv.cxx
+++ b/sw/source/uibase/app/appenv.cxx
@@ -402,13 +402,10 @@ void SwModule::InsertEnv( SfxRequest& rReq )
 
         // Apply page description
 
-        sal_uInt16 nPos;
-        pSh->FindPageDescByName( pDesc->GetName(),
-                                    false,
-                                    &nPos );
-
-        pSh->ChgPageDesc( nPos, *pDesc);
-        pSh->ChgCurPageDesc(*pDesc);
+        SwPageDesc *pd = pSh->FindPageDescByName( pDesc->GetName(),
+                                    false );
+        pSh->ChgPageDescP( *pDesc, pd );
+        pSh->ChgCurPageDesc( *pDesc );
 
         // Insert Frame
         SwFlyFrmAttrMgr aMgr(false, pSh, FRMMGR_TYPE_ENVELP);
commit a1df88f35d10e6fec9f0084d747cfaacc4e73a04
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed May 14 15:03:53 2014 +0200

    Optimize SwPageDesc lookup by pool ID
    
    There are just ten default page pool style IDs.
    
    So instead of walking the whole style list to find the matching
    style ID, this introduces an additional index / array for faster
    lookup.
    
    Change-Id: Iacfa40c76e5502dc90665be0a96388de50d5ec16

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index f41b853..e181e11 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -948,6 +948,7 @@ public:
     SwPageDesc& GetPageDesc( sal_uInt16 i ) { return *maPageDescs[i]; }
     SwPageDesc* FindPageDescByName( const OUString& rName, sal_uInt16* pPos = 0 ) const;
     SwPageDesc* FindPageDescByName( const OUString& rName, sal_uInt16* pPos = 0 );
+    SwPageDesc* FindPageDescByPoolId( sal_uInt16 nPoolId );
 
     /** Copy the complete PageDesc - beyond document and "deep"!
      Optionally copying of PoolFmtId, -HlpId can be prevented. */
diff --git a/sw/inc/pagedesc.hxx b/sw/inc/pagedesc.hxx
index 4a55307..45ff8b1 100644
--- a/sw/inc/pagedesc.hxx
+++ b/sw/inc/pagedesc.hxx
@@ -26,6 +26,7 @@
 #include <frmfmt.hxx>
 #include <editeng/numitem.hxx>
 #include <editeng/borderline.hxx>
+#include "poolfmt.hxx"
 
 class SfxPoolItem;
 class SwTxtFmtColl;
@@ -234,7 +235,7 @@ public:
 
     /// Query and set PoolFormat-Id.
     sal_uInt16 GetPoolFmtId() const         { return aMaster.GetPoolFmtId(); }
-    void SetPoolFmtId( sal_uInt16 nId )     { aMaster.SetPoolFmtId( nId ); }
+    void SetPoolFmtId( sal_uInt16 nId );
     sal_uInt16 GetPoolHelpId() const        { return aMaster.GetPoolHelpId(); }
     void SetPoolHelpId( sal_uInt16 nId )    { aMaster.SetPoolHelpId( nId ); }
     sal_uInt8 GetPoolHlpFileId() const      { return aMaster.GetPoolHlpFileId(); }
@@ -348,15 +349,30 @@ public:
 
 typedef std::vector<SwPageDesc*> SwPageDescsBase;
 
-// PageDescriptor-interface, Array because of inlines.
+#define RES_POOLPAGE_SIZE (RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)
+
 // Mimics o3tl::sorted_vector interface
 class SwPageDescs : private SwPageDescsBase
 {
+    // to update the poolpages array on PoolFmtId change
+    friend void SwPageDesc::SetPoolFmtId( sal_uInt16 nId );
+
 public:
     typedef typename SwPageDescsBase::const_iterator const_iterator;
     typedef typename SwPageDescsBase::size_type size_type;
     typedef typename SwPageDescsBase::value_type value_type;
 
+private:
+    // fast index for pool page resources
+    value_type poolpages[RES_POOLPAGE_SIZE];
+
+    void _erase( const value_type& x );
+    bool IsIdInPoolRange( sal_uInt16 nId, bool allowDefault ) const;
+
+    bool SetPoolPageDesc( const value_type& x, sal_uInt16 nId = USHRT_MAX );
+
+public:
+    SwPageDescs();
     // the destructor will free all objects still in the vector
     ~SwPageDescs();
 
@@ -383,6 +399,7 @@ public:
     const_iterator end() const { return SwPageDescsBase::end(); }
 
     bool Contains( const value_type& x ) const;
+    value_type GetPoolPageDesc( sal_uInt16 nId ) const;
 
 private:
     typedef typename SwPageDescsBase::iterator iterator;
diff --git a/sw/source/core/doc/DocumentStylePoolManager.cxx b/sw/source/core/doc/DocumentStylePoolManager.cxx
index 953ac99..cf58f58 100644
--- a/sw/source/core/doc/DocumentStylePoolManager.cxx
+++ b/sw/source/core/doc/DocumentStylePoolManager.cxx
@@ -1351,13 +1351,9 @@ SwPageDesc* DocumentStylePoolManager::GetPageDescFromPool( sal_uInt16 nId, bool
     OSL_ENSURE( RES_POOLPAGE_BEGIN <= nId && nId < RES_POOLPAGE_END,
             "Wrong AutoFormat Id" );
 
-    for( sal_uInt16 n = 0; n < m_rDoc.GetPageDescCnt(); ++n )
-    {
-        if ( nId == m_rDoc.GetPageDesc(n).GetPoolFmtId() )
-        {
-            return &m_rDoc.GetPageDesc(n);
-        }
-    }
+    SwPageDesc* ret = m_rDoc.FindPageDescByPoolId( nId );
+    if (ret)
+        return ret;
 
     if( RES_POOLPAGE_BEGIN > nId ||  nId >= RES_POOLPAGE_END )
     {
diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index 405b89b..bfdf31f 100644
--- a/sw/source/core/doc/docdesc.cxx
+++ b/sw/source/core/doc/docdesc.cxx
@@ -832,6 +832,11 @@ SwPageDesc* SwDoc::FindPageDescByName( const OUString & rName, sal_uInt16* pPos
     return lcl_FindPageDescByName( const_cast <SwPageDescs *>( &maPageDescs ), rName, pPos );
 }
 
+SwPageDesc* SwDoc::FindPageDescByPoolId( sal_uInt16 nPoolId )
+{
+    return maPageDescs.GetPoolPageDesc( nPoolId );
+}
+
 void SwDoc::DelPageDesc( const OUString & rName, bool bBroadcast )
 {
     SwPageDesc *pd = FindPageDescByName(rName);
diff --git a/sw/source/core/layout/pagedesc.cxx b/sw/source/core/layout/pagedesc.cxx
index 2ad5ccb..0cea710 100644
--- a/sw/source/core/layout/pagedesc.cxx
+++ b/sw/source/core/layout/pagedesc.cxx
@@ -246,6 +246,19 @@ void SwPageDesc::RegisterChange()
     }
 }
 
+void SwPageDesc::SetPoolFmtId( sal_uInt16 nId )
+{
+    sal_uInt16 nIdOld = aMaster.GetPoolFmtId();
+    if ( nId == nIdOld )
+        return;
+    aMaster.SetPoolFmtId( nId );
+    if (list != 0) {
+        bool ok = list->SetPoolPageDesc( this, nIdOld );
+        SAL_WARN_IF(!ok, "sw",
+                "Unable to set register the PoolFmtId from SetPoolFmtId");
+    }
+}
+
 /// special handling if the style of the grid alignment changes
 void SwPageDesc::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
 {
@@ -481,6 +494,11 @@ SwPageDescExt::operator SwPageDesc() const
     return aResult;
 }
 
+SwPageDescs::SwPageDescs()
+{
+    memset(poolpages, 0, sizeof(value_type) * RES_POOLPAGE_SIZE);
+}
+
 SwPageDescs::~SwPageDescs()
 {
     DeleteAndDestroyAll();
@@ -490,27 +508,49 @@ void SwPageDescs::DeleteAndDestroyAll()
 {
     for( const_iterator it = begin(); it != end(); ++it )
         delete *it;
+    memset(poolpages, 0, sizeof(value_type) * RES_POOLPAGE_SIZE);
     clear();
 }
 
 std::pair<SwPageDescs::const_iterator,bool> SwPageDescs::insert( const value_type& x )
 {
+    sal_uInt16 nId = x->GetPoolFmtId();
+    SAL_WARN_IF(nId != USHRT_MAX && NULL != GetPoolPageDesc( nId ),
+                "sw", "Inserting already assigned pool ID item!");
+
     const_iterator const ret = find( x );
     if (ret == end()) {
         SwPageDescsBase::push_back( x );
-        SAL_WARN_IF(x->list == 0, "sw", "Inserting already assigned item");
+        if (x->list != 0) {
+            SAL_WARN("sw", "Inserting already assigned item!");
+            SAL_WARN_IF(x->list != this, "sw",
+                        "Inserting assigned item from other list!");
+        }
         x->list = this;
+        if (nId != USHRT_MAX)
+            poolpages[ nId - RES_POOLPAGE_BEGIN ] = x;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list