LibreOffice Module vcl (master) 1
notebookbar.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 <sal/config.h>
11
12#include <string_view>
13#include <utility>
14
15#include <vcl/layout.hxx>
17#include <vcl/syswin.hxx>
18#include <vcl/taskpanelist.hxx>
22#include <rtl/bootstrap.hxx>
23#include <osl/file.hxx>
24#include <config_folders.h>
25#include <com/sun/star/frame/XFrame.hpp>
26#include <com/sun/star/frame/FrameAction.hpp>
27#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
28#include <comphelper/lok.hxx>
29
30static OUString getCustomizedUIRootDir()
31{
32 OUString sShareLayer("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE(
33 "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
34 rtl::Bootstrap::expandMacros(sShareLayer);
35 return sShareLayer;
36}
37
38static bool doesFileExist(std::u16string_view sUIDir, std::u16string_view sUIFile)
39{
40 OUString sUri = OUString::Concat(sUIDir) + sUIFile;
41 osl::File file(sUri);
42 return( file.open(0) == osl::FileBase::E_None );
43}
44
48class NotebookBarContextChangeEventListener : public ::cppu::WeakImplHelper<css::ui::XContextChangeEventListener, css::frame::XFrameActionListener>
49{
52 css::uno::Reference<css::frame::XFrame> mxFrame;
53public:
54 NotebookBarContextChangeEventListener(NotebookBar *p, css::uno::Reference<css::frame::XFrame> xFrame) :
55 mbActive(false),
56 mpParent(p),
57 mxFrame(std::move(xFrame))
58 {}
59
60 void setupFrameListener(bool bListen);
61 void setupListener(bool bListen);
62
63 // XContextChangeEventListener
64 virtual void SAL_CALL notifyContextChangeEvent(const css::ui::ContextChangeEventObject& rEvent) override;
65
66 // XFrameActionListener
67 virtual void SAL_CALL frameAction(const css::frame::FrameActionEvent& rEvent) override;
68
69 virtual void SAL_CALL disposing(const ::css::lang::EventObject&) override;
70};
71
72NotebookBar::NotebookBar(Window* pParent, const OString& rID, const OUString& rUIXMLDescription,
73 const css::uno::Reference<css::frame::XFrame>& rFrame,
74 const NotebookBarAddonsItem& aNotebookBarAddonsItem)
75 : Control(pParent)
76 , m_pEventListener(new NotebookBarContextChangeEventListener(this, rFrame))
77 , m_pViewShell(nullptr)
78 , m_bIsWelded(false)
79 , m_sUIXMLDescription(rUIXMLDescription)
80{
81 m_pEventListener->setupFrameListener(true);
82
84 OUString sUIDir = AllSettings::GetUIRootDir();
85 bool doesCustomizedUIExist = doesFileExist(getCustomizedUIRootDir(), rUIXMLDescription);
86 if ( doesCustomizedUIExist )
87 sUIDir = getCustomizedUIRootDir();
88
89 bool bIsWelded = comphelper::LibreOfficeKit::isActive();
90 if (bIsWelded)
91 {
92 m_bIsWelded = true;
95 // now access it using GetMainContainer and set dispose callback with SetDisposeCallback
96 }
97 else
98 {
99 m_pUIBuilder.reset(
100 new VclBuilder(this, sUIDir, rUIXMLDescription, rID, rFrame, true, &aNotebookBarAddonsItem));
101
102 // In the Notebookbar's .ui file must exist control handling context
103 // - implementing NotebookbarContextControl interface with id "ContextContainer"
104 // or "ContextContainerX" where X is a number >= 1
105 NotebookbarContextControl* pContextContainer = nullptr;
106 int i = 0;
107 do
108 {
109 OUString aName = "ContextContainer";
110 if (i)
111 aName += OUString::number(i);
112
113 pContextContainer = dynamic_cast<NotebookbarContextControl*>(m_pUIBuilder->get<Window>(OUStringToOString(aName, RTL_TEXTENCODING_UTF8)));
114 if (pContextContainer)
115 m_pContextContainers.push_back(pContextContainer);
116 i++;
117 }
118 while( pContextContainer != nullptr );
119 }
120
122}
123
125{
126 m_rDisposeLink = rDisposeCallback;
127 m_pViewShell = pViewShell;
128}
129
131{
132 disposeOnce();
133}
134
136{
137 m_pContextContainers.clear();
141
142 if (m_rDisposeLink.IsSet())
144
145 if (m_bIsWelded)
147 else
148 disposeBuilder();
149
150 m_pEventListener->setupFrameListener(false);
151 m_pEventListener->setupListener(false);
152 m_pEventListener.clear();
153
155}
156
158{
159 // capture KeyEvents for taskpane cycling
160 if (rNEvt.GetType() == NotifyEventType::KEYINPUT)
161 {
162 if (m_pSystemWindow)
163 return m_pSystemWindow->PreNotify(rNEvt);
164 }
165 return Window::PreNotify( rNEvt );
166}
167
169{
170 if (isLayoutEnabled(this))
172
174}
175
177{
178 bool bCanHandleSmallerWidth = false;
179 bool bCanHandleSmallerHeight = false;
180
181 bool bIsLayoutEnabled = isLayoutEnabled(this);
183
184 if (bIsLayoutEnabled && pChild->GetType() == WindowType::SCROLLWINDOW)
185 {
186 WinBits nStyle = pChild->GetStyle();
187 if (nStyle & (WB_AUTOHSCROLL | WB_HSCROLL))
188 bCanHandleSmallerWidth = true;
189 if (nStyle & (WB_AUTOVSCROLL | WB_VSCROLL))
190 bCanHandleSmallerHeight = true;
191 }
192
193 Size aSize(GetOptimalSize());
194 if (!bCanHandleSmallerWidth)
195 nWidth = std::max(nWidth, aSize.Width());
196 if (!bCanHandleSmallerHeight)
197 nHeight = std::max(nHeight, aSize.Height());
198
199 Control::setPosSizePixel(nX, nY, nWidth, nHeight, nFlags);
200
201 if (bIsLayoutEnabled && (nFlags & PosSizeFlags::Size))
202 VclContainer::setLayoutAllocation(*pChild, Point(0, 0), Size(nWidth, nHeight));
203}
204
206{
207 if(m_pUIBuilder && m_pUIBuilder->get_widget_root())
208 {
209 vcl::Window* pWindow = m_pUIBuilder->get_widget_root()->GetChild(0);
210 if (pWindow)
211 {
212 Size aSize = pWindow->GetSizePixel();
213 aSize.setWidth( GetSizePixel().Width() );
214 pWindow->SetSizePixel(aSize);
215 }
216 }
217 if(m_bIsWelded)
218 {
220 assert(pChild);
223 }
225}
226
228{
229 m_pSystemWindow = pSystemWindow;
232}
233
234void SAL_CALL NotebookBarContextChangeEventListener::notifyContextChangeEvent(const css::ui::ContextChangeEventObject& rEvent)
235{
236 if (mpParent)
237 {
238 for (NotebookbarContextControl* pControl : mpParent->m_pContextContainers)
239 pControl->SetContext(vcl::EnumContext::GetContextEnum(rEvent.ContextName));
240 }
241}
242
244{
246 return;
247
248 auto xMultiplexer(css::ui::ContextChangeEventMultiplexer::get(::comphelper::getProcessComponentContext()));
249
250 if (bListen)
251 {
252 try
253 {
254 xMultiplexer->addContextChangeEventListener(this, mxFrame->getController());
255 }
256 catch (const css::uno::Exception&)
257 {
258 }
259 }
260 else
261 xMultiplexer->removeAllContextChangeEventListeners(this);
262
263 mbActive = bListen;
264}
265
267{
268 if (bListen)
269 mxFrame->addFrameActionListener(this);
270 else
271 mxFrame->removeFrameActionListener(this);
272}
273
274void SAL_CALL NotebookBarContextChangeEventListener::frameAction(const css::frame::FrameActionEvent& rEvent)
275{
276 if (!mbActive)
277 return;
278
279 if (rEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED)
280 {
281 setupListener(true);
282 }
283 else if (rEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING)
284 {
285 setupListener(false);
286 // We don't want to give up on listening; just wait for
287 // another controller to be attached to the frame.
288 mbActive = true;
289 }
290}
291
293{
294 m_pEventListener->setupListener(bListen);
295}
296
297void SAL_CALL NotebookBarContextChangeEventListener::disposing(const ::css::lang::EventObject&)
298{
299 mpParent.clear();
300}
301
303{
305 Control::DataChanged(rDCEvt);
306}
307
309{
311 Control::StateChanged(nStateChange);
312 Invalidate();
313}
314
316{
317 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
318 const BitmapEx& aPersona = rStyleSettings.GetPersonaHeader();
319 Wallpaper aWallpaper(aPersona);
321 if (!aPersona.IsEmpty())
322 {
323 SetBackground(aWallpaper);
326 }
327 else
328 {
329 SetBackground(rStyleSettings.GetDialogColor());
332 }
333
335}
336
338{
339 AllSettings aAllSettings( GetSettings() );
340 StyleSettings aStyleSet( aAllSettings.GetStyleSettings() );
341
342 ::Color aTextColor = aStyleSet.GetFieldTextColor();
343 aStyleSet.SetDialogTextColor( aTextColor );
344 aStyleSet.SetButtonTextColor( aTextColor );
345 aStyleSet.SetRadioCheckTextColor( aTextColor );
346 aStyleSet.SetGroupTextColor( aTextColor );
347 aStyleSet.SetLabelTextColor( aTextColor );
348 aStyleSet.SetWindowTextColor( aTextColor );
349 aStyleSet.SetTabTextColor(aTextColor);
350 aStyleSet.SetToolTextColor(aTextColor);
351
352 aAllSettings.SetStyleSettings(aStyleSet);
353 DefaultSettings = aAllSettings;
354}
355
357{
358 AllSettings aAllSettings( GetSettings() );
359 StyleSettings aStyleSet( aAllSettings.GetStyleSettings() );
360
361 ::Color aTextColor = aStyleSet.GetPersonaMenuBarTextColor().value_or(COL_BLACK );
362 aStyleSet.SetDialogTextColor( aTextColor );
363 aStyleSet.SetButtonTextColor( aTextColor );
364 aStyleSet.SetRadioCheckTextColor( aTextColor );
365 aStyleSet.SetGroupTextColor( aTextColor );
366 aStyleSet.SetLabelTextColor( aTextColor );
367 aStyleSet.SetWindowTextColor( aTextColor );
368 aStyleSet.SetTabTextColor(aTextColor);
369 aStyleSet.SetToolTextColor(aTextColor);
370
371 aAllSettings.SetStyleSettings(aStyleSet);
372 PersonaSettings = aAllSettings;
373}
374
375/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const StyleSettings & GetStyleSettings() const
void SetStyleSettings(const StyleSettings &rSet)
static OUString GetUIRootDir()
Definition: dialog.cxx:557
bool IsEmpty() const
Definition: BitmapEx.cxx:177
Definition: ctrl.hxx:82
virtual void StateChanged(StateChangedType nStateChange) override
Definition: ctrl.cxx:257
virtual void Resize() override
Definition: ctrl.cxx:75
virtual Size GetOptimalSize() const override
Definition: ctrl.cxx:370
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
Definition: ctrl.cxx:59
split from the main class since it needs different ref-counting mana
Definition: notebookbar.cxx:49
css::uno::Reference< css::frame::XFrame > mxFrame
Definition: notebookbar.cxx:52
virtual void SAL_CALL disposing(const ::css::lang::EventObject &) override
virtual void SAL_CALL notifyContextChangeEvent(const css::ui::ContextChangeEventObject &rEvent) override
NotebookBarContextChangeEventListener(NotebookBar *p, css::uno::Reference< css::frame::XFrame > xFrame)
Definition: notebookbar.cxx:54
virtual void SAL_CALL frameAction(const css::frame::FrameActionEvent &rEvent) override
This implements Widget Layout-based notebook-like menu bar.
Definition: notebookbar.hxx:28
rtl::Reference< NotebookBarContextChangeEventListener > m_pEventListener
Definition: notebookbar.hxx:57
bool m_bIsWelded
Definition: notebookbar.hxx:62
virtual void Resize() override
virtual void setPosSizePixel(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags=PosSizeFlags::All) override
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
VclPtr< vcl::Window > m_xVclContentArea
Definition: notebookbar.hxx:61
virtual bool PreNotify(NotifyEvent &rNEvt) override
virtual Size GetOptimalSize() const override
void UpdateBackground()
const SfxViewShell * m_pViewShell
Definition: notebookbar.hxx:59
void SetSystemWindow(SystemWindow *pSystemWindow)
void StateChanged(const StateChangedType nStateChange) override
void UpdatePersonaSettings()
AllSettings PersonaSettings
Definition: notebookbar.hxx:67
Link< const SfxViewShell *, void > m_rDisposeLink
Definition: notebookbar.hxx:64
void SetupListener(bool bListen)
void DataChanged(const DataChangedEvent &rDCEvt) override
VclPtr< SystemWindow > m_pSystemWindow
Definition: notebookbar.hxx:56
void SetDisposeCallback(const Link< const SfxViewShell *, void > rDisposeCallback, const SfxViewShell *pViewShell)
AllSettings DefaultSettings
Definition: notebookbar.hxx:66
NotebookBar(Window *pParent, const OString &rID, const OUString &rUIXMLDescription, const css::uno::Reference< css::frame::XFrame > &rFrame, const NotebookBarAddonsItem &aNotebookBarAddonsItem)
Definition: notebookbar.cxx:72
std::vector< NotebookbarContextControl * > m_pContextContainers
Definition: notebookbar.hxx:58
virtual ~NotebookBar() override
void UpdateDefaultSettings()
NotifyEventType GetType() const
Definition: event.hxx:308
virtual void SetSettings(const AllSettings &rSettings)
Definition: outdev.cxx:215
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
constexpr tools::Long Width() const
const std::optional< Color > & GetPersonaMenuBarTextColor() const
void SetGroupTextColor(const Color &rColor)
BitmapEx const & GetPersonaHeader() const
const Color & GetFieldTextColor() const
void SetTabTextColor(const Color &rColor)
void SetRadioCheckTextColor(const Color &rColor)
const Color & GetDialogColor() const
void SetLabelTextColor(const Color &rColor)
void SetButtonTextColor(const Color &rColor)
void SetWindowTextColor(const Color &rColor)
void SetToolTextColor(const Color &rColor)
void SetDialogTextColor(const Color &rColor)
SAL_DLLPRIVATE bool ImplIsInTaskPaneList(vcl::Window *pWin)
Definition: syswin.cxx:955
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: syswin.cxx:198
TaskPaneList * GetTaskPaneList()
Definition: syswin.cxx:240
void AddWindow(vcl::Window *pWindow)
void RemoveWindow(vcl::Window *pWindow)
Creates a hierarchy of vcl::Windows (widgets) from a .ui file for dialogs, sidebar,...
Definition: builder.hxx:69
static void setLayoutAllocation(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
Definition: layout.cxx:95
static Size getLayoutRequisition(const vcl::Window &rWindow)
Definition: layout.cxx:170
void disposeAndClear()
Definition: vclptr.hxx:200
void clear()
Definition: vclptr.hxx:190
static VclPtr< reference_type > Create(Arg &&... arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
void SetStyle(WallpaperStyle eStyle)
Definition: wall.cxx:165
static Context GetContextEnum(const OUString &rsContextName)
void SetStyle(WinBits nStyle)
Definition: window.cxx:1966
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1293
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
WinBits GetStyle() const
Definition: window2.cxx:984
const AllSettings & GetSettings() const
Definition: window3.cxx:129
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2191
Window(WindowType nType)
Definition: window.cxx:95
::OutputDevice const * GetOutDev() const
Definition: window.cxx:567
virtual void setPosSizePixel(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags=PosSizeFlags::All)
Definition: window.cxx:2670
virtual Size GetSizePixel() const
Definition: window.cxx:2406
virtual void DataChanged(const DataChangedEvent &rDCEvt)
Definition: event.cxx:36
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1143
vcl::Window * GetChild(sal_uInt16 nChild) const
Definition: stacking.cxx:1017
void SetBackground()
Definition: window3.cxx:100
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
#define SAL_CONFIGFILE(name)
OUString aName
void * p
bool isLayoutEnabled(const vcl::Window *pWindow)
Definition: layout.cxx:2923
int i
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
long Long
static OUString getCustomizedUIRootDir()
Definition: notebookbar.cxx:30
static bool doesFileExist(std::u16string_view sUIDir, std::u16string_view sUIFile)
Definition: notebookbar.cxx:38
Reference< XFrame > xFrame
PosSizeFlags
Definition: window.hxx:127
StateChangedType
Definition: window.hxx:291
sal_Int64 WinBits
Definition: wintypes.hxx:109
WinBits const WB_DIALOGCONTROL
Definition: wintypes.hxx:113
WinBits const WB_AUTOVSCROLL
Definition: wintypes.hxx:163
WinBits const WB_AUTOHSCROLL
Definition: wintypes.hxx:161
WinBits const WB_VSCROLL
Definition: wintypes.hxx:178
WinBits const WB_HSCROLL
Definition: wintypes.hxx:177