1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <sal/config.h>
12 #include <string_view>
15 #include <vcl/layout.hxx>
16 #include <vcl/notebookbar/notebookbar.hxx>
17 #include <vcl/syswin.hxx>
18 #include <vcl/taskpanelist.hxx>
19 #include <vcl/NotebookbarContextControl.hxx>
20 #include <cppuhelper/implbase.hxx>
21 #include <comphelper/processfactory.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>
30 static OUString
getCustomizedUIRootDir()
32 OUString
sShareLayer(u
"${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/" SAL_CONFIGFILE(
33 "bootstrap") ":UserInstallation}/user/config/soffice.cfg/"_ustr
);
34 rtl::Bootstrap::expandMacros(sShareLayer
);
38 static bool doesFileExist(std::u16string_view sUIDir
, std::u16string_view sUIFile
)
40 OUString sUri
= OUString::Concat(sUIDir
) + sUIFile
;
42 return( file
.open(0) == osl::FileBase::E_None
);
46 * split from the main class since it needs different ref-counting mana
48 class NotebookBarContextChangeEventListener
: public ::cppu::WeakImplHelper
<css::ui::XContextChangeEventListener
, css::frame::XFrameActionListener
>
51 VclPtr
<NotebookBar
> mpParent
;
52 css::uno::Reference
<css::frame::XFrame
> mxFrame
;
54 NotebookBarContextChangeEventListener(NotebookBar
*p
, css::uno::Reference
<css::frame::XFrame
> xFrame
) :
57 mxFrame(std::move(xFrame
))
60 void setupFrameListener(bool bListen
);
61 void setupListener(bool bListen
);
63 // XContextChangeEventListener
64 virtual void SAL_CALL
notifyContextChangeEvent(const css::ui::ContextChangeEventObject
& rEvent
) override
;
66 // XFrameActionListener
67 virtual void SAL_CALL
frameAction(const css::frame::FrameActionEvent
& rEvent
) override
;
69 virtual void SAL_CALL
disposing(const ::css::lang::EventObject
&) override
;
72 NotebookBar::NotebookBar(Window
* pParent
, const OUString
& rID
, const OUString
& rUIXMLDescription
,
73 const css::uno::Reference
<css::frame::XFrame
>& rFrame
,
74 const NotebookBarAddonsItem
& aNotebookBarAddonsItem
)
76 , m_pEventListener(new NotebookBarContextChangeEventListener(this, rFrame
))
77 , m_pViewShell(nullptr)
79 , m_sUIXMLDescription(rUIXMLDescription
)
81 m_pEventListener
->setupFrameListener(true);
83 SetStyle(GetStyle() | WB_DIALOGCONTROL
);
84 OUString sUIDir
= AllSettings::GetUIRootDir();
85 bool doesCustomizedUIExist
= doesFileExist(getCustomizedUIRootDir(), rUIXMLDescription
);
86 if ( doesCustomizedUIExist
)
87 sUIDir
= getCustomizedUIRootDir();
89 bool bIsWelded
= comphelper::LibreOfficeKit::isActive();
93 m_xVclContentArea
= VclPtr
<VclVBox
>::Create(this);
94 m_xVclContentArea
->Show();
95 // now access it using GetMainContainer and set dispose callback with SetDisposeCallback
100 new VclBuilder(this, sUIDir
, rUIXMLDescription
, rID
, rFrame
, true, &aNotebookBarAddonsItem
));
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;
109 OUString aName
= u
"ContextContainer"_ustr
;
111 aName
+= OUString::number(i
);
113 pContextContainer
= dynamic_cast<NotebookbarContextControl
*>(m_pUIBuilder
->get
<Window
>(aName
));
114 if (pContextContainer
)
115 m_pContextContainers
.push_back(pContextContainer
);
118 while( pContextContainer
!= nullptr );
124 void NotebookBar::SetDisposeCallback(const Link
<const SfxViewShell
*, void> rDisposeCallback
, const SfxViewShell
* pViewShell
)
126 m_rDisposeLink
= rDisposeCallback
;
127 m_pViewShell
= pViewShell
;
130 NotebookBar::~NotebookBar()
135 void NotebookBar::dispose()
137 m_pContextContainers
.clear();
138 if (m_pSystemWindow
&& m_pSystemWindow
->ImplIsInTaskPaneList(this))
139 m_pSystemWindow
->GetTaskPaneList()->RemoveWindow(this);
140 m_pSystemWindow
.clear();
142 if (m_rDisposeLink
.IsSet())
143 m_rDisposeLink
.Call(m_pViewShell
);
146 m_xVclContentArea
.disposeAndClear();
150 m_pEventListener
->setupFrameListener(false);
151 m_pEventListener
->setupListener(false);
152 m_pEventListener
.clear();
157 bool NotebookBar::PreNotify(NotifyEvent
& rNEvt
)
159 // capture KeyEvents for taskpane cycling
160 if (rNEvt
.GetType() == NotifyEventType::KEYINPUT
)
163 return m_pSystemWindow
->PreNotify(rNEvt
);
165 return Window::PreNotify( rNEvt
);
168 Size
NotebookBar::GetOptimalSize() const
170 if (isLayoutEnabled(this))
171 return VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild
));
173 return Control::GetOptimalSize();
176 void NotebookBar::setPosSizePixel(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
, PosSizeFlags nFlags
)
178 bool bCanHandleSmallerWidth
= false;
179 bool bCanHandleSmallerHeight
= false;
181 bool bIsLayoutEnabled
= isLayoutEnabled(this);
182 Window
*pChild
= GetWindow(GetWindowType::FirstChild
);
184 if (bIsLayoutEnabled
&& pChild
->GetType() == WindowType::SCROLLWINDOW
)
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;
193 Size
aSize(GetOptimalSize());
194 if (!bCanHandleSmallerWidth
)
195 nWidth
= std::max(nWidth
, aSize
.Width());
196 if (!bCanHandleSmallerHeight
)
197 nHeight
= std::max(nHeight
, aSize
.Height());
199 Control::setPosSizePixel(nX
, nY
, nWidth
, nHeight
, nFlags
);
201 if (bIsLayoutEnabled
&& (nFlags
& PosSizeFlags::Size
))
202 VclContainer::setLayoutAllocation(*pChild
, Point(0, 0), Size(nWidth
, nHeight
));
205 void NotebookBar::Resize()
207 if(m_pUIBuilder
&& m_pUIBuilder
->get_widget_root())
209 vcl::Window
* pWindow
= m_pUIBuilder
->get_widget_root()->GetChild(0);
212 Size aSize
= pWindow
->GetSizePixel();
213 aSize
.setWidth( GetSizePixel().Width() );
214 pWindow
->SetSizePixel(aSize
);
219 vcl::Window
* pChild
= GetWindow(GetWindowType::FirstChild
);
221 VclContainer::setLayoutAllocation(*pChild
, Point(0, 0), GetSizePixel());
227 void NotebookBar::SetSystemWindow(SystemWindow
* pSystemWindow
)
229 m_pSystemWindow
= pSystemWindow
;
230 if (!m_pSystemWindow
->ImplIsInTaskPaneList(this))
231 m_pSystemWindow
->GetTaskPaneList()->AddWindow(this);
234 void SAL_CALL
NotebookBarContextChangeEventListener::notifyContextChangeEvent(const css::ui::ContextChangeEventObject
& rEvent
)
238 for (NotebookbarContextControl
* pControl
: mpParent
->m_pContextContainers
)
239 pControl
->SetContext(vcl::EnumContext::GetContextEnum(rEvent
.ContextName
));
243 void NotebookBarContextChangeEventListener::setupListener(bool bListen
)
245 if (comphelper::LibreOfficeKit::isActive())
248 auto xMultiplexer(css::ui::ContextChangeEventMultiplexer::get(::comphelper::getProcessComponentContext()));
254 xMultiplexer
->addContextChangeEventListener(this, mxFrame
->getController());
256 catch (const css::uno::Exception
&)
261 xMultiplexer
->removeAllContextChangeEventListeners(this);
266 void NotebookBarContextChangeEventListener::setupFrameListener(bool bListen
)
269 mxFrame
->addFrameActionListener(this);
271 mxFrame
->removeFrameActionListener(this);
274 void SAL_CALL
NotebookBarContextChangeEventListener::frameAction(const css::frame::FrameActionEvent
& rEvent
)
279 if (rEvent
.Action
== css::frame::FrameAction_COMPONENT_REATTACHED
)
283 else if (rEvent
.Action
== css::frame::FrameAction_COMPONENT_DETACHING
)
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.
292 void NotebookBar::SetupListener(bool bListen
)
294 m_pEventListener
->setupListener(bListen
);
297 void SAL_CALL
NotebookBarContextChangeEventListener::disposing(const ::css::lang::EventObject
&)
302 void NotebookBar::DataChanged(const DataChangedEvent
& rDCEvt
)
305 Control::DataChanged(rDCEvt
);
308 void NotebookBar::StateChanged(const StateChangedType nStateChange
)
311 Control::StateChanged(nStateChange
);
315 void NotebookBar::UpdateBackground()
317 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
318 SetBackground(rStyleSettings
.GetDialogColor());
319 UpdateDefaultSettings();
320 GetOutDev()->SetSettings( DefaultSettings
);
322 Invalidate(tools::Rectangle(Point(0,0), GetSizePixel()));
325 void NotebookBar::UpdateDefaultSettings()
327 AllSettings
aAllSettings( GetSettings() );
328 StyleSettings
aStyleSet( aAllSettings
.GetStyleSettings() );
330 ::Color aTextColor
= aStyleSet
.GetFieldTextColor();
331 aStyleSet
.SetDialogTextColor( aTextColor
);
332 aStyleSet
.SetButtonTextColor( aTextColor
);
333 aStyleSet
.SetRadioCheckTextColor( aTextColor
);
334 aStyleSet
.SetGroupTextColor( aTextColor
);
335 aStyleSet
.SetLabelTextColor( aTextColor
);
336 aStyleSet
.SetWindowTextColor( aTextColor
);
337 aStyleSet
.SetTabTextColor(aTextColor
);
338 aStyleSet
.SetToolTextColor(aTextColor
);
340 aAllSettings
.SetStyleSettings(aStyleSet
);
341 DefaultSettings
= std::move(aAllSettings
);
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */