Rebased ref, commits from common ancestor: commit dd276469af4a7a6b33c71ad58ca5f6bd89fd4558 Author: Jan-Marek Glogowski <glo...@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 9a58bc6..37091e1 100644 --- a/sw/inc/docary.hxx +++ b/sw/inc/docary.hxx @@ -102,9 +102,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 @@ -114,6 +116,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; @@ -141,9 +149,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; 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 e413a98..5d44172 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1298,36 +1298,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 9dd5a444b080787ebc0ba986ee098a3b5a01050f Author: Jan-Marek Glogowski <glo...@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 49054db..9a58bc6 100644 --- a/sw/inc/docary.hxx +++ b/sw/inc/docary.hxx @@ -98,9 +98,20 @@ public: virtual ~SwGrfFmtColls() {} }; +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, @@ -129,6 +140,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; 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 31f1b26..e413a98 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1351,12 +1351,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 5c08ad070e9e2c44b745ec45063b34000d2c95e1 Author: Jan-Marek Glogowski <glo...@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 4ef2e53..49054db 100644 --- a/sw/inc/docary.hxx +++ b/sw/inc/docary.hxx @@ -98,42 +98,38 @@ public: virtual ~SwGrfFmtColls() {} }; -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; virtual size_t GetFmtCount() const SAL_OVERRIDE @@ -144,12 +140,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 1298deb..70af138 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -2431,10 +2431,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 e0b4abd5933fd0cca332156ef7a9992fdcdf6035 Author: Jan-Marek Glogowski <glo...@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 8a7d493..4ef2e53 100644 --- a/sw/inc/docary.hxx +++ b/sw/inc/docary.hxx @@ -98,12 +98,65 @@ public: virtual ~SwGrfFmtColls() {} }; +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: - virtual ~SwFrmFmts() {} + 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; + + virtual size_t GetFmtCount() const SAL_OVERRIDE + { return SwFrmFmtsBase::size(); } + virtual SwFmt* GetFmt(size_t idx) const SAL_OVERRIDE + { return (SwFmt*) SwFrmFmtsBase::operator[](idx); } + 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 +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 1b60569..7f72b89 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 715f92a..01ce8fe 100644 --- a/sw/inc/frmfmt.hxx +++ b/sw/inc/frmfmt.hxx @@ -34,6 +34,7 @@ class SwRect; class SwContact; class SdrObject; namespace sw { class DocumentLayoutManager; } +class SwFrmFmts; /// Style of a layout element. class SW_DLLPUBLIC SwFrmFmt: public SwFmt @@ -41,6 +42,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; @@ -48,6 +50,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, @@ -139,6 +144,7 @@ public: //UUUU Access to DrawingLayer FillAttributes in a preprocessed form for primitive usage virtual drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const SAL_OVERRIDE; virtual bool IsAdaptedToNewFillProperties() 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 19e1a5f..46e6f88 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_rSwdoc.GetTblFrmFmts() ) + const SwFrmFmts *mpTblFrmFmtTbl = m_rSwdoc.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_rSwdoc.GetTblFrmFmts() ) + const SwFrmFmts *mpTblFrmFmtTbl = m_rSwdoc.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_rSwdoc.GetTblFrmFmts() ) + const SwFrmFmts *mpTblFrmFmtTbl = m_rSwdoc.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_rSwdoc.GetTblFrmFmts() ) + const SwFrmFmts *mpTblFrmFmtTbl = m_rSwdoc.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 456740a..f42472c 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 a3c30fb..31f1b26 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1407,7 +1407,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 ce046e7..d807ff8 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -303,7 +303,7 @@ SwDoc::SwDoc() * DefaultFormats and are also in the list. */ /* Formats */ - mpFrmFmtTbl->push_back(mpDfltFrmFmt); + mpFrmFmtTbl->insert(mpDfltFrmFmt); mpCharFmtTbl->push_back(mpDfltCharFmt); /* FmtColls */ @@ -376,16 +376,6 @@ SwDoc::SwDoc() getIDocumentState().ResetModified(); } -static void DeleteAndDestroy(SwFrmFmts& rFmts, int aStartIdx, int aEndIdx) -{ - if (aEndIdx < aStartIdx) - return; - for( SwFrmFmts::const_iterator it = rFmts.begin() + aStartIdx; - it != rFmts.begin() + aEndIdx; ++it ) - delete *it; - rFmts.erase( rFmts.begin() + aStartIdx, rFmts.begin() + aEndIdx); -} - static void DeleteAndDestroy(SwTxtFmtColls& rFmts, int aStartIdx, int aEndIdx) { if (aEndIdx < aStartIdx) @@ -515,10 +505,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 ); @@ -579,7 +569,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. - DeleteAndDestroy( *mpSpzFrmFmtTbl, 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 @@ -751,12 +741,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() ) ); - DeleteAndDestroy(*mpFrmFmtTbl, 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 - DeleteAndDestroy(*mpFrmFmtTbl, 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 3669a59..ea23fb9 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 1b11a28..1298deb 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,10 +2420,33 @@ SwFrmFmt::SwFrmFmt( const sal_uInt16* pWhichRange) : SwFmt(rPool, rFmtNm, (pWhichRange ? pWhichRange : aFrmFmtSetRange), pDrvdFrm, nFmtWhich), m_wXObject(), - maFillAttributes() + maFillAttributes(), + list(0) { } +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::IsAdaptedToNewFillProperties() const { return true; diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index 77d81bc..fb97ff2 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1124,14 +1124,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 3c4451c..6f6b52a 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -578,8 +578,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 3366de0..08985de 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 699ff4f..3d06c5a 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -289,13 +289,11 @@ bool SwUndoFmtAttr::IsFmtInDoc( SwDoc* pDoc ) // no break! case RES_DRAWFRMFMT: case RES_FLYFRMFMT: - nPos = pDoc->GetSpzFrmFmts()->GetPos( - static_cast<SwFrmFmt*>(m_pFmt) ); - if ( USHRT_MAX == nPos ) - { - nPos = pDoc->GetFrmFmts()->GetPos( - static_cast<SwFrmFmt*>(m_pFmt) ); - } + if ((pDoc->GetSpzFrmFmts()->Contains( + static_cast<SwFrmFmt*>(m_pFmt))) + || (pDoc->GetFrmFmts()->Contains( + static_cast<SwFrmFmt*>(m_pFmt))) ) + nPos = 1; break; } diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx index d88f53e..7a62ac4 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( (SwFrmFmt*) pOldFmt ) ) + if( rDoc.GetFrmFmts()->Contains( (SwFrmFmt*) 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( (SwFrmFmt*) pNewFmt ) ) + if( rDoc.GetFrmFmts()->find( (SwFrmFmt*) pNewFmt ) != rDoc.GetFrmFmts()->end() ) { 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 5172236..83994db 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 1c2f3ff..136f28a 100644 --- a/sw/source/filter/ww8/wrtw8esh.cxx +++ b/sw/source/filter/ww8/wrtw8esh.cxx @@ -1001,7 +1001,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 5e60c54ba2d1ec6d91f776c0fe2be6378379899c Author: Jan-Marek Glogowski <glo...@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 f74c1c4a25cc818ca7550788653ee245653d74e4 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Thu May 22 14:25:32 2014 +0200 Merge common code of sw format lists Moves the common code into an intermediate template class, which still provides an SwFmtsBase interface. The only changes are some dropped explicit "const" casts. Change-Id: I8894fbc53e7b1ac1b1e590bba932a9f9cc33f448 diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx index 0f75324..8a7d493 100644 --- a/sw/inc/docary.hxx +++ b/sw/inc/docary.hxx @@ -25,23 +25,17 @@ #include <algorithm> #include <o3tl/sorted_vector.hxx> -class SwFieldType; -class SwFmt; -class SwFrmFmt; -class SwCharFmt; -class SwTOXType; -class SwUndo; -class SwSectionFmt; -class SwNumRule; +#include "charfmt.hxx" +#include "fldbas.hxx" +#include "fmtcol.hxx" +#include "frmfmt.hxx" +#include "numrule.hxx" +#include "section.hxx" +#include "tox.hxx" +#include "unocrsr.hxx" + class SwRangeRedline; class SwExtraRedline; -class SwUnoCrsr; -class SwOLENode; -class SwTxtFmtColl; -class SwGrfFmtColl; -class SwTable; -class SwTableLine; -class SwTableBox; namespace com { namespace sun { namespace star { namespace i18n { struct ForbiddenCharacters; ///< comes from the I18N UNO interface @@ -56,91 +50,101 @@ class SwFmtsBase { public: virtual size_t GetFmtCount() const = 0; - virtual SwFmt* GetFmt(size_t idx) const = 0; - virtual ~SwFmtsBase() = 0; + virtual SwFmt* GetFmt(size_t) const = 0; + virtual ~SwFmtsBase() {} }; -class SwGrfFmtColls : public std::vector<SwGrfFmtColl*>, public SwFmtsBase +template<typename Value> +class SwFmtsBaseModify : public std::vector<Value>, public SwFmtsBase { public: - virtual size_t GetFmtCount() const SAL_OVERRIDE { return size(); } - virtual SwFmt* GetFmt(size_t idx) const SAL_OVERRIDE { return (SwFmt*)operator[](idx); } - sal_uInt16 GetPos(const SwGrfFmtColl* pFmt) const; - /// free's any remaining child objects - virtual ~SwGrfFmtColls() {} + typedef typename std::vector<Value>::const_iterator const_iterator; + +private: + const bool mCleanup; + +public: + SwFmtsBaseModify(bool cleanup = true) : mCleanup(cleanup) {} + + using std::vector<Value>::begin; + using std::vector<Value>::end; + + // free any remaining child objects based on mCleanup + virtual ~SwFmtsBaseModify() + { + if (mCleanup) + for(const_iterator it = begin(); it != end(); ++it) + delete *it; + } + + sal_uInt16 GetPos(Value const& p) const + { + const_iterator const it = std::find(begin(), end(), p); + return it == end() ? USHRT_MAX : it - begin(); + } + bool Contains(Value const& p) const + { return std::find(begin(), end(), p) != end(); } + virtual size_t GetFmtCount() const SAL_OVERRIDE + { return std::vector<Value>::size(); } + virtual SwFmt* GetFmt(size_t idx) const SAL_OVERRIDE + { return (SwFmt*) std::vector<Value>::operator[](idx); } + void dumpAsXml(xmlTextWriterPtr) const {}; }; -/// stupid base class to work around MSVC dllexport mess -class SAL_DLLPUBLIC_TEMPLATE SwFrmFmts_Base : public std::vector<SwFrmFmt*> {}; +class SwGrfFmtColls : public SwFmtsBaseModify<SwGrfFmtColl*> +{ +public: + SwGrfFmtColls() : SwFmtsBaseModify( false ) {} + virtual ~SwGrfFmtColls() {} +}; /// Specific frame formats (frames, DrawObjects). -class SW_DLLPUBLIC SwFrmFmts : public SwFrmFmts_Base, public SwFmtsBase +class SW_DLLPUBLIC SwFrmFmts : public SwFmtsBaseModify<SwFrmFmt*> { public: - virtual size_t GetFmtCount() const SAL_OVERRIDE { return size(); } - virtual SwFmt* GetFmt(size_t idx) const SAL_OVERRIDE { return (SwFmt*)operator[](idx); } - sal_uInt16 GetPos(const SwFrmFmt* pFmt) const; - bool Contains(const SwFrmFmt* pFmt) const; + virtual ~SwFrmFmts() {} void dumpAsXml(xmlTextWriterPtr w, const char* pName) const; - /// free's any remaining child objects - virtual ~SwFrmFmts(); }; -class SwCharFmts : public std::vector<SwCharFmt*>, public SwFmtsBase +class SwCharFmts : public SwFmtsBaseModify<SwCharFmt*> { public: - virtual size_t GetFmtCount() const SAL_OVERRIDE { return size(); } - virtual SwFmt* GetFmt(size_t idx) const SAL_OVERRIDE { return (SwFmt*)operator[](idx); } - sal_uInt16 GetPos(const SwCharFmt* pFmt) const; - bool Contains(const SwCharFmt* pFmt) const; + virtual ~SwCharFmts() {} void dumpAsXml(xmlTextWriterPtr w) const; - /// free's any remaining child objects - virtual ~SwCharFmts(); }; -class SwTxtFmtColls : public std::vector<SwTxtFmtColl*>, public SwFmtsBase +class SwTxtFmtColls : public SwFmtsBaseModify<SwTxtFmtColl*> { public: - virtual size_t GetFmtCount() const SAL_OVERRIDE { return size(); } - virtual SwFmt* GetFmt(size_t idx) const SAL_OVERRIDE { return (SwFmt*)operator[](idx); } - sal_uInt16 GetPos(const SwTxtFmtColl* pFmt) const; - void dumpAsXml(xmlTextWriterPtr w) const; + SwTxtFmtColls() : SwFmtsBaseModify( false ) {} virtual ~SwTxtFmtColls() {} + void dumpAsXml(xmlTextWriterPtr w) const; }; /// Array of Undo-history. -class SW_DLLPUBLIC SwSectionFmts : public std::vector<SwSectionFmt*>, public SwFmtsBase +class SW_DLLPUBLIC SwSectionFmts : public SwFmtsBaseModify<SwSectionFmt*> { public: - virtual size_t GetFmtCount() const SAL_OVERRIDE { return size(); } - virtual SwFmt* GetFmt(size_t idx) const SAL_OVERRIDE { return (SwFmt*)operator[](idx); } - sal_uInt16 GetPos(const SwSectionFmt* pFmt) const; - bool Contains(const SwSectionFmt* pFmt) const; + virtual ~SwSectionFmts() {} void dumpAsXml(xmlTextWriterPtr w) const; - /// free's any remaining child objects - virtual ~SwSectionFmts(); }; -class SwFldTypes : public std::vector<SwFieldType*> { +class SwFldTypes : public SwFmtsBaseModify<SwFieldType*> +{ public: - /// the destructor will free all objects still in the vector - ~SwFldTypes(); - sal_uInt16 GetPos(const SwFieldType* pFieldType) const; + virtual ~SwFldTypes() {} void dumpAsXml(xmlTextWriterPtr w) const; }; -class SwTOXTypes : public std::vector<SwTOXType*> { +class SwTOXTypes : public SwFmtsBaseModify<SwTOXType*> +{ public: - /// the destructor will free all objects still in the vector - ~SwTOXTypes(); - sal_uInt16 GetPos(const SwTOXType* pTOXType) const; + virtual ~SwTOXTypes() {} }; -class SW_DLLPUBLIC SwNumRuleTbl : public std::vector<SwNumRule*> { +class SW_DLLPUBLIC SwNumRuleTbl : public SwFmtsBaseModify<SwNumRule*> { public: - /// the destructor will free all objects still in the vector - ~SwNumRuleTbl(); - sal_uInt16 GetPos(const SwNumRule* pRule) const; + virtual ~SwNumRuleTbl() {} void dumpAsXml(xmlTextWriterPtr w) const; }; @@ -148,6 +152,7 @@ struct CompareSwRedlineTbl { bool operator()(SwRangeRedline* const &lhs, SwRangeRedline* const &rhs) const; }; + class _SwRedlineTbl : public o3tl::sorted_vector<SwRangeRedline*, CompareSwRedlineTbl, o3tl::find_partialorder_ptrequals> diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index 4459b55..5b74665 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -1739,16 +1739,4 @@ SwDoc::GetVbaEventProcessor() return mxVbaEvents; } -sal_uInt16 SwNumRuleTbl::GetPos(const SwNumRule* pRule) const -{ - const_iterator it = std::find(begin(), end(), pRule); - return it == end() ? USHRT_MAX : it - begin(); -} - -SwNumRuleTbl::~SwNumRuleTbl() -{ - for(const_iterator it = begin(); it != end(); ++it) - delete *it; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/docbasic.cxx b/sw/source/core/doc/docbasic.cxx index 4b2fdfe..c290c89 100644 --- a/sw/source/core/doc/docbasic.cxx +++ b/sw/source/core/doc/docbasic.cxx @@ -160,7 +160,7 @@ sal_uInt16 SwDoc::CallEvent( sal_uInt16 nEvent, const SwCallMouseEvent& rCallEve case EVENT_OBJECT_URLITEM: case EVENT_OBJECT_IMAGE: { - const SwFrmFmt* pFmt = (SwFrmFmt*)rCallEvent.PTR.pFmt; + SwFrmFmt* pFmt = (SwFrmFmt*)rCallEvent.PTR.pFmt; if( bCheckPtr ) { if ( GetSpzFrmFmts()->Contains( pFmt ) ) @@ -176,7 +176,7 @@ sal_uInt16 SwDoc::CallEvent( sal_uInt16 nEvent, const SwCallMouseEvent& rCallEve const IMapObject* pIMapObj = rCallEvent.PTR.IMAP.pIMapObj; if( bCheckPtr ) { - const SwFrmFmt* pFmt = (SwFrmFmt*)rCallEvent.PTR.IMAP.pFmt; + SwFrmFmt* pFmt = (SwFrmFmt*)rCallEvent.PTR.IMAP.pFmt; const ImageMap* pIMap; if( GetSpzFrmFmts()->Contains( pFmt ) && 0 != (pIMap = pFmt->GetURL().GetMap()) ) diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 00cd13a..5532aed 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -2010,40 +2010,4 @@ namespace docfunc } } -SwFmtsBase::~SwFmtsBase() {} - -sal_uInt16 SwFrmFmts::GetPos(const SwFrmFmt* p) const -{ - const_iterator it = std::find(begin(), end(), p); - return it == end() ? USHRT_MAX : it - begin(); -} - -bool SwFrmFmts::Contains(const SwFrmFmt* p) const -{ - return std::find(begin(), end(), p) != end(); -} - -SwFrmFmts::~SwFrmFmts() -{ - for(const_iterator it = begin(); it != end(); ++it) - delete *it; -} - -sal_uInt16 SwCharFmts::GetPos(const SwCharFmt* p) const -{ - const_iterator it = std::find(begin(), end(), p); - return it == end() ? USHRT_MAX : it - begin(); -} - -bool SwCharFmts::Contains(const SwCharFmt* p) const -{ - return std::find(begin(), end(), p) != end(); -} - -SwCharFmts::~SwCharFmts() -{ - for(const_iterator it = begin(); it != end(); ++it) - delete *it; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index 263e3d6..ce046e7 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -1167,16 +1167,4 @@ else pTargetShell->EndAllAction(); } -sal_uInt16 SwTxtFmtColls::GetPos(const SwTxtFmtColl* p) const -{ - const_iterator it = std::find(begin(), end(), p); - return it == end() ? USHRT_MAX : it - begin(); -} - -sal_uInt16 SwGrfFmtColls::GetPos(const SwGrfFmtColl* p) const -{ - const_iterator it = std::find(begin(), end(), p); - return it == end() ? USHRT_MAX : it - begin(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/docnode/section.cxx b/sw/source/core/docnode/section.cxx index a4e829d..f83cd24 100644 --- a/sw/source/core/docnode/section.cxx +++ b/sw/source/core/docnode/section.cxx @@ -1588,21 +1588,4 @@ bool SwIntrnlSectRefLink::IsInRange( sal_uLong nSttNd, sal_uLong nEndNd, pSttNd->EndOfSectionIndex() < nEndNd; } -sal_uInt16 SwSectionFmts::GetPos(const SwSectionFmt* p) const -{ - const_iterator it = std::find(begin(), end(), p); - return it == end() ? USHRT_MAX : it - begin(); -} - -bool SwSectionFmts::Contains(const SwSectionFmt* p) const -{ - return std::find(begin(), end(), p) != end(); -} - -SwSectionFmts::~SwSectionFmts() -{ - for(const_iterator it = begin(); it != end(); ++it) - delete *it; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx index 0827a7f..c09e5bf 100644 --- a/sw/source/core/fields/fldbas.cxx +++ b/sw/source/core/fields/fldbas.cxx @@ -750,16 +750,4 @@ bool SwField::IsClickable() const return false; } -sal_uInt16 SwFldTypes::GetPos(const SwFieldType* pFieldType) const -{ - const_iterator it = std::find(begin(), end(), pFieldType); - return it == end() ? USHRT_MAX : it - begin(); -} - -SwFldTypes::~SwFldTypes() -{ - for(const_iterator it = begin(); it != end(); ++it) - delete *it; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/tox/tox.cxx b/sw/source/core/tox/tox.cxx index bfa6cb2..8b830c5 100644 --- a/sw/source/core/tox/tox.cxx +++ b/sw/source/core/tox/tox.cxx @@ -858,16 +858,4 @@ const SwFormTokens& SwForm::GetPattern(sal_uInt16 nLevel) const return aPattern[nLevel]; } -sal_uInt16 SwTOXTypes::GetPos(const SwTOXType* pTOXType) const -{ - const_iterator it = std::find(begin(), end(), pTOXType); - return it == end() ? USHRT_MAX : it - begin(); -} - -SwTOXTypes::~SwTOXTypes() -{ - for(const_iterator it = begin(); it != end(); ++it) - delete *it; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx index a4f0e21..699ff4f 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -150,7 +150,7 @@ void SwUndoFmtAttr::Init() else if ( RES_FRMFMT == m_nFmtWhich ) { SwDoc* pDoc = m_pFmt->GetDoc(); - if ( pDoc->GetTblFrmFmts()->Contains(static_cast<const SwFrmFmt*>(m_pFmt))) + if ( pDoc->GetTblFrmFmts()->Contains(static_cast<SwFrmFmt*>(m_pFmt))) { // Table Format: save table position, table formats are volatile! SwTable * pTbl = SwIterator<SwTable,SwFmt>::FirstElement( *m_pFmt ); @@ -160,7 +160,7 @@ void SwUndoFmtAttr::Init() ->FindTableNode()->GetIndex(); } } - else if ( pDoc->GetSections().Contains(static_cast<const SwSectionFmt*>(m_pFmt))) + else if ( pDoc->GetSections().Contains(static_cast<SwSectionFmt*>(m_pFmt))) { m_nNodeIndex = m_pFmt->GetCntnt().GetCntntIdx()->GetIndex(); } @@ -238,12 +238,12 @@ bool SwUndoFmtAttr::IsFmtInDoc( SwDoc* pDoc ) { case RES_TXTFMTCOLL: nPos = pDoc->GetTxtFmtColls()->GetPos( - static_cast<const SwTxtFmtColl*>(m_pFmt) ); + static_cast<SwTxtFmtColl*>(m_pFmt) ); break; case RES_GRFFMTCOLL: nPos = pDoc->GetGrfFmtColls()->GetPos( - static_cast<const SwGrfFmtColl*>(m_pFmt) ); + static_cast<SwGrfFmtColl*>(m_pFmt) ); break; case RES_CHRFMT: @@ -290,11 +290,11 @@ bool SwUndoFmtAttr::IsFmtInDoc( SwDoc* pDoc ) case RES_DRAWFRMFMT: case RES_FLYFRMFMT: nPos = pDoc->GetSpzFrmFmts()->GetPos( - static_cast<const SwFrmFmt*>(m_pFmt) ); + static_cast<SwFrmFmt*>(m_pFmt) ); if ( USHRT_MAX == nPos ) { nPos = pDoc->GetFrmFmts()->GetPos( - static_cast<const SwFrmFmt*>(m_pFmt) ); + static_cast<SwFrmFmt*>(m_pFmt) ); } break; } diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx index 5c2d4fe..d88f53e 100644 --- a/sw/source/core/undo/undobj1.cxx +++ b/sw/source/core/undo/undobj1.cxx @@ -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( (const SwFrmFmt*)pOldFmt ) ) + if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (SwFrmFmt*) 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( (const SwFrmFmt*)pNewFmt ) ) + if( USHRT_MAX != rDoc.GetFrmFmts()->GetPos( (SwFrmFmt*) pNewFmt ) ) { if( bAnchorChgd ) commit 5924aa522ee8cfea41aed84b7025804d1ec4bf87 Author: Jan-Marek Glogowski <glo...@fbihome.de> Date: Mon Jun 2 17:46:39 2014 +0200 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 ceacf4a..77d81bc 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1116,7 +1116,7 @@ static bool lcl_InHeaderOrFooter( 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. @@ -1131,9 +1131,10 @@ void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib ) while ( !aCpy.empty() && aCpy.size() != nOldCnt ) { nOldCnt = aCpy.size(); - for ( int i = 0; i < int(aCpy.size()); ++i ) + SwFrmFmts::iterator it = aCpy.begin(); + while ( it != aCpy.end() ) { - SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ]; + SwFrmFmt *pFmt = *it; const SwFmtAnchor &rAnch = pFmt->GetAnchor(); bool bRemove = false; if ((rAnch.GetAnchorId() == FLY_AT_PAGE) || @@ -1157,9 +1158,17 @@ void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib ) } if ( bRemove ) { - aCpy.erase( aCpy.begin() + i ); - --i; + if ( (*it) != aCpy.back() ) { + (*it) = aCpy.back(); + aCpy.pop_back(); + } + else { + aCpy.pop_back(); + it = aCpy.end(); + } } + else + it++; } } aCpy.clear(); @@ -1554,7 +1563,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; } @@ -1744,7 +1753,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 e732d53382ba14b1ba03a73777332b7a267caa1a Author: Jan-Marek Glogowski <glo...@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 865324a..a3c30fb 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1311,7 +1311,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 5dd340852983aedb75f6765394224c2eabf2663a Author: Jan-Marek Glogowski <glo...@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 5955f97..2f086a6 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 9d6bd9cbfd471f2fa1c916eecfc55a8630a4b43a Author: Jan-Marek Glogowski <glo...@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 946211a..8714103 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -948,6 +948,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 2a10307..bd2d7a6 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -553,11 +553,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/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 a39d363..ff77d66 100644 --- a/sw/source/filter/inc/fltshell.hxx +++ b/sw/source/filter/inc/fltshell.hxx @@ -537,7 +537,6 @@ class SwFltShell SwPaM* pPaM; OUString sBaseURL; - sal_uInt16 nPageDescOffset; // fuers update der pagedescs rtl_TextEncoding eSrcCharSet; // charset der quelle friend class SwFltControlStack; bool bNewDoc; @@ -691,8 +690,6 @@ public: const OUString& GetBaseURL() const { return sBaseURL; } }; -SW_DLLPUBLIC void UpdatePageDescs(SwDoc &rDoc, sal_uInt16 nInPageDescOffset); - #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww1/fltshell.cxx b/sw/source/filter/ww1/fltshell.cxx index 6e97e7c..2eb398f 100644 --- a/sw/source/filter/ww1/fltshell.cxx +++ b/sw/source/filter/ww1/fltshell.cxx @@ -1018,7 +1018,6 @@ SwFltShell::SwFltShell(SwDoc* pDoc, SwPaM& rPaM, const OUString& rBaseURL, bool aEndStack(pDoc, nFieldFl), pPaM(new SwPaM(*(rPaM.GetPoint()))), sBaseURL(rBaseURL), - nPageDescOffset(GetDoc().GetPageDescCnt()), eSrcCharSet(RTL_TEXTENCODING_MS_1252), bNewDoc(bNew), bStdPD(false), @@ -1056,8 +1055,6 @@ SwFltShell::SwFltShell(SwDoc* pDoc, SwPaM& rPaM, const OUString& rBaseURL, bool SwFltShell::~SwFltShell() { - sal_uInt16 i; - if (eSubMode == Style) EndStyle(); if( pOutDoc->IsInTable() ) // if not properly terminated @@ -1071,9 +1068,10 @@ SwFltShell::~SwFltShell() aStack.SetAttr(*pPaM->GetPoint(), 0, false); aEndStack.SetAttr(*pPaM->GetPoint(), 0, false); aEndStack.SetAttr(*pPaM->GetPoint(), 0, false); + + SwDoc& rDoc = GetDoc(); if( bProtect ){ // The entire document is supposed to be protected - SwDoc& rDoc = GetDoc(); // 1. Create SectionFmt and Section SwSectionFmt* pSFmt = rDoc.MakeSectionFmt( 0 ); SwSectionData aSectionData(CONTENT_SECTION, OUString("PMW-Protect")); @@ -1094,15 +1092,13 @@ SwFltShell::~SwFltShell() pDocSh->SetReadOnlyUI( true ); } } - // Update document page descriptors (only this way also left - // pages get adjusted) - GetDoc().ChgPageDesc( 0, GetDoc().GetPageDesc( 0 )); // PageDesc "Standard" - for (i=nPageDescOffset;i<GetDoc().GetPageDescCnt();i++) - { - const SwPageDesc& rPD = GetDoc().GetPageDesc(i); - GetDoc().ChgPageDesc(i, rPD); - } + sal_uInt16 i; + + // Update document page descriptors (only this way also left + // pages get adjusted) + for (i = 0 ; i < rDoc.GetPageDescCnt(); i++) + GetDoc().ChgPageDescP( rDoc.GetPageDesc(i) ); delete pPaM; for (i=0; i<sizeof(pColls)/sizeof(*pColls); i++) @@ -2134,19 +2130,4 @@ void SwFltShell::NextStyle(sal_uInt16 nWhich, sal_uInt16 nNext) *pColls[nNext]->GetColl() ); } -// 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/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx index d13c635..0bb6b1b 100644 --- a/sw/source/filter/ww8/rtfexport.cxx +++ b/sw/source/filter/ww8/rtfexport.cxx @@ -481,12 +481,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 7c1331e..f68c21a 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -4963,8 +4963,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); @@ -5382,7 +5380,10 @@ sal_uLong SwWW8ImplReader::CoreLoad(WW8Glossary *pGloss, const SwPosition &rPos) if (mbNewDoc) ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits