1789 lines
49 KiB
C++
1789 lines
49 KiB
C++
/*************************************************************************
|
|
*
|
|
* 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(), AddShellId(), and RemoveShellId() 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);
|
|
|
|
/** Remove a shell. This is done only when the specified shell is a
|
|
member of the specified group. If it has been requested for another
|
|
group or if it has not been requested then this call is ignored.
|
|
@param eGroup
|
|
The group from which to remove the shell.
|
|
@param nId
|
|
The id of the shell to remove.
|
|
@return
|
|
Returns whether the shell is removed.
|
|
*/
|
|
bool RemoveShellId (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);
|
|
void RemoveToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId);
|
|
|
|
/** 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);
|
|
bool IsUpdateLocked (void) const;
|
|
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::SetValid (bool bValid)
|
|
{
|
|
if (mpImpl.get() != NULL)
|
|
mpImpl->SetValid(bValid);
|
|
}
|
|
|
|
|
|
|
|
|
|
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::RemoveToolBarShell (
|
|
ToolBarGroup eGroup,
|
|
ShellId nToolBarId)
|
|
{
|
|
if (mpImpl.get() != NULL)
|
|
{
|
|
UpdateLock aLock (shared_from_this());
|
|
mpImpl->RemoveToolBarShell(eGroup,nToolBarId);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ToolBarManager::IsUpdateLocked (void) const
|
|
{
|
|
if (mpImpl.get() != NULL)
|
|
return mpImpl->IsUpdateLocked();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
|
|
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::RemoveToolBarShell (
|
|
ToolBarGroup eGroup,
|
|
ShellId nToolBarId)
|
|
{
|
|
ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
|
|
if (pMainViewShell != NULL)
|
|
{
|
|
GetToolBarRules().SubShellRemoved(eGroup, nToolBarId);
|
|
maToolBarShellList.RemoveShellId(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()));
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ToolBarManager::Implementation::IsUpdateLocked (void) const
|
|
{
|
|
return mnLockCount;
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ToolBarShellList::RemoveShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId)
|
|
{
|
|
bool bRemoved (false);
|
|
|
|
GroupedShellList::iterator iDescriptor (maNewList.find(ShellDescriptor(nId,eGroup)));
|
|
if (iDescriptor != maNewList.end())
|
|
{
|
|
if (iDescriptor->meGroup == eGroup)
|
|
{
|
|
maNewList.erase(iDescriptor);
|
|
bRemoved = true;
|
|
}
|
|
}
|
|
|
|
return bRemoved;
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|