LibreOffice Module sfx2 (master) 1
SfxNotebookBar.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 */
9
10#include <sfx2/bindings.hxx>
11#include <sfx2/viewsh.hxx>
12#include <sfx2/dispatch.hxx>
15#include <vcl/syswin.hxx>
16#include <sfx2/viewfrm.hxx>
17#include <sfx2/sfxsids.hrc>
19#include <comphelper/lok.hxx>
20#include <com/sun/star/frame/UnknownModuleException.hpp>
21#include <com/sun/star/frame/XLayoutManager.hpp>
22#include <officecfg/Office/UI/ToolbarMode.hxx>
23#include <com/sun/star/frame/XModuleManager.hpp>
24#include <com/sun/star/frame/ModuleManager.hpp>
25#include <com/sun/star/beans/XPropertySet.hpp>
27#include <comphelper/types.hxx>
30#include <vector>
31#include <map>
33
34using namespace sfx2;
35using namespace css::uno;
36using namespace css::ui;
37using namespace css;
38
39constexpr OUStringLiteral MENUBAR_STR = u"private:resource/menubar/menubar";
40
41const char MERGE_NOTEBOOKBAR_URL[] = "URL";
42
43bool SfxNotebookBar::m_bLock = false;
44bool SfxNotebookBar::m_bHide = false;
45std::map<const SfxViewShell*, std::shared_ptr<WeldedTabbedNotebookbar>> SfxNotebookBar::m_pNotebookBarWeldedWrapper;
46
48 std::vector<Image>& aImageValues,
49 std::vector<css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>>>&
50 aExtensionValues)
51{
52 framework::AddonsOptions aAddonsItems;
53
54 for (int nIdx = 0; nIdx < aAddonsItems.GetAddonsNotebookBarCount(); nIdx++)
55 {
56 const css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>> aExtension
57 = aAddonsItems.GetAddonsNotebookBarPart(nIdx);
58 for (const css::uno::Sequence<css::beans::PropertyValue>& rExtensionVal : aExtension)
59 {
60 Image aImage;
61 bool isBigImage = true;
62 for (const auto& rProp : rExtensionVal)
63 {
64 if (rProp.Name == MERGE_NOTEBOOKBAR_URL)
65 {
66 OUString sImage;
67 rProp.Value >>= sImage;
68 aImage = Image(aAddonsItems.GetImageFromURL(sImage, isBigImage));
69 }
70 }
71 aImageValues.push_back(aImage);
72 }
73 aExtensionValues.push_back(aExtension);
74 }
75}
76
77static Reference<frame::XLayoutManager> lcl_getLayoutManager( const Reference<frame::XFrame>& xFrame )
78{
79 css::uno::Reference<css::frame::XLayoutManager> xLayoutManager;
80
81 if (xFrame.is())
82 {
83 Reference<css::beans::XPropertySet> xPropSet(xFrame, UNO_QUERY);
84
85 if (xPropSet.is())
86 {
87 Any aValue = xPropSet->getPropertyValue("LayoutManager");
88 aValue >>= xLayoutManager;
89 }
90 }
91
92 return xLayoutManager;
93}
94
96{
97 switch ( eApp )
98 {
100 return "Writer";
102 return "Calc";
104 return "Impress";
106 return "Draw";
108 return "Formula";
109 default:
110 return OUString();
111 }
112}
113
114static void lcl_setNotebookbarFileName( vcl::EnumContext::Application eApp, const OUString& sFileName )
115{
116 std::shared_ptr<comphelper::ConfigurationChanges> aBatch(
118 switch ( eApp )
119 {
121 officecfg::Office::UI::ToolbarMode::ActiveWriter::set( sFileName, aBatch );
122 break;
124 officecfg::Office::UI::ToolbarMode::ActiveCalc::set( sFileName, aBatch );
125 break;
127 officecfg::Office::UI::ToolbarMode::ActiveImpress::set( sFileName, aBatch );
128 break;
130 officecfg::Office::UI::ToolbarMode::ActiveDraw::set( sFileName, aBatch );
131 break;
132 default:
133 break;
134 }
135 aBatch->commit();
136}
137
139{
140 switch ( eApp )
141 {
143 return officecfg::Office::UI::ToolbarMode::ActiveWriter::get();
145 return officecfg::Office::UI::ToolbarMode::ActiveCalc::get();
147 return officecfg::Office::UI::ToolbarMode::ActiveImpress::get();
149 return officecfg::Office::UI::ToolbarMode::ActiveDraw::get();
150
151 default:
152 break;
153 }
154 return OUString();
155}
156
158{
159 return utl::OConfigurationTreeRoot(::comphelper::getProcessComponentContext(),
160 "org.openoffice.Office.UI.ToolbarMode/",
161 true);
162}
163
164static utl::OConfigurationNode lcl_getCurrentImplConfigNode(const Reference<css::frame::XFrame>& xFrame,
165 utl::OConfigurationTreeRoot const & rNotebookbarNode )
166{
167 if (!rNotebookbarNode.isValid())
169
170 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
171
173 OUString aActive = lcl_getNotebookbarFileName( eApp );
174
175 const utl::OConfigurationNode aImplsNode = rNotebookbarNode.openNode("Applications/" + lcl_getAppName( eApp) + "/Modes");
176 const Sequence<OUString> aModeNodeNames( aImplsNode.getNodeNames() );
177
178 for ( const auto& rModeNodeName : aModeNodeNames )
179 {
180 const utl::OConfigurationNode aImplNode( aImplsNode.openNode( rModeNodeName ) );
181 if ( !aImplNode.isValid() )
182 continue;
183
184 OUString aCommandArg = comphelper::getString( aImplNode.getNodeValue( "CommandArg" ) );
185
186 if ( aCommandArg == aActive )
187 {
188 return aImplNode;
189 }
190 }
191
193}
194
195void SfxNotebookBar::CloseMethod(SfxBindings& rBindings)
196{
197 SfxFrame& rFrame = rBindings.GetDispatcher_Impl()->GetFrame()->GetFrame();
199}
200
202{
203 if (pSysWindow)
204 {
205 if(pSysWindow->GetNotebookBar())
206 pSysWindow->CloseNotebookBar();
207 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
208 SfxNotebookBar::ShowMenubar(pViewFrm, true);
209 }
210}
211
213{
214 m_bHide = true;
215 m_bLock = true;
216}
217
219{
220 m_bHide = false;
221 m_bLock = false;
222}
223
224bool SfxNotebookBar::IsActive(bool bConsiderSingleToolbar)
225{
226 if (m_bHide)
227 return false;
228
230
231 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
232 {
233 const Reference<frame::XFrame>& xFrame = pViewFrm->GetFrame().GetFrameInterface();
234 if (!xFrame.is())
235 return false;
236
237 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
238 try
239 {
240 eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
241 }
242 catch (css::frame::UnknownModuleException& e)
243 {
244 SAL_WARN("sfx.appl", "SfxNotebookBar::IsActive(): " + e.Message);
245 return false;
246 }
247 }
248 else
249 return false;
250
251 OUString appName(lcl_getAppName( eApp ));
252
253 if (appName.isEmpty())
254 return false;
255
256
257 OUString aPath = "org.openoffice.Office.UI.ToolbarMode/Applications/" + appName;
258
259 const utl::OConfigurationTreeRoot aAppNode(
260 ::comphelper::getProcessComponentContext(),
261 aPath,
262 false);
263 if ( !aAppNode.isValid() )
264 return false;
265
266 OUString aActive = comphelper::getString( aAppNode.getNodeValue( "Active" ) );
267
268 if (bConsiderSingleToolbar && aActive == "Single")
269 return true;
270
271 if (comphelper::LibreOfficeKit::isActive() && aActive == "notebookbar_online.ui")
272 return true;
273
274 const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
275 const Sequence<OUString> aModeNodeNames( aModesNode.getNodeNames() );
276
277 for ( const auto& rModeNodeName : aModeNodeNames )
278 {
279 const utl::OConfigurationNode aModeNode( aModesNode.openNode( rModeNodeName ) );
280 if ( !aModeNode.isValid() )
281 continue;
282
283 OUString aCommandArg = comphelper::getString( aModeNode.getNodeValue( "CommandArg" ) );
284
285 if ( aCommandArg == aActive )
286 {
287 return comphelper::getBOOL( aModeNode.getNodeValue( "HasNotebookbar" ) );
288 }
289 }
290 return false;
291}
292
293void SfxNotebookBar::ExecMethod(SfxBindings& rBindings, const OUString& rUIName)
294{
295 // Save active UI file name
296 if (!rUIName.isEmpty())
297 {
298 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
299 {
300 const Reference<frame::XFrame>& xFrame = pViewFrm->GetFrame().GetFrameInterface();
301 if (xFrame.is())
302 {
303 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( ::comphelper::getProcessComponentContext() );
305 lcl_setNotebookbarFileName( eApp, rUIName );
306 }
307 }
308 }
309
310 // trigger the StateMethod
311 rBindings.Invalidate(SID_NOTEBOOKBAR);
312 rBindings.Update();
313}
314
315bool SfxNotebookBar::StateMethod(SfxBindings& rBindings, std::u16string_view rUIFile,
316 bool bReloadNotebookbar)
317{
318 SfxFrame& rFrame = rBindings.GetDispatcher_Impl()->GetFrame()->GetFrame();
319 return StateMethod(rFrame.GetSystemWindow(), rFrame.GetFrameInterface(), rUIFile,
320 bReloadNotebookbar);
321}
322
324 const Reference<css::frame::XFrame>& xFrame,
325 std::u16string_view rUIFile, bool bReloadNotebookbar)
326{
327 if (!pSysWindow)
328 {
330 if (pViewFrm && pViewFrm->GetWindow().GetSystemWindow())
331 pSysWindow = pViewFrm->GetWindow().GetSystemWindow();
332 else
333 return false;
334 }
335
336 if (IsActive())
337 {
338 css::uno::Reference<css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
339 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
340 OUString aModuleName = xModuleManager->identify( xFrame );
342
343 OUString sFile;
345 sFile = "notebookbar_online.ui";
346 else
347 sFile = lcl_getNotebookbarFileName( eApp );
348
349 OUString sNewFile = rUIFile + sFile;
350 OUString sCurrentFile;
351 VclPtr<NotebookBar> pNotebookBar = pSysWindow->GetNotebookBar();
352 if ( pNotebookBar )
353 sCurrentFile = pNotebookBar->GetUIFilePath();
354
355 bool bChangedFile = sNewFile != sCurrentFile;
356
357 if ((!sFile.isEmpty() && bChangedFile) || !pNotebookBar || !pNotebookBar->IsVisible()
358 || bReloadNotebookbar || comphelper::LibreOfficeKit::isActive())
359 {
360 const SfxViewShell* pViewShell = SfxViewShell::Current();
361
362 RemoveListeners(pSysWindow);
363
364 OUString aBuf = rUIFile + sFile;
365
366 //Addons For Notebookbar
367 std::vector<Image> aImageValues;
368 std::vector<css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > > aExtensionValues;
369 NotebookBarAddonsItem aNotebookBarAddonsItem;
370 NotebookbarAddonValues(aImageValues , aExtensionValues);
371 aNotebookBarAddonsItem.aAddonValues = aExtensionValues;
372 aNotebookBarAddonsItem.aImageValues = aImageValues;
373
374 // setup if necessary
376 {
377 // update the current LOK language and locale for the dialog tunneling
380 }
381
382 pSysWindow->SetNotebookBar(aBuf, xFrame, aNotebookBarAddonsItem , bReloadNotebookbar);
383 pNotebookBar = pSysWindow->GetNotebookBar();
384 pNotebookBar->Show();
385
386
387 bool hasWeldedWrapper = m_pNotebookBarWeldedWrapper.find(pViewShell) != m_pNotebookBarWeldedWrapper.end();
388 if ((!hasWeldedWrapper || bReloadNotebookbar) && pNotebookBar->IsWelded())
389 {
390 sal_uInt64 nWindowId = reinterpret_cast<sal_uInt64>(pViewShell);
391 m_pNotebookBarWeldedWrapper.emplace(std::make_pair(pViewShell,
392 new WeldedTabbedNotebookbar(pNotebookBar->GetMainContainer(),
393 pNotebookBar->GetUIFilePath(),
394 xFrame,
395 nWindowId)));
396 pNotebookBar->SetDisposeCallback(LINK(nullptr, SfxNotebookBar, VclDisposeHdl), pViewShell);
397 }
398
399 pNotebookBar->GetParent()->Resize();
400
402 const utl::OConfigurationNode aModeNode(lcl_getCurrentImplConfigNode(xFrame, aRoot));
403 SfxNotebookBar::ShowMenubar( comphelper::getBOOL( aModeNode.getNodeValue( "HasMenubar" ) ) );
404
406
407 if(pView)
408 {
409 pNotebookBar->SetupListener(true);
410 }
411 }
412
413 return true;
414 }
415 else if (auto pNotebookBar = pSysWindow->GetNotebookBar())
416 {
417 vcl::Window* pParent = pNotebookBar->GetParent();
418 pSysWindow->CloseNotebookBar();
419 pParent->Resize();
421 }
422
423 return false;
424}
425
427{
428 if (auto pNotebookBar = pSysWindow->GetNotebookBar())
429 {
430 pNotebookBar->SetupListener(false);
431 }
432}
433
435{
436 if (m_bLock)
437 return;
438
439 m_bLock = true;
440
441 Reference<frame::XFrame> xFrame;
443 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
444 const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create( xContext );
445
446 if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
447 {
448 xFrame = pViewFrm->GetFrame().GetFrameInterface();
449 eCurrentApp = vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
450 }
451
452 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst();
453 while( pViewFrame )
454 {
455 xFrame = pViewFrame->GetFrame().GetFrameInterface();
456 if ( xFrame.is() )
457 {
459 vcl::EnumContext::GetApplicationEnum( xModuleManager->identify( xFrame ) );
460
461 if ( eApp == eCurrentApp )
462 {
463 const Reference<frame::XLayoutManager>& xLayoutManager =
465
466 if (xLayoutManager.is())
467 {
468 if (xLayoutManager->getElement(MENUBAR_STR).is())
469 {
470 if (xLayoutManager->isElementVisible(MENUBAR_STR) && !bShow)
471 xLayoutManager->hideElement(MENUBAR_STR);
472 else if(!xLayoutManager->isElementVisible(MENUBAR_STR) && bShow)
473 xLayoutManager->showElement(MENUBAR_STR);
474 }
475 }
476 }
477 }
478
479 pViewFrame = SfxViewFrame::GetNext( *pViewFrame );
480 }
481 m_bLock = false;
482}
483
484void SfxNotebookBar::ShowMenubar(SfxViewFrame const * pViewFrame, bool bShow)
485{
486 if (m_bLock)
487 return;
488
489 m_bLock = true;
490
491 Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
492 if (xFrame.is())
493 {
494 const Reference<frame::XLayoutManager>& xLayoutManager = lcl_getLayoutManager(xFrame);
495 if (xLayoutManager.is())
496 {
497 if (xLayoutManager->getElement(MENUBAR_STR).is())
498 {
499 if (xLayoutManager->isElementVisible(MENUBAR_STR) && !bShow)
500 xLayoutManager->hideElement(MENUBAR_STR);
501 else if (!xLayoutManager->isElementVisible(MENUBAR_STR) && bShow)
502 xLayoutManager->showElement(MENUBAR_STR);
503 }
504 }
505 }
506 m_bLock = false;
507}
508
510{
512 if (!pViewFrm)
513 return;
514
515 const Reference<frame::XFrame>& xFrame = pViewFrm->GetFrame().GetFrameInterface();
516 if (!xFrame.is())
517 return;
518
519 const Reference<frame::XLayoutManager>& xLayoutManager =
521
522 bool bShow = true;
523 if (xLayoutManager.is() && xLayoutManager->getElement(MENUBAR_STR).is())
524 {
525 if (xLayoutManager->isElementVisible(MENUBAR_STR))
526 {
528 bShow = false;
529 }
530 else
532 }
533
534 // Save menubar settings
535 if (IsActive())
536 {
539 aModeNode.setNodeValue( "HasMenubar", toAny<bool>( bShow ) );
540 aRoot.commit();
541 }
542}
543
544void SfxNotebookBar::ReloadNotebookBar(std::u16string_view sUIPath)
545{
547 {
548 SfxViewShell* pViewShell = SfxViewShell::Current();
549 sfx2::SfxNotebookBar::StateMethod(pViewShell->GetViewFrame().GetBindings(), sUIPath, true);
550 }
551}
552
553IMPL_STATIC_LINK(SfxNotebookBar, VclDisposeHdl, const SfxViewShell*, pViewShell, void)
554{
555 m_pNotebookBarWeldedWrapper.erase(pViewShell);
556}
557
558/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static Reference< frame::XLayoutManager > lcl_getLayoutManager(const Reference< frame::XFrame > &xFrame)
constexpr OUStringLiteral MENUBAR_STR
static utl::OConfigurationTreeRoot lcl_getCurrentImplConfigRoot()
static utl::OConfigurationNode lcl_getCurrentImplConfigNode(const Reference< css::frame::XFrame > &xFrame, utl::OConfigurationTreeRoot const &rNotebookbarNode)
IMPL_STATIC_LINK(SfxNotebookBar, VclDisposeHdl, const SfxViewShell *, pViewShell, void)
static OUString lcl_getNotebookbarFileName(vcl::EnumContext::Application eApp)
static void lcl_setNotebookbarFileName(vcl::EnumContext::Application eApp, const OUString &sFileName)
static void NotebookbarAddonValues(std::vector< Image > &aImageValues, std::vector< css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > > &aExtensionValues)
const char MERGE_NOTEBOOKBAR_URL[]
static OUString lcl_getAppName(vcl::EnumContext::Application eApp)
SAL_DLLPRIVATE SfxDispatcher * GetDispatcher_Impl()
Definition: bindings.hxx:180
void Update(sal_uInt16 nId)
Definition: bindings.cxx:302
void Invalidate(sal_uInt16 nId)
Definition: bindings.cxx:639
SfxViewFrame * GetFrame() const
Returns a pointer to the <SfxViewFrame> instance, which belongs to this SfxDispatcher.
Definition: dispatch.cxx:557
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
Definition: frame.cxx:515
SystemWindow * GetSystemWindow() const
Definition: frame2.cxx:336
static SAL_WARN_UNUSED_RESULT SfxViewFrame * Current()
Definition: viewfrm.cxx:1975
vcl::Window & GetWindow() const
Definition: viewfrm.cxx:2792
SfxBindings & GetBindings()
Definition: viewfrm.hxx:110
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:2006
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:1983
SfxFrame & GetFrame() const
Definition: viewfrm.cxx:2782
One SfxViewShell more or less represents one edit window for a document, there can be multiple ones f...
Definition: viewsh.hxx:165
const LanguageTag & GetLOKLocale() const
Get the LibreOfficeKit locale of this view.
Definition: viewsh.hxx:462
SfxViewFrame & GetViewFrame() const
Definition: viewsh.hxx:290
const LanguageTag & GetLOKLanguageTag() const
Get the LibreOfficeKit language of this view.
Definition: viewsh.hxx:440
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
Definition: viewsh.cxx:1848
void CloseNotebookBar()
void SetNotebookBar(const OUString &rUIXMLDescription, const css::uno::Reference< css::frame::XFrame > &rFrame, const NotebookBarAddonsItem &aNotebookBarAddonsItem, bool bReloadNotebookbar=false)
VclPtr< NotebookBar > const & GetNotebookBar() const
static std::shared_ptr< ConfigurationChanges > create()
Helpers for easier access to NotebookBar via the sfx2 infrastructure.
static void UnlockNotebookBar()
Method restores normal behaviour of the Notebookbar.
static void ExecMethod(SfxBindings &rBindings, const OUString &rUIName)
Function to be called from the sdi's ExecMethod.
static std::map< const SfxViewShell *, std::shared_ptr< WeldedTabbedNotebookbar > > m_pNotebookBarWeldedWrapper
static void CloseMethod(SfxBindings &rBindings)
static void ShowMenubar(bool bShow)
Show menu bar in all frames of current application.
static void LockNotebookBar()
Method temporarily blocks showing of the NotebookBar.
static bool StateMethod(SfxBindings &rBindings, std::u16string_view rUIFile, bool bReloadNotebookbar=false)
Function to be called from the sdi's StateMethod.
static void ReloadNotebookBar(std::u16string_view sUIPath)
static void ToggleMenubar()
static bool IsActive(bool bConsiderSingleToolbar=false)
static void RemoveListeners(SystemWindow const *pSysWindow)
css::uno::Sequence< OUString > getNodeNames() const noexcept
css::uno::Any getNodeValue(const OUString &_rPath) const noexcept
bool setNodeValue(const OUString &_rPath, const css::uno::Any &_rValue) const noexcept
OConfigurationNode openNode(const OUString &_rPath) const noexcept
bool commit() const noexcept
static Application GetApplicationEnum(const OUString &rsApplicationName)
virtual void Resize()
SystemWindow * GetSystemWindow() const
float u
#define SAL_WARN(area, stream)
aBuf
Definition: mgetempl.cxx:389
void setLocale(const LanguageTag &languageTag)
void setLanguageTag(const LanguageTag &languageTag)
bool getBOOL(const Any &_rAny)
Reference< XComponentContext > getProcessComponentContext()
OUString getString(const Any &_rAny)
std::vector< Image > aImageValues
std::vector< css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > > aAddonValues
Reference< XFrame > xFrame