Drop some needless mappings to identical strings
[LibreOffice.git] / test / source / lokcallback.cxx
blob0fb3cefef2141ebe66aba146797daf18541e1316
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/.
8 */
10 #include <test/lokcallback.hxx>
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 #include <sfx2/childwin.hxx>
18 #include <sfx2/viewfrm.hxx>
19 #include <sfx2/sfxsids.hrc>
20 #include <sfx2/sidebar/SidebarDockingWindow.hxx>
22 TestLokCallbackWrapper::TestLokCallbackWrapper(LibreOfficeKitCallback callback, void* data)
23 : Idle("TestLokCallbackWrapper flush timer")
24 , m_callback(callback)
25 , m_data(data)
27 // Flushing timer needs to run with the lowest priority, so that all pending tasks
28 // such as invalidations are processed before it.
29 SetPriority(TaskPriority::LOWEST);
32 void TestLokCallbackWrapper::clear()
34 m_viewId = -1;
35 m_updatedTypes.clear();
36 m_updatedTypesPerViewId.clear();
39 inline void TestLokCallbackWrapper::startTimer()
41 if (!IsActive())
42 Start();
45 constexpr int NO_VIEWID = -1;
47 inline void TestLokCallbackWrapper::callCallback(int nType, const char* pPayload, int nViewId)
49 discardUpdatedTypes(nType, nViewId);
50 m_callback(nType, pPayload, m_data);
51 startTimer();
54 void TestLokCallbackWrapper::libreOfficeKitViewCallback(int nType, const rtl::OString& pPayload)
56 callCallback(nType, pPayload.getStr(), NO_VIEWID);
59 void TestLokCallbackWrapper::libreOfficeKitViewCallbackWithViewId(int nType,
60 const rtl::OString& pPayload,
61 int nViewId)
63 callCallback(nType, pPayload.getStr(), nViewId);
66 void TestLokCallbackWrapper::libreOfficeKitViewInvalidateTilesCallback(
67 const tools::Rectangle* pRect, int nPart, int nMode)
69 OStringBuffer buf(64);
70 if (pRect)
71 buf.append(pRect->toString());
72 else
73 buf.append("EMPTY");
74 if (comphelper::LibreOfficeKit::isPartInInvalidation())
76 buf.append(", " + OString::number(static_cast<sal_Int32>(nPart)) + ", "
77 + OString::number(static_cast<sal_Int32>(nMode)));
79 callCallback(LOK_CALLBACK_INVALIDATE_TILES, buf.makeStringAndClear().getStr(), NO_VIEWID);
82 // TODO This is probably a pointless code duplication with CallbackFlushHandler,
83 // and using this in unittests also means that CallbackFlushHandler does not get
84 // tested as thoroughly as it could. On the other hand, this class is simpler,
85 // so debugging those unittests should also be simpler. The proper solution
86 // is presumably this class using CallbackFlushHandler internally by default,
87 // but having an option to use this simpler code when needed.
89 void TestLokCallbackWrapper::libreOfficeKitViewUpdatedCallback(int nType)
91 if (std::find(m_updatedTypes.begin(), m_updatedTypes.end(), nType) == m_updatedTypes.end())
93 m_updatedTypes.push_back(nType);
94 startTimer();
98 void TestLokCallbackWrapper::libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId,
99 int nSourceViewId)
101 const PerViewIdData data{ nType, nViewId, nSourceViewId };
102 auto& l = m_updatedTypesPerViewId;
103 // The source view doesn't matter for uniqueness, just keep the latest one.
104 auto it = std::find_if(l.begin(), l.end(), [data](const PerViewIdData& other) {
105 return data.type == other.type && data.viewId == other.viewId;
107 if (it != l.end())
108 *it = data;
109 else
110 l.push_back(data);
111 startTimer();
114 void TestLokCallbackWrapper::libreOfficeKitViewAddPendingInvalidateTiles()
116 // Invoke() will call flushPendingLOKInvalidateTiles().
117 startTimer();
120 void TestLokCallbackWrapper::discardUpdatedTypes(int nType, int nViewId)
122 // If a callback is called directly with an event, drop the updated flag for it, since
123 // the direct event replaces it.
124 for (auto it = m_updatedTypes.begin(); it != m_updatedTypes.end();)
126 if (*it == nType)
127 it = m_updatedTypes.erase(it);
128 else
129 ++it;
131 // If we do not have a specific view id, drop flag for all views.
132 bool allViewIds = false;
133 if (nViewId < 0)
134 allViewIds = true;
135 if (nType == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR
136 && !comphelper::LibreOfficeKit::isViewIdForVisCursorInvalidation())
137 allViewIds = true;
138 for (auto it = m_updatedTypesPerViewId.begin(); it != m_updatedTypesPerViewId.end();)
140 if (it->type == nType && (allViewIds || it->viewId == nViewId))
141 it = m_updatedTypesPerViewId.erase(it);
142 else
143 ++it;
147 void TestLokCallbackWrapper::flushLOKData()
149 if (m_updatedTypes.empty() && m_updatedTypesPerViewId.empty())
150 return;
151 // Ask for payloads of all the pending types that need updating, and call the generic callback with that data.
152 assert(m_viewId >= 0);
153 SfxViewShell* viewShell = SfxViewShell::GetFirst(false, [this](const SfxViewShell& shell) {
154 return shell.GetViewShellId().get() == m_viewId;
156 assert(viewShell != nullptr);
157 // First move data to local structures, so that callbacks don't possibly modify it.
158 std::vector<int> updatedTypes;
159 std::swap(updatedTypes, m_updatedTypes);
160 std::vector<PerViewIdData> updatedTypesPerViewId;
161 std::swap(updatedTypesPerViewId, m_updatedTypesPerViewId);
163 for (int type : updatedTypes)
165 std::optional<OString> payload = viewShell->getLOKPayload(type, m_viewId);
166 if (payload)
167 libreOfficeKitViewCallback(type, *payload);
169 for (const PerViewIdData& data : updatedTypesPerViewId)
171 viewShell = SfxViewShell::GetFirst(false, [data](const SfxViewShell& shell) {
172 return shell.GetViewShellId().get() == data.sourceViewId;
174 assert(viewShell != nullptr);
175 std::optional<OString> payload = viewShell->getLOKPayload(data.type, data.viewId);
176 if (payload)
177 libreOfficeKitViewCallbackWithViewId(data.type, *payload, data.viewId);
181 void TestLokCallbackWrapper::Invoke()
183 // Timer timeout, flush any possibly pending data.
184 for (SfxViewShell* viewShell = SfxViewShell::GetFirst(false); viewShell != nullptr;
185 viewShell = SfxViewShell::GetNext(*viewShell, false))
187 viewShell->flushPendingLOKInvalidateTiles();
189 flushLOKData();
192 SfxChildWindow* TestLokCallbackWrapper::InitializeSidebar()
194 // in init.cxx we do setupSidebar which creates the controller, do it here
196 SfxViewShell* pViewShell = SfxViewShell::Current();
197 assert(pViewShell);
199 SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
200 rViewFrame.ShowChildWindow(SID_SIDEBAR);
201 SfxChildWindow* pSideBar = rViewFrame.GetChildWindow(SID_SIDEBAR);
202 assert(pSideBar);
204 auto pDockingWin = dynamic_cast<sfx2::sidebar::SidebarDockingWindow*>(pSideBar->GetWindow());
205 assert(pDockingWin);
207 pDockingWin->GetOrCreateSidebarController(); // just to create the controller
209 return pSideBar;
212 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */