/** Lock of the frame::XLayoutManager.
*/ class LayouterLock
{
Reference<frame::XLayoutManager> mxLayouter; public: explicit LayouterLock (const Reference<frame::XLayoutManager>& rxLayouter);
~LayouterLock(); bool is() const { return mxLayouter.is(); }
};
/** Store a list of tool bars for each of the tool bar groups. From thisthelistofrequestedtoolbarsisbuilt.
*/ class ToolBarList
{ public:
ToolBarList();
/** Manage tool bars that are implemented as sub shells of a view shell. Thetypicalprocedureofupdatingthesubshellsofaviewshellisto rebuildalistofsubshellsthatthecallerwouldliketohaveactive. ThemethodsClearGroup()andAddShellId()allowthecallertodothat.A finalcalltoUpdateShells()activatestherequestedshellsthatarenot activeanddeactivatestheactiveshellsthatarenotrequested.
Eachshellbelongstoonegroup.Differentgroupscanbemodified separately.
*/ class ToolBarShellList
{ public: /** Create a new object with an empty current list and an empty requestedlist.
*/
ToolBarShellList();
/** Remove all shells from a group. Calling this method should normally notbenecessarybecauseaftertheconstructionorafteracallto UpdateShells()therequestedlistisempty. @parameGroup Thegrouptoclear.Shellsinothergroupsarenotmodified.
*/ void ClearGroup (sd::ToolBarManager::ToolBarGroup eGroup);
/** Add a shell. When the specified shell has already been requested foranothergroupthenitismovedtothisgroup. @parameGroup Thegrouptowhichtoaddtheshell. @paramnId Theidoftheshelltoadd.
*/ void AddShellId (sd::ToolBarManager::ToolBarGroup eGroup, sd::ShellId nId);
/** Releasing all shells means that the given ToolBarRules object is informedthateveryshellmanagedbythecalledToolBarShellListis abouttoberemovedandthattheassociatedframeworktoolbarscan beremovedaswell.ThecallerstillhastocallUpdateShells().
*/ void ReleaseAllShells (ToolBarRules& rRules);
/** The requested list is made the current list by activating all shellsintherequestedlistandbydeactivatingtheshellsinthe currentlistthatarenotintherequestedlist. @parampMainViewShell Theshellsthatareactivatedordeactivatedaresubshellsof thisviewshell. @paramrManager ThisViewShellManagerisusedtoactivateordeactivateshells.
*/ void UpdateShells ( const std::shared_ptr<ViewShell>& rpMainViewShell, const std::shared_ptr<ViewShellManager>& rpManager);
/** The requested list of tool bar shells that will be active after the nextcalltoUpdateShells().
*/ typedef ::std::set<ShellDescriptor> GroupedShellList;
GroupedShellList maNewList;
/** The list of tool bar shells that are currently on the shell stack. UsingaGroupedShellListisnotstrictlynecessarybutitmakes thingseasieranddoesnotwastetoomuchmemory.
*/
GroupedShellList maCurrentList;
};
/** This class concentrates the knowledge about when to show what tool bars inoneplace.
*/ class ToolBarRules
{ public:
ToolBarRules (
std::shared_ptr<ToolBarManager> pToolBarManager,
std::shared_ptr<ViewShellManager> pViewShellManager);
/** This method calls MainViewShellChanged() and SelectionHasChanged() forthecurrentmainviewshellanditsview.
*/ void Update (ViewShellBase const & rBase);
/** Reset all tool bars in all groups and add tool bars and tool bar shellstotheToolBarGroup::PermanentgroupforthespecifiedViewShelltype.
*/ void MainViewShellChanged (ViewShell::ShellType nShellType);
/** Reset all tool bars in all groups and add tool bars and tool bar shellstotheToolBarGroup::PermanentgroupforthespecifiedViewShell.
*/ void MainViewShellChanged (const ViewShell& rMainViewShell);
/** Reset all tool bars in the ToolBarGroup::Function group and add tool bars and tool bar shellstothisgroupforthecurrentselection.
*/ 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);
/** Release all tool bar shells and the associated framework tool bars. Typicallycalledwhenthemainviewshellisbeingreplacedby another,alltoolbarshellsarereleased.Inthatprocessthe shellsaredestroyedanywayandwithoutcallingthismethodthey wouldstillbereferenced.
*/ void ReleaseAllToolBarShells();
void ToolBarsDestroyed();
void RequestUpdate();
void PreUpdate(); void PostUpdate(); /** Tell the XLayoutManager about the tool bars that we would like to be shown. @paramrpLayouterLock ThistypicallyisthempSynchronousLayouterLockthatisusedin thismethodandthatiseitherreleasedatitsendorassigned tompAsynchronousLockinordertobeunlockedlater.
*/ void Update (::std::unique_ptr<LayouterLock> pLayouterLock);
/** The order of statements is important. Firstunregisterlisteners,whichmaypostuserevents. Thenremovependinguserevents.
*/
ToolBarManager::Implementation::~Implementation()
{ // Unregister at broadcasters.
Link<tools::EventMultiplexerEvent&,void> aLink (LINK(this,ToolBarManager::Implementation,EventMultiplexerCallback));
mpEventMultiplexer->RemoveEventListener(aLink);
// Abort pending user calls. if (mnPendingUpdateCall != nullptr)
Application::RemoveUserEvent(mnPendingUpdateCall); if (mnPendingSetValidCall != nullptr)
Application::RemoveUserEvent(mnPendingSetValidCall);
}
mbIsValid = bValid; if (mbIsValid)
{
Reference<frame::XFrame> xFrame = mrBase.GetViewFrame().GetFrame().GetFrameInterface(); try
{
Reference<beans::XPropertySet> xFrameProperties (xFrame, UNO_QUERY_THROW);
Any aValue (xFrameProperties->getPropertyValue(u"LayoutManager"_ustr));
aValue >>= mxLayouter; // tdf#119997 if mpSynchronousLayouterLock was created before mxLayouter was // set then update it now that its available if (mpSynchronousLayouterLock && !mpSynchronousLayouterLock->is())
mpSynchronousLayouterLock.reset(new LayouterLock(mxLayouter));
} catch (const RuntimeException&)
{
}
// Get the list of tool bars that are not used anymore and are to be // deactivated.
std::vector<OUString> aToolBars;
maToolBarList.GetToolBarsToDeactivate(aToolBars);
// Turn off the tool bars. for (constauto& aToolBar : aToolBars)
{
OUString sFullName (GetToolBarResourceName(aToolBar));
SAL_INFO("sd.view", __func__ << ": turning off tool bar " << sFullName);
mxLayouter->destroyElement(sFullName);
maToolBarList.MarkToolBarAsNotActive(aToolBar);
}
// Turn on the tool bars that are visible in the new context. for (constauto& aToolBar : aToolBars)
{
OUString sFullName (GetToolBarResourceName(aToolBar));
SAL_INFO("sd.view", __func__ << ": turning on tool bar " << sFullName);
mxLayouter->requestElement(sFullName);
maToolBarList.MarkToolBarAsActive(aToolBar);
}
OSL_ASSERT(mnLockCount>0);
--mnLockCount; if (mnLockCount == 0)
{
Update(std::move(mpSynchronousLayouterLock));
}
}
void ToolBarManager::Implementation::Update (
::std::unique_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) return;
// During creation 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 != nullptr)
{
Application::RemoveUserEvent(mnPendingSetValidCall);
mnPendingSetValidCall = nullptr;
SetValid(true);
}
if (mbIsValid && mxLayouter.is() && (mbPreUpdatePending || mbPostUpdatePending))
{ // 1) Release UNO tool bars that are no 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 == nullptr)
mpViewShellManagerLock.reset( new ViewShellManager::UpdateLock(mrBase.GetViewShellManager()));
maToolBarShellList.UpdateShells(
mrBase.GetMainViewShell(),
mrBase.GetViewShellManager());
// 3) Unlock the ViewShellManager::UpdateLock. This updates the // shell stack.
mpViewShellManagerLock.reset();
// 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 (mnLockCount==0)
{
mpAsynchronousLayouterLock = std::move(pLocalLayouterLock); if (mnPendingUpdateCall==nullptr)
{
mnPendingUpdateCall = Application::PostUserEvent(
LINK(this,ToolBarManager::Implementation,UpdateCallback));
}
}
} else
{
mpViewShellManagerLock.reset();
pLocalLayouterLock.reset();
}
}
IMPL_LINK_NOARG(ToolBarManager::Implementation, UpdateCallback, void*, void)
{
mnPendingUpdateCall = nullptr; if (mnLockCount == 0)
{ if (mbPreUpdatePending)
PreUpdate(); if (mbPostUpdatePending)
PostUpdate(); if (mbIsValid && mxLayouter.is())
mpAsynchronousLayouterLock.reset();
}
}
IMPL_LINK(ToolBarManager::Implementation,EventMultiplexerCallback,
sd::tools::EventMultiplexerEvent&, rEvent, void)
{
SolarMutexGuard g; switch (rEvent.meEventId)
{ case EventMultiplexerEventId::ControllerAttached: if (mnPendingSetValidCall == nullptr)
mnPendingSetValidCall
= Application::PostUserEvent(LINK(this,Implementation,SetValidCallback)); break;
case EventMultiplexerEventId::ControllerDetached:
SetValid(false); break;
// Determine the plug in mode. bool bIsPlugInMode (false); do
{
SfxObjectShell* pObjectShell = mrBase.GetObjectShell(); if (pObjectShell == nullptr) break;
SfxMedium* pMedium = pObjectShell->GetMedium(); if (pMedium == nullptr) break;
switch(nShellType)
{ case ::sd::ViewShell::ST_IMPRESS: case ::sd::ViewShell::ST_NOTES: case ::sd::ViewShell::ST_HANDOUT: case ::sd::ViewShell::ST_DRAW:
mpToolBarManager->AddToolBar(
ToolBarManager::ToolBarGroup::Permanent,
ToolBarManager::msToolBar);
mpToolBarManager->AddToolBar(
ToolBarManager::ToolBarGroup::Permanent,
ToolBarManager::msOptionsToolBar);
mpToolBarManager->AddToolBar(
ToolBarManager::ToolBarGroup::Permanent,
ToolBarManager::msViewerToolBar); break;
case ::sd::ViewShell::ST_NOTESPANEL:
mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Permanent,
ToolbarId::Draw_Text_Toolbox_Sd); break;
switch (rView.GetContext())
{ case SdrViewContext::Graphic: if (!bTextEdit)
mpToolBarManager->SetToolBarShell(ToolBarManager::ToolBarGroup::Function,
ToolbarId::Draw_Graf_Toolbox); break;
case SdrViewContext::Media: if (!bTextEdit)
mpToolBarManager->SetToolBarShell(ToolBarManager::ToolBarGroup::Function,
ToolbarId::Draw_Media_Toolbox); break;
case SdrViewContext::Table:
mpToolBarManager->SetToolBarShell(ToolBarManager::ToolBarGroup::Function,
ToolbarId::Draw_Table_Toolbox);
bTextEdit = true; break;
case SdrViewContext::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::ToolBarGroup::Function,
ToolBarManager::msDrawingObjectToolBar);
mpToolBarManager->SetToolBar(ToolBarManager::ToolBarGroup::Permanent,
ToolBarManager::msToolBar); break; default: break;
} break;
}
}
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::ToolBarGroup::Function, ToolbarId::Svx_Extrusion_Bar);
if (svx::checkForSelectedFontWork(pView))
mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Function, ToolbarId::Svx_Fontwork_Bar);
// Switch on additional context-sensitive tool bars. if (rView.GetContext() == SdrViewContext::PointEdit)
mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Function, ToolbarId::Bezier_Toolbox_Sd);
}
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 ToolbarId::Draw_Graf_Toolbox:
mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msGraphicObjectBar); break;
case ToolbarId::Draw_Media_Toolbox:
mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msMediaObjectBar); break;
case ToolbarId::Draw_Text_Toolbox_Sd:
mpToolBarManager->RemoveToolBar(ToolBarManager::ToolBarGroup::Permanent, ToolBarManager::msToolBar);
mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTextObjectBar); break;
case ToolbarId::Bezier_Toolbox_Sd:
mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msBezierObjectBar); break;
case ToolbarId::Draw_Table_Toolbox: // tdf#142489 Do not show the table toolbar when the Notebookbar UI is active if (!sfx2::SfxNotebookBar::IsActive(true))
mpToolBarManager->AddToolBar(eGroup, ToolBarManager::msTableObjectBar); break;
default: 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 ToolbarId::Draw_Graf_Toolbox:
mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msGraphicObjectBar); break;
case ToolbarId::Draw_Media_Toolbox:
mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msMediaObjectBar); break;
case ToolbarId::Draw_Text_Toolbox_Sd:
mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTextObjectBar); break;
case ToolbarId::Bezier_Toolbox_Sd:
mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msBezierObjectBar); break;
case ToolbarId::Draw_Table_Toolbox:
mpToolBarManager->RemoveToolBar(eGroup, ToolBarManager::msTableObjectBar); break;
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); for (constauto& rDescriptor : aList)
{
rRules.SubShellRemoved(rDescriptor.meGroup, rDescriptor.mnId);
}
// Clear the list of requested tool bars.
maNewList.clear();
}
// 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 (constauto& rShell : aList)
{
SAL_INFO("sd.view", __func__ << ": deactivating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId));
rpManager->DeactivateSubShell(*pCurrentMainViewShell, rShell.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 (constauto& rShell : aList)
{
SAL_INFO("sd.view", __func__ << ": activating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId));
rpManager->ActivateSubShell(*pCurrentMainViewShell, rShell.mnId);
}
// The maNewList now reflects the current state and thus is made // maCurrentList.
maCurrentList = maNewList;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.