LCOV - code coverage report
Current view: top level - sd/source/ui/sidebar - RecentlyUsedMasterPages.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 161 0.6 %
Date: 2014-11-03 Functions: 2 22 9.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             :  * 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             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "RecentlyUsedMasterPages.hxx"
      21             : #include "MasterPageObserver.hxx"
      22             : #include "MasterPagesSelector.hxx"
      23             : #include "MasterPageDescriptor.hxx"
      24             : #include "tools/ConfigurationAccess.hxx"
      25             : #include "drawdoc.hxx"
      26             : #include "sdpage.hxx"
      27             : 
      28             : #include <algorithm>
      29             : #include <vector>
      30             : 
      31             : #include <comphelper/processfactory.hxx>
      32             : #include "unomodel.hxx"
      33             : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
      34             : #include <com/sun/star/drawing/XDrawPages.hpp>
      35             : #include <com/sun/star/frame/XComponentLoader.hpp>
      36             : #include <com/sun/star/container/XNameAccess.hpp>
      37             : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
      38             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      39             : #include <com/sun/star/beans/PropertyValue.hpp>
      40             : #include <com/sun/star/beans/PropertyState.hpp>
      41             : #include <unotools/confignode.hxx>
      42             : #include <osl/doublecheckedlocking.h>
      43             : #include <osl/getglobalmutex.hxx>
      44             : 
      45             : using namespace ::std;
      46             : using namespace ::com::sun::star;
      47             : using namespace ::com::sun::star::uno;
      48             : 
      49             : namespace {
      50             : 
      51           0 : static const OUString& GetPathToImpressConfigurationRoot (void)
      52             : {
      53           0 :     static const OUString sPathToImpressConfigurationRoot ("/org.openoffice.Office.Impress/");
      54           0 :     return sPathToImpressConfigurationRoot;
      55             : }
      56           0 : static const OUString& GetPathToSetNode (void)
      57             : {
      58           0 :     static const OUString sPathToSetNode("MultiPaneGUI/ToolPanel/RecentlyUsedMasterPages");
      59           0 :     return sPathToSetNode;
      60             : }
      61             : 
      62             : } // end of anonymous namespace
      63             : 
      64             : namespace sd { namespace sidebar {
      65             : 
      66             : RecentlyUsedMasterPages* RecentlyUsedMasterPages::mpInstance = NULL;
      67             : 
      68           0 : RecentlyUsedMasterPages&  RecentlyUsedMasterPages::Instance (void)
      69             : {
      70           0 :     if (mpInstance == NULL)
      71             :     {
      72             :         ::osl::GetGlobalMutex aMutexFunctor;
      73           0 :         ::osl::MutexGuard aGuard (aMutexFunctor());
      74           0 :         if (mpInstance == NULL)
      75             :         {
      76           0 :             RecentlyUsedMasterPages* pInstance = new RecentlyUsedMasterPages();
      77           0 :             pInstance->LateInit();
      78           0 :             SdGlobalResourceContainer::Instance().AddResource (
      79           0 :                 ::std::unique_ptr<SdGlobalResource>(pInstance));
      80             :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
      81           0 :             mpInstance = pInstance;
      82           0 :         }
      83             :     }
      84             :     else {
      85             :         OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
      86             :     }
      87             : 
      88           0 :     return *mpInstance;
      89             : }
      90             : 
      91           0 : RecentlyUsedMasterPages::RecentlyUsedMasterPages (void)
      92             :     : maListeners(),
      93             :       mvMasterPages(),
      94             :       mnMaxListSize(8),
      95           0 :       mpContainer(new MasterPageContainer())
      96             : {
      97           0 : }
      98             : 
      99           0 : RecentlyUsedMasterPages::~RecentlyUsedMasterPages (void)
     100             : {
     101           0 :     Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
     102           0 :     mpContainer->RemoveChangeListener(aLink);
     103             : 
     104           0 :     MasterPageObserver::Instance().RemoveEventListener(
     105           0 :         LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
     106           0 : }
     107             : 
     108           0 : void RecentlyUsedMasterPages::LateInit (void)
     109             : {
     110           0 :     Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
     111           0 :     mpContainer->AddChangeListener(aLink);
     112             : 
     113           0 :     LoadPersistentValues ();
     114           0 :     MasterPageObserver::Instance().AddEventListener(
     115           0 :         LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
     116           0 : }
     117             : 
     118           0 : void RecentlyUsedMasterPages::LoadPersistentValues (void)
     119             : {
     120             :     try
     121             :     {
     122             :         tools::ConfigurationAccess aConfiguration (
     123           0 :             GetPathToImpressConfigurationRoot(),
     124           0 :             tools::ConfigurationAccess::READ_ONLY);
     125             :         Reference<container::XNameAccess> xSet (
     126           0 :             aConfiguration.GetConfigurationNode(GetPathToSetNode()),
     127           0 :             UNO_QUERY);
     128           0 :         if ( ! xSet.is())
     129           0 :             return;
     130             : 
     131           0 :         const OUString sURLMemberName("URL");
     132           0 :         const OUString sNameMemberName("Name");
     133           0 :         OUString sURL;
     134           0 :         OUString sName;
     135             : 
     136             :         // Read the names and URLs of the master pages.
     137           0 :         Sequence<OUString> aKeys (xSet->getElementNames());
     138           0 :         mvMasterPages.clear();
     139           0 :         mvMasterPages.reserve(aKeys.getLength());
     140           0 :         for (int i=0; i<aKeys.getLength(); i++)
     141             :         {
     142             :             Reference<container::XNameAccess> xSetItem (
     143           0 :                 xSet->getByName(aKeys[i]), UNO_QUERY);
     144           0 :             if (xSetItem.is())
     145             :             {
     146           0 :                 Any aURL (xSetItem->getByName(sURLMemberName));
     147           0 :                 Any aName (xSetItem->getByName(sNameMemberName));
     148           0 :                 aURL >>= sURL;
     149           0 :                 aName >>= sName;
     150             :                 SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
     151             :                     MasterPageContainer::TEMPLATE,
     152             :                     -1,
     153             :                     sURL,
     154             :                     OUString(),
     155             :                     sName,
     156             :                     false,
     157             :                     ::boost::shared_ptr<PageObjectProvider>(
     158           0 :                         new TemplatePageObjectProvider(sURL)),
     159             :                     ::boost::shared_ptr<PreviewProvider>(
     160           0 :                         new TemplatePreviewProvider(sURL))));
     161             :                 // For user supplied templates we use a different
     162             :                 // preview provider: The preview in the document shows
     163             :                 // not only shapes on the master page but also shapes on
     164             :                 // the foreground.  This is misleading and therefore
     165             :                 // these previews are discarded and created directly
     166             :                 // from the page objects.
     167           0 :                 if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
     168           0 :                     pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
     169           0 :                         new PagePreviewProvider());
     170           0 :                 MasterPageContainer::Token aToken (mpContainer->PutMasterPage(pDescriptor));
     171           0 :                 mvMasterPages.push_back(Descriptor(aToken,sURL,sName));
     172             :             }
     173           0 :         }
     174             : 
     175           0 :         ResolveList();
     176             :     }
     177           0 :     catch (Exception&)
     178             :     {
     179             :         // Ignore exception.
     180             :     }
     181             : }
     182             : 
     183           0 : void RecentlyUsedMasterPages::SavePersistentValues (void)
     184             : {
     185             :     try
     186             :     {
     187             :         tools::ConfigurationAccess aConfiguration (
     188           0 :             GetPathToImpressConfigurationRoot(),
     189           0 :             tools::ConfigurationAccess::READ_WRITE);
     190             :         Reference<container::XNameContainer> xSet (
     191           0 :             aConfiguration.GetConfigurationNode(GetPathToSetNode()),
     192           0 :             UNO_QUERY);
     193           0 :         if ( ! xSet.is())
     194           0 :             return;
     195             : 
     196             :         // Clear the set.
     197           0 :         Sequence<OUString> aKeys (xSet->getElementNames());
     198             :         sal_Int32 i;
     199           0 :         for (i=0; i<aKeys.getLength(); i++)
     200           0 :             xSet->removeByName (aKeys[i]);
     201             : 
     202             :         // Fill it with the URLs of this object.
     203           0 :         const OUString sURLMemberName("URL");
     204           0 :         const OUString sNameMemberName("Name");
     205           0 :         Any aValue;
     206             :         Reference<lang::XSingleServiceFactory> xChildFactory (
     207           0 :             xSet, UNO_QUERY);
     208           0 :         if ( ! xChildFactory.is())
     209           0 :             return;
     210           0 :         MasterPageList::const_iterator iDescriptor;
     211           0 :         sal_Int32 nIndex(0);
     212           0 :         for (iDescriptor=mvMasterPages.begin();
     213           0 :                 iDescriptor!=mvMasterPages.end();
     214             :                 ++iDescriptor,++nIndex)
     215             :         {
     216             :             // Create new child.
     217           0 :             OUString sKey ("index_");
     218           0 :             sKey += OUString::number(nIndex);
     219             :             Reference<container::XNameReplace> xChild(
     220           0 :                 xChildFactory->createInstance(), UNO_QUERY);
     221           0 :             if (xChild.is())
     222             :             {
     223           0 :                 xSet->insertByName (sKey, makeAny(xChild));
     224             : 
     225           0 :                 aValue <<= OUString(iDescriptor->msURL);
     226           0 :                 xChild->replaceByName (sURLMemberName, aValue);
     227             : 
     228           0 :                 aValue <<= OUString(iDescriptor->msName);
     229           0 :                 xChild->replaceByName (sNameMemberName, aValue);
     230             :             }
     231           0 :         }
     232             : 
     233             :         // Write the data back to disk.
     234           0 :         aConfiguration.CommitChanges();
     235             :     }
     236           0 :     catch (Exception&)
     237             :     {
     238             :         // Ignore exception.
     239             :     }
     240             : }
     241             : 
     242           0 : void RecentlyUsedMasterPages::AddEventListener (const Link& rEventListener)
     243             : {
     244           0 :     if (::std::find (
     245             :         maListeners.begin(),
     246             :         maListeners.end(),
     247           0 :         rEventListener) == maListeners.end())
     248             :     {
     249           0 :         maListeners.push_back (rEventListener);
     250             :     }
     251           0 : }
     252             : 
     253           0 : void RecentlyUsedMasterPages::RemoveEventListener (const Link& rEventListener)
     254             : {
     255             :     maListeners.erase (
     256             :         ::std::find (
     257             :             maListeners.begin(),
     258             :             maListeners.end(),
     259           0 :             rEventListener));
     260           0 : }
     261             : 
     262           0 : int RecentlyUsedMasterPages::GetMasterPageCount (void) const
     263             : {
     264           0 :     return mvMasterPages.size();
     265             : }
     266             : 
     267           0 : MasterPageContainer::Token RecentlyUsedMasterPages::GetTokenForIndex (sal_uInt32 nIndex) const
     268             : {
     269           0 :     if(nIndex<mvMasterPages.size())
     270           0 :         return mvMasterPages[nIndex].maToken;
     271             :     else
     272           0 :         return MasterPageContainer::NIL_TOKEN;
     273             : }
     274             : 
     275           0 : void RecentlyUsedMasterPages::SendEvent (void)
     276             : {
     277           0 :     ::std::vector<Link>::iterator aLink (maListeners.begin());
     278           0 :     ::std::vector<Link>::iterator aEnd (maListeners.end());
     279           0 :     while (aLink!=aEnd)
     280             :     {
     281           0 :         aLink->Call (NULL);
     282           0 :         ++aLink;
     283             :     }
     284           0 : }
     285             : 
     286           0 : IMPL_LINK(RecentlyUsedMasterPages, MasterPageChangeListener,
     287             :     MasterPageObserverEvent*, pEvent)
     288             : {
     289           0 :     switch (pEvent->meType)
     290             :     {
     291             :         case MasterPageObserverEvent::ET_MASTER_PAGE_ADDED:
     292             :         case MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS:
     293             :             AddMasterPage(
     294           0 :                 mpContainer->GetTokenForStyleName(pEvent->mrMasterPageName));
     295           0 :             break;
     296             : 
     297             :         case MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED:
     298             :             // Do not change the list of recently master pages (the deleted
     299             :             // page was recently used) but tell the listeners.  They may want
     300             :             // to update their lists.
     301           0 :             SendEvent();
     302           0 :             break;
     303             :     }
     304           0 :     return 0;
     305             : }
     306             : 
     307           0 : IMPL_LINK(RecentlyUsedMasterPages, MasterPageContainerChangeListener,
     308             :     MasterPageContainerChangeEvent*, pEvent)
     309             : {
     310           0 :     if (pEvent != NULL)
     311           0 :         switch (pEvent->meEventType)
     312             :         {
     313             :             case MasterPageContainerChangeEvent::CHILD_ADDED:
     314             :             case MasterPageContainerChangeEvent::CHILD_REMOVED:
     315             :             case MasterPageContainerChangeEvent::INDEX_CHANGED:
     316             :             case MasterPageContainerChangeEvent::INDEXES_CHANGED:
     317           0 :                 ResolveList();
     318           0 :                 break;
     319             : 
     320             :             default:
     321             :                 // Ignored.
     322           0 :                 break;
     323             :         }
     324           0 :     return 0;
     325             : }
     326             : 
     327           0 : void RecentlyUsedMasterPages::AddMasterPage (
     328             :     MasterPageContainer::Token aToken,
     329             :     bool bMakePersistent)
     330             : {
     331             :     // For the page to be inserted the token has to be valid and the page
     332             :     // has to have a valid URL.  This excludes master pages that do not come
     333             :     // from template files.
     334           0 :     if (aToken != MasterPageContainer::NIL_TOKEN
     335           0 :         && !mpContainer->GetURLForToken(aToken).isEmpty())
     336             :     {
     337             : 
     338             :         MasterPageList::iterator aIterator (
     339             :             ::std::find_if(mvMasterPages.begin(),mvMasterPages.end(),
     340           0 :                 Descriptor::TokenComparator(aToken)));
     341           0 :         if (aIterator != mvMasterPages.end())
     342             :         {
     343             :             // When an entry for the given token already exists then remove
     344             :             // it now and insert it later at the head of the list.
     345           0 :             mvMasterPages.erase (aIterator);
     346             :         }
     347             : 
     348           0 :         mvMasterPages.insert(mvMasterPages.begin(),
     349             :             Descriptor(
     350             :                 aToken,
     351             :                 mpContainer->GetURLForToken(aToken),
     352           0 :                 mpContainer->GetStyleNameForToken(aToken)));
     353             : 
     354             :         // Shorten list to maximal size.
     355           0 :         while (mvMasterPages.size() > mnMaxListSize)
     356             :         {
     357           0 :             mvMasterPages.pop_back ();
     358             :         }
     359             : 
     360           0 :         if (bMakePersistent)
     361           0 :             SavePersistentValues ();
     362           0 :         SendEvent();
     363             :     }
     364           0 : }
     365             : 
     366           0 : void RecentlyUsedMasterPages::ResolveList (void)
     367             : {
     368           0 :     bool bNotify (false);
     369             : 
     370           0 :     MasterPageList::iterator iDescriptor;
     371           0 :     for (iDescriptor=mvMasterPages.begin(); iDescriptor!=mvMasterPages.end(); ++iDescriptor)
     372             :     {
     373           0 :         if (iDescriptor->maToken == MasterPageContainer::NIL_TOKEN)
     374             :         {
     375           0 :             MasterPageContainer::Token aToken (mpContainer->GetTokenForURL(iDescriptor->msURL));
     376           0 :             iDescriptor->maToken = aToken;
     377           0 :             if (aToken != MasterPageContainer::NIL_TOKEN)
     378           0 :                 bNotify = true;
     379             :         }
     380             :         else
     381             :         {
     382           0 :             if ( ! mpContainer->HasToken(iDescriptor->maToken))
     383             :             {
     384           0 :                 iDescriptor->maToken = MasterPageContainer::NIL_TOKEN;
     385           0 :                 bNotify = true;
     386             :             }
     387             :         }
     388             :     }
     389             : 
     390           0 :     if (bNotify)
     391           0 :         SendEvent();
     392           0 : }
     393             : 
     394         114 : } } // end of namespace sd::sidebar
     395             : 
     396             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10