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

Generated by: LCOV version 1.11