android: Update app-specific/MIME type icons
[LibreOffice.git] / svtools / source / control / toolbarmenu.cxx
blob92519ad356adbd3b059df9997c4d33fbdcbfa368
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <memory>
21 #include <comphelper/lok.hxx>
22 #include <comphelper/processfactory.hxx>
24 #include <utility>
25 #include <vcl/taskpanelist.hxx>
26 #include <vcl/svapp.hxx>
28 #include <framestatuslistener.hxx>
29 #include <svtools/toolbarmenu.hxx>
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::lang;
33 using namespace ::com::sun::star::frame;
34 using namespace ::com::sun::star::accessibility;
36 namespace {
38 SystemWindow* GetTopMostParentSystemWindow(const vcl::Window& rWindow)
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 )
46 if ( pWindow->IsSystemWindow() )
47 pTopMostSysWin = static_cast<SystemWindow*>(pWindow);
48 pWindow = pWindow->GetParent();
50 return pTopMostSysWin;
53 class ToolbarPopupStatusListener : public svt::FrameStatusListener
55 public:
56 ToolbarPopupStatusListener( const css::uno::Reference< css::frame::XFrame >& xFrame,
57 WeldToolbarPopup& rToolbarPopup );
59 virtual void SAL_CALL dispose() override;
60 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) override;
62 WeldToolbarPopup* mpPopup;
66 ToolbarPopupStatusListener::ToolbarPopupStatusListener(
67 const css::uno::Reference< css::frame::XFrame >& xFrame,
68 WeldToolbarPopup& rToolbarPopup )
69 : svt::FrameStatusListener( ::comphelper::getProcessComponentContext(), xFrame )
70 , mpPopup( &rToolbarPopup )
75 void SAL_CALL ToolbarPopupStatusListener::dispose()
77 mpPopup = nullptr;
78 svt::FrameStatusListener::dispose();
82 void SAL_CALL ToolbarPopupStatusListener::statusChanged( const css::frame::FeatureStateEvent& Event )
84 if( mpPopup )
85 mpPopup->statusChanged( Event );
90 void WeldToolbarPopup::AddStatusListener(const OUString& rCommandURL)
92 if (!m_xStatusListener.is())
93 m_xStatusListener.set(new ToolbarPopupStatusListener(m_xFrame, *this));
95 m_xStatusListener->addStatusListener(rCommandURL);
98 void WeldToolbarPopup::statusChanged(const css::frame::FeatureStateEvent& /*Event*/)
102 void InterimToolbarPopup::EndPopupMode()
104 GetDockingManager()->EndPopupMode(this);
107 WeldToolbarPopup::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))
115 m_xTopLevel->connect_focus_in(LINK(this, WeldToolbarPopup, FocusHdl));
118 WeldToolbarPopup::~WeldToolbarPopup()
120 if (m_xStatusListener.is())
121 m_xStatusListener->dispose();
124 IMPL_LINK_NOARG(WeldToolbarPopup, FocusHdl, weld::Widget&, void)
126 GrabFocus();
129 ToolbarPopupContainer::ToolbarPopupContainer(weld::Widget* pParent)
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"))
134 m_xTopLevel->connect_focus_in(LINK(this, ToolbarPopupContainer, FocusHdl));
137 void ToolbarPopupContainer::setPopover(std::unique_ptr<WeldToolbarPopup> xPopup)
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());
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
146 if (!comphelper::LibreOfficeKit::isActive())
147 m_xPopup->GrabFocus();
150 void ToolbarPopupContainer::unsetPopover()
152 if (!m_xPopup)
153 return;
154 m_xContainer->move(m_xPopup->getContainer(), m_xPopup->getTopLevel());
155 m_xPopup.reset();
158 ToolbarPopupContainer::~ToolbarPopupContainer()
160 unsetPopover();
163 IMPL_LINK_NOARG(ToolbarPopupContainer, FocusHdl, weld::Widget&, void)
165 if (m_xPopup)
166 m_xPopup->GrabFocus();
169 InterimToolbarPopup::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))
177 if (SystemWindow* pWindow = GetTopMostParentSystemWindow(*this))
178 pWindow->GetTaskPaneList()->AddWindow(this);
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());
184 void InterimToolbarPopup::GetFocus()
186 DropdownDockingWindow::GetFocus();
187 if (!m_xPopup)
188 return;
189 m_xPopup->GrabFocus();
192 void InterimToolbarPopup::dispose()
194 if (SystemWindow* pWindow = GetTopMostParentSystemWindow(*this))
195 pWindow->GetTaskPaneList()->RemoveWindow(this);
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())
201 if (auto xWindow = m_xFrame->getContainerWindow())
202 xWindow->setFocus();
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();
210 DropdownDockingWindow::dispose();
213 InterimToolbarPopup::~InterimToolbarPopup()
215 disposeOnce();
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */