File: | home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx |
Warning: | line 124, column 9 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | #include <sfx2/sidebar/SidebarDockingWindow.hxx> | |||
20 | #include <sfx2/sidebar/SidebarChildWindow.hxx> | |||
21 | #include <sfx2/sidebar/SidebarController.hxx> | |||
22 | #include <sidebar/PanelDescriptor.hxx> | |||
23 | ||||
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> | |||
36 | ||||
37 | #include <boost/property_tree/json_parser.hpp> | |||
38 | ||||
39 | using namespace css; | |||
40 | using namespace css::uno; | |||
41 | ||||
42 | namespace sfx2::sidebar { | |||
43 | ||||
44 | class SidebarNotifyIdle : public Idle | |||
45 | { | |||
46 | SidebarDockingWindow& m_rSidebarDockingWin; | |||
47 | std::string m_LastNotificationMessage; | |||
48 | vcl::LOKWindowId m_LastLOKWindowId; | |||
49 | ||||
50 | public: | |||
51 | SidebarNotifyIdle(SidebarDockingWindow &rSidebarDockingWin) : | |||
52 | Idle("Sidebar notify"), | |||
53 | m_rSidebarDockingWin(rSidebarDockingWin), | |||
54 | m_LastNotificationMessage(), | |||
55 | m_LastLOKWindowId(0) | |||
56 | { | |||
57 | SetPriority(TaskPriority::POST_PAINT); | |||
58 | } | |||
59 | ||||
60 | void Invoke() override | |||
61 | { | |||
62 | auto pNotifier = m_rSidebarDockingWin.GetLOKNotifier(); | |||
63 | auto pMobileNotifier = SfxViewShell::Current(); | |||
64 | if (!pNotifier || (!pMobileNotifier && !comphelper::LibreOfficeKit::isActive())) | |||
65 | return; | |||
66 | ||||
67 | try | |||
68 | { | |||
69 | if (pMobileNotifier && pMobileNotifier->isLOKMobilePhone()) | |||
70 | { | |||
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) | |||
78 | { | |||
79 | m_LastNotificationMessage = message; | |||
80 | pMobileNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, m_LastNotificationMessage.c_str()); | |||
81 | } | |||
82 | } | |||
83 | ||||
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(); | |||
90 | ||||
91 | const std::string message = OString(posMessage + sizeMessage).getStr(); | |||
92 | const vcl::LOKWindowId lokWindowId = m_rSidebarDockingWin.GetLOKWindowId(); | |||
93 | ||||
94 | if (lokWindowId != m_LastLOKWindowId || message != m_LastNotificationMessage) | |||
95 | { | |||
96 | m_LastLOKWindowId = lokWindowId; | |||
97 | m_LastNotificationMessage = message; | |||
98 | ||||
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); | |||
104 | } | |||
105 | } | |||
106 | catch (boost::property_tree::json_parser::json_parser_error& rError) | |||
107 | { | |||
108 | SAL_WARN("sfx.sidebar", rError.message())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sfx.sidebar")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << rError.message()) == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.sidebar" ), ("/home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx" ":" "108" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << rError.message()), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << rError .message(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN) , ("sfx.sidebar"), ("/home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx" ":" "108" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << rError.message()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sfx.sidebar"), ("/home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx" ":" "108" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << rError.message()), 0); } else { ::std:: ostringstream sal_detail_stream; sal_detail_stream << rError .message(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN) , ("sfx.sidebar"), ("/home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx" ":" "108" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
109 | } | |||
110 | } | |||
111 | }; | |||
112 | ||||
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)) | |||
119 | { | |||
120 | // Get the XFrame from the bindings. | |||
121 | if (pSfxBindings==nullptr || pSfxBindings->GetDispatcher()==nullptr) | |||
| ||||
122 | { | |||
123 | OSL_ASSERT(pSfxBindings!=nullptr)do { if (true && (!(pSfxBindings!=nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx" ":" "123" ": "), "OSL_ASSERT: %s", "pSfxBindings!=nullptr"); } } while (false); | |||
124 | OSL_ASSERT(pSfxBindings->GetDispatcher()!=nullptr)do { if (true && (!(pSfxBindings->GetDispatcher()!= nullptr))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN) , ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx" ":" "124" ": "), "OSL_ASSERT: %s", "pSfxBindings->GetDispatcher()!=nullptr" ); } } while (false); | |||
| ||||
125 | } | |||
126 | else | |||
127 | { | |||
128 | const SfxViewFrame* pViewFrame = pSfxBindings->GetDispatcher()->GetFrame(); | |||
129 | mpSidebarController.set(sfx2::sidebar::SidebarController::create(this, pViewFrame).get()); | |||
130 | } | |||
131 | } | |||
132 | ||||
133 | SidebarDockingWindow::~SidebarDockingWindow() | |||
134 | { | |||
135 | disposeOnce(); | |||
136 | } | |||
137 | ||||
138 | void SidebarDockingWindow::dispose() | |||
139 | { | |||
140 | if (comphelper::LibreOfficeKit::isActive()) | |||
141 | LOKClose(); | |||
142 | ||||
143 | Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpSidebarController.get()), UNO_QUERY); | |||
144 | mpSidebarController.clear(); | |||
145 | if (xComponent.is()) | |||
146 | xComponent->dispose(); | |||
147 | ||||
148 | SfxDockingWindow::dispose(); | |||
149 | } | |||
150 | ||||
151 | void SidebarDockingWindow::LOKClose() | |||
152 | { | |||
153 | assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive ()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()" , "/home/maarten/src/libreoffice/core/sfx2/source/sidebar/SidebarDockingWindow.cxx" , 153, __extension__ __PRETTY_FUNCTION__)); | |||
154 | if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
155 | { | |||
156 | mpIdleNotify->Stop(); | |||
157 | ||||
158 | pNotifier->notifyWindow(GetLOKWindowId(), "close"); | |||
159 | ReleaseLOKNotifier(); | |||
160 | } | |||
161 | } | |||
162 | ||||
163 | void SidebarDockingWindow::GetFocus() | |||
164 | { | |||
165 | if (mpSidebarController.is()) | |||
166 | { | |||
167 | mpSidebarController->RequestOpenDeck(); | |||
168 | mpSidebarController->GetFocusManager().GrabFocus(); | |||
169 | } | |||
170 | else | |||
171 | SfxDockingWindow::GetFocus(); | |||
172 | } | |||
173 | ||||
174 | bool SidebarDockingWindow::Close() | |||
175 | { | |||
176 | if (mpSidebarController.is()) | |||
177 | mpSidebarController->SetFloatingDeckClosed(true); | |||
178 | ||||
179 | return SfxDockingWindow::Close(); | |||
180 | } | |||
181 | ||||
182 | void SidebarDockingWindow::Resize() | |||
183 | { | |||
184 | SfxDockingWindow::Resize(); | |||
185 | ||||
186 | NotifyResize(); | |||
187 | } | |||
188 | ||||
189 | void SidebarDockingWindow::SyncUpdate() | |||
190 | { | |||
191 | if (mpSidebarController.is()) | |||
192 | mpSidebarController->SyncUpdate(); | |||
193 | } | |||
194 | ||||
195 | void SidebarDockingWindow::NotifyResize() | |||
196 | { | |||
197 | if (!(comphelper::LibreOfficeKit::isActive() && mpSidebarController.is() && SfxViewShell::Current())) | |||
198 | return; | |||
199 | ||||
200 | const vcl::ILibreOfficeKitNotifier* pCurrentView = SfxViewShell::Current(); | |||
201 | if (GetLOKNotifier() != pCurrentView) | |||
202 | { | |||
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(); | |||
206 | ||||
207 | SetLOKNotifier(pCurrentView); | |||
208 | } | |||
209 | ||||
210 | mpIdleNotify->Start(); | |||
211 | } | |||
212 | ||||
213 | SfxChildAlignment SidebarDockingWindow::CheckAlignment ( | |||
214 | SfxChildAlignment eCurrentAlignment, | |||
215 | SfxChildAlignment eRequestedAlignment) | |||
216 | { | |||
217 | switch (eRequestedAlignment) | |||
218 | { | |||
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; | |||
226 | ||||
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; | |||
234 | ||||
235 | default: | |||
236 | return eRequestedAlignment; | |||
237 | } | |||
238 | } | |||
239 | ||||
240 | bool SidebarDockingWindow::EventNotify(NotifyEvent& rEvent) | |||
241 | { | |||
242 | MouseNotifyEvent nType = rEvent.GetType(); | |||
243 | if (MouseNotifyEvent::KEYINPUT == nType) | |||
244 | { | |||
245 | const vcl::KeyCode& rKeyCode = rEvent.GetKeyEvent()->GetKeyCode(); | |||
246 | switch (rKeyCode.GetCode()) | |||
247 | { | |||
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: | |||
261 | { | |||
262 | return true; | |||
263 | } | |||
264 | default: | |||
265 | break; | |||
266 | } | |||
267 | if (!mpAccel) | |||
268 | { | |||
269 | mpAccel = svt::AcceleratorExecute::createAcceleratorHelper(); | |||
270 | mpAccel->init(comphelper::getProcessComponentContext(), mpSidebarController->getXFrame()); | |||
271 | } | |||
272 | const OUString aCommand(mpAccel->findCommand(svt::AcceleratorExecute::st_VCLKey2AWTKey(rKeyCode))); | |||
273 | if (".uno:DesignerDialog" == aCommand) | |||
274 | { | |||
275 | std::shared_ptr<PanelDescriptor> xPanelDescriptor = | |||
276 | mpSidebarController->GetResourceManager()->GetPanelDescriptor( "StyleListPanel" ); | |||
277 | if ( xPanelDescriptor && mpSidebarController->IsDeckVisible( xPanelDescriptor->msDeckId ) ) | |||
278 | Close(); | |||
279 | return true; | |||
280 | } | |||
281 | if (".uno:Undo" == aCommand || ".uno:Redo" == aCommand) | |||
282 | { | |||
283 | comphelper::dispatchCommand(aCommand, {}); | |||
284 | return true; | |||
285 | } | |||
286 | } | |||
287 | else if (MouseNotifyEvent::MOUSEBUTTONDOWN == nType) | |||
288 | { | |||
289 | const MouseEvent *mEvt = rEvent.GetMouseEvent(); | |||
290 | if (mEvt->IsLeft()) | |||
291 | { | |||
292 | tools::Rectangle aGrip = mpSidebarController->GetDeckDragArea(); | |||
293 | if ( aGrip.IsInside( mEvt->GetPosPixel() ) ) | |||
294 | mbIsReadyToDrag = true; | |||
295 | } | |||
296 | } | |||
297 | else if (MouseNotifyEvent::MOUSEMOVE == nType) | |||
298 | { | |||
299 | const MouseEvent *mEvt = rEvent.GetMouseEvent(); | |||
300 | tools::Rectangle aGrip = mpSidebarController->GetDeckDragArea(); | |||
301 | if (mEvt->IsLeft() && aGrip.IsInside( mEvt->GetPosPixel() ) && mbIsReadyToDrag ) | |||
302 | { | |||
303 | Point aPos = mEvt->GetPosPixel(); | |||
304 | vcl::Window* pWindow = rEvent.GetWindow(); | |||
305 | if ( pWindow != this ) | |||
306 | { | |||
307 | aPos = pWindow->OutputToScreenPixel( aPos ); | |||
308 | aPos = ScreenToOutputPixel( aPos ); | |||
309 | } | |||
310 | ImplStartDocking( aPos ); | |||
311 | } | |||
312 | } | |||
313 | ||||
314 | return SfxDockingWindow::EventNotify(rEvent); | |||
315 | } | |||
316 | ||||
317 | } // end of namespace sfx2::sidebar | |||
318 | ||||
319 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |