Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/sfx2/lokhelper.hxx
Line
Count
Source
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
#ifndef INCLUDED_SFX2_LOKHELPER_HXX
11
#define INCLUDED_SFX2_LOKHELPER_HXX
12
13
#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
14
#include <com/sun/star/security/XCertificate.hpp>
15
#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
16
17
#include <vcl/IDialogRenderable.hxx>
18
#include <vcl/ITiledRenderable.hxx>
19
#include <vcl/event.hxx>
20
#include <vcl/vclptr.hxx>
21
#include <vcl/window.hxx>
22
#include <sfx2/dllapi.h>
23
#include <sfx2/viewsh.hxx>
24
#include <tools/gen.hxx>
25
#include <cstddef>
26
#include <rtl/strbuf.hxx>
27
#include <rtl/string.hxx>
28
#include <list>
29
#include <optional>
30
#include <string_view>
31
#include <unordered_map>
32
33
#include <boost/property_tree/ptree_fwd.hpp>
34
35
#define LOK_NOTIFY_LOG_TO_CLIENT 1
36
37
#define LOK_LOG_STREAM(level, area, stream) \
38
0
    do { \
39
0
            ::std::ostringstream lok_detail_stream; \
40
0
            lok_detail_stream << level << ':'; \
41
0
            if (std::strcmp(level, "debug") != 0) \
42
0
                lok_detail_stream << area << ':'; \
43
0
            const char* const where = SAL_WHERE; \
44
0
            lok_detail_stream << where << stream; \
45
0
            SfxLokHelper::notifyLog(lok_detail_stream); \
46
0
        } while (false)
47
48
#if LOK_NOTIFY_LOG_TO_CLIENT > 0
49
#define LOK_INFO(area, stream) \
50
0
    LOK_LOG_STREAM("info", area, stream) \
51
52
#define LOK_WARN(area, stream) \
53
0
    LOK_LOG_STREAM("warn", area, stream)
54
55
#else
56
#define LOK_INFO(area, stream) \
57
    SAL_INFO(area, stream) \
58
59
#define LOK_WARN(area, stream) \
60
    SAL_WARN(area, stream)
61
62
#endif
63
64
struct SFX2_DLLPUBLIC LokMouseEventData
65
{
66
    int mnType;
67
    Point maPosition;
68
    int mnCount;
69
    MouseEventModifiers meModifiers;
70
    int mnButtons;
71
    int mnModifier;
72
    std::optional<Point> maLogicPosition;
73
74
    LokMouseEventData(int nType, Point aPosition, int nCount, MouseEventModifiers eModifiers, int nButtons, int nModifier)
75
0
        : mnType(nType)
76
0
        , maPosition(aPosition)
77
0
        , mnCount(nCount)
78
0
        , meModifiers(eModifiers)
79
0
        , mnButtons(nButtons)
80
0
        , mnModifier(nModifier)
81
0
    {}
82
};
83
84
namespace com::sun::star::ui { struct ContextChangeEventObject; };
85
86
class SFX2_DLLPUBLIC SfxLokHelper
87
{
88
public:
89
    /// Gets the short cut accelerators.
90
    static std::unordered_map<OUString, css::uno::Reference<css::ui::XAcceleratorConfiguration>>& getAcceleratorConfs();
91
    /// Create a new view shell from the current view frame.
92
    /// This assumes a single document is ever loaded.
93
    static int createView();
94
    /// Create a new view shell for the given DocId, for multi-document support.
95
    static int createView(int nDocId);
96
    /// Destroy a view shell from the global shell list.
97
    static void destroyView(int nId);
98
    /// Set a view shell as current one.
99
    static void setView(int nId);
100
    /// Determines if a call to setView() is in progress or not.
101
    static bool isSettingView();
102
    /// Set the edit mode for a document with callbacks disabled.
103
    static void setEditMode(int nMode, vcl::ITiledRenderable* pDoc);
104
    /// Get view shell with id
105
    static SfxViewShell* getViewOfId(int nId);
106
    /// Get view id of view shell
107
    static int getView(const SfxViewShell& rViewShell);
108
    /// Get the currently active view shell id
109
    static int getCurrentView();
110
    /// Get the number of views of the current DocId.
111
    static std::size_t getViewsCount(int nDocId);
112
    /// Get the number of docs
113
    static std::size_t getDocsCount();
114
    /// Get the most recently active viewId of the DocId.
115
    static int getViewId(int nDocId);
116
    /// Get viewIds of views of the DocId.
117
    static bool getViewIds(int nDocId, int* pArray, size_t nSize);
118
    /// Set View Blocked for some uno commands
119
    static void setBlockedCommandList(int nViewId, const char* blockedCommandList);
120
    /// Get the document id for a view
121
    static int getDocumentIdOfView(int nViewId);
122
    /// Get the default language that should be used for views
123
    static const LanguageTag & getDefaultLanguage();
124
    /// Set language of the given view.
125
    static void setViewLanguage(int nId, const OUString& rBcp47LanguageTag);
126
    /// Set the default language for views.
127
    static void setDefaultLanguage(const OUString& rBcp47LanguageTag);
128
    /// Enable/Disable AT support for the given view.
129
    static void setAccessibilityState(int nId, bool nEnabled);
130
    // Set the readonly state of the view.
131
    static void setViewReadOnly(int nId, bool readOnly);
132
    // In readonly view, can user add / modify comments or not.
133
    static void setAllowChangeComments(int nId, bool allow);
134
    // In readonly view, can user accept / reject tracked changes or not.
135
    static void setAllowManageRedlines(int nId, bool allow);
136
    /// Get the language used by the loading view (used for all save operations).
137
    static const LanguageTag & getLoadLanguage();
138
    /// Set the language used by the loading view (used for all save operations).
139
    static void setLoadLanguage(const OUString& rBcp47LanguageTag);
140
    /// Set the locale for the given view.
141
    static void setViewLocale(int nId, const OUString& rBcp47LanguageTag);
142
    /// Set the language and locale for the given view.
143
    static void setViewLanguageAndLocale(int nId, const OUString& rBcp47LanguageTag);
144
    /// Get the device form factor that should be used for a new view.
145
    static LOKDeviceFormFactor getDeviceFormFactor();
146
    /// Set the device form factor that should be used for a new view.
147
    static void setDeviceFormFactor(std::u16string_view rDeviceFormFactor);
148
    /// Set color preview state for the given view.
149
    static void setColorPreviewState(int nId, bool nEnabled);
150
151
    /// Set timezone of the given view.
152
    /// @isSet true to use @rTimezone, even if it's empty. Otherwise, no timezone.
153
    /// @rTimezone the value to set (which could be empty).
154
    static void setDefaultTimezone(bool isSet, const OUString& rTimezone);
155
    /// Get timezone of the given view. See @setDefaultTimezone.
156
    static std::pair<bool, OUString> getDefaultTimezone();
157
    /// Set the timezone of the given view.
158
    static void setViewTimezone(int nId, bool isSet, const OUString& rTimezone);
159
    /// Get the timezone of the given view.
160
    static std::pair<bool, OUString> getViewTimezone(int nId);
161
162
    /// Iterate over any view shell, except pThisViewShell, passing it to the f function.
163
    template<typename ViewShellType, typename FunctionType>
164
    static void forEachOtherView(ViewShellType* pThisViewShell, FunctionType f);
165
166
    /// Invoke the LOK callback of all other views showing the same document as pThisView, with a payload of rKey-rPayload.
167
    static void notifyOtherViews(const SfxViewShell* pThisView, int nType, std::string_view rKey,
168
                                 const OString& rPayload);
169
    /// Invoke the LOK callback of all views except pThisView, with a JSON payload created from the given property tree.
170
    static void notifyOtherViews(const SfxViewShell* pThisView, int nType,
171
                                 const boost::property_tree::ptree& rTree);
172
    /// Same as notifyOtherViews(), but works on a selected "other" view, not on all of them.
173
    static void notifyOtherView(const SfxViewShell& rThisView, SfxViewShell const* pOtherView,
174
                                int nType, std::string_view rKey, const OString& rPayload);
175
    /// Same as notifyOtherViews(), the property-tree version, but works on a selected "other" view, not on all of them.
176
    static void notifyOtherView(const SfxViewShell& rThisView, SfxViewShell const* pOtherView,
177
                                int nType, const boost::property_tree::ptree& rTree);
178
179
    /// Emits a LOK_CALLBACK_STATE_CHANGED
180
    static void sendUnoStatus(const SfxViewShell* pShell, const SfxPoolItem* pItem);
181
    /// Emits a LOK_CALLBACK_WINDOW
182
    static void notifyWindow(const SfxViewShell* pThisView,
183
                             vcl::LOKWindowId nWindowId,
184
                             std::u16string_view rAction,
185
                             const std::vector<vcl::LOKPayloadItem>& rPayload = std::vector<vcl::LOKPayloadItem>());
186
    /// Emits a LOK_CALLBACK_DOCUMENT_SIZE_CHANGED - if @bInvalidateAll - first invalidates all parts
187
    static void notifyDocumentSizeChanged(SfxViewShell const* pThisView, const OString& rPayload, vcl::ITiledRenderable* pDoc, bool bInvalidateAll = true);
188
    /// Emits a LOK_CALLBACK_DOCUMENT_SIZE_CHANGED for all views of the same document - if @bInvalidateAll - first invalidates all parts
189
    static void notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable* pDoc, bool bInvalidateAll = true);
190
    /// Emits a LOK_CALLBACK_STATE_CHANGED for all views of the same document - with payload ".uno:CurrentPageResize"
191
    static void notifyCurrentPageSizeChangedAllViews(const vcl::ITiledRenderable* pDoc);
192
    /// Emits a LOK_CALLBACK_DOCUMENT_SIZE_CHANGED for all views of the same document with the same part
193
    static void notifyPartSizeChangedAllViews(vcl::ITiledRenderable* pDoc, int nPart);
194
    /// Emits a LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR
195
    static void notifyCursorInvalidation(SfxViewShell const* pThisView, tools::Rectangle const * pRect, bool bControlEvent, int windowID);
196
    /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
197
    static void notifyInvalidation(SfxViewShell const* pThisView, int nPart, tools::Rectangle const *);
198
    /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed
199
    /// uses the Part reported by pThisView
200
    static void notifyInvalidation(SfxViewShell const* pThisView, tools::Rectangle const *);
201
    /// Notifies all views with the given type and payload.
202
    static void notifyAllViews(int nType, const OString& rPayload);
203
204
    /// Notify about the editing context change.
205
    static void notifyContextChange(const css::ui::ContextChangeEventObject& rEvent);
206
207
    /// Emits an LOK_CALLBACK_VIEW_RENDER_STATE
208
    static void notifyViewRenderState(SfxViewShell const* pViewShell, vcl::ITiledRenderable* pDoc);
209
210
    // Notify about the given type needing an update.
211
    static void notifyUpdate(SfxViewShell const* pViewShell, int nType);
212
    // Notify about the given type needing a per-viewid update.
213
    static void notifyUpdatePerViewId(SfxViewShell const& rViewShell, int nType);
214
    /// Same as notifyUpdatePerViewId(), pTargetShell will be notified, relevant viewId in pViewShell,
215
    /// pSourceView->getLOKPayload() will be called to get the data.
216
    static void notifyUpdatePerViewId(SfxViewShell const& rTargetShell, SfxViewShell const* pViewShell,
217
        SfxViewShell const& rSourceShell, int nType);
218
    // Notify other views about the given type needing a per-viewid update.
219
    static void notifyOtherViewsUpdatePerViewId(SfxViewShell const* pViewShell, int nType);
220
221
    static OString makePayloadJSON(const SfxViewShell* pThisView, int nViewId, std::string_view rKey, const OString& rPayload);
222
    /// Makes a LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR payload, but tweaks it according to setOptionalFeatures() if needed.
223
    static OString makeVisCursorInvalidation(int nViewId, const OString& rRectangle,
224
                                             bool bMispelledWord = false, const OString& rHyperlink = ""_ostr);
225
226
    /// Helper for posting async key event
227
    static void postKeyEventAsync(const VclPtr<vcl::Window> &xWindow,
228
                                  int nType, int nCharCode, int nKeyCode, int nRepeat = 0);
229
230
    /// Helper for posting input event
231
    static void postExtTextEventAsync(const VclPtr<vcl::Window> &xWindow,
232
                                      int nType, const OUString &rText);
233
234
    /// Helper for posting async mouse event
235
    static void postMouseEventAsync(const VclPtr<vcl::Window> &xWindow, LokMouseEventData const & rLokMouseEventData);
236
237
    /// A special value to signify 'infinity'.
238
    /// This value is chosen such that sal_Int32 will not overflow when manipulated.
239
    static const tools::Long MaxTwips = 1e9;
240
241
    /// Helper for diagnosing run-time problems
242
    static void dumpState(rtl::OStringBuffer &rState);
243
244
    /// Process the mouse event in the currently active in-place component (if any).
245
    /// Returns true if the event has been processed, and no further processing is necessary.
246
    static bool testInPlaceComponentMouseEventHit(SfxViewShell* pViewShell, int nType, int nX,
247
                                                  int nY, int nCount, int nButtons, int nModifier,
248
                                                  double fScaleX, double fScaleY,
249
                                                  bool bNegativeX = false);
250
251
    static VclPtr<vcl::Window> getInPlaceDocWindow(SfxViewShell* pViewShell);
252
253
    /// Sends Network Access error to LOK
254
    static void sendNetworkAccessError(std::string_view rAction);
255
256
    static void notifyLog(const std::ostringstream& stream);
257
258
    /// Extracts base64 data inside begin/end markers.
259
    static std::string extractCertificate(const std::string& rCert);
260
    /// Extracts multiple certificates in base64 from inside begin/end markers.
261
    static std::vector<std::string> extractCertificates(const std::string& rCerts);
262
    /// Takes a single CA certificate to add them to the list of trusted certificates.
263
    static css::uno::Reference<css::security::XCertificate> addCertificate(const css::uno::Reference<css::xml::crypto::XCertificateCreator>& xCertificateCreator, const css::uno::Sequence<sal_Int8>& rCert);
264
    /// Takes a CA chain to add them to the list of trusted certificates.
265
    static void addCertificates(const std::vector<std::string>& rCerts);
266
    /// Parses a private key + certificate pair.
267
    static css::uno::Reference<css::security::XCertificate> getSigningCertificate(const std::string& rCert, const std::string& rKey);
268
    /// Decides if it's OK to call getCommandValues(rCommand).
269
    static bool supportsCommand(std::u16string_view rCommand);
270
    /// Returns information about a given command in JSON format.
271
    static void getCommandValues(tools::JsonWriter& rJsonWriter, std::string_view rCommand);
272
    /// Parses key-value parameters of rCommand.
273
    static std::map<OUString, OUString> parseCommandParameters(std::u16string_view rCommand);
274
    /// Registers function pointers in comphelper/ to set/get of the current LOK view.
275
    static void registerViewCallbacks();
276
277
    static void dispatchUnoCommand(const boost::property_tree::ptree& tree);
278
279
private:
280
    static int createView(SfxViewFrame& rViewFrame, ViewShellDocId docId);
281
};
282
283
template<typename ViewShellType, typename FunctionType>
284
void SfxLokHelper::forEachOtherView(ViewShellType* pThisViewShell, FunctionType f)
285
0
{
286
0
    SfxViewShell* pViewShell = SfxViewShell::GetFirst();
287
0
    while (pViewShell)
288
0
    {
289
0
        auto pOtherViewShell = dynamic_cast<ViewShellType*>(pViewShell);
290
0
        if (pOtherViewShell != nullptr && pOtherViewShell != pThisViewShell && pOtherViewShell->GetDocId() == pThisViewShell->GetDocId())
291
0
        {
292
0
            f(pOtherViewShell);
293
0
        }
294
0
        pViewShell = SfxViewShell::GetNext(*pViewShell);
295
0
    }
296
0
}
Unexecuted instantiation: tabview3.cxx:void SfxLokHelper::forEachOtherView<ScTabViewShell, ScTabView::OnLibreOfficeKitTabChanged()::$_0>(ScTabViewShell*, ScTabView::OnLibreOfficeKitTabChanged()::$_0)
Unexecuted instantiation: tabview3.cxx:void SfxLokHelper::forEachOtherView<ScTabViewShell, ScTabView::KillEditView(bool)::$_0>(ScTabViewShell*, ScTabView::KillEditView(bool)::$_0)
Unexecuted instantiation: tabview5.cxx:void SfxLokHelper::forEachOtherView<ScTabViewShell, ScTabView::~ScTabView()::$_0>(ScTabViewShell*, ScTabView::~ScTabView()::$_0)
Unexecuted instantiation: tabvwsh3.cxx:void SfxLokHelper::forEachOtherView<ScTabViewShell, ScTabViewShell::Execute(SfxRequest&)::$_2>(ScTabViewShell*, ScTabViewShell::Execute(SfxRequest&)::$_2)
Unexecuted instantiation: tabvwsh3.cxx:void SfxLokHelper::forEachOtherView<ScTabViewShell, ScTabViewShell::Execute(SfxRequest&)::$_3>(ScTabViewShell*, ScTabViewShell::Execute(SfxRequest&)::$_3)
Unexecuted instantiation: viewdata.cxx:void SfxLokHelper::forEachOtherView<ScTabViewShell, (anonymous namespace)::lcl_LOKRemoveWindow(ScTabViewShell*, ScSplitPos)::$_0>(ScTabViewShell*, (anonymous namespace)::lcl_LOKRemoveWindow(ScTabViewShell*, ScSplitPos)::$_0)
Unexecuted instantiation: viewdata.cxx:void SfxLokHelper::forEachOtherView<ScTabViewShell, ScViewData::SetEditEngine(ScSplitPos, ScEditEngineDefaulter&, vcl::Window*, short, int)::$_0>(ScTabViewShell*, ScViewData::SetEditEngine(ScSplitPos, ScEditEngineDefaulter&, vcl::Window*, short, int)::$_0)
297
298
/// If LOK is active, switch to the language/locale of the provided shell and back on delete.
299
class SfxLokLanguageGuard
300
{
301
    bool m_bSetLanguage;
302
    const SfxViewShell* m_pOldShell;
303
304
public:
305
    SfxLokLanguageGuard(const SfxViewShell* pNewShell);
306
    ~SfxLokLanguageGuard();
307
};
308
309
typedef std::list<SfxViewShell*> ViewShellList;
310
311
/// Used to keep track of the last N views that text edited a document through an EditView
312
class SFX2_DLLPUBLIC LOKEditViewHistory
313
{
314
public:
315
    typedef std::list<SfxViewShell*> ViewShellList;
316
    typedef std::unordered_map<int, ViewShellList> EditViewHistoryMap;
317
318
    static void Update(bool bRemove = false);
319
    static ViewShellList GetHistoryForDoc(ViewShellDocId aDocId);
320
    static ViewShellList GetSortedViewsForDoc(ViewShellDocId aDocId);
321
private:
322
    static EditViewHistoryMap maEditViewHistory;
323
};
324
325
#endif
326
327
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */