summaryrefslogtreecommitdiff
path: root/sd/source/ui/view/ToolBarManager.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/view/ToolBarManager.cxx')
-rwxr-xr-xsd/source/ui/view/ToolBarManager.cxx1697
1 files changed, 1697 insertions, 0 deletions
diff --git a/sd/source/ui/view/ToolBarManager.cxx b/sd/source/ui/view/ToolBarManager.cxx
new file mode 100755
index 000000000000..ce3064392d40
--- /dev/null
+++ b/sd/source/ui/view/ToolBarManager.cxx
@@ -0,0 +1,1697 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 "ToolBarManager.hxx"
+
+#include "DrawViewShell.hxx"
+#include "EventMultiplexer.hxx"
+#include "ViewShellBase.hxx"
+#include "ViewShellManager.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/ref.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/eitem.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/unohlp.hxx>
+#endif
+#include <tools/link.hxx>
+
+#include <map>
+#include <vector>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+#undef VERBOSE
+
+#undef OUSTRING // Remove definition made in the SFX
+#define OUSTRING(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)))
+
+namespace {
+
+using namespace sd;
+
+class ToolBarRules;
+
+/** Lock of the frame::XLayoutManager.
+*/
+class LayouterLock
+{
+public:
+ LayouterLock (const Reference<frame::XLayoutManager>& rxLayouter);
+ ~LayouterLock (void);
+private:
+ Reference<frame::XLayoutManager> mxLayouter;
+};
+
+
+typedef ::std::vector<rtl::OUString> NameList;
+
+/** Store a list of tool bars for each of the tool bar groups. From
+ this the list of requested tool bars is built.
+*/
+class ToolBarList
+{
+public:
+ ToolBarList (void);
+
+ void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup);
+ void AddToolBar (sd::ToolBarManager::ToolBarGroup eGroup, const ::rtl::OUString& rsName);
+ bool RemoveToolBar (sd::ToolBarManager::ToolBarGroup eGroup, const ::rtl::OUString& rsName);
+
+ void GetToolBarsToActivate (NameList& rToolBars) const;
+ void GetToolBarsToDeactivate (NameList& rToolBars) const;
+
+ void MarkToolBarAsActive (const ::rtl::OUString& rsName);
+ void MarkToolBarAsNotActive (const ::rtl::OUString& rsName);
+ void MarkAllToolBarsAsNotActive (void);
+
+private:
+ typedef ::std::map<sd::ToolBarManager::ToolBarGroup,NameList> Groups;
+ Groups maGroups;
+ NameList maActiveToolBars;
+
+ void MakeRequestedToolBarList (NameList& rToolBars) const;
+};
+
+
+
+
+/** Manage tool bars that are implemented as sub shells of a view shell.
+ The typical procedure of updating the sub shells of a view shell is to
+ rebuild a list of sub shells that the caller would like to have active.
+ The methods ClearGroup() and AddShellId() allow the caller to do that. A
+ final call to UpdateShells() activates the requested shells that are not
+ active and deactivates the active shells that are not requested .
+
+ This is done by maintaining two lists. One (the current list)
+ reflects the current state. The other (the requested list) contains the
+ currently requested shells. UpdateShells() makes the requested
+ list the current list and clears the current list.
+
+ Each shell belongs to one group. Different groups can be modified
+ seperately.
+*/
+class ToolBarShellList
+{
+public:
+ /** Create a new object with an empty current list and an empty
+ requested list.
+ */
+ ToolBarShellList (void);
+
+ /** Remove all shells from a group. Calling this method should normally
+ not be necessary because after the construction or after a call to
+ UpdateShells() the requested list is empty.
+ @param eGroup
+ The group to clear. Shells in other groups are not modified.
+ */
+ void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup);
+
+ /** Add a shell. When the specified shell has alreadt been requested
+ for another group then it is moved to this group.
+ @param eGroup
+ The group to which to add the shell.
+ @param nId
+ The id of the shell to add.
+ */
+ void AddShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId);
+
+ /** Releasing all shells means that the given ToolBarRules object is
+ informed that every shell mananged by the called ToolBarShellList is
+ about to be removed and that the associated framework tool bars can
+ be removed as well. The caller still has to call UpdateShells().
+ */
+ void ReleaseAllShells (ToolBarRules& rRules);
+
+ /** The requested list is made the current list by activating all
+ shells in the requested list and by deactivating the shells in the
+ current list that are not in the requested list.
+ @param pMainViewShell
+ The shells that are activated or deactivated are sub shells of
+ this view shell.
+ @param rManager
+ This ViewShellManager is used to activate or deactivate shells.
+ */
+ void UpdateShells (
+ const ::boost::shared_ptr<ViewShell>& rpMainViewShell,
+ const ::boost::shared_ptr<ViewShellManager>& rpManager);
+
+private:
+ class ShellDescriptor
+ {public:
+ ShellDescriptor (ShellId nId,sd::ToolBarManager::ToolBarGroup eGroup);
+ ShellId mnId;
+ sd::ToolBarManager::ToolBarGroup meGroup;
+ friend bool operator<(const ShellDescriptor& r1, const ShellDescriptor& r2)
+ { return r1.mnId < r2.mnId; }
+ };
+
+ /** The requested list of tool bar shells that will be active after the
+ next call to UpdateShells().
+ */
+ typedef ::std::set<ShellDescriptor> GroupedShellList;
+ GroupedShellList maNewList;
+
+ /** The list of tool bar shells that are currently on the shell stack.
+ Using a GroupedShellList is not strictly necessary but it makes
+ things easier and does not waste too much memory.
+ */
+ GroupedShellList maCurrentList;
+};
+
+
+
+
+/** This class concentrates the knowledge about when to show what tool bars
+ in one place.
+*/
+class ToolBarRules
+{
+public:
+ ToolBarRules (
+ const ::boost::shared_ptr<ToolBarManager>& rpToolBarManager,
+ const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager);
+
+ /** This method calls MainViewShellChanged() and SelectionHasChanged()
+ for the current main view shell and its view.
+ */
+ void Update (ViewShellBase& rBase);
+
+ /** Reset all tool bars in all groups and add tool bars and tool bar
+ shells to the TBG_PERMANENT group for the specified ViewShell type.
+ */
+ void MainViewShellChanged (ViewShell::ShellType nShellType);
+
+ /** Reset all tool bars in all groups and add tool bars and tool bar
+ shells to the TBG_PERMANENT group for the specified ViewShell.
+ */
+ void MainViewShellChanged (const ViewShell& rMainViewShell);
+
+ /** Reset all tool bars in the TBG_FUNCTION group and add tool bars and tool bar
+ shells to this group for the current selection.
+ */
+ void SelectionHasChanged (
+ const ::sd::ViewShell& rViewShell,
+ const SdrView& rView);
+
+ /** Add a tool bar for the specified tool bar shell.
+ */
+ void SubShellAdded (
+ ::sd::ToolBarManager::ToolBarGroup eGroup,
+ sd::ShellId nShellId);
+
+ /** Remove a tool bar for the specified tool bar shell.
+ */
+ void SubShellRemoved (
+ ::sd::ToolBarManager::ToolBarGroup eGroup,
+ sd::ShellId nShellId);
+
+private:
+ ::boost::shared_ptr<ToolBarManager> mpToolBarManager;
+ ::boost::shared_ptr<ViewShellManager> mpViewShellManager;
+};
+
+} // end of anonymous namespace
+
+
+
+
+namespace sd {
+
+//===== ToolBarManager::Implementation ========================================
+
+class ToolBarManager::Implementation
+{
+public:
+ /** This constructor takes three arguments even though the
+ ToolBarManager could be taken from the ViewShellBase. This is so to
+ state explicitly which information has to be present when this
+ constructor is called. The ViewShellBase may not have been fully
+ initialized at this point and must not be asked for this values.
+ */
+ Implementation (
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<sd::tools::EventMultiplexer>& rpMultiplexer,
+ const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager,
+ const ::boost::shared_ptr<ToolBarManager>& rpToolBarManager);
+ ~Implementation (void);
+
+ void SetValid (bool bValid);
+
+ void ResetToolBars (ToolBarGroup eGroup);
+ void ResetAllToolBars (void);
+ void AddToolBar (ToolBarGroup eGroup, const ::rtl::OUString& rsToolBarName);
+ void AddToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId);
+ void RemoveToolBar (ToolBarGroup eGroup, const ::rtl::OUString& rsToolBarName);
+
+ /** Release all tool bar shells and the associated framework tool bars.
+ Typically called when the main view shell is being replaced by
+ another, all tool bar shells are released. In that process the
+ shells are destroyed anyway and whithout calling this method they
+ would still be referenced.
+ */
+ void ReleaseAllToolBarShells (void);
+
+ void ToolBarsDestroyed(void);
+
+ void RequestUpdate (void);
+
+ void PreUpdate (void);
+ void PostUpdate (void);
+ /** Tell the XLayoutManager about the tool bars that we would like to be
+ shown.
+ @param rpLayouterLock
+ This typically is the mpSynchronousLayouterLock that is used in
+ this method and that is either released at its end or assigned
+ to mpAsynchronousLock in order to be unlocked later.
+ */
+ void Update (::std::auto_ptr<LayouterLock> pLayouterLock);
+
+ class UpdateLockImplementation
+ {
+ public:
+ UpdateLockImplementation (Implementation& rImplementation)
+ : mrImplementation(rImplementation) { mrImplementation.LockUpdate(); }
+ ~UpdateLockImplementation (void) { mrImplementation.UnlockUpdate(); }
+ private:
+ Implementation& mrImplementation;
+ };
+
+ void LockViewShellManager (void);
+ void LockUpdate (void);
+ void UnlockUpdate (void);
+
+ ToolBarRules& GetToolBarRules (void);
+
+private:
+ const static ::rtl::OUString msToolBarResourcePrefix;
+
+ mutable ::osl::Mutex maMutex;
+ ViewShellBase& mrBase;
+ ::boost::shared_ptr<sd::tools::EventMultiplexer> mpEventMultiplexer;
+ bool mbIsValid;
+ ToolBarList maToolBarList;
+ ToolBarShellList maToolBarShellList;
+ Reference<frame::XLayoutManager> mxLayouter;
+ sal_Int32 mnLockCount;
+ bool mbPreUpdatePending;
+ bool mbPostUpdatePending;
+ /** The layouter locks manage the locking of the XLayoutManager. The
+ lock() and unlock() functions are not called directly because the
+ (final) unlocking is usually done asynchronously *after* the
+ list of requested toolbars is updated.
+ */
+ ::std::auto_ptr<LayouterLock> mpSynchronousLayouterLock;
+ ::std::auto_ptr<LayouterLock> mpAsynchronousLayouterLock;
+ ::std::auto_ptr<ViewShellManager::UpdateLock> mpViewShellManagerLock;
+ ULONG mnPendingUpdateCall;
+ ULONG mnPendingSetValidCall;
+ ToolBarRules maToolBarRules;
+
+ ::rtl::OUString GetToolBarResourceName (const ::rtl::OUString& rsBaseName) const;
+ bool CheckPlugInMode (const ::rtl::OUString& rsName) const;
+
+ DECL_LINK(UpdateCallback,bool*);
+ DECL_LINK(EventMultiplexerCallback, sd::tools::EventMultiplexerEvent*);
+ DECL_LINK(SetValidCallback,void*);
+};
+
+
+
+//===== ToolBarManager ========================================================
+
+const ::rtl::OUString ToolBarManager::msToolBar(OUSTRING("toolbar"));
+const ::rtl::OUString ToolBarManager::msOptionsToolBar(OUSTRING("optionsbar"));
+const ::rtl::OUString ToolBarManager::msCommonTaskToolBar(OUSTRING("commontaskbar"));
+const ::rtl::OUString ToolBarManager::msViewerToolBar(OUSTRING("viewerbar"));
+const ::rtl::OUString ToolBarManager::msSlideSorterToolBar(OUSTRING("slideviewtoolbar"));
+const ::rtl::OUString ToolBarManager::msSlideSorterObjectBar(OUSTRING("slideviewobjectbar"));
+const ::rtl::OUString ToolBarManager::msOutlineToolBar(OUSTRING("outlinetoolbar"));
+const ::rtl::OUString ToolBarManager::msMasterViewToolBar(OUSTRING("masterviewtoolbar"));
+const ::rtl::OUString ToolBarManager::msDrawingObjectToolBar(OUSTRING("drawingobjectbar"));
+const ::rtl::OUString ToolBarManager::msGluePointsToolBar(OUSTRING("gluepointsobjectbar"));
+const ::rtl::OUString ToolBarManager::msTextObjectBar(OUSTRING("textobjectbar"));
+const ::rtl::OUString ToolBarManager::msBezierObjectBar(OUSTRING("bezierobjectbar"));
+const ::rtl::OUString ToolBarManager::msGraphicObjectBar(OUSTRING("graphicobjectbar"));
+const ::rtl::OUString ToolBarManager::msMediaObjectBar(OUSTRING("mediaobjectbar"));
+const ::rtl::OUString ToolBarManager::msTableObjectBar(OUSTRING("tableobjectbar"));
+
+
+::boost::shared_ptr<ToolBarManager> ToolBarManager::Create (
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<sd::tools::EventMultiplexer>& rpMultiplexer,
+ const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager)
+{
+ ::boost::shared_ptr<ToolBarManager> pManager (new ToolBarManager());
+ pManager->mpImpl.reset(
+ new Implementation(rBase,rpMultiplexer,rpViewShellManager,pManager));
+ return pManager;
+}
+
+
+
+
+ToolBarManager::ToolBarManager (void)
+ : mpImpl()
+{
+}
+
+
+
+
+ToolBarManager::~ToolBarManager (void)
+{
+}
+
+
+
+
+void ToolBarManager::Shutdown (void)
+{
+ if (mpImpl.get() != NULL)
+ mpImpl.reset();
+}
+
+
+
+
+void ToolBarManager::ResetToolBars (ToolBarGroup eGroup)
+{
+ if (mpImpl.get() != NULL)
+ {
+ UpdateLock aLock (shared_from_this());
+ mpImpl->ResetToolBars(eGroup);
+ }
+}
+
+
+
+
+void ToolBarManager::ResetAllToolBars (void)
+{
+ if (mpImpl.get() != NULL)
+ {
+ UpdateLock aLock (shared_from_this());
+ mpImpl->ResetAllToolBars();
+ }
+}
+
+
+
+
+void ToolBarManager::AddToolBar (
+ ToolBarGroup eGroup,
+ const ::rtl::OUString& rsToolBarName)
+{
+ if (mpImpl.get() != NULL)
+ {
+ UpdateLock aLock (shared_from_this());
+ mpImpl->AddToolBar(eGroup,rsToolBarName);
+ }
+}
+
+
+
+
+void ToolBarManager::AddToolBarShell (
+ ToolBarGroup eGroup,
+ ShellId nToolBarId)
+{
+ if (mpImpl.get() != NULL)
+ {
+ UpdateLock aLock (shared_from_this());
+ mpImpl->AddToolBarShell(eGroup,nToolBarId);
+ }
+}
+
+
+
+
+void ToolBarManager::RemoveToolBar (
+ ToolBarGroup eGroup,
+ const ::rtl::OUString& rsToolBarName)
+{
+ if (mpImpl.get() != NULL)
+ {
+ UpdateLock aLock (shared_from_this());
+ mpImpl->RemoveToolBar(eGroup,rsToolBarName);
+ }
+}
+
+
+
+
+void ToolBarManager::SetToolBar (
+ ToolBarGroup eGroup,
+ const ::rtl::OUString& rsToolBarName)
+{
+ if (mpImpl.get() != NULL)
+ {
+ UpdateLock aLock (shared_from_this());
+ mpImpl->ResetToolBars(eGroup);
+ mpImpl->AddToolBar(eGroup,rsToolBarName);
+ }
+}
+
+
+
+
+void ToolBarManager::SetToolBarShell (
+ ToolBarGroup eGroup,
+ ShellId nToolBarId)
+{
+ if (mpImpl.get() != NULL)
+ {
+ UpdateLock aLock (shared_from_this());
+ mpImpl->ResetToolBars(eGroup);
+ mpImpl->AddToolBarShell(eGroup,nToolBarId);
+ }
+}
+
+
+
+
+void ToolBarManager::PreUpdate (void)
+{
+ if (mpImpl.get()!=NULL)
+ mpImpl->PreUpdate();
+}
+
+
+
+
+void ToolBarManager::RequestUpdate (void)
+{
+ if (mpImpl.get()!=NULL)
+ mpImpl->RequestUpdate();
+}
+
+
+
+
+void ToolBarManager::LockViewShellManager (void)
+{
+ if (mpImpl.get() != NULL)
+ mpImpl->LockViewShellManager();
+}
+
+
+
+
+void ToolBarManager::LockUpdate (void)
+{
+ if (mpImpl.get()!=NULL)
+ mpImpl->LockUpdate();
+}
+
+
+
+
+void ToolBarManager::UnlockUpdate (void)
+{
+ if (mpImpl.get()!=NULL)
+ mpImpl->UnlockUpdate();
+}
+
+
+
+
+void ToolBarManager::MainViewShellChanged (ViewShell::ShellType nShellType)
+{
+ if (mpImpl.get() != NULL)
+ {
+ mpImpl->ReleaseAllToolBarShells();
+ mpImpl->GetToolBarRules().MainViewShellChanged(nShellType);
+ }
+}
+
+
+
+
+void ToolBarManager::MainViewShellChanged (const ViewShell& rMainViewShell)
+{
+ if (mpImpl.get() != NULL)
+ {
+ mpImpl->ReleaseAllToolBarShells();
+ mpImpl->GetToolBarRules().MainViewShellChanged(rMainViewShell);
+ }
+}
+
+
+
+
+void ToolBarManager::SelectionHasChanged (
+ const ViewShell& rViewShell,
+ const SdrView& rView)
+{
+ if (mpImpl.get() != NULL)
+ mpImpl->GetToolBarRules().SelectionHasChanged(rViewShell,rView);
+}
+
+
+void ToolBarManager::ToolBarsDestroyed(void)
+{
+ if (mpImpl.get() != NULL)
+ mpImpl->ToolBarsDestroyed();
+}
+
+
+//===== ToolBarManager::Implementation =======================================
+
+const ::rtl::OUString ToolBarManager::Implementation::msToolBarResourcePrefix(
+ OUSTRING("private:resource/toolbar/"));
+
+ToolBarManager::Implementation::Implementation (
+ ViewShellBase& rBase,
+ const ::boost::shared_ptr<sd::tools::EventMultiplexer>& rpMultiplexer,
+ const ::boost::shared_ptr<ViewShellManager>& rpViewShellManager,
+ const ::boost::shared_ptr<ToolBarManager>& rpToolBarManager)
+ : maMutex(),
+ mrBase(rBase),
+ mpEventMultiplexer(rpMultiplexer),
+ mbIsValid(false),
+ maToolBarList(),
+ maToolBarShellList(),
+ mxLayouter(NULL),
+ mnLockCount(0),
+ mbPreUpdatePending(false),
+ mbPostUpdatePending(false),
+ mpSynchronousLayouterLock(),
+ mpAsynchronousLayouterLock(),
+ mpViewShellManagerLock(),
+ mnPendingUpdateCall(0),
+ mnPendingSetValidCall(0),
+ maToolBarRules(rpToolBarManager,rpViewShellManager)
+{
+ Link aLink (LINK(this,ToolBarManager::Implementation,EventMultiplexerCallback));
+ mpEventMultiplexer->AddEventListener(
+ aLink,
+ tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED
+ | tools::EventMultiplexerEvent::EID_CONTROLLER_DETACHED
+ | tools::EventMultiplexerEvent::EID_PANE_MANAGER_DYING);
+}
+
+
+
+/** The order of statements is important.
+ First unregister listeners, which may post user events.
+ Then remove pending user events.
+*/
+ToolBarManager::Implementation::~Implementation (void)
+{
+ // Unregister at broadcasters.
+ Link aLink (LINK(this,ToolBarManager::Implementation,EventMultiplexerCallback));
+ mpEventMultiplexer->RemoveEventListener(aLink);
+
+ // Abort pending user calls.
+ if (mnPendingUpdateCall != 0)
+ Application::RemoveUserEvent(mnPendingUpdateCall);
+ if (mnPendingSetValidCall != 0)
+ Application::RemoveUserEvent(mnPendingSetValidCall);
+}
+
+
+void ToolBarManager::Implementation::ToolBarsDestroyed(void)
+{
+ maToolBarList.MarkAllToolBarsAsNotActive();
+}
+
+
+void ToolBarManager::Implementation::SetValid (bool bValid)
+{
+ ::osl::MutexGuard aGuard(maMutex);
+
+ if (mbIsValid != bValid)
+ {
+ UpdateLockImplementation aUpdateLock (*this);
+
+ mbIsValid = bValid;
+ if (mbIsValid)
+ {
+ Reference<frame::XFrame> xFrame;
+ if (mrBase.GetViewFrame() != NULL)
+ xFrame = mrBase.GetViewFrame()->GetFrame().GetFrameInterface();
+ try
+ {
+ Reference<beans::XPropertySet> xFrameProperties (xFrame, UNO_QUERY_THROW);
+ Any aValue (xFrameProperties->getPropertyValue(OUSTRING("LayoutManager")));
+ aValue >>= mxLayouter;
+ }
+ catch (RuntimeException aException)
+ {
+ }
+
+ GetToolBarRules().Update(mrBase);
+ }
+ else
+ {
+ ResetAllToolBars();
+ mxLayouter = NULL;
+ }
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::ResetToolBars (ToolBarGroup eGroup)
+{
+ ::osl::MutexGuard aGuard(maMutex);
+
+ maToolBarList.ClearGroup(eGroup);
+ maToolBarShellList.ClearGroup(eGroup);
+
+ mbPreUpdatePending = true;
+}
+
+
+
+
+void ToolBarManager::Implementation::ResetAllToolBars (void)
+{
+#ifdef VERBOSE
+ OSL_TRACE("resetting all tool bars\n");
+#endif
+ for (int i=TBG__FIRST; i<=TBG__LAST; ++i)
+ ResetToolBars((ToolBarGroup)i);
+}
+
+
+
+
+void ToolBarManager::Implementation::AddToolBar (
+ ToolBarGroup eGroup,
+ const ::rtl::OUString& rsToolBarName)
+{
+ ::osl::MutexGuard aGuard(maMutex);
+
+ if (CheckPlugInMode(rsToolBarName))
+ {
+ maToolBarList.AddToolBar(eGroup,rsToolBarName);
+
+ mbPostUpdatePending = true;
+ if (mnLockCount == 0)
+ PostUpdate();
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::RemoveToolBar (
+ ToolBarGroup eGroup,
+ const ::rtl::OUString& rsToolBarName)
+{
+ ::osl::MutexGuard aGuard(maMutex);
+
+ if (maToolBarList.RemoveToolBar(eGroup,rsToolBarName))
+ {
+ mbPreUpdatePending = true;
+ if (mnLockCount == 0)
+ PreUpdate();
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::AddToolBarShell (
+ ToolBarGroup eGroup,
+ ShellId nToolBarId)
+{
+ ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
+ if (pMainViewShell != NULL)
+ {
+ maToolBarShellList.AddShellId(eGroup,nToolBarId);
+ GetToolBarRules().SubShellAdded(eGroup, nToolBarId);
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::ReleaseAllToolBarShells (void)
+{
+ maToolBarShellList.ReleaseAllShells(GetToolBarRules());
+ maToolBarShellList.UpdateShells(mrBase.GetMainViewShell(), mrBase.GetViewShellManager());
+}
+
+
+
+
+void ToolBarManager::Implementation::RequestUpdate (void)
+{
+ if (mnPendingUpdateCall == 0)
+ {
+ mnPendingUpdateCall = Application::PostUserEvent(
+ LINK(this,ToolBarManager::Implementation,UpdateCallback));
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::PreUpdate (void)
+{
+ ::osl::MutexGuard aGuard(maMutex);
+
+ if (mbIsValid
+ && mbPreUpdatePending
+ && mxLayouter.is())
+ {
+ mbPreUpdatePending = false;
+
+#ifdef VERBOSE
+ OSL_TRACE("ToolBarManager::PreUpdate [");
+#endif
+
+ // Get the list of tool bars that are not used anymore and are to be
+ // deactivated.
+ NameList aToolBars;
+ maToolBarList.GetToolBarsToDeactivate(aToolBars);
+
+ // Turn off the tool bars.
+ NameList::const_iterator iToolBar;
+ for (iToolBar=aToolBars.begin(); iToolBar!=aToolBars.end(); ++iToolBar)
+ {
+ ::rtl::OUString sFullName (GetToolBarResourceName(*iToolBar));
+#ifdef VERBOSE
+ OSL_TRACE(" turning off tool bar %s",
+ ::rtl::OUStringToOString(sFullName, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ mxLayouter->destroyElement(sFullName);
+ maToolBarList.MarkToolBarAsNotActive(*iToolBar);
+ }
+
+#ifdef VERBOSE
+ OSL_TRACE("ToolBarManager::PreUpdate ]\n");
+#endif
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::PostUpdate (void)
+{
+ ::osl::MutexGuard aGuard(maMutex);
+
+ if (mbIsValid
+ && mbPostUpdatePending
+ && mxLayouter.is())
+ {
+ mbPostUpdatePending = false;
+
+ // Create the list of requested tool bars.
+ NameList aToolBars;
+ maToolBarList.GetToolBarsToActivate(aToolBars);
+
+#ifdef VERBOSE
+ OSL_TRACE("ToolBarManager::PostUpdate [");
+#endif
+
+ // Turn on the tool bars that are visible in the new context.
+ NameList::const_iterator iToolBar;
+ for (iToolBar=aToolBars.begin(); iToolBar!=aToolBars.end(); ++iToolBar)
+ {
+ ::rtl::OUString sFullName (GetToolBarResourceName(*iToolBar));
+#ifdef VERBOSE
+ OSL_TRACE(" turning on tool bar %s",
+ ::rtl::OUStringToOString(sFullName, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ mxLayouter->requestElement(sFullName);
+ maToolBarList.MarkToolBarAsActive(*iToolBar);
+ }
+
+#ifdef VERBOSE
+ OSL_TRACE("ToolBarManager::PostUpdate ]\n");
+#endif
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::LockViewShellManager (void)
+{
+ if (mpViewShellManagerLock.get() == NULL)
+ mpViewShellManagerLock.reset(
+ new ViewShellManager::UpdateLock(mrBase.GetViewShellManager()));
+}
+
+
+
+
+void ToolBarManager::Implementation::LockUpdate (void)
+{
+#ifdef VERBOSE
+ OSL_TRACE("LockUpdate %d\n", mnLockCount);
+#endif
+ ::osl::MutexGuard aGuard(maMutex);
+
+ DBG_ASSERT(mnLockCount<100, "ToolBarManager lock count unusually high");
+ if (mnLockCount == 0)
+ {
+ OSL_ASSERT(mpSynchronousLayouterLock.get()==NULL);
+
+ mpSynchronousLayouterLock.reset(new LayouterLock(mxLayouter));
+ }
+ ++mnLockCount;
+}
+
+
+
+
+void ToolBarManager::Implementation::UnlockUpdate (void)
+{
+#ifdef VERBOSE
+ OSL_TRACE("UnlockUpdate %d\n", mnLockCount);
+#endif
+ ::osl::MutexGuard aGuard(maMutex);
+
+ OSL_ASSERT(mnLockCount>0);
+ --mnLockCount;
+ if (mnLockCount == 0)
+ {
+ Update(mpSynchronousLayouterLock);
+ }
+}
+
+
+
+
+void ToolBarManager::Implementation::Update (
+ ::std::auto_ptr<LayouterLock> pLocalLayouterLock)
+{
+ // When the lock is released and there are pending changes to the set of
+ // tool bars then update this set now.
+ if (mnLockCount == 0)
+ {
+ // During ceation of ViewShellBase we may have the situation that
+ // the controller has already been created and attached to the frame
+ // but that the ToolBarManager has not yet completed its
+ // initialization (by initializing the mxLayouter member.) We do
+ // this here so that we do not have to wait for the next Update()
+ // call to show the tool bars.
+ if (mnPendingSetValidCall != 0)
+ {
+ Application::RemoveUserEvent(mnPendingSetValidCall);
+ mnPendingSetValidCall = 0;
+ SetValid(true);
+ }
+
+ if (mbIsValid && mxLayouter.is() && (mbPreUpdatePending || mbPostUpdatePending))
+ {
+ // 1) Release UNO tool bars that are not longer used. Do this
+ // now so that they are not updated when the SFX shell stack is
+ // modified.
+ if (mbPreUpdatePending)
+ PreUpdate();
+
+ // 2) Update the requested shells that represent tool bar
+ // functionality. Those that are not used anymore are
+ // deactivated now. Those that are missing are activated in the
+ // next step together with the view shells.
+ if (mpViewShellManagerLock.get() == NULL)
+ mpViewShellManagerLock.reset(
+ new ViewShellManager::UpdateLock(mrBase.GetViewShellManager()));
+ maToolBarShellList.UpdateShells(
+ mrBase.GetMainViewShell(),
+ mrBase.GetViewShellManager());
+
+ // 3) Unlock the ViewShellManager::UpdateLock. This updates the
+ // shell stack. We have to be carfull here. The deletion of
+ // the lock may end in a synchronous call to LockUpdate(). When
+ // at this time the lock has been deleted but the auto_ptr has
+ // not yet been reset then the lock is deleted a second time.
+ ViewShellManager::UpdateLock* pLock = mpViewShellManagerLock.release();
+ delete pLock;
+
+ // 4) Make the UNO tool bars visible. The outstanding call to
+ // PostUpdate() is done via PostUserEvent() so that it is
+ // guaranteed to be executed when the SFX shell stack has been
+ // updated (under the assumption that our lock to the
+ // ViewShellManager was the only one open. If that is not the
+ // case then all should still be well but not as fast.)
+ //
+ // Note that the lock count may have been increased since
+ // entering this method. In that case one of the next
+ // UnlockUpdate() calls will post the UpdateCallback.
+ if (mnPendingUpdateCall==0 && mnLockCount==0)
+ {
+ mpAsynchronousLayouterLock = pLocalLayouterLock;
+ mnPendingUpdateCall = Application::PostUserEvent(
+ LINK(this,ToolBarManager::Implementation,UpdateCallback));
+ }
+ }
+ else
+ {
+ mpViewShellManagerLock.reset();
+ pLocalLayouterLock.reset();
+ }
+ }
+}
+
+
+
+
+ToolBarRules& ToolBarManager::Implementation::GetToolBarRules (void)
+{
+ return maToolBarRules;
+}
+
+
+
+
+IMPL_LINK(ToolBarManager::Implementation,UpdateCallback,bool*,EMPTYARG)
+{
+ mnPendingUpdateCall = 0;
+ if (mnLockCount == 0)
+ {
+ if (mbPreUpdatePending)
+ PreUpdate();
+ if (mbPostUpdatePending)
+ PostUpdate();
+ if (mbIsValid && mxLayouter.is())
+ mpAsynchronousLayouterLock.reset();
+ }
+ return 0;
+}
+
+
+
+
+IMPL_LINK(ToolBarManager::Implementation,EventMultiplexerCallback,
+ sd::tools::EventMultiplexerEvent*,pEvent)
+{
+ if (pEvent != NULL)
+ {
+ switch (pEvent->meEventId)
+ {
+ case tools::EventMultiplexerEvent::EID_CONTROLLER_ATTACHED:
+ if (mnPendingSetValidCall == 0)
+ mnPendingSetValidCall
+ = Application::PostUserEvent(LINK(this,Implementation,SetValidCallback));
+ break;
+
+ case tools::EventMultiplexerEvent::EID_CONTROLLER_DETACHED:
+ SetValid(false);
+ break;
+
+ case tools::EventMultiplexerEvent::EID_PANE_MANAGER_DYING:
+ SetValid(false);
+ break;
+ }
+ }
+ return 0;
+}
+
+
+
+
+IMPL_LINK(ToolBarManager::Implementation, SetValidCallback,void*,EMPTYARG)
+{
+ mnPendingSetValidCall = 0;
+ SetValid(true);
+ return 0;
+}
+
+
+
+
+
+::rtl::OUString ToolBarManager::Implementation::GetToolBarResourceName (
+ const ::rtl::OUString& rsBaseName) const
+{
+ ::rtl::OUString sToolBarName (msToolBarResourcePrefix);
+ sToolBarName += rsBaseName;
+ return sToolBarName;
+}
+
+
+
+
+bool ToolBarManager::Implementation::CheckPlugInMode (const ::rtl::OUString& rsName) const
+{
+ bool bValid (false);
+
+ // Determine the plug in mode.
+ bool bIsPlugInMode (false);
+ do
+ {
+ SfxObjectShell* pObjectShell = mrBase.GetObjectShell();
+ if (pObjectShell == NULL)
+ break;
+
+ SfxMedium* pMedium = pObjectShell->GetMedium();
+ if (pMedium == NULL)
+ break;
+
+ SFX_ITEMSET_ARG(pMedium->GetItemSet(),pViewOnlyItem,SfxBoolItem,SID_VIEWONLY,sal_False);
+ if (pViewOnlyItem == NULL)
+ break;
+
+ bIsPlugInMode = pViewOnlyItem->GetValue();
+ }
+ while (false);
+
+ if (rsName.equals(msViewerToolBar))
+ bValid = bIsPlugInMode;
+ else
+ bValid = ! bIsPlugInMode;
+
+ return bValid;
+}
+
+
+
+
+} // end of namespace sd
+
+
+
+
+namespace {
+
+using namespace ::sd;
+
+//===== LayouterLock ==========================================================
+
+LayouterLock::LayouterLock (const Reference<frame::XLayoutManager>& rxLayouter)
+ : mxLayouter(rxLayouter)
+{
+#ifdef VERBOSE
+ OSL_TRACE("LayouterLock %d", mxLayouter.is() ? 1 :0);
+#endif
+ if (mxLayouter.is())
+ mxLayouter->lock();
+}
+
+
+
+
+LayouterLock::~LayouterLock (void)
+{
+#ifdef VERBOSE
+ OSL_TRACE("~LayouterLock %d", mxLayouter.is() ? 1 :0);
+#endif
+ if (mxLayouter.is())
+ mxLayouter->unlock();
+}
+
+
+
+
+//===== ToolBarRules ==========================================================
+
+ToolBarRules::ToolBarRules (
+ const ::boost::shared_ptr<sd::ToolBarManager>& rpToolBarManager,
+ const ::boost::shared_ptr<sd::ViewShellManager>& rpViewShellManager)
+ : mpToolBarManager(rpToolBarManager),
+ mpViewShellManager(rpViewShellManager)
+{
+}
+
+
+
+
+void ToolBarRules::Update (ViewShellBase& rBase)
+{
+ ViewShell* pMainViewShell = rBase.GetMainViewShell().get();
+ if (pMainViewShell != NULL)
+ {
+ MainViewShellChanged(pMainViewShell->GetShellType());
+ if (pMainViewShell->GetView())
+ SelectionHasChanged (*pMainViewShell, *pMainViewShell->GetView());
+ }
+ else
+ MainViewShellChanged(ViewShell::ST_NONE);
+}
+
+
+
+
+void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType)
+{
+ ::sd::ToolBarManager::UpdateLock aToolBarManagerLock (mpToolBarManager);
+ ::sd::ViewShellManager::UpdateLock aViewShellManagerLock (mpViewShellManager);
+
+ mpToolBarManager->ResetAllToolBars();
+
+ switch(nShellType)
+ {
+ case ::sd::ViewShell::ST_IMPRESS:
+ case ::sd::ViewShell::ST_NOTES:
+ case ::sd::ViewShell::ST_HANDOUT:
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msOptionsToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msCommonTaskToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msViewerToolBar);
+ break;
+
+ case ::sd::ViewShell::ST_DRAW:
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msOptionsToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msViewerToolBar);
+ break;
+
+ case ViewShell::ST_OUTLINE:
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msOutlineToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msViewerToolBar);
+ mpToolBarManager->AddToolBarShell(
+ ToolBarManager::TBG_PERMANENT, RID_DRAW_TEXT_TOOLBOX);
+ break;
+
+ case ViewShell::ST_SLIDE_SORTER:
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msViewerToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msSlideSorterToolBar);
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_PERMANENT,
+ ToolBarManager::msSlideSorterObjectBar);
+ break;
+
+ case ViewShell::ST_NONE:
+ case ViewShell::ST_PRESENTATION:
+ case ViewShell::ST_TASK_PANE:
+ default:
+ break;
+ }
+}
+
+
+
+
+void ToolBarRules::MainViewShellChanged (const ViewShell& rMainViewShell)
+{
+ ::sd::ToolBarManager::UpdateLock aToolBarManagerLock (mpToolBarManager);
+ ::sd::ViewShellManager::UpdateLock aViewShellManagerLock (mpViewShellManager);
+
+ MainViewShellChanged(rMainViewShell.GetShellType());
+ switch(rMainViewShell.GetShellType())
+ {
+ case ::sd::ViewShell::ST_IMPRESS:
+ case ::sd::ViewShell::ST_DRAW:
+ case ::sd::ViewShell::ST_NOTES:
+ {
+ const DrawViewShell* pDrawViewShell
+ = dynamic_cast<const DrawViewShell*>(&rMainViewShell);
+ if (pDrawViewShell != NULL)
+ if (pDrawViewShell->GetEditMode() == EM_MASTERPAGE)
+ mpToolBarManager->AddToolBar(
+ ToolBarManager::TBG_MASTER_MODE,
+ ToolBarManager::msMasterViewToolBar);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+
+
+void ToolBarRules::SelectionHasChanged (
+ const ::sd::ViewShell& rViewShell,
+ const SdrView& rView)
+{
+ ::sd::ToolBarManager::UpdateLock aLock (mpToolBarManager);
+ mpToolBarManager->LockViewShellManager();
+ bool bTextEdit = rView.IsTextEdit();
+
+ mpToolBarManager->ResetToolBars(ToolBarManager::TBG_FUNCTION);
+
+ switch (rView.GetContext())
+ {
+ case SDRCONTEXT_GRAPHIC:
+ if( !bTextEdit )
+ mpToolBarManager->SetToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_GRAF_TOOLBOX);
+ break;
+
+ case SDRCONTEXT_MEDIA:
+ if( !bTextEdit )
+ mpToolBarManager->SetToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_MEDIA_TOOLBOX);
+ break;
+
+ case SDRCONTEXT_TABLE:
+ mpToolBarManager->SetToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_TABLE_TOOLBOX);
+ bTextEdit = true;
+ break;
+
+ case SDRCONTEXT_STANDARD:
+ default:
+ if( !bTextEdit )
+ {
+ switch(rViewShell.GetShellType())
+ {
+ case ::sd::ViewShell::ST_IMPRESS:
+ case ::sd::ViewShell::ST_DRAW:
+ case ::sd::ViewShell::ST_NOTES:
+ case ::sd::ViewShell::ST_HANDOUT:
+ mpToolBarManager->SetToolBar(
+ ToolBarManager::TBG_FUNCTION,
+ ToolBarManager::msDrawingObjectToolBar);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+
+ if( bTextEdit )
+ mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_DRAW_TEXT_TOOLBOX);
+
+ SdrView* pView = &const_cast<SdrView&>(rView);
+ // Check if the extrusion tool bar and the fontwork tool bar have to
+ // be activated.
+ if (svx::checkForSelectedCustomShapes(pView, true /* bOnlyExtruded */ ))
+ mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_SVX_EXTRUSION_BAR);
+ sal_uInt32 nCheckStatus = 0;
+ if (svx::checkForSelectedFontWork(pView, nCheckStatus))
+ mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_SVX_FONTWORK_BAR);
+
+ // Switch on additional context-sensitive tool bars.
+ if (rView.GetContext() == SDRCONTEXT_POINTEDIT)
+ mpToolBarManager->AddToolBarShell(ToolBarManager::TBG_FUNCTION, RID_BEZIER_TOOLBOX);
+}
+
+
+
+
+void ToolBarRules::SubShellAdded (
+ ::sd::ToolBarManager::ToolBarGroup eGroup,
+ sd::ShellId nShellId)
+{
+ // For some tool bar shells (those defined in sd) we have to add the
+ // actual tool bar here.
+ switch (nShellId)
+ {
+ case RID_DRAW_GRAF_TOOLBOX:
+ mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msGraphicObjectBar);
+ break;
+
+ case RID_DRAW_MEDIA_TOOLBOX:
+ mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msMediaObjectBar);
+ break;
+
+ case RID_DRAW_TEXT_TOOLBOX:
+ mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTextObjectBar);
+ break;
+
+ case RID_BEZIER_TOOLBOX:
+ mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msBezierObjectBar);
+ break;
+
+ case RID_DRAW_TABLE_TOOLBOX:
+ mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTableObjectBar);
+ break;
+ }
+}
+
+
+
+
+void ToolBarRules::SubShellRemoved (
+ ::sd::ToolBarManager::ToolBarGroup eGroup,
+ sd::ShellId nShellId)
+{
+ // For some tool bar shells (those defined in sd) we have to add the
+ // actual tool bar here.
+ switch (nShellId)
+ {
+ case RID_DRAW_GRAF_TOOLBOX:
+ mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msGraphicObjectBar);
+ break;
+
+ case RID_DRAW_MEDIA_TOOLBOX:
+ mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msMediaObjectBar);
+ break;
+
+ case RID_DRAW_TEXT_TOOLBOX:
+ mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTextObjectBar);
+ break;
+
+ case RID_BEZIER_TOOLBOX:
+ mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msBezierObjectBar);
+ break;
+
+ case RID_DRAW_TABLE_TOOLBOX:
+ mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTableObjectBar);
+ break;
+ }
+}
+
+
+
+
+//===== ToolBarList ===========================================================
+
+ToolBarList::ToolBarList (void)
+ : maGroups(),
+ maActiveToolBars()
+{
+}
+
+
+
+
+void ToolBarList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup)
+{
+ Groups::iterator iGroup (maGroups.find(eGroup));
+ if (iGroup != maGroups.end())
+ {
+ if ( ! iGroup->second.empty())
+ {
+ iGroup->second.clear();
+ }
+ }
+}
+
+
+
+
+void ToolBarList::AddToolBar (
+ sd::ToolBarManager::ToolBarGroup eGroup,
+ const ::rtl::OUString& rsName)
+{
+ Groups::iterator iGroup (maGroups.find(eGroup));
+ if (iGroup == maGroups.end())
+ iGroup = maGroups.insert(Groups::value_type(eGroup,NameList())).first;
+
+ if (iGroup != maGroups.end())
+ {
+ NameList::const_iterator iBar (
+ ::std::find(iGroup->second.begin(),iGroup->second.end(),rsName));
+ if (iBar == iGroup->second.end())
+ {
+ iGroup->second.push_back(rsName);
+ }
+ }
+}
+
+
+
+
+bool ToolBarList::RemoveToolBar (
+ sd::ToolBarManager::ToolBarGroup eGroup,
+ const ::rtl::OUString& rsName)
+{
+ Groups::iterator iGroup (maGroups.find(eGroup));
+ if (iGroup != maGroups.end())
+ {
+ NameList::iterator iBar (
+ ::std::find(iGroup->second.begin(),iGroup->second.end(),rsName));
+ if (iBar != iGroup->second.end())
+ {
+ iGroup->second.erase(iBar);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+void ToolBarList::MakeRequestedToolBarList (NameList& rRequestedToolBars) const
+{
+ for (int i=sd::ToolBarManager::TBG__FIRST; i<=sd::ToolBarManager::TBG__LAST; ++i)
+ {
+ ::sd::ToolBarManager::ToolBarGroup eGroup = (::sd::ToolBarManager::ToolBarGroup)i;
+ Groups::const_iterator iGroup (maGroups.find(eGroup));
+ if (iGroup != maGroups.end())
+ ::std::copy(
+ iGroup->second.begin(),
+ iGroup->second.end(),
+ ::std::inserter(rRequestedToolBars,rRequestedToolBars.end()));
+ }
+}
+
+
+
+
+void ToolBarList::GetToolBarsToActivate (NameList& rToolBars) const
+{
+ NameList aRequestedToolBars;
+ MakeRequestedToolBarList(aRequestedToolBars);
+
+ NameList::const_iterator iToolBar;
+ for (iToolBar=aRequestedToolBars.begin(); iToolBar!=aRequestedToolBars.end(); ++iToolBar)
+ {
+ if (::std::find(maActiveToolBars.begin(),maActiveToolBars.end(),*iToolBar)
+ == maActiveToolBars.end())
+ {
+ rToolBars.push_back(*iToolBar);
+ }
+ }
+}
+
+
+
+
+void ToolBarList::GetToolBarsToDeactivate (NameList& rToolBars) const
+{
+ NameList aRequestedToolBars;
+ MakeRequestedToolBarList(aRequestedToolBars);
+
+ NameList::const_iterator iToolBar;
+ for (iToolBar=maActiveToolBars.begin(); iToolBar!=maActiveToolBars.end(); ++iToolBar)
+ {
+ if (::std::find(aRequestedToolBars.begin(),aRequestedToolBars.end(),*iToolBar)
+ == aRequestedToolBars.end())
+ {
+ rToolBars.push_back(*iToolBar);
+ }
+ }
+}
+
+
+
+
+void ToolBarList::MarkToolBarAsActive (const ::rtl::OUString& rsName)
+{
+ maActiveToolBars.push_back(rsName);
+}
+
+
+
+
+void ToolBarList::MarkToolBarAsNotActive (const ::rtl::OUString& rsName)
+{
+ maActiveToolBars.erase(
+ ::std::find(maActiveToolBars.begin(),maActiveToolBars.end(), rsName));
+}
+
+
+
+
+void ToolBarList::MarkAllToolBarsAsNotActive (void)
+{
+ maActiveToolBars.clear();
+}
+
+
+
+
+//===== ToolBarShellList ======================================================
+
+ToolBarShellList::ShellDescriptor::ShellDescriptor (
+ ShellId nId,
+ sd::ToolBarManager::ToolBarGroup eGroup)
+ : mnId(nId),
+ meGroup(eGroup)
+{
+}
+
+
+
+
+ToolBarShellList::ToolBarShellList (void)
+: maNewList()
+, maCurrentList()
+{
+}
+
+
+
+
+void ToolBarShellList::ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup)
+{
+ // In every loop we erase the first member of the specified group.
+ // Because that invalidates the iterator another loop is started after
+ // that. The loop is left only when no member of the group is found and
+ // no element is erased
+ bool bLoop;
+ do
+ {
+ bLoop = false;
+
+ GroupedShellList::iterator iDescriptor;
+ for (iDescriptor=maNewList.begin(); iDescriptor!=maNewList.end(); ++iDescriptor)
+ if (iDescriptor->meGroup == eGroup)
+ {
+ maNewList.erase(iDescriptor);
+ // Erasing the descriptor invalidated the iterator so we
+ // have to exit the for loop and start anew to search for
+ // further elements of the group.
+ bLoop = true;
+ break;
+ }
+ }
+ while (bLoop);
+}
+
+
+
+
+void ToolBarShellList::AddShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId)
+{
+ // Make sure that the shell is not added twice (and possibly in
+ // different groups.)
+ ShellDescriptor aDescriptor (nId,eGroup);
+ GroupedShellList::iterator iDescriptor (maNewList.find(aDescriptor));
+ if (iDescriptor != maNewList.end())
+ {
+ // The shell is already requested.
+ if (iDescriptor->meGroup != eGroup)
+ {
+ // It is now being requested for another group.
+ // (Is this an error?)
+ // Move it to that group.
+ maNewList.erase(iDescriptor);
+ maNewList.insert(aDescriptor);
+ }
+ // else nothing to do.
+ }
+ else
+ maNewList.insert(aDescriptor);
+}
+
+
+
+
+void ToolBarShellList::ReleaseAllShells (ToolBarRules& rRules)
+{
+ // Release the currently active tool bars.
+ GroupedShellList aList (maCurrentList);
+ GroupedShellList::iterator iDescriptor;
+ for (iDescriptor=aList.begin(); iDescriptor!=aList.end(); ++iDescriptor)
+ {
+ rRules.SubShellRemoved(iDescriptor->meGroup, iDescriptor->mnId);
+ }
+
+ // Clear the list of requested tool bars.
+ maNewList.clear();
+}
+
+
+
+
+void ToolBarShellList::UpdateShells (
+ const ::boost::shared_ptr<ViewShell>& rpMainViewShell,
+ const ::boost::shared_ptr<ViewShellManager>& rpManager)
+{
+ if (rpMainViewShell.get() != NULL)
+ {
+ GroupedShellList aList;
+
+ // Deactivate shells that are in maCurrentList, but not in
+ // maNewList.
+ ::std::set_difference(maCurrentList.begin(), maCurrentList.end(),
+ maNewList.begin(), maNewList.end(),
+ std::insert_iterator<GroupedShellList>(aList,aList.begin()));
+ for (GroupedShellList::iterator iShell=aList.begin(); iShell!=aList.end(); ++iShell)
+ {
+#ifdef VERBOSE
+ OSL_TRACE("deactivating tool bar shell %d\n", iShell->mnId);
+#endif
+ rpManager->DeactivateSubShell(*rpMainViewShell, iShell->mnId);
+ }
+
+ // Activate shells that are in maNewList, but not in
+ // maCurrentList.
+ aList.clear();
+ ::std::set_difference(maNewList.begin(), maNewList.end(),
+ maCurrentList.begin(), maCurrentList.end(),
+ std::insert_iterator<GroupedShellList>(aList,aList.begin()));
+ for (GroupedShellList::iterator iShell=aList.begin(); iShell!=aList.end(); ++iShell)
+ {
+#ifdef VERBOSE
+ OSL_TRACE("activating tool bar shell %d\n", iShell->mnId);
+#endif
+ rpManager->ActivateSubShell(*rpMainViewShell, iShell->mnId);
+ }
+
+ // The maNewList now refelects the current state and thus is made
+ // maCurrentList.
+ maCurrentList = maNewList;
+ }
+}
+
+
+
+
+} // end of anonymous namespace