LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/ui/wrtsh - navmgr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 42 86 48.8 %
Date: 2013-07-09 Functions: 6 9 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "navmgr.hxx"
      11             : #include "wrtsh.hxx"
      12             : #include <sfx2/bindings.hxx>
      13             : #include <sfx2/viewfrm.hxx>
      14             : #include <cmdid.h>
      15             : #include <view.hxx>
      16             : #include <doc.hxx>
      17             : #include <unocrsr.hxx>
      18             : 
      19             : #include <com/sun/star/frame/XLayoutManager.hpp>
      20             : 
      21             : /**
      22             :  *  If SMART is defined, the navigation history has recency with temporal ordering enhancement,
      23             :  *  as described on http://zing.ncsl.nist.gov/hfweb/proceedings/greenberg/
      24             :  */
      25             : 
      26             : #define SMART 1
      27             : 
      28             : // This method positions the cursor to the position rPos.
      29             : 
      30           0 : void SwNavigationMgr::GotoSwPosition(const SwPosition &rPos) {
      31             :     // EnterStdMode() prevents the cursor to 'block' the current
      32             :     // shell when it should move from the image back to the normal shell
      33           0 :     m_rMyShell.EnterStdMode();
      34           0 :     m_rMyShell.StartAllAction();
      35             :     // cursor consists of two SwPositions: Point and Mark.
      36             :     // Such a pair is called a PaM. SwPaM is derived from SwRing.
      37             :     // The Ring contains the single regions of a multi-selection.
      38           0 :     SwPaM* pPaM = m_rMyShell.GetCrsr();
      39             : 
      40           0 :     if(pPaM->HasMark())
      41           0 :         pPaM->DeleteMark();      // If there was a selection, get rid of it
      42           0 :     *pPaM->GetPoint() = rPos;    // Position Cursor
      43             : 
      44           0 :     m_rMyShell.EndAllAction();
      45           0 : }
      46             : 
      47             : // Ctor for the SwNavigationMgr class
      48             : // Sets the shell to the current shell
      49             : // and the index of the current position to 0
      50             : 
      51         793 : SwNavigationMgr::SwNavigationMgr(SwWrtShell & rShell)
      52         793 :     : m_nCurrent(0), m_rMyShell(rShell)
      53             : {
      54         793 : }
      55             : 
      56             : // This method is used by the navigation shell - defined in sw/source/ui/inc/navsh.hxx
      57             : // and implemented in sw/source/ui/shells/navsh.cxx
      58             : // It is called when we want to check if the back button should be enabled or not.
      59             : // The back button should be enabled only if there are some entries in the navigation history
      60             : 
      61          10 : bool SwNavigationMgr::backEnabled() {
      62          10 :     return (m_nCurrent > 0);
      63             : }
      64             : 
      65             : // Similar to backEnabled() method.
      66             : // The forward button should be enabled if we ever clicked back
      67             : // Due to the implementation of the navigation class, this is when the
      68             : // current position within the navigation history entries in not the last one
      69             : // i.e. when the m_nCurrent index is not at the end of the m_entries vector
      70             : 
      71          10 : bool SwNavigationMgr::forwardEnabled() {
      72          10 :     return m_nCurrent+1 < m_entries.size();
      73             : }
      74             : 
      75             : // The goBack() method positions the cursor to the previous entry in the navigation history
      76             : // If there was no history to go forward to, it adds the current position of the cursor
      77             : // to the history so we could go forward to where we came from
      78             : 
      79           0 : void SwNavigationMgr::goBack()  {
      80             : 
      81             :     // Although the button should be disabled whenever the backEnabled() returns false,
      82             :     // the UI is sometimes not as responsive as we would like it to be :)
      83             :     // this check prevents segmentation faults and in this way the class is not relying on the UI
      84             : 
      85           0 :     if (backEnabled()) {
      86             :         /* Trying to get the current cursor */
      87           0 :         SwPaM* pPaM = m_rMyShell.GetCrsr();
      88           0 :         if (!pPaM) {
      89           0 :             return;
      90             :         }
      91             :         // This flag will be used to manually refresh the buttons
      92             : 
      93           0 :         bool bForwardWasDisabled = !forwardEnabled();
      94             : 
      95             :         // If we're going backwards in our history, but the current location is not
      96             :         // in the history then we need to add *here* to it so that we can "go
      97             :         // forward" to here again.
      98             : 
      99           0 :         if (bForwardWasDisabled) {
     100             : 
     101             :             // the cursor consists of two SwPositions: Point and Mark.
     102             :             // We are adding the current Point to the navigation history
     103             :             // so we could later navigate forward to it
     104             : 
     105             :             // The addEntry() method returns true iff we should decrement
     106             :             // the index before navigating back
     107             : 
     108           0 :             if (addEntry(*pPaM->GetPoint()) ) {
     109           0 :                 m_nCurrent--;
     110             :             }
     111             :         }
     112           0 :         m_nCurrent--;
     113             :         // Position cursor to appropriate navigation history entry
     114           0 :         GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
     115             :         // Refresh the buttons
     116           0 :         if (bForwardWasDisabled)
     117           0 :             m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
     118           0 :         if (!backEnabled())
     119           0 :             m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
     120             :     }
     121             : }
     122             : 
     123             : // The goForward() method positions the cursor to the next entry in the navigation history
     124             : 
     125           0 : void SwNavigationMgr::goForward() {
     126             : 
     127             :     // Although the button should be disabled whenever the backForward() returns false,
     128             :     // the UI is sometimes not as responsive as we would like it to be :)
     129             :     // this check prevents segmentation faults and in this way the class is not relying on the UI
     130             : 
     131           0 :     if (forwardEnabled()) {
     132             :         // This flag will be used to manually refresh the buttons
     133           0 :         bool bBackWasDisabled = !backEnabled();
     134             :         // The current index is positioned at the current entry in the navigation history
     135             :         // We have to increment it to go to the next entry
     136           0 :         m_nCurrent++;
     137           0 :         GotoSwPosition(*m_entries[m_nCurrent]->GetPoint());
     138             :         // Refresh the buttons
     139           0 :         if (bBackWasDisabled)
     140           0 :             m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
     141           0 :         if (!forwardEnabled())
     142           0 :             m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
     143             :     }
     144           0 : }
     145             : 
     146             : // This method adds the SwPosition rPos to the navigation history
     147             : // rPos is usually the current position of the cursor in the document
     148             : 
     149           9 : bool SwNavigationMgr::addEntry(const SwPosition& rPos) {
     150             :     // Flags that will be used for refreshing the buttons
     151           9 :     bool bBackWasDisabled = !backEnabled();
     152           9 :     bool bForwardWasEnabled = forwardEnabled();
     153             : 
     154           9 :     bool bRet = false; // return value of the function.
     155             :                        // Indicates whether the index should be decremented before
     156             :                        // jumping back or not
     157             : #if SMART
     158             :     // If any forward history exists, twist the tail of the
     159             :     // list from the current position to the end
     160           9 :     if (bForwardWasEnabled) {
     161             : 
     162           0 :         size_t number_ofm_entries = m_entries.size(); // To avoid calling m_entries.size() multiple times
     163           0 :         int curr = m_nCurrent; // Index from which we'll twist the tail.
     164           0 :         int n = (number_ofm_entries - curr) / 2; // Number of entries that will swap places
     165           0 :         for (int i = 0; i < n; i++) {
     166           0 :             ::std::swap(m_entries[curr + i], m_entries[number_ofm_entries -1 - i]);
     167             :         }
     168             : 
     169           0 :         if (*m_entries.back()->GetPoint() != rPos)
     170             :         {
     171           0 :             SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
     172           0 :             m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
     173             :         }
     174           0 :         bRet = true;
     175             :     }
     176             :     else {
     177           9 :         if ( (!m_entries.empty() && *m_entries.back()->GetPoint() != rPos) || m_entries.empty() ) {
     178           9 :             SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
     179           9 :             m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
     180           9 :             bRet = true;
     181             :         }
     182           9 :         if (m_entries.size() > 1 && *m_entries.back()->GetPoint() == rPos)
     183           6 :             bRet = true;
     184           9 :         if (m_entries.size() == 1 && *m_entries.back()->GetPoint() == rPos)
     185           3 :             bRet = false;
     186             :     }
     187             : #else
     188             :     m_entries.erase(m_entries.begin() + m_nCurrent, m_entries.end());
     189             :     SwUnoCrsr *const pCursor = m_rMyShell.GetDoc()->CreateUnoCrsr(rPos);
     190             :     m_entries.push_back(::boost::shared_ptr<SwUnoCrsr>(pCursor));
     191             :     bRet = true;
     192             : #endif
     193           9 :     m_nCurrent = m_entries.size();
     194             : 
     195             :     // Refresh buttons
     196           9 :     if (bBackWasDisabled)
     197           3 :         m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_BACK);
     198           9 :     if (bForwardWasEnabled)
     199           0 :         m_rMyShell.GetView().GetViewFrame()->GetBindings().Invalidate(FN_NAVIGATION_FORWARD);
     200             : 
     201             :     // show the Navigation toolbar
     202             :     css::uno::Reference< css::frame::XFrame > xFrame =
     203           9 :         m_rMyShell.GetView().GetViewFrame()->GetFrame().GetFrameInterface();
     204           9 :     if (xFrame.is())
     205             :     {
     206           9 :         css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY);
     207           9 :         if (xPropSet.is())
     208             :         {
     209           9 :             css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
     210          18 :             css::uno::Any aValue = xPropSet->getPropertyValue("LayoutManager");
     211             : 
     212           9 :             aValue >>= xLayoutManager;
     213           9 :             if (xLayoutManager.is())
     214             :             {
     215           9 :                 const OUString sResourceURL( "private:resource/toolbar/navigationobjectbar" );
     216          18 :                 css::uno::Reference< css::ui::XUIElement > xUIElement = xLayoutManager->getElement(sResourceURL);
     217           9 :                 if (!xUIElement.is())
     218             :                 {
     219           3 :                     xLayoutManager->createElement( sResourceURL );
     220           3 :                     xLayoutManager->showElement( sResourceURL );
     221           9 :                 }
     222           9 :             }
     223           9 :         }
     224             :     }
     225             : 
     226           9 :     return bRet;
     227          99 : }
     228             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10