File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 113, column 13 Use of memory after it is freed |
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 | |||||||
10 | #include <sfx2/lokhelper.hxx> | ||||||
11 | |||||||
12 | #include <com/sun/star/frame/Desktop.hpp> | ||||||
13 | |||||||
14 | #include <comphelper/processfactory.hxx> | ||||||
15 | #include <rtl/strbuf.hxx> | ||||||
16 | #include <rtl/ustrbuf.hxx> | ||||||
17 | #include <vcl/lok.hxx> | ||||||
18 | #include <vcl/svapp.hxx> | ||||||
19 | #include <vcl/commandevent.hxx> | ||||||
20 | #include <sal/log.hxx> | ||||||
21 | #include <sfx2/app.hxx> | ||||||
22 | #include <sfx2/msg.hxx> | ||||||
23 | #include <sfx2/viewsh.hxx> | ||||||
24 | #include <sfx2/request.hxx> | ||||||
25 | #include <sfx2/sfxsids.hrc> | ||||||
26 | #include <sfx2/viewfrm.hxx> | ||||||
27 | #include <LibreOfficeKit/LibreOfficeKitEnums.h> | ||||||
28 | #include <comphelper/lok.hxx> | ||||||
29 | #include <editeng/outliner.hxx> | ||||||
30 | #include <sfx2/msgpool.hxx> | ||||||
31 | |||||||
32 | #include <shellimpl.hxx> | ||||||
33 | |||||||
34 | #include <boost/property_tree/json_parser.hpp> | ||||||
35 | |||||||
36 | using namespace com::sun::star; | ||||||
37 | |||||||
38 | namespace { | ||||||
39 | /// Used to disable callbacks. | ||||||
40 | /// Needed to avoid recursion when switching views, | ||||||
41 | /// which can cause clients to invoke LOKit API and | ||||||
42 | /// implicitly set the view, which might cause an | ||||||
43 | /// infinite recursion if not detected and prevented. | ||||||
44 | class DisableCallbacks | ||||||
45 | { | ||||||
46 | public: | ||||||
47 | DisableCallbacks() | ||||||
48 | { | ||||||
49 | assert(m_nDisabled >= 0 && "Expected non-negative DisabledCallbacks state when disabling.")(static_cast <bool> (m_nDisabled >= 0 && "Expected non-negative DisabledCallbacks state when disabling." ) ? void (0) : __assert_fail ("m_nDisabled >= 0 && \"Expected non-negative DisabledCallbacks state when disabling.\"" , "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 49, __extension__ __PRETTY_FUNCTION__)); | ||||||
50 | ++m_nDisabled; | ||||||
51 | } | ||||||
52 | |||||||
53 | ~DisableCallbacks() | ||||||
54 | { | ||||||
55 | assert(m_nDisabled > 0 && "Expected positive DisabledCallbacks state when re-enabling.")(static_cast <bool> (m_nDisabled > 0 && "Expected positive DisabledCallbacks state when re-enabling." ) ? void (0) : __assert_fail ("m_nDisabled > 0 && \"Expected positive DisabledCallbacks state when re-enabling.\"" , "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 55, __extension__ __PRETTY_FUNCTION__)); | ||||||
56 | --m_nDisabled; | ||||||
57 | } | ||||||
58 | |||||||
59 | static bool disabled() { return m_nDisabled != 0; } | ||||||
60 | |||||||
61 | private: | ||||||
62 | static int m_nDisabled; | ||||||
63 | }; | ||||||
64 | |||||||
65 | int DisableCallbacks::m_nDisabled = 0; | ||||||
66 | } | ||||||
67 | |||||||
68 | namespace | ||||||
69 | { | ||||||
70 | LanguageTag g_defaultLanguageTag("en-US", true); | ||||||
71 | LOKDeviceFormFactor g_deviceFormFactor = LOKDeviceFormFactor::UNKNOWN; | ||||||
72 | } | ||||||
73 | |||||||
74 | int SfxLokHelper::createView() | ||||||
75 | { | ||||||
76 | SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(); | ||||||
77 | if (!pViewFrame) | ||||||
78 | return -1; | ||||||
79 | SfxViewShell* pPrevViewShell = SfxViewShell::Current(); | ||||||
80 | ViewShellDocId nId; | ||||||
81 | if (pPrevViewShell) | ||||||
82 | nId = pPrevViewShell->GetDocId(); | ||||||
83 | SfxRequest aRequest(pViewFrame, SID_NEWWINDOW(5000 + 620)); | ||||||
84 | pViewFrame->ExecView_Impl(aRequest); | ||||||
85 | SfxViewShell* pViewShell = SfxViewShell::Current(); | ||||||
86 | if (!pViewShell) | ||||||
87 | return -1; | ||||||
88 | if (pPrevViewShell) | ||||||
89 | pViewShell->SetDocId(nId); | ||||||
90 | return static_cast<sal_Int32>(pViewShell->GetViewShellId()); | ||||||
91 | } | ||||||
92 | |||||||
93 | void SfxLokHelper::destroyView(int nId) | ||||||
94 | { | ||||||
95 | SfxApplication* pApp = SfxApplication::Get(); | ||||||
96 | if (!pApp) | ||||||
97 | return; | ||||||
98 | |||||||
99 | int nViewShellId = nId; | ||||||
100 | SfxViewShellArr_Impl& rViewArr = pApp->GetViewShells_Impl(); | ||||||
101 | |||||||
102 | for (SfxViewShell* pViewShell : rViewArr) | ||||||
103 | { | ||||||
104 | if (static_cast<sal_Int32>(pViewShell->GetViewShellId()) == nViewShellId) | ||||||
105 | { | ||||||
106 | SfxViewFrame* pViewFrame = pViewShell->GetViewFrame(); | ||||||
107 | SfxRequest aRequest(pViewFrame, SID_CLOSEWIN(5000 + 621)); | ||||||
108 | pViewFrame->Exec_Impl(aRequest); | ||||||
109 | break; | ||||||
110 | } | ||||||
111 | } | ||||||
112 | } | ||||||
113 | |||||||
114 | void SfxLokHelper::setView(int nId) | ||||||
115 | { | ||||||
116 | SfxApplication* pApp = SfxApplication::Get(); | ||||||
117 | if (!pApp) | ||||||
118 | return; | ||||||
119 | |||||||
120 | int nViewShellId = nId; | ||||||
121 | SfxViewShellArr_Impl& rViewArr = pApp->GetViewShells_Impl(); | ||||||
122 | |||||||
123 | for (SfxViewShell* pViewShell : rViewArr) | ||||||
124 | { | ||||||
125 | if (static_cast<sal_Int32>(pViewShell->GetViewShellId()) == nViewShellId) | ||||||
126 | { | ||||||
127 | DisableCallbacks dc; | ||||||
128 | |||||||
129 | // update the current LOK language and locale for the dialog tunneling | ||||||
130 | comphelper::LibreOfficeKit::setLanguageTag(pViewShell->GetLOKLanguageTag()); | ||||||
131 | comphelper::LibreOfficeKit::setLocale(pViewShell->GetLOKLocale()); | ||||||
132 | |||||||
133 | if (pViewShell == SfxViewShell::Current()) | ||||||
134 | return; | ||||||
135 | |||||||
136 | SfxViewFrame* pViewFrame = pViewShell->GetViewFrame(); | ||||||
137 | pViewFrame->MakeActive_Impl(false); | ||||||
138 | |||||||
139 | // Make comphelper::dispatchCommand() find the correct frame. | ||||||
140 | uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface(); | ||||||
141 | uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(comphelper::getProcessComponentContext()); | ||||||
142 | xDesktop->setActiveFrame(xFrame); | ||||||
143 | return; | ||||||
144 | } | ||||||
145 | } | ||||||
146 | |||||||
147 | } | ||||||
148 | |||||||
149 | int SfxLokHelper::getView(SfxViewShell* pViewShell) | ||||||
150 | { | ||||||
151 | if (!pViewShell) | ||||||
152 | pViewShell = SfxViewShell::Current(); | ||||||
153 | // Still no valid view shell? Then no idea. | ||||||
154 | if (!pViewShell) | ||||||
155 | return -1; | ||||||
156 | |||||||
157 | return static_cast<sal_Int32>(pViewShell->GetViewShellId()); | ||||||
158 | } | ||||||
159 | |||||||
160 | std::size_t SfxLokHelper::getViewsCount() | ||||||
161 | { | ||||||
162 | SfxApplication* pApp = SfxApplication::Get(); | ||||||
163 | if (!pApp) | ||||||
164 | return 0; | ||||||
165 | |||||||
166 | const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); | ||||||
167 | const ViewShellDocId nCurrentDocId = pCurrentViewShell ? pCurrentViewShell->GetDocId() : ViewShellDocId(-1); | ||||||
168 | std::size_t n = 0; | ||||||
169 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
170 | while (pViewShell) | ||||||
171 | { | ||||||
172 | if (pViewShell->GetDocId() == nCurrentDocId) | ||||||
173 | n++; | ||||||
174 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
175 | } | ||||||
176 | return n; | ||||||
177 | } | ||||||
178 | |||||||
179 | bool SfxLokHelper::getViewIds(int* pArray, size_t nSize) | ||||||
180 | { | ||||||
181 | SfxApplication* pApp = SfxApplication::Get(); | ||||||
182 | if (!pApp) | ||||||
183 | return false; | ||||||
184 | |||||||
185 | const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); | ||||||
186 | const ViewShellDocId nCurrentDocId = pCurrentViewShell ? pCurrentViewShell->GetDocId() : ViewShellDocId(-1); | ||||||
187 | std::size_t n = 0; | ||||||
188 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
189 | while (pViewShell) | ||||||
190 | { | ||||||
191 | if (n == nSize) | ||||||
192 | return false; | ||||||
193 | if (pViewShell->GetDocId() == nCurrentDocId) | ||||||
194 | { | ||||||
195 | pArray[n] = static_cast<sal_Int32>(pViewShell->GetViewShellId()); | ||||||
196 | n++; | ||||||
197 | } | ||||||
198 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
199 | } | ||||||
200 | return true; | ||||||
201 | } | ||||||
202 | |||||||
203 | void SfxLokHelper::setDocumentIdOfView(int nId) | ||||||
204 | { | ||||||
205 | SfxViewShell* pViewShell = SfxViewShell::Current(); | ||||||
206 | assert(pViewShell)(static_cast <bool> (pViewShell) ? void (0) : __assert_fail ("pViewShell", "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 206, __extension__ __PRETTY_FUNCTION__)); | ||||||
207 | if (!pViewShell) | ||||||
208 | return; | ||||||
209 | pViewShell->SetDocId(ViewShellDocId(nId)); | ||||||
210 | } | ||||||
211 | |||||||
212 | int SfxLokHelper::getDocumentIdOfView(int nViewId) | ||||||
213 | { | ||||||
214 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
215 | while (pViewShell) | ||||||
216 | { | ||||||
217 | if (pViewShell->GetViewShellId() == ViewShellId(nViewId)) | ||||||
218 | return static_cast<int>(pViewShell->GetDocId()); | ||||||
219 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
220 | } | ||||||
221 | return -1; | ||||||
222 | } | ||||||
223 | |||||||
224 | LanguageTag SfxLokHelper::getDefaultLanguage() | ||||||
225 | { | ||||||
226 | return g_defaultLanguageTag; | ||||||
227 | } | ||||||
228 | |||||||
229 | void SfxLokHelper::setDefaultLanguage(const OUString& rBcp47LanguageTag) | ||||||
230 | { | ||||||
231 | g_defaultLanguageTag = LanguageTag(rBcp47LanguageTag, true); | ||||||
232 | } | ||||||
233 | |||||||
234 | void SfxLokHelper::setViewLanguage(int nId, const OUString& rBcp47LanguageTag) | ||||||
235 | { | ||||||
236 | SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); | ||||||
237 | |||||||
238 | for (SfxViewShell* pViewShell : rViewArr) | ||||||
239 | { | ||||||
240 | if (pViewShell->GetViewShellId() == ViewShellId(nId)) | ||||||
241 | { | ||||||
242 | pViewShell->SetLOKLanguageTag(rBcp47LanguageTag); | ||||||
243 | return; | ||||||
244 | } | ||||||
245 | } | ||||||
246 | } | ||||||
247 | |||||||
248 | void SfxLokHelper::setViewLocale(int nId, const OUString& rBcp47LanguageTag) | ||||||
249 | { | ||||||
250 | SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); | ||||||
251 | |||||||
252 | for (SfxViewShell* pViewShell : rViewArr) | ||||||
253 | { | ||||||
254 | if (pViewShell->GetViewShellId() == ViewShellId(nId)) | ||||||
255 | { | ||||||
256 | pViewShell->SetLOKLocale(rBcp47LanguageTag); | ||||||
257 | return; | ||||||
258 | } | ||||||
259 | } | ||||||
260 | } | ||||||
261 | |||||||
262 | LOKDeviceFormFactor SfxLokHelper::getDeviceFormFactor() | ||||||
263 | { | ||||||
264 | return g_deviceFormFactor; | ||||||
265 | } | ||||||
266 | |||||||
267 | void SfxLokHelper::setDeviceFormFactor(const OUString& rDeviceFormFactor) | ||||||
268 | { | ||||||
269 | if (rDeviceFormFactor == "desktop") | ||||||
270 | g_deviceFormFactor = LOKDeviceFormFactor::DESKTOP; | ||||||
271 | else if (rDeviceFormFactor == "tablet") | ||||||
272 | g_deviceFormFactor = LOKDeviceFormFactor::TABLET; | ||||||
273 | else if (rDeviceFormFactor == "mobile") | ||||||
274 | g_deviceFormFactor = LOKDeviceFormFactor::MOBILE; | ||||||
275 | else | ||||||
276 | g_deviceFormFactor = LOKDeviceFormFactor::UNKNOWN; | ||||||
277 | } | ||||||
278 | |||||||
279 | static OString lcl_escapeQuotes(const OString &rStr) | ||||||
280 | { | ||||||
281 | if (rStr.getLength() < 1) | ||||||
282 | return rStr; | ||||||
283 | // FIXME: need an optimized 'escape' method for O[U]String. | ||||||
284 | OStringBuffer aBuf(rStr.getLength() + 8); | ||||||
285 | for (sal_Int32 i = 0; i < rStr.getLength(); ++i) | ||||||
286 | { | ||||||
287 | if (rStr[i] == '"' || rStr[i] == '\\') | ||||||
288 | aBuf.append('\\'); | ||||||
289 | aBuf.append(rStr[i]); | ||||||
290 | } | ||||||
291 | return aBuf.makeStringAndClear(); | ||||||
292 | } | ||||||
293 | |||||||
294 | static OString lcl_generateJSON(SfxViewShell* pView, const boost::property_tree::ptree& rTree) | ||||||
295 | { | ||||||
296 | boost::property_tree::ptree aMessageProps = rTree; | ||||||
297 | aMessageProps.put("viewId", SfxLokHelper::getView(pView)); | ||||||
298 | aMessageProps.put("part", pView->getPart()); | ||||||
299 | std::stringstream aStream; | ||||||
300 | boost::property_tree::write_json(aStream, aMessageProps, false /* pretty */); | ||||||
301 | return OString(aStream.str().c_str()).trim(); | ||||||
302 | } | ||||||
303 | |||||||
304 | void SfxLokHelper::notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload) | ||||||
305 | { | ||||||
306 | if (DisableCallbacks::disabled()) | ||||||
307 | return; | ||||||
308 | |||||||
309 | OString aPayload = OStringLiteral("{ \"viewId\": \"") + OString::number(SfxLokHelper::getView(pThisView)) + | ||||||
310 | "\", \"part\": \"" + OString::number(pThisView->getPart()) + | ||||||
311 | "\", \"" + rKey + "\": \"" + lcl_escapeQuotes(rPayload) + "\" }"; | ||||||
312 | |||||||
313 | pOtherView->libreOfficeKitViewCallback(nType, aPayload.getStr()); | ||||||
314 | } | ||||||
315 | |||||||
316 | void SfxLokHelper::notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, | ||||||
317 | const boost::property_tree::ptree& rTree) | ||||||
318 | { | ||||||
319 | if (DisableCallbacks::disabled()) | ||||||
320 | return; | ||||||
321 | |||||||
322 | pOtherView->libreOfficeKitViewCallback(nType, lcl_generateJSON(pThisView, rTree).getStr()); | ||||||
323 | } | ||||||
324 | |||||||
325 | void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const OString& rKey, const OString& rPayload) | ||||||
326 | { | ||||||
327 | if (DisableCallbacks::disabled()) | ||||||
328 | return; | ||||||
329 | |||||||
330 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
331 | while (pViewShell) | ||||||
332 | { | ||||||
333 | if (pViewShell != pThisView && pViewShell->GetDocId() == pThisView-> GetDocId()) | ||||||
334 | notifyOtherView(pThisView, pViewShell, nType, rKey, rPayload); | ||||||
335 | |||||||
336 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
337 | } | ||||||
338 | } | ||||||
339 | |||||||
340 | void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const boost::property_tree::ptree& rTree) | ||||||
341 | { | ||||||
342 | if (SfxLokHelper::getViewsCount() <= 1 || DisableCallbacks::disabled()) | ||||||
343 | return; | ||||||
344 | |||||||
345 | // Payload is only dependent on pThisView. | ||||||
346 | OString aPayload = lcl_generateJSON(pThisView, rTree); | ||||||
347 | |||||||
348 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
349 | while (pViewShell) | ||||||
350 | { | ||||||
351 | if (pViewShell != pThisView) | ||||||
352 | pViewShell->libreOfficeKitViewCallback(nType, aPayload.getStr()); | ||||||
353 | |||||||
354 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
355 | } | ||||||
356 | } | ||||||
357 | |||||||
358 | namespace { | ||||||
359 | OUString lcl_getNameForSlot(const SfxViewShell* pShell, sal_uInt16 nWhich) | ||||||
360 | { | ||||||
361 | if (pShell && pShell->GetFrame()) | ||||||
362 | { | ||||||
363 | const SfxSlot* pSlot = SfxSlotPool::GetSlotPool(pShell->GetFrame()).GetSlot(nWhich); | ||||||
364 | if (pSlot) | ||||||
365 | { | ||||||
366 | const char* pName = pSlot->GetUnoName(); | ||||||
367 | if (pName) | ||||||
368 | { | ||||||
369 | return ".uno:" + OStringToOUString(pName, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11))); | ||||||
370 | } | ||||||
371 | } | ||||||
372 | } | ||||||
373 | |||||||
374 | return ""; | ||||||
375 | } | ||||||
376 | } | ||||||
377 | |||||||
378 | void SfxLokHelper::sendUnoStatus(const SfxViewShell* pShell, const SfxPoolItem* pItem) | ||||||
379 | { | ||||||
380 | if (!pShell || !pItem || pItem == INVALID_POOL_ITEMreinterpret_cast<SfxPoolItem*>(-1) || DisableCallbacks::disabled()) | ||||||
381 | return; | ||||||
382 | |||||||
383 | boost::property_tree::ptree aItem = pItem->dumpAsJSON(); | ||||||
384 | |||||||
385 | if (aItem.count("state")) | ||||||
386 | { | ||||||
387 | OUString sCommand = lcl_getNameForSlot(pShell, pItem->Which()); | ||||||
388 | if (!sCommand.isEmpty()) | ||||||
389 | aItem.put("commandName", sCommand); | ||||||
390 | |||||||
391 | std::stringstream aStream; | ||||||
392 | boost::property_tree::write_json(aStream, aItem); | ||||||
393 | pShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aStream.str().c_str()); | ||||||
394 | } | ||||||
395 | } | ||||||
396 | |||||||
397 | void SfxLokHelper::notifyWindow(const SfxViewShell* pThisView, | ||||||
398 | vcl::LOKWindowId nLOKWindowId, | ||||||
399 | const OUString& rAction, | ||||||
400 | const std::vector<vcl::LOKPayloadItem>& rPayload) | ||||||
401 | { | ||||||
402 | assert(pThisView)(static_cast <bool> (pThisView) ? void (0) : __assert_fail ("pThisView", "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 402, __extension__ __PRETTY_FUNCTION__)); | ||||||
403 | |||||||
404 | if (SfxLokHelper::getViewsCount() <= 0 || nLOKWindowId == 0 || DisableCallbacks::disabled()) | ||||||
405 | return; | ||||||
406 | |||||||
407 | OStringBuffer aPayload; | ||||||
408 | aPayload.append("{ \"id\": \"").append(OString::number(nLOKWindowId)).append("\""); | ||||||
409 | aPayload.append(", \"action\": \"").append(OUStringToOString(rAction, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)))).append("\""); | ||||||
410 | |||||||
411 | for (const auto& rItem: rPayload) | ||||||
412 | { | ||||||
413 | if (!rItem.first.isEmpty() && !rItem.second.isEmpty()) | ||||||
414 | { | ||||||
415 | aPayload.append(", \"").append(rItem.first).append("\": \"") | ||||||
416 | .append(rItem.second).append("\""); | ||||||
417 | } | ||||||
418 | } | ||||||
419 | aPayload.append("}"); | ||||||
420 | |||||||
421 | auto s = aPayload.makeStringAndClear(); | ||||||
422 | pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_WINDOW, s.getStr()); | ||||||
423 | } | ||||||
424 | |||||||
425 | void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, const OString& rPayload) | ||||||
426 | { | ||||||
427 | OStringBuffer aBuf(32); | ||||||
428 | |||||||
429 | if (DisableCallbacks::disabled()) | ||||||
430 | return; | ||||||
431 | |||||||
432 | aBuf.append(rPayload); | ||||||
433 | if (comphelper::LibreOfficeKit::isPartInInvalidation()) | ||||||
434 | { | ||||||
435 | aBuf.append(", "); | ||||||
436 | aBuf.append(static_cast<sal_Int32>(pThisView->getPart())); | ||||||
437 | } | ||||||
438 | pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_TILES, aBuf.makeStringAndClear().getStr()); | ||||||
439 | } | ||||||
440 | |||||||
441 | void SfxLokHelper::notifyDocumentSizeChanged(SfxViewShell const* pThisView, const OString& rPayload, vcl::ITiledRenderable* pDoc, bool bInvalidateAll) | ||||||
442 | { | ||||||
443 | if (!pDoc || pDoc->isDisposed() || !comphelper::LibreOfficeKit::isActive() || DisableCallbacks::disabled()) | ||||||
444 | return; | ||||||
445 | |||||||
446 | if (bInvalidateAll) | ||||||
447 | { | ||||||
448 | for (int i = 0; i < pDoc->getParts(); ++i) | ||||||
449 | { | ||||||
450 | tools::Rectangle aRectangle(0, 0, 1000000000, 1000000000); | ||||||
451 | OString sPayload = aRectangle.toString() + ", " + OString::number(i); | ||||||
452 | pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_TILES, sPayload.getStr()); | ||||||
453 | } | ||||||
454 | } | ||||||
455 | pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, rPayload.getStr()); | ||||||
456 | } | ||||||
457 | |||||||
458 | void SfxLokHelper::notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable* pDoc, bool bInvalidateAll) | ||||||
459 | { | ||||||
460 | if (!comphelper::LibreOfficeKit::isActive() || DisableCallbacks::disabled()) | ||||||
461 | return; | ||||||
462 | |||||||
463 | // FIXME: Do we know whether it is the views for the document that is in the "current" view that has changed? | ||||||
464 | const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); | ||||||
465 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
466 | while (pViewShell) | ||||||
467 | { | ||||||
468 | // FIXME: What if SfxViewShell::Current() returned null? | ||||||
469 | // Should we then do this for all views of all open documents | ||||||
470 | // or not? | ||||||
471 | if (pCurrentViewShell == nullptr || pViewShell->GetDocId() == pCurrentViewShell-> GetDocId()) | ||||||
472 | SfxLokHelper::notifyDocumentSizeChanged(pViewShell, "", pDoc, bInvalidateAll); | ||||||
473 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
474 | } | ||||||
475 | } | ||||||
476 | |||||||
477 | void SfxLokHelper::notifyVisCursorInvalidation(OutlinerViewShell const* pThisView, const OString& rRectangle, bool bMispelledWord, const OString& rHyperlink) | ||||||
478 | { | ||||||
479 | if (DisableCallbacks::disabled()) | ||||||
480 | return; | ||||||
481 | |||||||
482 | OString sPayload; | ||||||
483 | if (comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation()) | ||||||
484 | { | ||||||
485 | OString sHyperlink = rHyperlink.isEmpty() ? "{}" : rHyperlink; | ||||||
486 | sPayload = OStringLiteral("{ \"viewId\": \"") + OString::number(SfxLokHelper::getView()) + | ||||||
487 | "\", \"rectangle\": \"" + rRectangle + | ||||||
488 | "\", \"mispelledWord\": \"" + OString::number(bMispelledWord ? 1 : 0) + | ||||||
489 | "\", \"hyperlink\": " + sHyperlink + " }"; | ||||||
490 | } | ||||||
491 | else | ||||||
492 | { | ||||||
493 | sPayload = rRectangle; | ||||||
494 | } | ||||||
495 | pThisView->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, sPayload.getStr()); | ||||||
496 | } | ||||||
497 | |||||||
498 | void SfxLokHelper::notifyAllViews(int nType, const OString& rPayload) | ||||||
499 | { | ||||||
500 | if (DisableCallbacks::disabled()) | ||||||
501 | return; | ||||||
502 | |||||||
503 | const auto payload = rPayload.getStr(); | ||||||
504 | const SfxViewShell* const pCurrentViewShell = SfxViewShell::Current(); | ||||||
505 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
506 | while (pViewShell) | ||||||
507 | { | ||||||
508 | if (pViewShell->GetDocId() == pCurrentViewShell->GetDocId()) | ||||||
509 | pViewShell->libreOfficeKitViewCallback(nType, payload); | ||||||
510 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
511 | } | ||||||
512 | } | ||||||
513 | |||||||
514 | void SfxLokHelper::notifyContextChange(SfxViewShell const* pViewShell, const OUString& aApplication, const OUString& aContext) | ||||||
515 | { | ||||||
516 | if (DisableCallbacks::disabled()) | ||||||
517 | return; | ||||||
518 | |||||||
519 | OString aBuffer = | ||||||
520 | OUStringToOString(aApplication.replace(' ', '_'), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))) + | ||||||
521 | " " + | ||||||
522 | OUStringToOString(aContext.replace(' ', '_'), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))); | ||||||
523 | pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CONTEXT_CHANGED, aBuffer.getStr()); | ||||||
524 | } | ||||||
525 | |||||||
526 | |||||||
527 | namespace | ||||||
528 | { | ||||||
529 | struct LOKAsyncEventData | ||||||
530 | { | ||||||
531 | int mnView; // Window is not enough. | ||||||
532 | VclPtr<vcl::Window> mpWindow; | ||||||
533 | VclEventId mnEvent; | ||||||
534 | MouseEvent maMouseEvent; | ||||||
535 | KeyEvent maKeyEvent; | ||||||
536 | OUString maText; | ||||||
537 | }; | ||||||
538 | |||||||
539 | void LOKPostAsyncEvent(void* pEv, void*) | ||||||
540 | { | ||||||
541 | LOKAsyncEventData* pLOKEv = static_cast<LOKAsyncEventData*>(pEv); | ||||||
542 | if (pLOKEv->mpWindow->IsDisposed()) | ||||||
543 | return; | ||||||
544 | |||||||
545 | int nView = SfxLokHelper::getView(nullptr); | ||||||
546 | if (nView
| ||||||
547 | { | ||||||
548 | SAL_INFO("sfx.view", "LOK - view mismatch " << nView << " vs. " << pLOKEv->mnView)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "LOK - view mismatch " << nView << " vs. " << pLOKEv->mnView) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view" ), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "548" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "LOK - view mismatch " << nView << " vs. " << pLOKEv->mnView), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "LOK - view mismatch " << nView << " vs. " << pLOKEv->mnView; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view") , ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "548" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "LOK - view mismatch " << nView << " vs. " << pLOKEv->mnView) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "548" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "LOK - view mismatch " << nView << " vs. " << pLOKEv->mnView), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "LOK - view mismatch " << nView << " vs. " << pLOKEv->mnView; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view") , ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "548" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
549 | SfxLokHelper::setView(pLOKEv->mnView); | ||||||
550 | } | ||||||
551 | |||||||
552 | if (!pLOKEv->mpWindow->HasChildPathFocus(true)) | ||||||
553 | { | ||||||
554 | SAL_INFO("sfx.view", "LOK - focus mismatch, switching focus")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "sfx.view")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "LOK - focus mismatch, switching focus" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view" ), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "554" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "LOK - focus mismatch, switching focus" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "LOK - focus mismatch, switching focus"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "554" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "LOK - focus mismatch, switching focus") == 1) { :: sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view"), ( "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "554" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "LOK - focus mismatch, switching focus" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "LOK - focus mismatch, switching focus"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("sfx.view"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "554" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
555 | pLOKEv->mpWindow->GrabFocus(); | ||||||
556 | } | ||||||
557 | |||||||
558 | VclPtr<vcl::Window> pFocusWindow = pLOKEv->mpWindow->GetFocusedWindow(); | ||||||
559 | if (!pFocusWindow) | ||||||
560 | pFocusWindow = pLOKEv->mpWindow; | ||||||
561 | |||||||
562 | switch (pLOKEv->mnEvent) | ||||||
563 | { | ||||||
564 | case VclEventId::WindowKeyInput: | ||||||
565 | { | ||||||
566 | sal_uInt16 nRepeat = pLOKEv->maKeyEvent.GetRepeat(); | ||||||
567 | KeyEvent singlePress(pLOKEv->maKeyEvent.GetCharCode(), | ||||||
568 | pLOKEv->maKeyEvent.GetKeyCode()); | ||||||
569 | for (sal_uInt16 i = 0; i <= nRepeat; ++i) | ||||||
570 | pFocusWindow->KeyInput(singlePress); | ||||||
571 | break; | ||||||
572 | } | ||||||
573 | case VclEventId::WindowKeyUp: | ||||||
574 | pFocusWindow->KeyUp(pLOKEv->maKeyEvent); | ||||||
575 | break; | ||||||
576 | case VclEventId::WindowMouseButtonDown: | ||||||
577 | pLOKEv->mpWindow->LogicMouseButtonDown(pLOKEv->maMouseEvent); | ||||||
578 | // Invoke the context menu | ||||||
579 | if (pLOKEv->maMouseEvent.GetButtons() & MOUSE_RIGHT(sal_uInt16(0x0004))) | ||||||
580 | { | ||||||
581 | const CommandEvent aCEvt(pLOKEv->maMouseEvent.GetPosPixel(), CommandEventId::ContextMenu, true, nullptr); | ||||||
582 | pLOKEv->mpWindow->Command(aCEvt); | ||||||
583 | } | ||||||
584 | break; | ||||||
585 | case VclEventId::WindowMouseButtonUp: | ||||||
586 | pLOKEv->mpWindow->LogicMouseButtonUp(pLOKEv->maMouseEvent); | ||||||
587 | |||||||
588 | // sometimes MouseButtonDown captures mouse and starts tracking, and VCL | ||||||
589 | // will not take care of releasing that with tiled rendering | ||||||
590 | if (pLOKEv->mpWindow->IsTracking()) | ||||||
591 | pLOKEv->mpWindow->EndTracking(); | ||||||
592 | |||||||
593 | break; | ||||||
594 | case VclEventId::WindowMouseMove: | ||||||
595 | pLOKEv->mpWindow->LogicMouseMove(pLOKEv->maMouseEvent); | ||||||
596 | break; | ||||||
597 | case VclEventId::ExtTextInput: | ||||||
598 | case VclEventId::EndExtTextInput: | ||||||
599 | pLOKEv->mpWindow->PostExtTextInputEvent(pLOKEv->mnEvent, pLOKEv->maText); | ||||||
600 | break; | ||||||
601 | default: | ||||||
602 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 602, __extension__ __PRETTY_FUNCTION__)); | ||||||
603 | break; | ||||||
604 | } | ||||||
605 | |||||||
606 | delete pLOKEv; | ||||||
607 | } | ||||||
608 | |||||||
609 | void postEventAsync(LOKAsyncEventData *pEvent) | ||||||
610 | { | ||||||
611 | if (!pEvent->mpWindow || pEvent->mpWindow->IsDisposed()) | ||||||
612 | { | ||||||
613 | SAL_WARN("vcl", "Async event post - but no valid window as destination " << pEvent->mpWindow.get())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Async event post - but no valid window as destination " << pEvent->mpWindow.get()) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "613" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Async event post - but no valid window as destination " << pEvent->mpWindow.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Async event post - but no valid window as destination " << pEvent->mpWindow.get(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "613" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Async event post - but no valid window as destination " << pEvent->mpWindow.get()) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "613" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Async event post - but no valid window as destination " << pEvent->mpWindow.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Async event post - but no valid window as destination " << pEvent->mpWindow.get(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "613" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
614 | delete pEvent; | ||||||
615 | return; | ||||||
616 | } | ||||||
617 | |||||||
618 | pEvent->mnView = SfxLokHelper::getView(nullptr); | ||||||
619 | if (vcl::lok::isUnipoll()) | ||||||
620 | { | ||||||
621 | if (!Application::IsMainThread()) | ||||||
622 | SAL_WARN("lok", "Posting event directly but not called from main thread!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "lok")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Posting event directly but not called from main thread!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok" ), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "622" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Posting event directly but not called from main thread!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Posting event directly but not called from main thread!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "622" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Posting event directly but not called from main thread!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok" ), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "622" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Posting event directly but not called from main thread!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Posting event directly but not called from main thread!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok"), ("/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" ":" "622" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
623 | LOKPostAsyncEvent(pEvent, nullptr); | ||||||
624 | } | ||||||
625 | else | ||||||
626 | Application::PostUserEvent(Link<void*, void>(pEvent, LOKPostAsyncEvent)); | ||||||
627 | } | ||||||
628 | } | ||||||
629 | |||||||
630 | void SfxLokHelper::postKeyEventAsync(const VclPtr<vcl::Window> &xWindow, | ||||||
631 | int nType, int nCharCode, int nKeyCode, int nRepeat) | ||||||
632 | { | ||||||
633 | LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; | ||||||
634 | switch (nType) | ||||||
635 | { | ||||||
636 | case LOK_KEYEVENT_KEYINPUT: | ||||||
637 | pLOKEv->mnEvent = VclEventId::WindowKeyInput; | ||||||
638 | break; | ||||||
639 | case LOK_KEYEVENT_KEYUP: | ||||||
640 | pLOKEv->mnEvent = VclEventId::WindowKeyUp; | ||||||
641 | break; | ||||||
642 | default: | ||||||
643 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 643, __extension__ __PRETTY_FUNCTION__)); | ||||||
644 | } | ||||||
645 | pLOKEv->maKeyEvent = KeyEvent(nCharCode, nKeyCode, nRepeat); | ||||||
646 | pLOKEv->mpWindow = xWindow; | ||||||
647 | postEventAsync(pLOKEv); | ||||||
648 | } | ||||||
649 | |||||||
650 | void SfxLokHelper::postExtTextEventAsync(const VclPtr<vcl::Window> &xWindow, | ||||||
651 | int nType, const OUString &rText) | ||||||
652 | { | ||||||
653 | LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; | ||||||
654 | switch (nType) | ||||||
655 | { | ||||||
656 | case LOK_EXT_TEXTINPUT: | ||||||
657 | pLOKEv->mnEvent = VclEventId::ExtTextInput; | ||||||
658 | pLOKEv->maText = rText; | ||||||
659 | break; | ||||||
660 | case LOK_EXT_TEXTINPUT_END: | ||||||
661 | pLOKEv->mnEvent = VclEventId::EndExtTextInput; | ||||||
662 | pLOKEv->maText = ""; | ||||||
663 | break; | ||||||
664 | default: | ||||||
665 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 665, __extension__ __PRETTY_FUNCTION__)); | ||||||
666 | } | ||||||
667 | pLOKEv->mpWindow = xWindow; | ||||||
668 | postEventAsync(pLOKEv); | ||||||
669 | } | ||||||
670 | |||||||
671 | void SfxLokHelper::postMouseEventAsync(const VclPtr<vcl::Window> &xWindow, LokMouseEventData const & rLokMouseEventData) | ||||||
672 | { | ||||||
673 | LOKAsyncEventData* pLOKEv = new LOKAsyncEventData; | ||||||
674 | switch (rLokMouseEventData.mnType) | ||||||
| |||||||
675 | { | ||||||
676 | case LOK_MOUSEEVENT_MOUSEBUTTONDOWN: | ||||||
677 | pLOKEv->mnEvent = VclEventId::WindowMouseButtonDown; | ||||||
678 | break; | ||||||
679 | case LOK_MOUSEEVENT_MOUSEBUTTONUP: | ||||||
680 | pLOKEv->mnEvent = VclEventId::WindowMouseButtonUp; | ||||||
681 | break; | ||||||
682 | case LOK_MOUSEEVENT_MOUSEMOVE: | ||||||
683 | pLOKEv->mnEvent = VclEventId::WindowMouseMove; | ||||||
684 | break; | ||||||
685 | default: | ||||||
686 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 686, __extension__ __PRETTY_FUNCTION__)); | ||||||
687 | } | ||||||
688 | |||||||
689 | // no reason - just always true so far. | ||||||
690 | assert (rLokMouseEventData.meModifiers == MouseEventModifiers::SIMPLECLICK)(static_cast <bool> (rLokMouseEventData.meModifiers == MouseEventModifiers ::SIMPLECLICK) ? void (0) : __assert_fail ("rLokMouseEventData.meModifiers == MouseEventModifiers::SIMPLECLICK" , "/home/maarten/src/libreoffice/core/sfx2/source/view/lokhelper.cxx" , 690, __extension__ __PRETTY_FUNCTION__)); | ||||||
691 | |||||||
692 | pLOKEv->maMouseEvent = MouseEvent(rLokMouseEventData.maPosition, rLokMouseEventData.mnCount, | ||||||
693 | rLokMouseEventData.meModifiers, rLokMouseEventData.mnButtons, | ||||||
694 | rLokMouseEventData.mnModifier); | ||||||
695 | if (rLokMouseEventData.maLogicPosition) | ||||||
696 | { | ||||||
697 | pLOKEv->maMouseEvent.setLogicPosition(*rLokMouseEventData.maLogicPosition); | ||||||
698 | } | ||||||
699 | pLOKEv->mpWindow = xWindow; | ||||||
700 | postEventAsync(pLOKEv); | ||||||
701 | } | ||||||
702 | |||||||
703 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_RTL_REF_HXX | ||||||||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||||||||
22 | |||||||||||||
23 | #include "sal/config.h" | ||||||||||||
24 | |||||||||||||
25 | #include <cassert> | ||||||||||||
26 | #include <cstddef> | ||||||||||||
27 | #include <functional> | ||||||||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
29 | #include <type_traits> | ||||||||||||
30 | #endif | ||||||||||||
31 | |||||||||||||
32 | #include "sal/types.h" | ||||||||||||
33 | |||||||||||||
34 | namespace rtl | ||||||||||||
35 | { | ||||||||||||
36 | |||||||||||||
37 | /** Template reference class for reference type. | ||||||||||||
38 | */ | ||||||||||||
39 | template <class reference_type> | ||||||||||||
40 | class Reference | ||||||||||||
41 | { | ||||||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||||||
43 | */ | ||||||||||||
44 | reference_type * m_pBody; | ||||||||||||
45 | |||||||||||||
46 | |||||||||||||
47 | public: | ||||||||||||
48 | /** Constructor... | ||||||||||||
49 | */ | ||||||||||||
50 | Reference() | ||||||||||||
51 | : m_pBody (NULL__null) | ||||||||||||
52 | {} | ||||||||||||
53 | |||||||||||||
54 | |||||||||||||
55 | /** Constructor... | ||||||||||||
56 | */ | ||||||||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||||||||
58 | : m_pBody (pBody) | ||||||||||||
59 | { | ||||||||||||
60 | } | ||||||||||||
61 | |||||||||||||
62 | /** Constructor... | ||||||||||||
63 | */ | ||||||||||||
64 | Reference (reference_type * pBody) | ||||||||||||
65 | : m_pBody (pBody) | ||||||||||||
66 | { | ||||||||||||
67 | if (m_pBody) | ||||||||||||
68 | m_pBody->acquire(); | ||||||||||||
69 | } | ||||||||||||
70 | |||||||||||||
71 | /** Copy constructor... | ||||||||||||
72 | */ | ||||||||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||||||||
74 | : m_pBody (handle.m_pBody) | ||||||||||||
75 | { | ||||||||||||
76 | if (m_pBody) | ||||||||||||
77 | m_pBody->acquire(); | ||||||||||||
78 | } | ||||||||||||
79 | |||||||||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
81 | /** Move constructor... | ||||||||||||
82 | */ | ||||||||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||||||||
84 | : m_pBody (handle.m_pBody) | ||||||||||||
85 | { | ||||||||||||
86 | handle.m_pBody = nullptr; | ||||||||||||
87 | } | ||||||||||||
88 | #endif | ||||||||||||
89 | |||||||||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||||||||
92 | |||||||||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||||||||
94 | |||||||||||||
95 | @param rRef another reference | ||||||||||||
96 | */ | ||||||||||||
97 | template< class derived_type > | ||||||||||||
98 | inline Reference( | ||||||||||||
99 | const Reference< derived_type > & rRef, | ||||||||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||||||||
101 | : m_pBody (rRef.get()) | ||||||||||||
102 | { | ||||||||||||
103 | if (m_pBody) | ||||||||||||
104 | m_pBody->acquire(); | ||||||||||||
105 | } | ||||||||||||
106 | #endif | ||||||||||||
107 | |||||||||||||
108 | /** Destructor... | ||||||||||||
109 | */ | ||||||||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||||||||
111 | { | ||||||||||||
112 | if (m_pBody
| ||||||||||||
113 | m_pBody->release(); | ||||||||||||
| |||||||||||||
114 | } | ||||||||||||
115 | |||||||||||||
116 | /** Set... | ||||||||||||
117 | Similar to assignment. | ||||||||||||
118 | */ | ||||||||||||
119 | Reference<reference_type> & | ||||||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||||||
121 | { | ||||||||||||
122 | if (pBody) | ||||||||||||
123 | pBody->acquire(); | ||||||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||||||
125 | m_pBody = pBody; | ||||||||||||
126 | if (pOld) | ||||||||||||
127 | pOld->release(); | ||||||||||||
128 | return *this; | ||||||||||||
129 | } | ||||||||||||
130 | |||||||||||||
131 | /** Assignment. | ||||||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||||||
133 | bind it to the body represented by the handle. | ||||||||||||
134 | */ | ||||||||||||
135 | Reference<reference_type> & | ||||||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||||||
137 | { | ||||||||||||
138 | return set( handle.m_pBody ); | ||||||||||||
139 | } | ||||||||||||
140 | |||||||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
142 | /** Assignment. | ||||||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||||||
144 | * bind it to the body represented by the handle, and | ||||||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||||||
146 | */ | ||||||||||||
147 | Reference<reference_type> & | ||||||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||||||
149 | { | ||||||||||||
150 | // self-movement guts ourself | ||||||||||||
151 | if (m_pBody) | ||||||||||||
152 | m_pBody->release(); | ||||||||||||
153 | m_pBody = handle.m_pBody; | ||||||||||||
154 | handle.m_pBody = nullptr; | ||||||||||||
155 | return *this; | ||||||||||||
156 | } | ||||||||||||
157 | #endif | ||||||||||||
158 | |||||||||||||
159 | /** Assignment... | ||||||||||||
160 | */ | ||||||||||||
161 | Reference<reference_type> & | ||||||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||||||
163 | { | ||||||||||||
164 | return set( pBody ); | ||||||||||||
165 | } | ||||||||||||
166 | |||||||||||||
167 | /** Unbind the body from this handle. | ||||||||||||
168 | Note that for a handle representing a large body, | ||||||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||||||
171 | since in the second case two large objects exist in memory | ||||||||||||
172 | (the old body and the new body). | ||||||||||||
173 | */ | ||||||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||||||
175 | { | ||||||||||||
176 | if (m_pBody) | ||||||||||||
177 | { | ||||||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||||||
179 | m_pBody = NULL__null; | ||||||||||||
180 | pOld->release(); | ||||||||||||
181 | } | ||||||||||||
182 | return *this; | ||||||||||||
183 | } | ||||||||||||
184 | |||||||||||||
185 | |||||||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||||||
188 | are the same. | ||||||||||||
189 | */ | ||||||||||||
190 | reference_type * SAL_CALL get() const | ||||||||||||
191 | { | ||||||||||||
192 | return m_pBody; | ||||||||||||
193 | } | ||||||||||||
194 | |||||||||||||
195 | |||||||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||||||
197 | */ | ||||||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||||||
199 | { | ||||||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
201 | return m_pBody; | ||||||||||||
202 | } | ||||||||||||
203 | |||||||||||||
204 | |||||||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||||||
206 | */ | ||||||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||||||
208 | { | ||||||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
210 | return *m_pBody; | ||||||||||||
211 | } | ||||||||||||
212 | |||||||||||||
213 | |||||||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||||||
215 | */ | ||||||||||||
216 | bool SAL_CALL is() const | ||||||||||||
217 | { | ||||||||||||
218 | return (m_pBody != NULL__null); | ||||||||||||
219 | } | ||||||||||||
220 | |||||||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||||||
223 | */ | ||||||||||||
224 | explicit operator bool() const | ||||||||||||
225 | { | ||||||||||||
226 | return is(); | ||||||||||||
227 | } | ||||||||||||
228 | #endif | ||||||||||||
229 | |||||||||||||
230 | /** Returns True if this points to pBody. | ||||||||||||
231 | */ | ||||||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||||||
233 | { | ||||||||||||
234 | return (m_pBody == pBody); | ||||||||||||
235 | } | ||||||||||||
236 | |||||||||||||
237 | |||||||||||||
238 | /** Returns True if handle points to the same body. | ||||||||||||
239 | */ | ||||||||||||
240 | bool | ||||||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||||||
242 | { | ||||||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||||||
244 | } | ||||||||||||
245 | |||||||||||||
246 | |||||||||||||
247 | /** Needed to place References into STL collection. | ||||||||||||
248 | */ | ||||||||||||
249 | bool | ||||||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||||||
251 | { | ||||||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||||||
253 | } | ||||||||||||
254 | |||||||||||||
255 | |||||||||||||
256 | /** Needed to place References into STL collection. | ||||||||||||
257 | */ | ||||||||||||
258 | bool | ||||||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||||||
260 | { | ||||||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||||||
262 | } | ||||||||||||
263 | |||||||||||||
264 | |||||||||||||
265 | /** Needed to place References into STL collection. | ||||||||||||
266 | */ | ||||||||||||
267 | bool | ||||||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||||||
269 | { | ||||||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||||||
271 | } | ||||||||||||
272 | }; | ||||||||||||
273 | |||||||||||||
274 | } // namespace rtl | ||||||||||||
275 | |||||||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
277 | namespace std | ||||||||||||
278 | { | ||||||||||||
279 | |||||||||||||
280 | /// @cond INTERNAL | ||||||||||||
281 | /** | ||||||||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||||||||
283 | |||||||||||||
284 | @since LibreOffice 6.3 | ||||||||||||
285 | */ | ||||||||||||
286 | template<typename T> | ||||||||||||
287 | struct hash<::rtl::Reference<T>> | ||||||||||||
288 | { | ||||||||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||||||||
290 | { return std::size_t(s.get()); } | ||||||||||||
291 | }; | ||||||||||||
292 | /// @endcond | ||||||||||||
293 | |||||||||||||
294 | } | ||||||||||||
295 | |||||||||||||
296 | #endif | ||||||||||||
297 | |||||||||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||||||||
299 | |||||||||||||
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |