LibreOffice Module svtools (master) 1
toolbarmenu.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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <memory>
21#include <comphelper/lok.hxx>
23
24#include <utility>
25#include <vcl/taskpanelist.hxx>
26#include <vcl/svapp.hxx>
27
30
31using namespace ::com::sun::star::uno;
32using namespace ::com::sun::star::lang;
33using namespace ::com::sun::star::frame;
34using namespace ::com::sun::star::accessibility;
35
36namespace {
37
38SystemWindow* GetTopMostParentSystemWindow(const vcl::Window& rWindow)
39{
40 // ->manually search topmost system window
41 // required because their might be another system window between this and the top window
42 vcl::Window* pWindow = rWindow.GetParent();
43 SystemWindow* pTopMostSysWin = nullptr;
44 while ( pWindow )
45 {
46 if ( pWindow->IsSystemWindow() )
47 pTopMostSysWin = static_cast<SystemWindow*>(pWindow);
48 pWindow = pWindow->GetParent();
49 }
50 return pTopMostSysWin;
51}
52
53class ToolbarPopupStatusListener : public svt::FrameStatusListener
54{
55public:
56 ToolbarPopupStatusListener( const css::uno::Reference< css::frame::XFrame >& xFrame,
57 WeldToolbarPopup& rToolbarPopup );
58
59 virtual void SAL_CALL dispose() override;
60 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) override;
61
62 WeldToolbarPopup* mpPopup;
63};
64
65
66ToolbarPopupStatusListener::ToolbarPopupStatusListener(
67 const css::uno::Reference< css::frame::XFrame >& xFrame,
68 WeldToolbarPopup& rToolbarPopup )
69: svt::FrameStatusListener( ::comphelper::getProcessComponentContext(), xFrame )
70, mpPopup( &rToolbarPopup )
71{
72}
73
74
75void SAL_CALL ToolbarPopupStatusListener::dispose()
76{
77 mpPopup = nullptr;
79}
80
81
82void SAL_CALL ToolbarPopupStatusListener::statusChanged( const css::frame::FeatureStateEvent& Event )
83{
84 if( mpPopup )
85 mpPopup->statusChanged( Event );
86}
87
88}
89
90void WeldToolbarPopup::AddStatusListener(const OUString& rCommandURL)
91{
92 if (!m_xStatusListener.is())
93 m_xStatusListener.set(new ToolbarPopupStatusListener(m_xFrame, *this));
94
95 m_xStatusListener->addStatusListener(rCommandURL);
96}
97
98void WeldToolbarPopup::statusChanged(const css::frame::FeatureStateEvent& /*Event*/)
99{
100}
101
103{
105}
106
107WeldToolbarPopup::WeldToolbarPopup(css::uno::Reference<css::frame::XFrame> xFrame,
108 weld::Widget* pParent, const OUString& rUIFile,
109 const OUString& rId)
110 : m_xBuilder(Application::CreateBuilder(pParent, rUIFile))
111 , m_xTopLevel(m_xBuilder->weld_popover(rId))
112 , m_xContainer(m_xBuilder->weld_container("container"))
113 , m_xFrame(std::move(xFrame))
114{
115 m_xTopLevel->connect_focus_in(LINK(this, WeldToolbarPopup, FocusHdl));
116}
117
119{
120 if (m_xStatusListener.is())
121 m_xStatusListener->dispose();
122}
123
125{
126 GrabFocus();
127}
128
130 : m_xBuilder(Application::CreateBuilder(pParent, "svx/ui/toolbarpopover.ui"))
131 , m_xTopLevel(m_xBuilder->weld_container("ToolbarPopover"))
132 , m_xContainer(m_xBuilder->weld_container("container"))
133{
134 m_xTopLevel->connect_focus_in(LINK(this, ToolbarPopupContainer, FocusHdl));
135}
136
137void ToolbarPopupContainer::setPopover(std::unique_ptr<WeldToolbarPopup> xPopup)
138{
139 m_xPopup = std::move(xPopup);
140 // move the WeldToolbarPopup contents into this toolbar so on-demand contents can appear inside a preexisting gtk popover
141 // because the arrow for the popover is only enabled if there's a popover set
142 m_xPopup->getTopLevel()->move(m_xPopup->getContainer(), m_xContainer.get());
143
144 // in online LoseFocus event is fired due to this line and popup is closed
145 // when first time opened any popup from not focused sidebar
147 m_xPopup->GrabFocus();
148}
149
151{
152 if (!m_xPopup)
153 return;
154 m_xContainer->move(m_xPopup->getContainer(), m_xPopup->getTopLevel());
155 m_xPopup.reset();
156}
157
159{
160 unsetPopover();
161}
162
164{
165 if (m_xPopup)
166 m_xPopup->GrabFocus();
167}
168
169InterimToolbarPopup::InterimToolbarPopup(const css::uno::Reference<css::frame::XFrame>& rFrame, vcl::Window* pParent,
170 std::unique_ptr<WeldToolbarPopup> xPopup, bool bTearable)
171 : DropdownDockingWindow(pParent, rFrame, bTearable)
172 , m_xFrame(rFrame)
173 , m_xBuilder(Application::CreateInterimBuilder(m_xBox.get(), "svt/ui/interimparent.ui", false))
174 , m_xContainer(m_xBuilder->weld_container("container"))
175 , m_xPopup(std::move(xPopup))
176{
177 if (SystemWindow* pWindow = GetTopMostParentSystemWindow(*this))
178 pWindow->GetTaskPaneList()->AddWindow(this);
179
180 // move the WeldToolbarPopup contents into this interim toolbar so welded contents can appear as a dropdown in an unwelded toolbar
181 m_xPopup->getTopLevel()->move(m_xPopup->getContainer(), m_xContainer.get());
182}
183
185{
187 if (!m_xPopup)
188 return;
189 m_xPopup->GrabFocus();
190}
191
193{
194 if (SystemWindow* pWindow = GetTopMostParentSystemWindow(*this))
195 pWindow->GetTaskPaneList()->RemoveWindow(this);
196
197 // if we have focus when disposed, pick the document window as destination
198 // for focus rather than let it go to an arbitrary windows
199 if (HasFocus())
200 {
201 if (auto xWindow = m_xFrame->getContainerWindow())
202 xWindow->setFocus();
203 }
204 // move the contents back where it belongs
205 m_xContainer->move(m_xPopup->getContainer(), m_xPopup->getTopLevel());
206 m_xPopup.reset();
207 m_xContainer.reset();
208 m_xBuilder.reset();
209 m_xFrame.clear();
211}
212
214{
215 disposeOnce();
216}
217
218/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::lang::XComponent > m_xFrame
void EndPopupMode(const vcl::Window *pWin)
virtual void dispose() override
css::uno::Reference< css::frame::XFrame > m_xFrame
Definition: toolbarmenu.hxx:87
virtual void dispose() override
std::unique_ptr< weld::Builder > m_xBuilder
Definition: toolbarmenu.hxx:88
virtual ~InterimToolbarPopup() override
virtual void GetFocus() override
InterimToolbarPopup(const css::uno::Reference< css::frame::XFrame > &rFrame, vcl::Window *pParent, std::unique_ptr< WeldToolbarPopup > xPopup, bool bTearable=false)
std::unique_ptr< WeldToolbarPopup > m_xPopup
Definition: toolbarmenu.hxx:90
std::unique_ptr< weld::Container > m_xContainer
Definition: toolbarmenu.hxx:89
std::unique_ptr< weld::Container > m_xContainer
Definition: toolbarmenu.hxx:72
std::unique_ptr< weld::Container > m_xTopLevel
Definition: toolbarmenu.hxx:71
std::unique_ptr< WeldToolbarPopup > m_xPopup
Definition: toolbarmenu.hxx:73
ToolbarPopupContainer(weld::Widget *pParent)
void setPopover(std::unique_ptr< WeldToolbarPopup > xPopup)
std::unique_ptr< weld::Container > m_xTopLevel
Definition: toolbarmenu.hxx:41
virtual ~WeldToolbarPopup()
void AddStatusListener(const OUString &rCommandURL)
Definition: toolbarmenu.cxx:90
rtl::Reference< svt::FrameStatusListener > m_xStatusListener
Definition: toolbarmenu.hxx:44
virtual void statusChanged(const css::frame::FeatureStateEvent &Event)
Definition: toolbarmenu.cxx:98
css::uno::Reference< css::frame::XFrame > m_xFrame
Definition: toolbarmenu.hxx:43
WeldToolbarPopup(css::uno::Reference< css::frame::XFrame > xFrame, weld::Widget *pParent, const OUString &rUIFile, const OUString &rId)
virtual void SAL_CALL dispose() override
virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent &Event) override=0
virtual void GetFocus()
vcl::Window * GetParent() const
static DockingManager * GetDockingManager()
bool HasFocus() const
bool IsSystemWindow() const
Reference< XComponentContext > getProcessComponentContext()
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
Reference< XNameAccess > m_xContainer
Reference< XFrame > xFrame
IMPL_LINK_NOARG(WeldToolbarPopup, FocusHdl, weld::Widget &, void)