nss: upgrade to release 3.73
[LibreOffice.git] / sfx2 / source / notebookbar / SfxNotebookBar.cxx
blob39e60f61dfe99ba95637c712eeb25af289778d11
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sfx2/bindings.hxx>
11 #include <sfx2/viewsh.hxx>
12 #include <sfx2/dispatch.hxx>
13 #include <sfx2/notebookbar/SfxNotebookBar.hxx>
14 #include <vcl/notebookbar.hxx>
15 #include <vcl/syswin.hxx>
16 #include <sfx2/viewfrm.hxx>
17 #include <sfx2/sfxsids.hrc>
18 #include <comphelper/processfactory.hxx>
19 #include <comphelper/lok.hxx>
20 #include <com/sun/star/frame/UnknownModuleException.hpp>
21 #include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
22 #include <com/sun/star/ui/XContextChangeEventMultiplexer.hpp>
23 #include <com/sun/star/frame/XLayoutManager.hpp>
24 #include <officecfg/Office/UI/ToolbarMode.hxx>
25 #include <com/sun/star/frame/XModuleManager.hpp>
26 #include <com/sun/star/frame/ModuleManager.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <unotools/confignode.hxx>
29 #include <comphelper/types.hxx>
30 #include <framework/addonsoptions.hxx>
31 #include <vcl/NotebookBarAddonsMerger.hxx>
32 #include <vector>
33 #include <map>
34 #include <vcl/WeldedTabbedNotebookbar.hxx>
36 using namespace sfx2;
37 using namespace css::uno;
38 using namespace css::ui;
39 using namespace css;
41 #define MENUBAR_STR "private:resource/menubar/menubar"
43 const char MERGE_NOTEBOOKBAR_URL[] = "URL";
45 bool SfxNotebookBar::m_bLock = false;
46 bool SfxNotebookBar::m_bHide = false;
47 std::map<const SfxViewShell*, std::shared_ptr<WeldedTabbedNotebookbar>> SfxNotebookBar::m_pNotebookBarWeldedWrapper;
49 static void NotebookbarAddonValues(
50 std::vector<Image>& aImageValues,
51 std::vector<css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>>>&
52 aExtensionValues)
54 framework::AddonsOptions aAddonsItems;
56 for (int nIdx = 0; nIdx < aAddonsItems.GetAddonsNotebookBarCount(); nIdx++)
58 const css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>> aExtension
59 = aAddonsItems.GetAddonsNotebookBarPart(nIdx);
60 for (const css::uno::Sequence<css::beans::PropertyValue>& rExtensionVal : aExtension)
62 Image aImage;
63 bool isBigImage = true;
64 for (const auto& rProp : rExtensionVal)
66 if (rProp.Name == MERGE_NOTEBOOKBAR_URL)
68 OUString sImage;
69 rProp.Value >>= sImage;
70 aImage = Image(framework::AddonsOptions().GetImageFromURL(sImage, isBigImage));
73 aImageValues.push_back(aImage);
75 aExtensionValues.push_back(aExtension);
79 static Reference<frame::XLayoutManager> lcl_getLayoutManager( const Reference<frame::XFrame>& xFrame )
81 css::uno::Reference<css::frame::XLayoutManager> xLayoutManager;
83 if (xFrame.is())
85 Reference<css::beans::XPropertySet> xPropSet(xFrame, UNO_QUERY);
87 if (xPropSet.is())
89 Any aValue = xPropSet->getPropertyValue("LayoutManager");
90 aValue >>= xLayoutManager;
94 return xLayoutManager;
97 static OUString lcl_getAppName( vcl::EnumContext::Application eApp )
99 switch ( eApp )
101 case vcl::EnumContext::Application::Writer:
102 return "Writer";
103 break;
104 case vcl::EnumContext::Application::Calc:
105 return "Calc";
106 break;
107 case vcl::EnumContext::Application::Impress:
108 return "Impress";
109 break;
110 case vcl::EnumContext::Application::Draw:
111 return "Draw";
112 break;
113 case vcl::EnumContext::Application::Formula:
114 return "Formula";
115 break;
116 default:
117 return OUString();
118 break;
122 static void lcl_setNotebookbarFileName( vcl::EnumContext::Application eApp, const OUString& sFileName )
124 std::shared_ptr<comphelper::ConfigurationChanges> aBatch(
125 comphelper::ConfigurationChanges::create( ::comphelper::getProcessComponentContext() ) );
126 switch ( eApp )
128 case vcl::EnumContext::Application::Writer:
129 officecfg::Office::UI::ToolbarMode::ActiveWriter::set( sFileName, aBatch );
130 break;
131 case vcl::EnumContext::Application::Calc:
132 officecfg::Office::UI::ToolbarMode::ActiveCalc::set( sFileName, aBatch );
133 break;
134 case vcl::EnumContext::Application::Impress:
135 officecfg::Office::UI::ToolbarMode::ActiveImpress::set( sFileName, aBatch );
136 break;
137 case vcl::EnumContext::Application::Draw:
138 officecfg::Office::UI::ToolbarMode::ActiveDraw::set( sFileName, aBatch );
139 break;
140 default:
141 break;
143 aBatch->commit();
146 static OUString lcl_getNotebookbarFileName( vcl::EnumContext::Application eApp )
148 switch ( eApp )
150 case vcl::EnumContext::Application::Writer:
151 return officecfg::Office::UI::ToolbarMode::ActiveWriter::get();
152 break;
153 case vcl::EnumContext::Application::Calc:
154 return officecfg::Office::UI::ToolbarMode::ActiveCalc::get();
155 break;
156 case vcl::EnumContext::Application::Impress:
157 return officecfg::Office::UI::ToolbarMode::ActiveImpress::get();
158 break;
159 case vcl::EnumContext::Application::Draw:
160 return officecfg::Office::UI::ToolbarMode::ActiveDraw::get();
161 break;
163 default:
164 break;
166 return OUString();
169 static utl::OConfigurationTreeRoot lcl_getCurrentImplConfigRoot()
171 return utl::OConfigurationTreeRoot(::comphelper::getProcessComponentContext(),
172 "org.openoffice.Office.UI.ToolbarMode/",
173 true);
176 static utl::OConfigurationNode lcl_getCurrentImplConfigNode(const Reference<css::frame::XFrame>& xFrame,
177 utl::OConfigurationTreeRoot const & rNotebookbarNode )
179 if (!rNotebookbarNode.isValid())
180 return utl::OConfigurationNode();
182 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
184 vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
185 OUString aActive = lcl_getNotebookbarFileName( eApp );
187 const utl::OConfigurationNode aImplsNode = rNotebookbarNode.openNode("Applications/" + lcl_getAppName( eApp) + "/Modes");
188 const Sequence<OUString> aModeNodeNames( aImplsNode.getNodeNames() );
190 for ( const auto& rModeNodeName : aModeNodeNames )
192 const utl::OConfigurationNode aImplNode( aImplsNode.openNode( rModeNodeName ) );
193 if ( !aImplNode.isValid() )
194 continue;
196 OUString aCommandArg = comphelper::getString( aImplNode.getNodeValue( "CommandArg" ) );
198 if ( aCommandArg == aActive )
200 return aImplNode;
204 return utl::OConfigurationNode();
207 void SfxNotebookBar::CloseMethod(SfxBindings& rBindings)
209 SfxFrame& rFrame = rBindings.GetDispatcher_Impl()->GetFrame()->GetFrame();
210 CloseMethod(rFrame.GetSystemWindow());
213 void SfxNotebookBar::CloseMethod(SystemWindow* pSysWindow)
215 if (pSysWindow)
217 RemoveListeners(pSysWindow);
218 if(pSysWindow->GetNotebookBar())
219 pSysWindow->CloseNotebookBar();
220 if (SfxViewFrame::Current())
221 SfxNotebookBar::ShowMenubar(SfxViewFrame::Current(), true);
225 void SfxNotebookBar::LockNotebookBar()
227 m_bHide = true;
228 m_bLock = true;
231 void SfxNotebookBar::UnlockNotebookBar()
233 m_bHide = false;
234 m_bLock = false;
237 bool SfxNotebookBar::IsActive()
239 if (m_bHide)
240 return false;
242 vcl::EnumContext::Application eApp = vcl::EnumContext::Application::Any;
244 if (SfxViewFrame::Current())
246 const Reference<frame::XFrame>& xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
247 if (!xFrame.is())
248 return false;
250 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
253 eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
255 catch (css::frame::UnknownModuleException& e)
257 SAL_WARN("sfx.appl", "SfxNotebookBar::IsActive(): " + e.Message);
258 return false;
261 else
262 return false;
264 OUString appName(lcl_getAppName( eApp ));
266 if (appName.isEmpty())
267 return false;
270 OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" + appName;
272 const utl::OConfigurationTreeRoot aAppNode(
273 ::comphelper::getProcessComponentContext(),
274 aPath,
275 false);
276 if ( !aAppNode.isValid() )
277 return false;
279 OUString aActive = comphelper::getString( aAppNode.getNodeValue( "Active" ) );
281 const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
282 const Sequence<OUString> aModeNodeNames( aModesNode.getNodeNames() );
284 for ( const auto& rModeNodeName : aModeNodeNames )
286 const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
287 if ( !aModeNode.isValid() )
288 continue;
290 OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
292 if ( aCommandArg == aActive )
294 return comphelper::getBOOL( aModeNode.getNodeValue( "HasNotebookbar" ) );
297 return false;
300 void SfxNotebookBar::ExecMethod(SfxBindings& rBindings, const OUString& rUIName)
302 // Save active UI file name
303 if ( !rUIName.isEmpty() && SfxViewFrame::Current() )
305 const Reference<frame::XFrame>& xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
306 if (xFrame.is())
308 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
309 vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
310 lcl_setNotebookbarFileName( eApp, rUIName );
314 // trigger the StateMethod
315 rBindings.Invalidate(SID_NOTEBOOKBAR);
316 rBindings.Update();
319 bool SfxNotebookBar::StateMethod(SfxBindings& rBindings, const OUString& rUIFile,
320 bool bReloadNotebookbar)
322 SfxFrame& rFrame = rBindings.GetDispatcher_Impl()->GetFrame()->GetFrame();
323 return StateMethod(rFrame.GetSystemWindow(), rFrame.GetFrameInterface(), rUIFile,
324 bReloadNotebookbar);
327 bool SfxNotebookBar::StateMethod(SystemWindow* pSysWindow,
328 const Reference<css::frame::XFrame>& xFrame,
329 const OUString& rUIFile, bool bReloadNotebookbar)
331 if (!pSysWindow)
333 if (SfxViewFrame::Current() && SfxViewFrame::Current()->GetWindow().GetSystemWindow())
334 pSysWindow = SfxViewFrame::Current()->GetWindow().GetSystemWindow();
335 else
336 return false;
339 if (IsActive())
341 css::uno::Reference<css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
342 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
343 OUString aModuleName = xModuleManager->identify( xFrame );
344 vcl::EnumContext::Application eApp = vcl::EnumContext::GetApplicationEnum( aModuleName );
345 OUString sFile = lcl_getNotebookbarFileName( eApp );
346 OUString sNewFile = rUIFile + sFile;
347 OUString sCurrentFile;
348 VclPtr<NotebookBar> pNotebookBar = pSysWindow->GetNotebookBar();
349 if ( pNotebookBar )
350 sCurrentFile = pNotebookBar->GetUIFilePath();
352 bool bChangedFile = sNewFile != sCurrentFile;
354 if ((!sFile.isEmpty() && bChangedFile) || !pNotebookBar || !pNotebookBar->IsVisible()
355 || bReloadNotebookbar || comphelper::LibreOfficeKit::isActive())
357 const SfxViewShell* pViewShell = SfxViewShell::Current();
359 // Notebookbar was loaded too early what caused:
360 // * in LOK: Paste Special feature was incorrectly initialized
361 // Skip first request so Notebookbar will be initialized after document was loaded
362 static std::map<const void*, bool> bSkippedFirstInit;
363 if (comphelper::LibreOfficeKit::isActive()
364 && bSkippedFirstInit.find(pViewShell) == bSkippedFirstInit.end())
366 bSkippedFirstInit[pViewShell] = true;
367 return false;
370 RemoveListeners(pSysWindow);
372 OUString aBuf = rUIFile + sFile;
374 //Addons For Notebookbar
375 std::vector<Image> aImageValues;
376 std::vector<css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > > aExtensionValues;
377 NotebookBarAddonsItem aNotebookBarAddonsItem;
378 NotebookbarAddonValues(aImageValues , aExtensionValues);
379 aNotebookBarAddonsItem.aAddonValues = aExtensionValues;
380 aNotebookBarAddonsItem.aImageValues = aImageValues;
382 // setup if necessary
383 if (comphelper::LibreOfficeKit::isActive())
385 // update the current LOK language and locale for the dialog tunneling
386 comphelper::LibreOfficeKit::setLanguageTag(pViewShell->GetLOKLanguageTag());
387 comphelper::LibreOfficeKit::setLocale(pViewShell->GetLOKLocale());
390 pSysWindow->SetNotebookBar(aBuf, xFrame, aNotebookBarAddonsItem , bReloadNotebookbar);
391 pNotebookBar = pSysWindow->GetNotebookBar();
392 pNotebookBar->Show();
395 bool hasWeldedWrapper = m_pNotebookBarWeldedWrapper.find(pViewShell) != m_pNotebookBarWeldedWrapper.end();
396 if ((!hasWeldedWrapper || bReloadNotebookbar) && pNotebookBar->IsWelded())
398 sal_uInt64 nWindowId = reinterpret_cast<sal_uInt64>(pViewShell);
399 m_pNotebookBarWeldedWrapper.emplace(std::make_pair(pViewShell,
400 new WeldedTabbedNotebookbar(pNotebookBar->GetMainContainer(),
401 pNotebookBar->GetUIFilePath(),
402 xFrame,
403 nWindowId)));
404 pNotebookBar->SetDisposeCallback(LINK(nullptr, SfxNotebookBar, VclDisposeHdl), pViewShell);
407 pNotebookBar->GetParent()->Resize();
409 utl::OConfigurationTreeRoot aRoot(lcl_getCurrentImplConfigRoot());
410 const utl::OConfigurationNode aModeNode(lcl_getCurrentImplConfigNode(xFrame, aRoot));
411 SfxNotebookBar::ShowMenubar( comphelper::getBOOL( aModeNode.getNodeValue( "HasMenubar" ) ) );
413 SfxViewFrame* pView = SfxViewFrame::Current();
415 if(pView)
417 pNotebookBar->ControlListenerForCurrentController(true);
421 return true;
423 else if (auto pNotebookBar = pSysWindow->GetNotebookBar())
425 pNotebookBar->Hide();
426 pNotebookBar->GetParent()->Resize();
427 SfxNotebookBar::ShowMenubar(true);
430 return false;
433 void SfxNotebookBar::RemoveListeners(SystemWindow const * pSysWindow)
435 if (auto pNotebookBar = pSysWindow->GetNotebookBar())
437 pNotebookBar->StopListeningAllControllers();
441 void SfxNotebookBar::ShowMenubar(bool bShow)
443 if (m_bLock)
444 return;
446 m_bLock = true;
448 Reference<frame::XFrame> xFrame;
449 vcl::EnumContext::Application eCurrentApp = vcl::EnumContext::Application::NONE;
450 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
451 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
453 if ( SfxViewFrame::Current() )
455 xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
456 eCurrentApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
459 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst();
460 while( pViewFrame )
462 xFrame = pViewFrame->GetFrame().GetFrameInterface();
463 if ( xFrame.is() )
465 vcl::EnumContext::Application eApp =
466 vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
468 if ( eApp == eCurrentApp )
470 const Reference<frame::XLayoutManager>& xLayoutManager =
471 lcl_getLayoutManager( xFrame );
473 if (xLayoutManager.is())
475 xLayoutManager->lock();
477 if (xLayoutManager->getElement(MENUBAR_STR).is())
479 if (xLayoutManager->isElementVisible(MENUBAR_STR) && !bShow)
480 xLayoutManager->hideElement(MENUBAR_STR);
481 else if(!xLayoutManager->isElementVisible(MENUBAR_STR) && bShow)
482 xLayoutManager->showElement(MENUBAR_STR);
485 xLayoutManager->unlock();
490 pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
492 m_bLock = false;
495 void SfxNotebookBar::ShowMenubar(SfxViewFrame const * pViewFrame, bool bShow)
497 if (m_bLock)
498 return;
500 m_bLock = true;
502 Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
503 if (xFrame.is())
505 const Reference<frame::XLayoutManager>& xLayoutManager = lcl_getLayoutManager(xFrame);
506 if (xLayoutManager.is())
508 xLayoutManager->lock();
510 if (xLayoutManager->getElement(MENUBAR_STR).is())
512 if (xLayoutManager->isElementVisible(MENUBAR_STR) && !bShow)
513 xLayoutManager->hideElement(MENUBAR_STR);
514 else if (!xLayoutManager->isElementVisible(MENUBAR_STR) && bShow)
515 xLayoutManager->showElement(MENUBAR_STR);
518 xLayoutManager->unlock();
521 m_bLock = false;
524 void SfxNotebookBar::ToggleMenubar()
526 if (!SfxViewFrame::Current())
527 return;
529 const Reference<frame::XFrame>& xFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
530 if (!xFrame.is())
531 return;
533 const Reference<frame::XLayoutManager>& xLayoutManager =
534 lcl_getLayoutManager(xFrame);
536 bool bShow = true;
537 if (xLayoutManager.is() && xLayoutManager->getElement(MENUBAR_STR).is())
539 if (xLayoutManager->isElementVisible(MENUBAR_STR))
541 SfxNotebookBar::ShowMenubar(false);
542 bShow = false;
544 else
545 SfxNotebookBar::ShowMenubar(true);
548 // Save menubar settings
549 if (IsActive())
551 utl::OConfigurationTreeRoot aRoot(lcl_getCurrentImplConfigRoot());
552 utl::OConfigurationNode aModeNode(lcl_getCurrentImplConfigNode(xFrame, aRoot));
553 aModeNode.setNodeValue( "HasMenubar", toAny<bool>( bShow ) );
554 aRoot.commit();
558 void SfxNotebookBar::ReloadNotebookBar(const OUString& sUIPath)
560 if (SfxNotebookBar::IsActive())
562 SfxViewShell* pViewShell = SfxViewShell::Current();
563 sfx2::SfxNotebookBar::StateMethod(pViewShell->GetViewFrame()->GetBindings(), sUIPath, true);
567 IMPL_STATIC_LINK(SfxNotebookBar, VclDisposeHdl, const SfxViewShell*, pViewShell, void)
569 m_pNotebookBarWeldedWrapper.erase(pViewShell);
572 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */