nss: upgrade to release 3.73
[LibreOffice.git] / sfx2 / source / sidebar / SidebarDockingWindow.cxx
blobc3bbe327fab7fd544cf43c39b37325a0c6ffe07d
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 .
19 #include <sfx2/sidebar/SidebarDockingWindow.hxx>
20 #include <sfx2/sidebar/SidebarChildWindow.hxx>
21 #include <sfx2/sidebar/SidebarController.hxx>
22 #include <sidebar/PanelDescriptor.hxx>
24 #include <comphelper/dispatchcommand.hxx>
25 #include <comphelper/processfactory.hxx>
26 #include <sfx2/lokhelper.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <svtools/acceleratorexecute.hxx>
31 #include <tools/gen.hxx>
32 #include <tools/json_writer.hxx>
33 #include <vcl/event.hxx>
34 #include <comphelper/lok.hxx>
35 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
37 #include <boost/property_tree/json_parser.hpp>
39 using namespace css;
40 using namespace css::uno;
42 namespace sfx2::sidebar {
44 class SidebarNotifyIdle : public Idle
46 SidebarDockingWindow& m_rSidebarDockingWin;
47 std::string m_LastNotificationMessage;
48 vcl::LOKWindowId m_LastLOKWindowId;
50 public:
51 SidebarNotifyIdle(SidebarDockingWindow &rSidebarDockingWin) :
52 Idle("Sidebar notify"),
53 m_rSidebarDockingWin(rSidebarDockingWin),
54 m_LastNotificationMessage(),
55 m_LastLOKWindowId(0)
57 SetPriority(TaskPriority::POST_PAINT);
60 void Invoke() override
62 auto pNotifier = m_rSidebarDockingWin.GetLOKNotifier();
63 auto pMobileNotifier = SfxViewShell::Current();
64 if (!pNotifier || (!pMobileNotifier && !comphelper::LibreOfficeKit::isActive()))
65 return;
67 try
69 if (pMobileNotifier && pMobileNotifier->isLOKMobilePhone())
71 // Mobile phone.
72 tools::JsonWriter aJsonWriter;
73 m_rSidebarDockingWin.DumpAsPropertyTree(aJsonWriter);
74 aJsonWriter.put("id", m_rSidebarDockingWin.GetLOKWindowId());
75 std::unique_ptr<char[]> data( aJsonWriter.extractData());
76 std::string_view message(data.get());
77 if (message != m_LastNotificationMessage)
79 m_LastNotificationMessage = message;
80 pMobileNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, m_LastNotificationMessage.c_str());
84 // Notify the sidebar is created, and its LOKWindowId, which
85 // is needed on mobile phones, tablets, and desktop.
86 const Point pos(m_rSidebarDockingWin.GetOutOffXPixel(),
87 m_rSidebarDockingWin.GetOutOffYPixel());
88 const OString posMessage = pos.toString();
89 const OString sizeMessage = m_rSidebarDockingWin.GetSizePixel().toString();
91 const std::string message = OString(posMessage + sizeMessage).getStr();
92 const vcl::LOKWindowId lokWindowId = m_rSidebarDockingWin.GetLOKWindowId();
94 if (lokWindowId != m_LastLOKWindowId || message != m_LastNotificationMessage)
96 m_LastLOKWindowId = lokWindowId;
97 m_LastNotificationMessage = message;
99 std::vector<vcl::LOKPayloadItem> aItems;
100 aItems.emplace_back("type", "deck");
101 aItems.emplace_back("position", posMessage);
102 aItems.emplace_back("size", sizeMessage);
103 pNotifier->notifyWindow(lokWindowId, "created", aItems);
106 catch (boost::property_tree::json_parser::json_parser_error& rError)
108 SAL_WARN("sfx.sidebar", rError.message());
113 SidebarDockingWindow::SidebarDockingWindow(SfxBindings* pSfxBindings, SidebarChildWindow& rChildWindow,
114 vcl::Window* pParentWindow, WinBits nBits)
115 : SfxDockingWindow(pSfxBindings, &rChildWindow, pParentWindow, nBits)
116 , mpSidebarController()
117 , mbIsReadyToDrag(false)
118 , mpIdleNotify(new SidebarNotifyIdle(*this))
120 // Get the XFrame from the bindings.
121 if (pSfxBindings==nullptr || pSfxBindings->GetDispatcher()==nullptr)
123 OSL_ASSERT(pSfxBindings!=nullptr);
124 OSL_ASSERT(pSfxBindings->GetDispatcher()!=nullptr);
126 else
128 const SfxViewFrame* pViewFrame = pSfxBindings->GetDispatcher()->GetFrame();
129 mpSidebarController.set(sfx2::sidebar::SidebarController::create(this, pViewFrame).get());
133 SidebarDockingWindow::~SidebarDockingWindow()
135 disposeOnce();
138 void SidebarDockingWindow::dispose()
140 if (comphelper::LibreOfficeKit::isActive())
141 LOKClose();
143 Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpSidebarController.get()), UNO_QUERY);
144 mpSidebarController.clear();
145 if (xComponent.is())
146 xComponent->dispose();
148 SfxDockingWindow::dispose();
151 void SidebarDockingWindow::LOKClose()
153 assert(comphelper::LibreOfficeKit::isActive());
154 if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
156 mpIdleNotify->Stop();
158 pNotifier->notifyWindow(GetLOKWindowId(), "close");
159 ReleaseLOKNotifier();
163 void SidebarDockingWindow::GetFocus()
165 if (mpSidebarController.is())
167 mpSidebarController->RequestOpenDeck();
168 mpSidebarController->GetFocusManager().GrabFocus();
170 else
171 SfxDockingWindow::GetFocus();
174 bool SidebarDockingWindow::Close()
176 if (mpSidebarController.is())
177 mpSidebarController->SetFloatingDeckClosed(true);
179 return SfxDockingWindow::Close();
182 void SidebarDockingWindow::Resize()
184 SfxDockingWindow::Resize();
186 NotifyResize();
189 void SidebarDockingWindow::SyncUpdate()
191 if (mpSidebarController.is())
192 mpSidebarController->SyncUpdate();
195 void SidebarDockingWindow::NotifyResize()
197 if (!(comphelper::LibreOfficeKit::isActive() && mpSidebarController.is() && SfxViewShell::Current()))
198 return;
200 const vcl::ILibreOfficeKitNotifier* pCurrentView = SfxViewShell::Current();
201 if (GetLOKNotifier() != pCurrentView)
203 // ViewShell not yet set, or has changed. Reset it.
204 // Note GetLOKWindowId will return a new value after resetting, so we must notify clients.
205 LOKClose();
207 SetLOKNotifier(pCurrentView);
210 mpIdleNotify->Start();
213 SfxChildAlignment SidebarDockingWindow::CheckAlignment (
214 SfxChildAlignment eCurrentAlignment,
215 SfxChildAlignment eRequestedAlignment)
217 switch (eRequestedAlignment)
219 case SfxChildAlignment::TOP:
220 case SfxChildAlignment::HIGHESTTOP:
221 case SfxChildAlignment::LOWESTTOP:
222 case SfxChildAlignment::BOTTOM:
223 case SfxChildAlignment::LOWESTBOTTOM:
224 case SfxChildAlignment::HIGHESTBOTTOM:
225 return eCurrentAlignment;
227 case SfxChildAlignment::LEFT:
228 case SfxChildAlignment::RIGHT:
229 case SfxChildAlignment::FIRSTLEFT:
230 case SfxChildAlignment::LASTLEFT:
231 case SfxChildAlignment::FIRSTRIGHT:
232 case SfxChildAlignment::LASTRIGHT:
233 return eRequestedAlignment;
235 default:
236 return eRequestedAlignment;
240 bool SidebarDockingWindow::EventNotify(NotifyEvent& rEvent)
242 MouseNotifyEvent nType = rEvent.GetType();
243 if (MouseNotifyEvent::KEYINPUT == nType)
245 const vcl::KeyCode& rKeyCode = rEvent.GetKeyEvent()->GetKeyCode();
246 switch (rKeyCode.GetCode())
248 case KEY_UP:
249 case KEY_DOWN:
250 case KEY_PAGEUP:
251 case KEY_PAGEDOWN:
252 case KEY_HOME:
253 case KEY_END:
254 case KEY_LEFT:
255 case KEY_RIGHT:
256 case KEY_BACKSPACE:
257 case KEY_DELETE:
258 case KEY_INSERT:
259 case KEY_RETURN:
260 case KEY_ESCAPE:
262 return true;
264 default:
265 break;
267 if (!mpAccel)
269 mpAccel = svt::AcceleratorExecute::createAcceleratorHelper();
270 mpAccel->init(comphelper::getProcessComponentContext(), mpSidebarController->getXFrame());
272 const OUString aCommand(mpAccel->findCommand(svt::AcceleratorExecute::st_VCLKey2AWTKey(rKeyCode)));
273 if (".uno:DesignerDialog" == aCommand)
275 std::shared_ptr<PanelDescriptor> xPanelDescriptor =
276 mpSidebarController->GetResourceManager()->GetPanelDescriptor( "StyleListPanel" );
277 if ( xPanelDescriptor && mpSidebarController->IsDeckVisible( xPanelDescriptor->msDeckId ) )
278 Close();
279 return true;
281 if (".uno:Undo" == aCommand || ".uno:Redo" == aCommand)
283 comphelper::dispatchCommand(aCommand, {});
284 return true;
287 else if (MouseNotifyEvent::MOUSEBUTTONDOWN == nType)
289 const MouseEvent *mEvt = rEvent.GetMouseEvent();
290 if (mEvt->IsLeft())
292 tools::Rectangle aGrip = mpSidebarController->GetDeckDragArea();
293 if ( aGrip.IsInside( mEvt->GetPosPixel() ) )
294 mbIsReadyToDrag = true;
297 else if (MouseNotifyEvent::MOUSEMOVE == nType)
299 const MouseEvent *mEvt = rEvent.GetMouseEvent();
300 tools::Rectangle aGrip = mpSidebarController->GetDeckDragArea();
301 if (mEvt->IsLeft() && aGrip.IsInside( mEvt->GetPosPixel() ) && mbIsReadyToDrag )
303 Point aPos = mEvt->GetPosPixel();
304 vcl::Window* pWindow = rEvent.GetWindow();
305 if ( pWindow != this )
307 aPos = pWindow->OutputToScreenPixel( aPos );
308 aPos = ScreenToOutputPixel( aPos );
310 ImplStartDocking( aPos );
314 return SfxDockingWindow::EventNotify(rEvent);
317 } // end of namespace sfx2::sidebar
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */