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 <vcl/layout.hxx>
11 #include <vcl/notebookbar.hxx>
12 #include <vcl/syswin.hxx>
13 #include <vcl/taskpanelist.hxx>
14 #include <vcl/NotebookbarContextControl.hxx>
15 #include <cppuhelper/implbase.hxx>
16 #include <comphelper/processfactory.hxx>
17 #include <rtl/bootstrap.hxx>
18 #include <osl/file.hxx>
19 #include <config_folders.h>
20 #include <com/sun/star/frame/XFrame.hpp>
21 #include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
22 #include <comphelper/lok.hxx>
24 static OUString
getCustomizedUIRootDir()
26 OUString
sShareLayer("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/" SAL_CONFIGFILE(
27 "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
28 rtl::Bootstrap::expandMacros(sShareLayer
);
32 static bool doesFileExist(const OUString
& sUIDir
, const OUString
& sUIFile
)
34 OUString sUri
= sUIDir
+ sUIFile
;
36 return( file
.open(0) == osl::FileBase::E_None
);
40 * split from the main class since it needs different ref-counting mana
42 class NotebookBarContextChangeEventListener
: public ::cppu::WeakImplHelper
<css::ui::XContextChangeEventListener
>
44 VclPtr
<NotebookBar
> mpParent
;
46 explicit NotebookBarContextChangeEventListener(NotebookBar
*p
) : mpParent(p
) {}
48 // XContextChangeEventListener
49 virtual void SAL_CALL
notifyContextChangeEvent(const css::ui::ContextChangeEventObject
& rEvent
) override
;
51 virtual void SAL_CALL
disposing(const ::css::lang::EventObject
&) override
;
54 NotebookBar::NotebookBar(Window
* pParent
, const OString
& rID
, const OUString
& rUIXMLDescription
,
55 const css::uno::Reference
<css::frame::XFrame
>& rFrame
,
56 const NotebookBarAddonsItem
& aNotebookBarAddonsItem
)
58 , m_pEventListener(new NotebookBarContextChangeEventListener(this))
59 , m_pViewShell(nullptr)
61 , m_sUIXMLDescription(rUIXMLDescription
)
65 SetStyle(GetStyle() | WB_DIALOGCONTROL
);
66 OUString sUIDir
= AllSettings::GetUIRootDir();
67 bool doesCustomizedUIExist
= doesFileExist(getCustomizedUIRootDir(), rUIXMLDescription
);
68 if ( doesCustomizedUIExist
)
69 sUIDir
= getCustomizedUIRootDir();
71 bool bIsWelded
= comphelper::LibreOfficeKit::isActive()
72 && (rUIXMLDescription
== "modules/swriter/ui/notebookbar.ui"
73 || rUIXMLDescription
== "modules/scalc/ui/notebookbar.ui"
74 || rUIXMLDescription
== "modules/simpress/ui/notebookbar.ui");
78 m_xVclContentArea
= VclPtr
<VclVBox
>::Create(this);
79 m_xVclContentArea
->Show();
80 // now access it using GetMainContainer and set dispose callback with SetDisposeCallback
85 new VclBuilder(this, sUIDir
, rUIXMLDescription
, rID
, rFrame
, true, &aNotebookBarAddonsItem
));
87 // In the Notebookbar's .ui file must exist control handling context
88 // - implementing NotebookbarContextControl interface with id "ContextContainer"
89 // or "ContextContainerX" where X is a number >= 1
90 NotebookbarContextControl
* pContextContainer
= nullptr;
94 OUString aName
= "ContextContainer";
96 aName
+= OUString::number(i
);
98 pContextContainer
= dynamic_cast<NotebookbarContextControl
*>(m_pUIBuilder
->get
<Window
>(OUStringToOString(aName
, RTL_TEXTENCODING_UTF8
)));
99 if (pContextContainer
)
100 m_pContextContainers
.push_back(pContextContainer
);
103 while( pContextContainer
!= nullptr );
109 void NotebookBar::SetDisposeCallback(const Link
<const SfxViewShell
*, void> rDisposeCallback
, const SfxViewShell
* pViewShell
)
111 m_rDisposeLink
= rDisposeCallback
;
112 m_pViewShell
= pViewShell
;
115 NotebookBar::~NotebookBar()
120 void NotebookBar::dispose()
122 m_pContextContainers
.clear();
123 if (m_pSystemWindow
&& m_pSystemWindow
->ImplIsInTaskPaneList(this))
124 m_pSystemWindow
->GetTaskPaneList()->RemoveWindow(this);
125 m_pSystemWindow
.clear();
127 if (m_rDisposeLink
.IsSet())
128 m_rDisposeLink
.Call(m_pViewShell
);
131 m_xVclContentArea
.disposeAndClear();
135 assert(m_alisteningControllers
.empty());
136 m_pEventListener
.clear();
141 bool NotebookBar::PreNotify(NotifyEvent
& rNEvt
)
143 // capture KeyEvents for taskpane cycling
144 if (rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
147 return m_pSystemWindow
->PreNotify(rNEvt
);
149 return Window::PreNotify( rNEvt
);
152 Size
NotebookBar::GetOptimalSize() const
154 if (isLayoutEnabled(this))
155 return VclContainer::getLayoutRequisition(*GetWindow(GetWindowType::FirstChild
));
157 return Control::GetOptimalSize();
160 void NotebookBar::setPosSizePixel(tools::Long nX
, tools::Long nY
, tools::Long nWidth
, tools::Long nHeight
, PosSizeFlags nFlags
)
162 bool bCanHandleSmallerWidth
= false;
163 bool bCanHandleSmallerHeight
= false;
165 bool bIsLayoutEnabled
= isLayoutEnabled(this);
166 Window
*pChild
= GetWindow(GetWindowType::FirstChild
);
168 if (bIsLayoutEnabled
&& pChild
->GetType() == WindowType::SCROLLWINDOW
)
170 WinBits nStyle
= pChild
->GetStyle();
171 if (nStyle
& (WB_AUTOHSCROLL
| WB_HSCROLL
))
172 bCanHandleSmallerWidth
= true;
173 if (nStyle
& (WB_AUTOVSCROLL
| WB_VSCROLL
))
174 bCanHandleSmallerHeight
= true;
177 Size
aSize(GetOptimalSize());
178 if (!bCanHandleSmallerWidth
)
179 nWidth
= std::max(nWidth
, aSize
.Width());
180 if (!bCanHandleSmallerHeight
)
181 nHeight
= std::max(nHeight
, aSize
.Height());
183 Control::setPosSizePixel(nX
, nY
, nWidth
, nHeight
, nFlags
);
185 if (bIsLayoutEnabled
&& (nFlags
& PosSizeFlags::Size
))
186 VclContainer::setLayoutAllocation(*pChild
, Point(0, 0), Size(nWidth
, nHeight
));
189 void NotebookBar::Resize()
191 if(m_pUIBuilder
&& m_pUIBuilder
->get_widget_root())
193 vcl::Window
* pWindow
= m_pUIBuilder
->get_widget_root()->GetChild(0);
196 Size aSize
= pWindow
->GetSizePixel();
197 aSize
.setWidth( GetSizePixel().Width() );
198 pWindow
->SetSizePixel(aSize
);
203 vcl::Window
* pChild
= GetWindow(GetWindowType::FirstChild
);
205 VclContainer::setLayoutAllocation(*pChild
, Point(0, 0), GetSizePixel());
211 void NotebookBar::SetSystemWindow(SystemWindow
* pSystemWindow
)
213 m_pSystemWindow
= pSystemWindow
;
214 if (!m_pSystemWindow
->ImplIsInTaskPaneList(this))
215 m_pSystemWindow
->GetTaskPaneList()->AddWindow(this);
218 void SAL_CALL
NotebookBarContextChangeEventListener::notifyContextChangeEvent(const css::ui::ContextChangeEventObject
& rEvent
)
222 for (NotebookbarContextControl
* pControl
: mpParent
->m_pContextContainers
)
223 pControl
->SetContext(vcl::EnumContext::GetContextEnum(rEvent
.ContextName
));
227 void NotebookBar::ControlListenerForCurrentController(bool bListen
)
229 if (comphelper::LibreOfficeKit::isActive())
232 auto xController
= mxFrame
->getController();
236 if (m_alisteningControllers
.count(xController
) == 0)
238 auto xMultiplexer(css::ui::ContextChangeEventMultiplexer::get(
239 ::comphelper::getProcessComponentContext()));
240 xMultiplexer
->addContextChangeEventListener(m_pEventListener
, xController
);
241 m_alisteningControllers
.insert(xController
);
247 if (m_alisteningControllers
.count(xController
))
249 auto xMultiplexer(css::ui::ContextChangeEventMultiplexer::get(
250 ::comphelper::getProcessComponentContext()));
251 xMultiplexer
->removeContextChangeEventListener(m_pEventListener
, xController
);
252 m_alisteningControllers
.erase(xController
);
257 void NotebookBar::StopListeningAllControllers()
259 if (comphelper::LibreOfficeKit::isActive())
263 css::ui::ContextChangeEventMultiplexer::get(comphelper::getProcessComponentContext()));
264 xMultiplexer
->removeAllContextChangeEventListeners(m_pEventListener
);
265 m_alisteningControllers
.clear();
268 void SAL_CALL
NotebookBarContextChangeEventListener::disposing(const ::css::lang::EventObject
&)
273 void NotebookBar::DataChanged(const DataChangedEvent
& rDCEvt
)
276 Control::DataChanged(rDCEvt
);
279 void NotebookBar::StateChanged(const StateChangedType nStateChange
)
282 Control::StateChanged(nStateChange
);
286 void NotebookBar::UpdateBackground()
288 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
289 const BitmapEx
& aPersona
= rStyleSettings
.GetPersonaHeader();
290 Wallpaper
aWallpaper(aPersona
);
291 aWallpaper
.SetStyle(WallpaperStyle::TopRight
);
292 if (!aPersona
.IsEmpty())
294 SetBackground(aWallpaper
);
295 UpdatePersonaSettings();
296 SetSettings( PersonaSettings
);
300 SetBackground(rStyleSettings
.GetDialogColor());
301 UpdateDefaultSettings();
302 SetSettings( DefaultSettings
);
305 Invalidate(tools::Rectangle(Point(0,0), GetSizePixel()));
308 void NotebookBar::UpdateDefaultSettings()
310 AllSettings
aAllSettings( GetSettings() );
311 StyleSettings
aStyleSet( aAllSettings
.GetStyleSettings() );
313 ::Color aTextColor
= aStyleSet
.GetFieldTextColor();
314 aStyleSet
.SetDialogTextColor( aTextColor
);
315 aStyleSet
.SetButtonTextColor( aTextColor
);
316 aStyleSet
.SetRadioCheckTextColor( aTextColor
);
317 aStyleSet
.SetGroupTextColor( aTextColor
);
318 aStyleSet
.SetLabelTextColor( aTextColor
);
319 aStyleSet
.SetWindowTextColor( aTextColor
);
320 aStyleSet
.SetTabTextColor(aTextColor
);
321 aStyleSet
.SetToolTextColor(aTextColor
);
323 aAllSettings
.SetStyleSettings(aStyleSet
);
324 DefaultSettings
= aAllSettings
;
327 void NotebookBar::UpdatePersonaSettings()
329 AllSettings
aAllSettings( GetSettings() );
330 StyleSettings
aStyleSet( aAllSettings
.GetStyleSettings() );
332 ::Color aTextColor
= aStyleSet
.GetPersonaMenuBarTextColor().value_or(COL_BLACK
);
333 aStyleSet
.SetDialogTextColor( aTextColor
);
334 aStyleSet
.SetButtonTextColor( aTextColor
);
335 aStyleSet
.SetRadioCheckTextColor( aTextColor
);
336 aStyleSet
.SetGroupTextColor( aTextColor
);
337 aStyleSet
.SetLabelTextColor( aTextColor
);
338 aStyleSet
.SetWindowTextColor( aTextColor
);
339 aStyleSet
.SetTabTextColor(aTextColor
);
340 aStyleSet
.SetToolTextColor(aTextColor
);
342 aAllSettings
.SetStyleSettings(aStyleSet
);
343 PersonaSettings
= aAllSettings
;
346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */