fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / ui / toolpanel / controls / RecentlyUsedMasterPages.cxx
blobb471040d4b5397ebe9627a05dff2ec42eb64a78c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "RecentlyUsedMasterPages.hxx"
22 #include "MasterPageObserver.hxx"
23 #include "MasterPagesSelector.hxx"
24 #include "MasterPageDescriptor.hxx"
25 #include "tools/ConfigurationAccess.hxx"
26 #include "drawdoc.hxx"
27 #include "sdpage.hxx"
29 #include <algorithm>
30 #include <vector>
32 #include <comphelper/processfactory.hxx>
33 #include "unomodel.hxx"
34 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
35 #include <com/sun/star/drawing/XDrawPages.hpp>
36 #include <com/sun/star/frame/XComponentLoader.hpp>
37 #include <com/sun/star/container/XNameAccess.hpp>
38 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/beans/PropertyValue.hpp>
41 #include <com/sun/star/beans/PropertyState.hpp>
42 #include <unotools/confignode.hxx>
43 #include <osl/doublecheckedlocking.h>
44 #include <osl/getglobalmutex.hxx>
46 using namespace ::std;
47 using namespace ::com::sun::star;
48 using namespace ::com::sun::star::uno;
51 namespace {
53 static const OUString& GetPathToImpressConfigurationRoot (void)
55 static const OUString sPathToImpressConfigurationRoot ("/org.openoffice.Office.Impress/");
56 return sPathToImpressConfigurationRoot;
58 static const OUString& GetPathToSetNode (void)
60 static const OUString sPathToSetNode("MultiPaneGUI/ToolPanel/RecentlyUsedMasterPages");
61 return sPathToSetNode;
65 class Descriptor
67 public:
68 OUString msURL;
69 OUString msName;
70 ::sd::toolpanel::controls::MasterPageContainer::Token maToken;
71 Descriptor (const OUString& rsURL, const OUString& rsName)
72 : msURL(rsURL),
73 msName(rsName),
74 maToken(::sd::toolpanel::controls::MasterPageContainer::NIL_TOKEN)
76 Descriptor (::sd::toolpanel::controls::MasterPageContainer::Token aToken,
77 const OUString& rsURL, const OUString& rsName)
78 : msURL(rsURL),
79 msName(rsName),
80 maToken(aToken)
82 class TokenComparator
84 public:
85 TokenComparator(::sd::toolpanel::controls::MasterPageContainer::Token aToken)
86 : maToken(aToken) {}
87 bool operator () (const Descriptor& rDescriptor) const
88 { return maToken==rDescriptor.maToken; }
89 private:
90 ::sd::toolpanel::controls::MasterPageContainer::Token maToken;
94 } // end of anonymous namespace
99 namespace sd { namespace toolpanel { namespace controls {
101 class RecentlyUsedMasterPages::MasterPageList : public ::std::vector<Descriptor>
103 public:
104 MasterPageList (void) {}
108 RecentlyUsedMasterPages* RecentlyUsedMasterPages::mpInstance = NULL;
111 RecentlyUsedMasterPages& RecentlyUsedMasterPages::Instance (void)
113 if (mpInstance == NULL)
115 ::osl::GetGlobalMutex aMutexFunctor;
116 ::osl::MutexGuard aGuard (aMutexFunctor());
117 if (mpInstance == NULL)
119 RecentlyUsedMasterPages* pInstance = new RecentlyUsedMasterPages();
120 pInstance->LateInit();
121 SdGlobalResourceContainer::Instance().AddResource (
122 ::std::auto_ptr<SdGlobalResource>(pInstance));
123 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
124 mpInstance = pInstance;
127 else {
128 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
131 return *mpInstance;
137 RecentlyUsedMasterPages::RecentlyUsedMasterPages (void)
138 : maListeners(),
139 mpMasterPages(new MasterPageList()),
140 mnMaxListSize(8),
141 mpContainer(new MasterPageContainer())
148 RecentlyUsedMasterPages::~RecentlyUsedMasterPages (void)
150 Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
151 mpContainer->RemoveChangeListener(aLink);
153 MasterPageObserver::Instance().RemoveEventListener(
154 LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
160 void RecentlyUsedMasterPages::LateInit (void)
162 Link aLink (LINK(this,RecentlyUsedMasterPages,MasterPageContainerChangeListener));
163 mpContainer->AddChangeListener(aLink);
165 LoadPersistentValues ();
166 MasterPageObserver::Instance().AddEventListener(
167 LINK(this,RecentlyUsedMasterPages,MasterPageChangeListener));
173 void RecentlyUsedMasterPages::LoadPersistentValues (void)
177 tools::ConfigurationAccess aConfiguration (
178 GetPathToImpressConfigurationRoot(),
179 tools::ConfigurationAccess::READ_ONLY);
180 Reference<container::XNameAccess> xSet (
181 aConfiguration.GetConfigurationNode(GetPathToSetNode()),
182 UNO_QUERY);
183 if ( ! xSet.is())
184 return;
186 const OUString sURLMemberName("URL");
187 const OUString sNameMemberName("Name");
188 OUString sURL;
189 OUString sName;
191 // Read the names and URLs of the master pages.
192 Sequence<OUString> aKeys (xSet->getElementNames());
193 mpMasterPages->clear();
194 mpMasterPages->reserve(aKeys.getLength());
195 for (int i=0; i<aKeys.getLength(); i++)
197 Reference<container::XNameAccess> xSetItem (
198 xSet->getByName(aKeys[i]), UNO_QUERY);
199 if (xSetItem.is())
201 Any aURL (xSetItem->getByName(sURLMemberName));
202 Any aName (xSetItem->getByName(sNameMemberName));
203 aURL >>= sURL;
204 aName >>= sName;
205 SharedMasterPageDescriptor pDescriptor (new MasterPageDescriptor(
206 MasterPageContainer::TEMPLATE,
208 sURL,
209 String(),
210 sName,
211 false,
212 ::boost::shared_ptr<PageObjectProvider>(
213 new TemplatePageObjectProvider(sURL)),
214 ::boost::shared_ptr<PreviewProvider>(
215 new TemplatePreviewProvider(sURL))));
216 // For user supplied templates we use a different
217 // preview provider: The preview in the document shows
218 // not only shapes on the master page but also shapes on
219 // the foreground. This is misleading and therefore
220 // these previews are discarded and created directly
221 // from the page objects.
222 if (pDescriptor->GetURLClassification() == MasterPageDescriptor::URLCLASS_USER)
223 pDescriptor->mpPreviewProvider = ::boost::shared_ptr<PreviewProvider>(
224 new PagePreviewProvider());
225 MasterPageContainer::Token aToken (mpContainer->PutMasterPage(pDescriptor));
226 mpMasterPages->push_back(Descriptor(aToken,sURL,sName));
230 ResolveList();
232 catch (Exception&)
234 // Ignore exception.
241 void RecentlyUsedMasterPages::SavePersistentValues (void)
245 tools::ConfigurationAccess aConfiguration (
246 GetPathToImpressConfigurationRoot(),
247 tools::ConfigurationAccess::READ_WRITE);
248 Reference<container::XNameContainer> xSet (
249 aConfiguration.GetConfigurationNode(GetPathToSetNode()),
250 UNO_QUERY);
251 if ( ! xSet.is())
252 return;
254 // Clear the set.
255 Sequence<OUString> aKeys (xSet->getElementNames());
256 sal_Int32 i;
257 for (i=0; i<aKeys.getLength(); i++)
258 xSet->removeByName (aKeys[i]);
260 // Fill it with the URLs of this object.
261 const OUString sURLMemberName("URL");
262 const OUString sNameMemberName("Name");
263 Any aValue;
264 Reference<lang::XSingleServiceFactory> xChildFactory (
265 xSet, UNO_QUERY);
266 if ( ! xChildFactory.is())
267 return;
268 MasterPageList::const_iterator iDescriptor;
269 sal_Int32 nIndex(0);
270 for (iDescriptor=mpMasterPages->begin();
271 iDescriptor!=mpMasterPages->end();
272 ++iDescriptor,++nIndex)
274 // Create new child.
275 OUString sKey ("index_");
276 sKey += OUString::valueOf(nIndex);
277 Reference<container::XNameReplace> xChild(
278 xChildFactory->createInstance(), UNO_QUERY);
279 if (xChild.is())
281 xSet->insertByName (sKey, makeAny(xChild));
283 aValue <<= OUString(iDescriptor->msURL);
284 xChild->replaceByName (sURLMemberName, aValue);
286 aValue <<= OUString(iDescriptor->msName);
287 xChild->replaceByName (sNameMemberName, aValue);
291 // Write the data back to disk.
292 aConfiguration.CommitChanges();
294 catch (Exception&)
296 // Ignore exception.
303 void RecentlyUsedMasterPages::AddEventListener (const Link& rEventListener)
305 if (::std::find (
306 maListeners.begin(),
307 maListeners.end(),
308 rEventListener) == maListeners.end())
310 maListeners.push_back (rEventListener);
317 void RecentlyUsedMasterPages::RemoveEventListener (const Link& rEventListener)
319 maListeners.erase (
320 ::std::find (
321 maListeners.begin(),
322 maListeners.end(),
323 rEventListener));
329 int RecentlyUsedMasterPages::GetMasterPageCount (void) const
331 return mpMasterPages->size();
337 MasterPageContainer::Token RecentlyUsedMasterPages::GetTokenForIndex (sal_uInt32 nIndex) const
339 if(nIndex<mpMasterPages->size())
340 return (*mpMasterPages)[nIndex].maToken;
341 else
342 return MasterPageContainer::NIL_TOKEN;
348 void RecentlyUsedMasterPages::SendEvent (void)
350 ::std::vector<Link>::iterator aLink (maListeners.begin());
351 ::std::vector<Link>::iterator aEnd (maListeners.end());
352 while (aLink!=aEnd)
354 aLink->Call (NULL);
355 ++aLink;
362 IMPL_LINK(RecentlyUsedMasterPages, MasterPageChangeListener,
363 MasterPageObserverEvent*, pEvent)
365 switch (pEvent->meType)
367 case MasterPageObserverEvent::ET_MASTER_PAGE_ADDED:
368 case MasterPageObserverEvent::ET_MASTER_PAGE_EXISTS:
369 AddMasterPage(
370 mpContainer->GetTokenForStyleName(pEvent->mrMasterPageName));
371 break;
373 case MasterPageObserverEvent::ET_MASTER_PAGE_REMOVED:
374 // Do not change the list of recently master pages (the deleted
375 // page was recently used) but tell the listeners. They may want
376 // to update their lists.
377 SendEvent();
378 break;
380 return 0;
386 IMPL_LINK(RecentlyUsedMasterPages, MasterPageContainerChangeListener,
387 MasterPageContainerChangeEvent*, pEvent)
389 if (pEvent != NULL)
390 switch (pEvent->meEventType)
392 case MasterPageContainerChangeEvent::CHILD_ADDED:
393 case MasterPageContainerChangeEvent::CHILD_REMOVED:
394 case MasterPageContainerChangeEvent::INDEX_CHANGED:
395 case MasterPageContainerChangeEvent::INDEXES_CHANGED:
396 ResolveList();
397 break;
399 default:
400 // Ignored.
401 break;
403 return 0;
409 void RecentlyUsedMasterPages::AddMasterPage (
410 MasterPageContainer::Token aToken,
411 bool bMakePersistent)
413 // For the page to be inserted the token has to be valid and the page
414 // has to have a valid URL. This excludes master pages that do not come
415 // from template files.
416 if (aToken != MasterPageContainer::NIL_TOKEN
417 && mpContainer->GetURLForToken(aToken).Len()>0)
420 MasterPageList::iterator aIterator (
421 ::std::find_if(mpMasterPages->begin(),mpMasterPages->end(),
422 Descriptor::TokenComparator(aToken)));
423 if (aIterator != mpMasterPages->end())
425 // When an entry for the given token already exists then remove
426 // it now and insert it later at the head of the list.
427 mpMasterPages->erase (aIterator);
430 mpMasterPages->insert(mpMasterPages->begin(),
431 Descriptor(
432 aToken,
433 mpContainer->GetURLForToken(aToken),
434 mpContainer->GetStyleNameForToken(aToken)));
436 // Shorten list to maximal size.
437 while (mpMasterPages->size() > mnMaxListSize)
439 mpMasterPages->pop_back ();
442 if (bMakePersistent)
443 SavePersistentValues ();
444 SendEvent();
451 void RecentlyUsedMasterPages::ResolveList (void)
453 bool bNotify (false);
455 MasterPageList::iterator iDescriptor;
456 for (iDescriptor=mpMasterPages->begin(); iDescriptor!=mpMasterPages->end(); ++iDescriptor)
458 if (iDescriptor->maToken == MasterPageContainer::NIL_TOKEN)
460 MasterPageContainer::Token aToken (mpContainer->GetTokenForURL(iDescriptor->msURL));
461 iDescriptor->maToken = aToken;
462 if (aToken != MasterPageContainer::NIL_TOKEN)
463 bNotify = true;
465 else
467 if ( ! mpContainer->HasToken(iDescriptor->maToken))
469 iDescriptor->maToken = MasterPageContainer::NIL_TOKEN;
470 bNotify = true;
475 if (bNotify)
476 SendEvent();
480 } } } // end of namespace ::sd::toolpanel::controls
482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */