workaround segfault in compiler on macos-clang-intel
[LibreOffice.git] / include / sfx2 / lokhelper.hxx
blob3820558d65007c229f4a73fb05484222e9d07701
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 #ifndef INCLUDED_SFX2_LOKHELPER_HXX
11 #define INCLUDED_SFX2_LOKHELPER_HXX
13 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
15 #include <vcl/IDialogRenderable.hxx>
16 #include <vcl/ITiledRenderable.hxx>
17 #include <vcl/event.hxx>
18 #include <vcl/vclptr.hxx>
19 #include <vcl/window.hxx>
20 #include <sfx2/dllapi.h>
21 #include <sfx2/viewsh.hxx>
22 #include <tools/gen.hxx>
23 #include <cstddef>
24 #include <rtl/strbuf.hxx>
25 #include <rtl/string.hxx>
26 #include <list>
27 #include <optional>
28 #include <string_view>
29 #include <unordered_map>
31 #define LOK_NOTIFY_LOG_TO_CLIENT 1
33 #define LOK_LOG_STREAM(level, area, stream) \
34 do { \
35 ::std::ostringstream lok_detail_stream; \
36 lok_detail_stream << level << ':'; \
37 if (std::strcmp(level, "debug") != 0) \
38 lok_detail_stream << area << ':'; \
39 const char* const where = SAL_WHERE; \
40 lok_detail_stream << where << stream; \
41 SfxLokHelper::notifyLog(lok_detail_stream); \
42 } while (false)
44 #if LOK_NOTIFY_LOG_TO_CLIENT > 0
45 #define LOK_INFO(area, stream) \
46 LOK_LOG_STREAM("info", area, stream) \
48 #define LOK_WARN(area, stream) \
49 LOK_LOG_STREAM("warn", area, stream)
51 #else
52 #define LOK_INFO(area, stream) \
53 SAL_INFO(area, stream) \
55 #define LOK_WARN(area, stream) \
56 SAL_WARN(area, stream)
58 #endif
60 struct SFX2_DLLPUBLIC LokMouseEventData
62 int mnType;
63 Point maPosition;
64 int mnCount;
65 MouseEventModifiers meModifiers;
66 int mnButtons;
67 int mnModifier;
68 std::optional<Point> maLogicPosition;
70 LokMouseEventData(int nType, Point aPosition, int nCount, MouseEventModifiers eModifiers, int nButtons, int nModifier)
71 : mnType(nType)
72 , maPosition(aPosition)
73 , mnCount(nCount)
74 , meModifiers(eModifiers)
75 , mnButtons(nButtons)
76 , mnModifier(nModifier)
80 #include <boost/property_tree/ptree_fwd.hpp>
82 namespace com::sun::star::ui { struct ContextChangeEventObject; };
84 class SFX2_DLLPUBLIC SfxLokHelper
86 public:
87 /// Gets the short cut accelerators.
88 static std::unordered_map<OUString, css::uno::Reference<com::sun::star::ui::XAcceleratorConfiguration>>& getAcceleratorConfs();
89 /// Create a new view shell from the current view frame.
90 /// This assumes a single document is ever loaded.
91 static int createView();
92 /// Create a new view shell for the given DocId, for multi-document support.
93 static int createView(int nDocId);
94 /// Destroy a view shell from the global shell list.
95 static void destroyView(int nId);
96 /// Set a view shell as current one.
97 static void setView(int nId);
98 /// Determines if a call to setView() is in progress or not.
99 static bool isSettingView();
100 /// Set the edit mode for a document with callbacks disabled.
101 static void setEditMode(int nMode, vcl::ITiledRenderable* pDoc);
102 /// Get view shell with id
103 static SfxViewShell* getViewOfId(int nId);
104 /// Get the currently active view.
105 static int getView(const SfxViewShell* pViewShell = nullptr);
106 /// Get the number of views of the current DocId.
107 static std::size_t getViewsCount(int nDocId);
108 /// Get viewIds of views of the current DocId.
109 static bool getViewIds(int nDocId, int* pArray, size_t nSize);
110 /// Set View Blocked for some uno commands
111 static void setBlockedCommandList(int nViewId, const char* blockedCommandList);
112 /// Get the document id for a view
113 static int getDocumentIdOfView(int nViewId);
114 /// Get the default language that should be used for views
115 static const LanguageTag & getDefaultLanguage();
116 /// Set language of the given view.
117 static void setViewLanguage(int nId, const OUString& rBcp47LanguageTag);
118 /// Set the default language for views.
119 static void setDefaultLanguage(const OUString& rBcp47LanguageTag);
120 /// Enable/Disable AT support for the given view.
121 static void setAccessibilityState(int nId, bool nEnabled);
122 // Set the readonly state of the view.
123 static void setViewReadOnly(int nId, bool readOnly);
124 // In readonly view, can user add / modify comments or not.
125 static void setAllowChangeComments(int nId, bool allow);
126 /// Get the language used by the loading view (used for all save operations).
127 static const LanguageTag & getLoadLanguage();
128 /// Set the language used by the loading view (used for all save operations).
129 static void setLoadLanguage(const OUString& rBcp47LanguageTag);
130 /// Set the locale for the given view.
131 static void setViewLocale(int nId, const OUString& rBcp47LanguageTag);
132 /// Get the device form factor that should be used for a new view.
133 static LOKDeviceFormFactor getDeviceFormFactor();
134 /// Set the device form factor that should be used for a new view.
135 static void setDeviceFormFactor(std::u16string_view rDeviceFormFactor);
137 /// Set timezone of the given view.
138 /// @isSet true to use @rTimezone, even if it's empty. Otherwise, no timezone.
139 /// @rTimezone the value to set (which could be empty).
140 static void setDefaultTimezone(bool isSet, const OUString& rTimezone);
141 /// Get timezone of the given view. See @setDefaultTimezone.
142 static std::pair<bool, OUString> getDefaultTimezone();
143 /// Set the timezone of the given view.
144 static void setViewTimezone(int nId, bool isSet, const OUString& rTimezone);
145 /// Get the timezone of the given view.
146 static std::pair<bool, OUString> getViewTimezone(int nId);
148 /// Iterate over any view shell, except pThisViewShell, passing it to the f function.
149 template<typename ViewShellType, typename FunctionType>
150 static void forEachOtherView(ViewShellType* pThisViewShell, FunctionType f);
152 /// Invoke the LOK callback of all other views showing the same document as pThisView, with a payload of rKey-rPayload.
153 static void notifyOtherViews(const SfxViewShell* pThisView, int nType, std::string_view rKey,
154 const OString& rPayload);
155 /// Invoke the LOK callback of all views except pThisView, with a JSON payload created from the given property tree.
156 static void notifyOtherViews(const SfxViewShell* pThisView, int nType,
157 const boost::property_tree::ptree& rTree);
158 /// Same as notifyOtherViews(), but works on a selected "other" view, not on all of them.
159 static void notifyOtherView(const SfxViewShell* pThisView, SfxViewShell const* pOtherView,
160 int nType, std::string_view rKey, const OString& rPayload);
161 /// Same as notifyOtherViews(), the property-tree version, but works on a selected "other" view, not on all of them.
162 static void notifyOtherView(const SfxViewShell* pThisView, SfxViewShell const* pOtherView,
163 int nType, const boost::property_tree::ptree& rTree);
165 /// Emits a LOK_CALLBACK_STATE_CHANGED
166 static void sendUnoStatus(const SfxViewShell* pShell, const SfxPoolItem* pItem);
167 /// Emits a LOK_CALLBACK_WINDOW
168 static void notifyWindow(const SfxViewShell* pThisView,
169 vcl::LOKWindowId nWindowId,
170 std::u16string_view rAction,
171 const std::vector<vcl::LOKPayloadItem>& rPayload = std::vector<vcl::LOKPayloadItem>());
172 /// Emits a LOK_CALLBACK_DOCUMENT_SIZE_CHANGED - if @bInvalidateAll - first invalidates all parts
173 static void notifyDocumentSizeChanged(SfxViewShell const* pThisView, const OString& rPayload, vcl::ITiledRenderable* pDoc, bool bInvalidateAll = true);
174 /// Emits a LOK_CALLBACK_DOCUMENT_SIZE_CHANGED for all views of the same document - if @bInvalidateAll - first invalidates all parts
175 static void notifyDocumentSizeChangedAllViews(vcl::ITiledRenderable* pDoc, bool bInvalidateAll = true);
176 /// Emits a LOK_CALLBACK_DOCUMENT_SIZE_CHANGED for all views of the same document with the same part
177 static void notifyPartSizeChangedAllViews(vcl::ITiledRenderable* pDoc, int nPart);
178 /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
179 static void notifyInvalidation(SfxViewShell const* pThisView, int nPart, tools::Rectangle const *);
180 /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed
181 /// uses the Part reported by pThisView
182 static void notifyInvalidation(SfxViewShell const* pThisView, tools::Rectangle const *);
183 /// Notifies all views with the given type and payload.
184 static void notifyAllViews(int nType, const OString& rPayload);
186 /// Notify about the editing context change.
187 static void notifyContextChange(const css::ui::ContextChangeEventObject& rEvent);
189 /// Emits an LOK_CALLBACK_VIEW_RENDER_STATE
190 static void notifyViewRenderState(SfxViewShell const* pViewShell, vcl::ITiledRenderable* pDoc);
192 // Notify about the given type needing an update.
193 static void notifyUpdate(SfxViewShell const* pViewShell, int nType);
194 // Notify about the given type needing a per-viewid update.
195 static void notifyUpdatePerViewId(SfxViewShell const* pViewShell, int nType);
196 /// Same as notifyUpdatePerViewId(), pTargetShell will be notified, relevant viewId in pViewShell,
197 /// pSourceView->getLOKPayload() will be called to get the data.
198 static void notifyUpdatePerViewId(SfxViewShell const* pTargetShell, SfxViewShell const* pViewShell,
199 SfxViewShell const* pSourceShell, int nType);
200 // Notify other views about the given type needing a per-viewid update.
201 static void notifyOtherViewsUpdatePerViewId(SfxViewShell const* pViewShell, int nType);
203 static OString makePayloadJSON(const SfxViewShell* pThisView, int nViewId, std::string_view rKey, const OString& rPayload);
204 /// Makes a LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR payload, but tweaks it according to setOptionalFeatures() if needed.
205 static OString makeVisCursorInvalidation(int nViewId, const OString& rRectangle,
206 bool bMispelledWord = false, const OString& rHyperlink = ""_ostr);
208 /// Helper for posting async key event
209 static void postKeyEventAsync(const VclPtr<vcl::Window> &xWindow,
210 int nType, int nCharCode, int nKeyCode, int nRepeat = 0);
212 /// Helper for posting input event
213 static void postExtTextEventAsync(const VclPtr<vcl::Window> &xWindow,
214 int nType, const OUString &rText);
216 /// Helper for posting async mouse event
217 static void postMouseEventAsync(const VclPtr<vcl::Window> &xWindow, LokMouseEventData const & rLokMouseEventData);
219 /// A special value to signify 'infinity'.
220 /// This value is chosen such that sal_Int32 will not overflow when manipulated.
221 static const tools::Long MaxTwips = 1e9;
223 /// Helper for diagnosing run-time problems
224 static void dumpState(rtl::OStringBuffer &rState);
226 /// Process the mouse event in the currently active in-place component (if any).
227 /// Returns true if the event has been processed, and no further processing is necessary.
228 static bool testInPlaceComponentMouseEventHit(SfxViewShell* pViewShell, int nType, int nX,
229 int nY, int nCount, int nButtons, int nModifier,
230 double fScaleX, double fScaleY,
231 bool bNegativeX = false);
233 static VclPtr<vcl::Window> getInPlaceDocWindow(SfxViewShell* pViewShell);
235 /// Sends Network Access error to LOK
236 static void sendNetworkAccessError(std::string_view rAction);
238 static void notifyLog(const std::ostringstream& stream);
240 private:
241 static int createView(SfxViewFrame& rViewFrame, ViewShellDocId docId);
244 template<typename ViewShellType, typename FunctionType>
245 void SfxLokHelper::forEachOtherView(ViewShellType* pThisViewShell, FunctionType f)
247 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
248 while (pViewShell)
250 auto pOtherViewShell = dynamic_cast<ViewShellType*>(pViewShell);
251 if (pOtherViewShell != nullptr && pOtherViewShell != pThisViewShell && pOtherViewShell->GetDocId() == pThisViewShell->GetDocId())
253 f(pOtherViewShell);
255 pViewShell = SfxViewShell::GetNext(*pViewShell);
259 /// If LOK is active, switch to the language/locale of the provided shell and back on delete.
260 class SfxLokLanguageGuard
262 bool m_bSetLanguage;
263 const SfxViewShell* m_pOldShell;
265 public:
266 SfxLokLanguageGuard(SfxViewShell* pNewShell);
267 ~SfxLokLanguageGuard();
270 typedef std::list<SfxViewShell*> ViewShellList;
272 /// Used to keep track of the last N views that text edited a document through an EditView
273 class SFX2_DLLPUBLIC LOKEditViewHistory
275 public:
276 typedef std::list<SfxViewShell*> ViewShellList;
277 typedef std::unordered_map<int, ViewShellList> EditViewHistoryMap;
279 static void Update(bool bRemove = false);
280 static ViewShellList GetHistoryForDoc(ViewShellDocId aDocId);
281 static ViewShellList GetSortedViewsForDoc(ViewShellDocId aDocId);
282 private:
283 static EditViewHistoryMap maEditViewHistory;
286 #endif
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */