Files
libreoffice/sd/source/ui/toolpanel/controls/RecentlyUsedMasterPages.cxx
Vladimir Glazounov 3824483c6e CWS-TOOLING: integrate CWS sjfixes10
2009-01-15 14:02:24 +0100 af  r266369 : #i88851# Finding the right font size is now an iterative process.
2009-01-15 11:01:59 +0100 wg  r266354 : i97985
2009-01-15 10:57:33 +0100 wg  r266353 : i97985
2009-01-15 10:48:53 +0100 wg  r266347 : i97985
2009-01-15 10:48:23 +0100 wg  r266346 : i97985
2009-01-15 10:46:47 +0100 wg  r266345 : i97985
2009-01-15 10:45:43 +0100 wg  r266344 : i97985
2009-01-15 10:45:14 +0100 wg  r266343 : i97985
2009-01-15 10:44:38 +0100 wg  r266342 : i97985
2009-01-15 10:43:56 +0100 wg  r266341 : i97985
2009-01-15 10:42:50 +0100 wg  r266340 : i97985
2009-01-15 10:41:40 +0100 wg  r266339 : i97985
2009-01-15 10:39:46 +0100 wg  r266337 : i97985
2009-01-15 10:00:09 +0100 hde  r266336 : i98065
2009-01-13 15:48:20 +0100 wg  r266232 : i97985
2009-01-13 13:22:05 +0100 wg  r266217 : i97985
2009-01-13 12:34:05 +0100 wg  r266210 : i97985
2009-01-13 12:30:56 +0100 wg  r266209 : i97985
2009-01-13 12:26:56 +0100 wg  r266208 : i97985
2009-01-12 15:58:06 +0100 wg  r266165 : i97985
2009-01-12 15:43:24 +0100 wg  r266163 : i97985
2009-01-08 16:21:47 +0100 sj  r266023 : fixed warning
2009-01-08 15:33:34 +0100 sj  r266017 : fixed warning
2009-01-06 18:13:42 +0100 sj  r265935 : CWS-TOOLING: rebase CWS sjfixes10 to trunk@265758 (milestone: DEV300:m38)
2008-12-10 16:54:02 +0100 af  r265206 : #i43354# Do not delete all unused master pages automatically.
2008-12-04 13:12:50 +0100 af  r264836 : #i92795# Use BitmapEx for icons to allow transparency.
2008-12-02 17:01:49 +0100 af  r264723 : #i93082# Fixed SID_INSERTPAGE_LAYOUT_MENU.
2008-11-28 14:37:28 +0100 af  r264555 : #i88851# Changed association of Ctrl-'?' to views.
2008-11-28 11:38:52 +0100 af  r264535 : #i96681# Set version to 1.0.2
2008-11-28 11:30:04 +0100 af  r264533 : #i88851# Ctrl-1,2,3 switch to slide overview, notes, normal view.
2008-11-27 16:41:25 +0100 af  r264505 : #i92144# Removed unused code.
2008-11-26 15:29:56 +0100 af  r264401 : #i92574# Do not lock configuration controller when main pane is not available.
2008-11-21 10:13:40 +0100 sj  r264112 : #i96146# applied patch (ambiguous && ||)
2008-11-20 20:12:06 +0100 sj  r264097 : #i96083# applied patch (ambigous && ||)
2008-11-20 19:13:53 +0100 sj  r264096 : #i96163# applied patch (ambigous && ||)
2008-11-20 18:39:10 +0100 sj  r264093 : #i96165# applied patch (ambigous && ||)
2008-11-03 18:12:29 +0100 sj  r263303 : #i93996# fixed word wrapping problem
2008-11-03 18:11:02 +0100 sj  r263302 : #i93996# fixed word wrapping problem
2008-11-03 18:08:41 +0100 sj  r263301 : #i93996# fixed word wrapping problem
2008-11-03 18:06:45 +0100 sj  r263300 : #i93996# fixed word wrapping problem
2008-11-03 18:05:00 +0100 sj  r263299 : #i94831,i93616# fixed crash when importing diagonal cell border lines, fixed table import
2008-11-03 18:00:43 +0100 sj  r263298 : #i93718# spellchecking is no longer triggering the autolayout of connector objects
2009-01-21 14:22:27 +00:00

505 lines
15 KiB
C++

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: RecentlyUsedMasterPages.cxx,v $
* $Revision: 1.13 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"
#include "RecentlyUsedMasterPages.hxx"
#include "MasterPageObserver.hxx"
#include "MasterPagesSelector.hxx"
#include "MasterPageDescriptor.hxx"
#include "tools/ConfigurationAccess.hxx"
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include <algorithm>
#include <vector>
#include <comphelper/processfactory.hxx>
#include "unomodel.hxx"
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPages.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/PropertyState.hpp>
#include <tools/urlobj.hxx>
#include <unotools/confignode.hxx>
#include <osl/doublecheckedlocking.h>
#include <osl/getglobalmutex.hxx>
using namespace ::std;
using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
namespace {
static const OUString& GetPathToImpressConfigurationRoot (void)
{
static const OUString sPathToImpressConfigurationRoot (
RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Impress/"));
return sPathToImpressConfigurationRoot;
}
static const OUString& GetPathToSetNode (void)
{
static const OUString sPathToSetNode(
RTL_CONSTASCII_USTRINGPARAM(
"MultiPaneGUI/ToolPanel/RecentlyUsedMasterPages"));
return sPathToSetNode;
}
class Descriptor
{
public:
::rtl::OUString msURL;
::rtl::OUString msName;
::sd::toolpanel::controls::MasterPageContainer::Token maToken;
Descriptor (const ::rtl::OUString& rsURL, const ::rtl::OUString& rsName)
: msURL(rsURL),
msName(rsName),
maToken(::sd::toolpanel::controls::MasterPageContainer::NIL_TOKEN)
{}
Descriptor (::sd::toolpanel::controls::MasterPageContainer::Token aToken,
const ::rtl::OUString& rsURL, const ::rtl::OUString& rsName)
: msURL(rsURL),
msName(rsName),
maToken(aToken)
{}
class TokenComparator
{ public:
TokenComparator(::sd::toolpanel::controls::MasterPageContainer::Token aToken)
: maToken(aToken) {}
bool operator () (const Descriptor& rDescriptor)
{ return maToken==rDescriptor.maToken; }
private: ::sd::toolpanel::controls::MasterPageContainer::Token maToken;
};
};
} // end of anonymous namespace
namespace sd { namespace toolpanel { namespace controls {
class RecentlyUsedMasterPages::MasterPageList : public ::std::vector<Descriptor>
{
public:
MasterPageList (void) {}
};
RecentlyUsedMasterPages* RecentlyUsedMasterPages::mpInstance = NULL;
RecentlyUsedMasterPages& RecentlyUsedMasterPages::Instance (void)
{
if (mpInstance == NULL)
{
::osl::GetGlobalMutex aMutexFunctor;
::osl::MutexGuard aGuard (aMutexFunctor());
if (mpInstance == NULL)
{
RecentlyUsedMasterPages* pInstance = new RecentlyUsedMasterPages();
pInstance->LateInit();
SdGlobalResourceContainer::Instance().AddResource (
::std::auto_ptr<SdGlobalResource>(pInstance));
OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
mpInstance = pInstance;
}
}
else {
OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
}
return *mpInstance;
}
RecentlyUsedMasterPages::RecentlyUsedMasterPages (void)
: maListeners(),
mpMasterPages(new MasterPageList()),
mnMaxListSize(8),
mpContainer(new MasterPageContainer())
{
}
RecentlyUsedMasterPages::~RecentlyUsedMasterPages (void)
{
Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
mpContainer->RemoveChangeListener(aLink);
MasterPageObserver::Instance().RemoveEventListener(
LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
}
void RecentlyUsedMasterPages::LateInit (void)
{
Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
mpContainer->AddChangeListener(aLink);
LoadPersistentValues ();
MasterPageObserver::Instance().AddEventListener(
LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
}
void RecentlyUsedMasterPages::LoadPersistentValues (void)
{
try
{
do
{
tools::ConfigurationAccess aConfiguration (
GetPathToImpressConfigurationRoot(),
tools::ConfigurationAccess::READ_ONLY);
Reference<container::XNameAccess> xSet (
aConfiguration.GetConfigurationNode(GetPathToSetNode()),
UNO_QUERY);
if ( ! xSet.is())
break;
const String sURLMemberName (OUString::createFromAscii("URL"));
const String sNameMemberName (OUString::createFromAscii("Name"));
OUString sURL;
OUString sName;
// Read the names and URLs of the master pages.
Sequence<OUString> aKeys (xSet->getElementNames());
mpMasterPages->clear();
mpMasterPages->reserve(aKeys.getLength());
for (int i=0; i<aKeys.getLength(); i++)
{
Reference<container::XNameAccess> xSetItem (
xSet->getByName(aKeys[i]), UNO_QUERY);
if (xSetItem.is())
{
Any aURL (xSetItem->getByName(sURLMemberName));
Any aName (xSetItem->getByName(sNameMemberName));
aURL >>= sURL;
aName >>= sName;
SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
MasterPageContainer::TEMPLATE,
-1,
sURL,
String(),
sName,
false,
::boost::shared_ptr<PageObjectProvider>(
new TemplatePageObjectProvider(sURL)),
::boost::shared_ptr<PreviewProvider>(
new TemplatePreviewProvider(sURL))));
// For user supplied templates we use a different
// preview provider: The preview in the document shows
// not only shapes on the master page but also shapes on
// the foreground. This is misleading and therefore
// these previews are discarded and created directly
// from the page objects.
if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
new PagePreviewProvider());
MasterPageContainer::Token aToken (mpContainer->PutMasterPage(pDescriptor));
mpMasterPages->push_back(Descriptor(aToken,sURL,sName));
}
}
ResolveList();
}
while (false);
}
catch (Exception&)
{
// Ignore exception.
}
}
void RecentlyUsedMasterPages::SavePersistentValues (void)
{
try
{
do
{
tools::ConfigurationAccess aConfiguration (
GetPathToImpressConfigurationRoot(),
tools::ConfigurationAccess::READ_WRITE);
Reference<container::XNameContainer> xSet (
aConfiguration.GetConfigurationNode(GetPathToSetNode()),
UNO_QUERY);
if ( ! xSet.is())
break;
// Clear the set.
Sequence<OUString> aKeys (xSet->getElementNames());
sal_Int32 i;
for (i=0; i<aKeys.getLength(); i++)
xSet->removeByName (aKeys[i]);
// Fill it with the URLs of this object.
const String sURLMemberName (OUString::createFromAscii("URL"));
const String sNameMemberName (OUString::createFromAscii("Name"));
Any aValue;
Reference<lang::XSingleServiceFactory> xChildFactory (
xSet, UNO_QUERY);
if ( ! xChildFactory.is())
break;
MasterPageList::const_iterator iDescriptor;
sal_Int32 nIndex(0);
for (iDescriptor=mpMasterPages->begin();
iDescriptor!=mpMasterPages->end();
++iDescriptor,++nIndex)
{
// Create new child.
OUString sKey (OUString::createFromAscii("index_"));
sKey += OUString::valueOf(nIndex);
Reference<container::XNameReplace> xChild(
xChildFactory->createInstance(), UNO_QUERY);
if (xChild.is())
{
xSet->insertByName (sKey, makeAny(xChild));
aValue <<= OUString(iDescriptor->msURL);
xChild->replaceByName (sURLMemberName, aValue);
aValue <<= OUString(iDescriptor->msName);
xChild->replaceByName (sNameMemberName, aValue);
}
}
// Write the data back to disk.
aConfiguration.CommitChanges();
}
while (false);
}
catch (Exception&)
{
// Ignore exception.
}
}
void RecentlyUsedMasterPages::AddEventListener (const Link& rEventListener)
{
if (::std::find (
maListeners.begin(),
maListeners.end(),
rEventListener) == maListeners.end())
{
maListeners.push_back (rEventListener);
}
}
void RecentlyUsedMasterPages::RemoveEventListener (const Link& rEventListener)
{
maListeners.erase (
::std::find (
maListeners.begin(),
maListeners.end(),
rEventListener));
}
int RecentlyUsedMasterPages::GetMasterPageCount (void) const
{
return mpMasterPages->size();
}
MasterPageContainer::Token RecentlyUsedMasterPages::GetTokenForIndex (sal_uInt32 nIndex) const
{
if(nIndex<mpMasterPages->size())
return (*mpMasterPages)[nIndex].maToken;
else
return MasterPageContainer::NIL_TOKEN;
}
void RecentlyUsedMasterPages::SendEvent (void)
{
::std::vector<Link>::iterator aLink (maListeners.begin());
::std::vector<Link>::iterator aEnd (maListeners.end());
while (aLink!=aEnd)
{
aLink->Call (NULL);
++aLink;
}
}
IMPL_LINK(RecentlyUsedMasterPages, MasterPageChangeListener,
MasterPageObserverEvent*, pEvent)
{
switch (pEvent->meType)
{
case MasterPageObserverEvent::ET_MASTER_PAGE_ADDED:
case MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS:
AddMasterPage(
mpContainer->GetTokenForStyleName(pEvent->mrMasterPageName));
break;
case MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED:
// Do not change the list of recently master pages (the deleted
// page was recently used) but tell the listeners. They may want
// to update their lists.
SendEvent();
break;
}
return 0;
}
IMPL_LINK(RecentlyUsedMasterPages, MasterPageContainerChangeListener,
MasterPageContainerChangeEvent*, pEvent)
{
if (pEvent != NULL)
switch (pEvent->meEventType)
{
case MasterPageContainerChangeEvent::CHILD_ADDED:
case MasterPageContainerChangeEvent::CHILD_REMOVED:
case MasterPageContainerChangeEvent::INDEX_CHANGED:
case MasterPageContainerChangeEvent::INDEXES_CHANGED:
ResolveList();
break;
default:
// Ignored.
break;
}
return 0;
}
void RecentlyUsedMasterPages::AddMasterPage (
MasterPageContainer::Token aToken,
bool bMakePersistent)
{
// For the page to be inserted the token has to be valid and the page
// has to have a valid URL. This excludes master pages that do not come
// from template files.
if (aToken != MasterPageContainer::NIL_TOKEN
&& mpContainer->GetURLForToken(aToken).Len()>0)
{
MasterPageList::iterator aIterator (
::std::find_if(mpMasterPages->begin(),mpMasterPages->end(),
Descriptor::TokenComparator(aToken)));
if (aIterator != mpMasterPages->end())
{
// When an entry for the given token already exists then remove
// it now and insert it later at the head of the list.
mpMasterPages->erase (aIterator);
}
mpMasterPages->insert(mpMasterPages->begin(),
Descriptor(
aToken,
mpContainer->GetURLForToken(aToken),
mpContainer->GetStyleNameForToken(aToken)));
// Shorten list to maximal size.
while (mpMasterPages->size() > mnMaxListSize)
{
mpMasterPages->pop_back ();
}
if (bMakePersistent)
SavePersistentValues ();
SendEvent();
}
}
void RecentlyUsedMasterPages::ResolveList (void)
{
bool bNotify (false);
MasterPageList::iterator iDescriptor;
for (iDescriptor=mpMasterPages->begin(); iDescriptor!=mpMasterPages->end(); ++iDescriptor)
{
if (iDescriptor->maToken == MasterPageContainer::NIL_TOKEN)
{
MasterPageContainer::Token aToken (mpContainer->GetTokenForURL(iDescriptor->msURL));
iDescriptor->maToken = aToken;
if (aToken != MasterPageContainer::NIL_TOKEN)
bNotify = true;
}
else
{
if ( ! mpContainer->HasToken(iDescriptor->maToken))
{
iDescriptor->maToken = MasterPageContainer::NIL_TOKEN;
bNotify = true;
}
}
}
if (bNotify)
SendEvent();
}
} } } // end of namespace ::sd::toolpanel::controls