[PATCH] Resolves: fdo#48932 super slow typing and scrolling in large documents

Caolán McNamara caolanm at redhat.com
Thu May 24 00:57:17 PDT 2012


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


--=-AIlDZvSwaKSte1YeFLuG--



More information about the LibreOffice mailing list