fdo#48932 is a large 7000 page document which reacts very slowly on text
input and scrolling around. It appears to be mostly managing the
header/footer and page break indicators which makes it sluggish
b63766b3dd453a82f59db505c736d861f662cc0f make it fast again, and seem to
have no side efforts. Though I'd like to have someone else verify that.
Attached is a backport to 3-5 to apply cleanly.
C.
From 4bada122523dfaf4441341e0f86b1ba98b5ce3b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Thu, 24 May 2012 08:57:17 +0100
Subject: [PATCH] Resolves: fdo#48932 super slow typing and scrolling in large
documents
AFAICS it appears that theres a one to one mapping from a SwFrameControl to
a SwFrm, so in any of the three given classes of Page, Footer or Header a
SwFrm will have zero or one SwFrameControls and a SwFrameControl doesn't
get rebound to a different SwFrm or anything like that, so we can use
a map and index off the SwFrm* to find them rather than constantly
looping over vectors to find the right one.
Maybe could move the SwFrameControl directly in the SwPageFrm's
themselves.
Change-Id: I4de0a34f657143ef2d4409b604cc8e114dad132f
---
sw/source/ui/docvw/FrameControlsManager.cxx | 110 ++++++++-------------------
sw/source/ui/inc/FrameControlsManager.hxx | 6 +-
2 files changed, 37 insertions(+), 79 deletions(-)
diff --git a/sw/source/ui/docvw/FrameControlsManager.cxx
b/sw/source/ui/docvw/FrameControlsManager.cxx
index 5c00b58..1413942 100644
--- a/sw/source/ui/docvw/FrameControlsManager.cxx
+++ b/sw/source/ui/docvw/FrameControlsManager.cxx
@@ -37,21 +37,6 @@
using namespace std;
-namespace
-{
- class FramePredicate
- {
- const SwFrm* m_pToMatch;
-
- public:
- FramePredicate( const SwFrm* pFrm ) : m_pToMatch( pFrm ) { };
- virtual ~FramePredicate() {};
-
- virtual bool operator()( SwFrameControlPtr pToCheck )
- { return m_pToMatch == pToCheck->GetFrame(); };
- };
-}
-
SwFrameControlsManager::SwFrameControlsManager( SwEditWin* pEditWin ) :
m_pEditWin( pEditWin ),
m_aControls( )
@@ -60,14 +45,6 @@ SwFrameControlsManager::SwFrameControlsManager( SwEditWin* pEditWin ) :
SwFrameControlsManager::~SwFrameControlsManager()
{
- map< FrameControlType, vector< SwFrameControlPtr > >::iterator pIt = m_aControls.begin();
-
- while ( pIt != m_aControls.end() )
- {
- pIt->second.clear( );
- ++pIt;
- }
- m_aControls.clear();
}
SwFrameControlsManager::SwFrameControlsManager( const SwFrameControlsManager& rCopy ) :
@@ -85,75 +62,66 @@ const SwFrameControlsManager& SwFrameControlsManager::operator=( const SwFrameCo
SwFrameControlPtr SwFrameControlsManager::GetControl( FrameControlType eType, const SwFrm* pFrm )
{
- SwFrameControlPtr pControl;
-
- vector< SwFrameControlPtr >& aControls = m_aControls[eType];
+ SwFrameControlPtrMap& rControls = m_aControls[eType];
- vector< SwFrameControlPtr >::iterator pIt = find_if(
- aControls.begin(), aControls.end( ), FramePredicate( pFrm ) );
+ SwFrameControlPtrMap::iterator aIt = rControls.find(pFrm);
- if ( pIt != aControls.end() )
- pControl = *pIt;
+ if (aIt != rControls.end())
+ return aIt->second;
- return pControl;
+ return SwFrameControlPtr();
}
-std::vector< SwFrameControlPtr >& SwFrameControlsManager::GetControls( FrameControlType eType )
+SwFrameControlPtrMap& SwFrameControlsManager::GetControls( FrameControlType eType )
{
return m_aControls[eType];
}
void SwFrameControlsManager::AddControl( FrameControlType eType, SwFrameControlPtr pControl )
{
- m_aControls[eType].push_back( pControl );
+ m_aControls[eType].insert(make_pair(pControl->GetFrame(), pControl));
}
void SwFrameControlsManager::RemoveControls( const SwFrm* pFrm )
{
- map< FrameControlType, vector< SwFrameControlPtr > >::iterator pIt = m_aControls.begin();
+ map< FrameControlType, SwFrameControlPtrMap >::iterator pIt = m_aControls.begin();
while ( pIt != m_aControls.end() )
{
- vector< SwFrameControlPtr >& aVect = pIt->second;
- aVect.erase( remove_if( aVect.begin(),
- aVect.end(),
- FramePredicate( pFrm ) ), aVect.end() );
+ SwFrameControlPtrMap& rMap = pIt->second;
+ rMap.erase(pFrm);
++pIt;
}
}
void SwFrameControlsManager::RemoveControlsByType( FrameControlType eType, const SwFrm* pFrm )
{
- vector< SwFrameControlPtr >& aVect = m_aControls[eType];
- aVect.erase( remove_if( aVect.begin(),
- aVect.end(),
- FramePredicate( pFrm ) ), aVect.end() );
+ SwFrameControlPtrMap& rMap = m_aControls[eType];
+ rMap.erase(pFrm);
}
-
void SwFrameControlsManager::HideControls( FrameControlType eType )
{
- vector< SwFrameControlPtr >::iterator pIt = m_aControls[eType].begin();
+ SwFrameControlPtrMap::iterator pIt = m_aControls[eType].begin();
while ( pIt != m_aControls[eType].end() )
{
- ( *pIt )->ShowAll( false );
- pIt++;
+ pIt->second->ShowAll( false );
+ ++pIt;
}
}
void SwFrameControlsManager::SetReadonlyControls( bool bReadonly )
{
- map< FrameControlType, vector< SwFrameControlPtr > >::iterator pIt = m_aControls.begin();
+ map< FrameControlType, SwFrameControlPtrMap >::iterator pIt = m_aControls.begin();
while ( pIt != m_aControls.end() )
{
- vector< SwFrameControlPtr >::iterator pVectIt = pIt->second.begin();
- while ( pVectIt != pIt->second.end() )
+ SwFrameControlPtrMap::iterator aCtrlIt = pIt->second.begin();
+ while ( aCtrlIt != pIt->second.end() )
{
- ( *pVectIt )->SetReadonly( bReadonly );
- ++pVectIt;
+ aCtrlIt->second->SetReadonly( bReadonly );
+ ++aCtrlIt;
}
- ++pIt;
}
}
@@ -165,30 +133,24 @@ void SwFrameControlsManager::SetHeaderFooterControl( const SwPageFrm*
pPageFrm,
SwFrameControlPtr pControl;
const bool bHeader = ( eType == Header );
- vector< SwFrameControlPtr >& aControls = m_aControls[eType];
+ SwFrameControlPtrMap& rControls = m_aControls[eType];
- vector< SwFrameControlPtr >::iterator pIt = aControls.begin();
- while ( pIt != aControls.end() && !pControl.get() )
- {
- SwHeaderFooterWin* pToTest = dynamic_cast< SwHeaderFooterWin* >( pIt->get() );
- if ( pToTest->GetPageFrame( ) == pPageFrm &&
- pToTest->IsHeader( ) == bHeader )
- pControl = *pIt;
- pIt++;
- }
-
- if ( !pControl.get() )
+ SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrm);
+ if (lb != rControls.end() && !(rControls.key_comp()(pPageFrm, lb->first)))
+ pControl = lb->second;
+ else
{
SwFrameControlPtr pNewControl( new SwHeaderFooterWin( m_pEditWin, pPageFrm, bHeader ) );
const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
pNewControl->SetReadonly( pViewOpt->IsReadonly() );
- AddControl( eType, pNewControl );
+ rControls.insert(lb, make_pair(pPageFrm, pNewControl));
pControl.swap( pNewControl );
}
Rectangle aPageRect = m_pEditWin->LogicToPixel( pPageFrm->Frm().SVRect() );
SwHeaderFooterWin* pHFWin = dynamic_cast< SwHeaderFooterWin* >( pControl.get() );
+ assert(pHFWin->IsHeader() == bHeader);
pHFWin->SetOffset( aOffset, aPageRect.Left(), aPageRect.Right() );
if ( !pHFWin->IsVisible() )
@@ -200,23 +162,17 @@ void SwFrameControlsManager::SetPageBreakControl( const SwPageFrm* pPageFrm )
// Check if we already have the control
SwFrameControlPtr pControl;
- vector< SwFrameControlPtr >& aControls = m_aControls[PageBreak];
-
- vector< SwFrameControlPtr >::iterator pIt = aControls.begin();
- while ( pIt != aControls.end() && !pControl.get() )
- {
- SwPageBreakWin* pToTest = dynamic_cast< SwPageBreakWin* >( pIt->get() );
- if ( pToTest->GetPageFrame( ) == pPageFrm )
- pControl = *pIt;
- pIt++;
- }
+ SwFrameControlPtrMap& rControls = m_aControls[PageBreak];
- if ( !pControl.get() )
+ SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrm);
+ if (lb != rControls.end() && !(rControls.key_comp()(pPageFrm, lb->first)))
+ pControl = lb->second;
+ else
{
SwFrameControlPtr pNewControl( new SwPageBreakWin( m_pEditWin, pPageFrm ) );
const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
pNewControl->SetReadonly( pViewOpt->IsReadonly() );
- AddControl( PageBreak, pNewControl );
+ rControls.insert(lb, make_pair(pPageFrm, pNewControl));
pControl.swap( pNewControl );
}
diff --git a/sw/source/ui/inc/FrameControlsManager.hxx b/sw/source/ui/inc/FrameControlsManager.hxx
index 06e618c..d007362 100644
--- a/sw/source/ui/inc/FrameControlsManager.hxx
+++ b/sw/source/ui/inc/FrameControlsManager.hxx
@@ -42,13 +42,15 @@ class SwEditWin;
typedef boost::shared_ptr< SwFrameControl > SwFrameControlPtr;
+typedef std::map<const SwFrm*, SwFrameControlPtr> SwFrameControlPtrMap;
+
/** A container for the Header/Footer, or PageBreak controls.
*/
class SwFrameControlsManager
{
private:
SwEditWin* m_pEditWin;
- std::map< FrameControlType, std::vector< SwFrameControlPtr > > m_aControls;
+ std::map< FrameControlType, SwFrameControlPtrMap > m_aControls;
public:
SwFrameControlsManager( SwEditWin* pEditWin );
@@ -58,7 +60,7 @@ class SwFrameControlsManager
const SwFrameControlsManager& operator=( const SwFrameControlsManager& rCopy );
SwFrameControlPtr GetControl( FrameControlType eType, const SwFrm* pFrm );
- std::vector< SwFrameControlPtr >& GetControls( FrameControlType eType );
+ SwFrameControlPtrMap& GetControls( FrameControlType eType );
void AddControl( FrameControlType eType, SwFrameControlPtr pControl );
void RemoveControls( const SwFrm* pFrm );
void RemoveControlsByType( FrameControlType eType, const SwFrm* pFrm );
--
1.7.7.6
Context
- [REVIEW 3-5] fdo#48932 speed up scrolling/typing in huge writer documents · Caolán McNamara
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.