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

Generated by: LCOV version 1.10