/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: */ |