LibreOffice Module test (master) 1
lokcallback.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
10#include <test/lokcallback.hxx>
11
12#include <LibreOfficeKit/LibreOfficeKitEnums.h>
13#include <rtl/strbuf.hxx>
14#include <tools/gen.hxx>
15#include <comphelper/lok.hxx>
16#include <sfx2/viewsh.hxx>
17
18TestLokCallbackWrapper::TestLokCallbackWrapper(LibreOfficeKitCallback callback, void* data)
19 : Idle("TestLokCallbackWrapper flush timer")
20 , m_callback(callback)
21 , m_data(data)
22{
23 // Flushing timer needs to run with the lowest priority, so that all pending tasks
24 // such as invalidations are processed before it.
25 SetPriority(TaskPriority::LOWEST);
26}
27
29{
30 m_viewId = -1;
31 m_updatedTypes.clear();
33}
34
36{
37 if (!IsActive())
38 Start();
39}
40
41constexpr int NO_VIEWID = -1;
42
43inline void TestLokCallbackWrapper::callCallback(int nType, const char* pPayload, int nViewId)
44{
45 discardUpdatedTypes(nType, nViewId);
46 m_callback(nType, pPayload, m_data);
47 startTimer();
48}
49
50void TestLokCallbackWrapper::libreOfficeKitViewCallback(int nType, const rtl::OString& pPayload)
51{
52 callCallback(nType, pPayload.getStr(), NO_VIEWID);
53}
54
56 const rtl::OString& pPayload,
57 int nViewId)
58{
59 callCallback(nType, pPayload.getStr(), nViewId);
60}
61
63 const tools::Rectangle* pRect, int nPart, int nMode)
64{
65 OStringBuffer buf(64);
66 if (pRect)
67 buf.append(pRect->toString());
68 else
69 buf.append("EMPTY");
71 {
72 buf.append(", " + OString::number(static_cast<sal_Int32>(nPart)) + ", "
73 + OString::number(static_cast<sal_Int32>(nMode)));
74 }
75 callCallback(LOK_CALLBACK_INVALIDATE_TILES, buf.makeStringAndClear().getStr(), NO_VIEWID);
76}
77
78// TODO This is probably a pointless code duplication with CallbackFlushHandler,
79// and using this in unittests also means that CallbackFlushHandler does not get
80// tested as thoroughly as it could. On the other hand, this class is simpler,
81// so debugging those unittests should also be simpler. The proper solution
82// is presumably this class using CallbackFlushHandler internally by default,
83// but having an option to use this simpler code when needed.
84
86{
87 if (std::find(m_updatedTypes.begin(), m_updatedTypes.end(), nType) == m_updatedTypes.end())
88 {
89 m_updatedTypes.push_back(nType);
90 startTimer();
91 }
92}
93
95 int nSourceViewId)
96{
97 const PerViewIdData data{ nType, nViewId, nSourceViewId };
99 // The source view doesn't matter for uniqueness, just keep the latest one.
100 auto it = std::find_if(l.begin(), l.end(), [data](const PerViewIdData& other) {
101 return data.type == other.type && data.viewId == other.viewId;
102 });
103 if (it != l.end())
104 *it = data;
105 else
106 l.push_back(data);
107 startTimer();
108}
109
111{
112 // Invoke() will call flushPendingLOKInvalidateTiles().
113 startTimer();
114}
115
117{
118 // If a callback is called directly with an event, drop the updated flag for it, since
119 // the direct event replaces it.
120 for (auto it = m_updatedTypes.begin(); it != m_updatedTypes.end();)
121 {
122 if (*it == nType)
123 it = m_updatedTypes.erase(it);
124 else
125 ++it;
126 }
127 // If we do not have a specific view id, drop flag for all views.
128 bool allViewIds = false;
129 if (nViewId < 0)
130 allViewIds = true;
131 if (nType == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR
133 allViewIds = true;
134 for (auto it = m_updatedTypesPerViewId.begin(); it != m_updatedTypesPerViewId.end();)
135 {
136 if (it->type == nType && (allViewIds || it->viewId == nViewId))
137 it = m_updatedTypesPerViewId.erase(it);
138 else
139 ++it;
140 }
141}
142
144{
145 if (m_updatedTypes.empty() && m_updatedTypesPerViewId.empty())
146 return;
147 // Ask for payloads of all the pending types that need updating, and call the generic callback with that data.
148 assert(m_viewId >= 0);
149 SfxViewShell* viewShell = SfxViewShell::GetFirst(false, [this](const SfxViewShell* shell) {
150 return shell->GetViewShellId().get() == m_viewId;
151 });
152 assert(viewShell != nullptr);
153 // First move data to local structures, so that callbacks don't possibly modify it.
154 std::vector<int> updatedTypes;
155 std::swap(updatedTypes, m_updatedTypes);
156 std::vector<PerViewIdData> updatedTypesPerViewId;
157 std::swap(updatedTypesPerViewId, m_updatedTypesPerViewId);
158
159 for (int type : updatedTypes)
160 {
161 std::optional<OString> payload = viewShell->getLOKPayload(type, m_viewId);
162 if (payload)
164 }
165 for (const PerViewIdData& data : updatedTypesPerViewId)
166 {
167 viewShell = SfxViewShell::GetFirst(false, [data](const SfxViewShell* shell) {
168 return shell->GetViewShellId().get() == data.sourceViewId;
169 });
170 assert(viewShell != nullptr);
171 std::optional<OString> payload = viewShell->getLOKPayload(data.type, data.viewId);
172 if (payload)
173 libreOfficeKitViewCallbackWithViewId(data.type, *payload, data.viewId);
174 }
175}
176
178{
179 // Timer timeout, flush any possibly pending data.
180 for (SfxViewShell* viewShell = SfxViewShell::GetFirst(false); viewShell != nullptr;
181 viewShell = SfxViewShell::GetNext(*viewShell, false))
182 {
183 viewShell->flushPendingLOKInvalidateTiles();
184 }
185 flushLOKData();
186}
187
188/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void Start(bool bStartTimer=true) override
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
static SAL_WARN_UNUSED_RESULT SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
virtual std::optional< OString > getLOKPayload(int nType, int nViewId) const
bool IsActive() const
void SetPriority(TaskPriority ePriority)
virtual void libreOfficeKitViewCallback(int nType, const rtl::OString &pPayload) override
Definition: lokcallback.cxx:50
virtual void libreOfficeKitViewUpdatedCallback(int nType) override
Definition: lokcallback.cxx:85
virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId) override
Definition: lokcallback.cxx:94
void discardUpdatedTypes(int nType, int nViewId)
virtual void Invoke() override
virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle *pRect, int nPart, int nMode) override
Definition: lokcallback.cxx:62
std::vector< int > m_updatedTypes
Definition: lokcallback.hxx:55
TestLokCallbackWrapper(LibreOfficeKitCallback callback, void *data)
Definition: lokcallback.cxx:18
void callCallback(int nType, const char *pPayload, int nViewId)
Definition: lokcallback.cxx:43
virtual void libreOfficeKitViewCallbackWithViewId(int nType, const rtl::OString &pPayload, int nViewId) override
Definition: lokcallback.cxx:55
LibreOfficeKitCallback m_callback
Definition: lokcallback.hxx:52
void clear()
Discard all possibly still held events.
Definition: lokcallback.cxx:28
virtual void libreOfficeKitViewAddPendingInvalidateTiles() override
std::vector< PerViewIdData > m_updatedTypesPerViewId
Definition: lokcallback.hxx:62
rtl::OString toString() const
constexpr int NO_VIEWID
Definition: lokcallback.cxx:41
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
QPRO_FUNC_TYPE nType
ResultType type