LibreOffice Module desktop (master)  1
init.hxx
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 #pragma once
11 
12 #include <map>
13 #include <unordered_map>
14 #include <memory>
15 #include <mutex>
16 #include <string_view>
17 
18 #include <boost/property_tree/ptree.hpp>
19 #include <boost/variant.hpp>
20 #include <boost/container/flat_map.hpp>
21 
22 #include <osl/thread.h>
23 #include <rtl/ref.hxx>
24 #include <vcl/idle.hxx>
25 #include <LibreOfficeKit/LibreOfficeKit.h>
26 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/lang/XComponent.hpp>
29 #include <tools/gen.hxx>
30 #include <sfx2/lokcallback.hxx>
31 #include <sfx2/lokhelper.hxx>
32 
33 #include <desktop/dllapi.h>
34 
36 
37 namespace desktop {
38 
41  {
43  int m_nPart;
44 
45  // This is the "EMPTY" rectangle, which somewhat confusingly actually means
46  // to drop all rectangles (see LOK_CALLBACK_INVALIDATE_TILES documentation),
47  // and so it is actually an infinite rectangle and not an empty one.
49 
51  : m_nPart(INT_MIN) // -1 is reserved to mean "all parts".
52  {
53  }
54 
55  RectangleAndPart(const tools::Rectangle* pRect, int nPart)
56  : m_aRectangle( pRect ? SanitizedRectangle(*pRect) : emptyAllRectangle)
57  , m_nPart(nPart)
58  {
59  }
60 
61  OString toString() const
62  {
63  if (m_nPart >= -1)
64  return (isInfinite() ? "EMPTY" : m_aRectangle.toString())
65  + ", " + OString::number(m_nPart);
66  else
67  return (isInfinite() ? "EMPTY" : m_aRectangle.toString());
68  }
69 
72  bool isInfinite() const
73  {
74  return m_aRectangle.GetWidth() >= SfxLokHelper::MaxTwips &&
75  m_aRectangle.GetHeight() >= SfxLokHelper::MaxTwips;
76  }
77 
79  bool isEmpty() const
80  {
81  return m_aRectangle.IsEmpty();
82  }
83 
84  static RectangleAndPart Create(const std::string& rPayload);
88  };
89 
92  {
93  public:
94  explicit CallbackFlushHandler(LibreOfficeKitDocument* pDocument, LibreOfficeKitCallback pCallback, void* pData);
95  virtual ~CallbackFlushHandler() override;
96  virtual void Invoke() override;
97  // TODO This should be dropped and the binary libreOfficeKitViewCallback() variants should be called?
98  void queue(const int type, const char* data);
99 
102  void disableCallbacks() { ++m_nDisableCallbacks; }
105  void enableCallbacks() { --m_nDisableCallbacks; }
107  bool callbacksDisabled() const { return m_nDisableCallbacks != 0; }
108 
109  void addViewStates(int viewId);
110  void removeViewStates(int viewId);
111 
112  void setViewId( int viewId ) { m_viewId = viewId; }
113 
114  // SfxLockCallbackInterface
115  virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) override;
116  virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId) override;
117  virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart) override;
118  virtual void libreOfficeKitViewUpdatedCallback(int nType) override;
119  virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId) override;
120 
121  private:
123  {
124  CallbackData(const char* payload)
125  : PayloadString(payload ? payload : "(nil)")
126  {
127  }
128 
129  CallbackData(const char* payload, int viewId)
130  : PayloadString(payload ? payload : "(nil)")
131  , PayloadObject(viewId)
132  {
133  }
134 
135  CallbackData(const tools::Rectangle* pRect, int viewId)
136  : PayloadObject(RectangleAndPart(pRect, viewId))
137  { // PayloadString will be done on demand
138  }
139 
140  const std::string& getPayload() const;
142  void updateRectangleAndPart(const RectangleAndPart& rRectAndPart);
144  const RectangleAndPart& getRectangleAndPart() const;
146  boost::property_tree::ptree& setJson(const std::string& payload);
148  void setJson(const boost::property_tree::ptree& rTree);
150  const boost::property_tree::ptree& getJson() const;
151 
152  int getViewId() const;
153 
154  bool isEmpty() const
155  {
156  return PayloadString.empty() && PayloadObject.which() == 0;
157  }
158  void clear()
159  {
160  PayloadString.clear();
161  PayloadObject = boost::blank();
162  }
163 
165  bool validate() const;
166 
168  bool isCached() const { return PayloadObject.which() != 0; }
169 
170  private:
171  mutable std::string PayloadString;
172 
174  mutable boost::variant<boost::blank, RectangleAndPart, boost::property_tree::ptree, int> PayloadObject;
175  };
176 
177  typedef std::vector<int> queue_type1;
178  typedef std::vector<CallbackData> queue_type2;
179 
180  void startTimer();
181  bool removeAll(int type);
182  bool removeAll(int type, const std::function<bool (const CallbackData&)>& rTestFunc);
183  bool processInvalidateTilesEvent(int type, CallbackData& aCallbackData);
184  bool processWindowEvent(int type, CallbackData& aCallbackData);
185  queue_type2::iterator toQueue2(queue_type1::iterator);
186  queue_type2::reverse_iterator toQueue2(queue_type1::reverse_iterator);
187  void queue(const int type, CallbackData& data);
188  void enqueueUpdatedTypes();
189  void enqueueUpdatedType( int type, const SfxViewShell* sourceViewShell, int viewId );
190 
193  queue_type1 m_queue1;
194  queue_type2 m_queue2;
195  std::map<int, std::string> m_states;
196  std::unordered_map<std::string, std::string> m_lastStateChange;
197  std::unordered_map<int, std::unordered_map<int, std::string>> m_viewStates;
198 
199  // For some types only the last message matters (see isUpdatedType()) or only the last message
200  // per each viewId value matters (see isUpdatedTypePerViewId()), so instead of using push model
201  // where we'd get flooded by repeated messages (which might be costly to generate and process),
202  // the preferred way is that libreOfficeKitViewUpdatedCallback()
203  // or libreOfficeKitViewUpdatedCallbackPerViewId() get called to notify about such a message being
204  // needed, and we'll set a flag here to fetch the actual message before flushing.
205  void setUpdatedType( int nType, bool value );
206  void setUpdatedTypePerViewId( int nType, int nViewId, int nSourceViewId, bool value );
207  void resetUpdatedType( int nType);
208  void resetUpdatedTypePerViewId( int nType, int nViewId );
209  std::vector<bool> m_updatedTypes; // index is type, value is if set
211  {
212  bool set = false; // value is if set
214  };
215  // Flat_map is used in preference to unordered_map because the map is accessed very often.
216  boost::container::flat_map<int, std::vector<PerViewIdData>> m_updatedTypesPerViewId; // key is view, index is type
217 
218  LibreOfficeKitDocument* m_pDocument;
219  int m_viewId = -1; // view id of the associated SfxViewShell
220  LibreOfficeKitCallback m_pCallback;
221  void *m_pData;
223  std::mutex m_mutex;
224  class TimeoutIdle : public Timer
225  {
226  public:
227  TimeoutIdle( CallbackFlushHandler* handler );
228  virtual void Invoke() override;
229  private:
231  };
233  };
234 
235  struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public _LibreOfficeKitDocument
236  {
237  css::uno::Reference<css::lang::XComponent> mxComponent;
238  std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass;
239  std::map<size_t, std::shared_ptr<CallbackFlushHandler>> mpCallbackFlushHandlers;
240  const int mnDocumentId;
241 
242  explicit LibLODocument_Impl(const css::uno::Reference<css::lang::XComponent>& xComponent,
243  int nDocumentId);
245  };
246 
247  struct DESKTOP_DLLPUBLIC LibLibreOffice_Impl : public _LibreOfficeKit
248  {
250  std::shared_ptr< LibreOfficeKitClass > m_pOfficeClass;
251  oslThread maThread;
252  LibreOfficeKitCallback mpCallback;
255  std::map<OString, rtl::Reference<LOKInteractionHandler>> mInteractionMap;
256 
259 
260  bool hasOptionalFeature(LibreOfficeKitOptionalFeatures const feature)
261  {
262  return (mOptionalFeatures & feature) != 0;
263  }
264  };
265 
269  DESKTOP_DLLPUBLIC OUString extractParameter(OUString& aOptions, std::u16string_view rName);
270 
273  DESKTOP_DLLPUBLIC std::vector<com::sun::star::beans::PropertyValue> jsonToPropertyValuesVector(const char* pJSON);
274 }
275 
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
One instance of this per view, handles flushing callbacks.
Definition: init.hxx:91
queue_type1 m_queue1
we frequently want to scan the queue, and mostly when we do so, we only care about the element type s...
Definition: init.hxx:193
void disableCallbacks()
Disables callbacks on this handler.
Definition: init.hxx:102
std::map< OString, rtl::Reference< LOKInteractionHandler > > mInteractionMap
Definition: init.hxx:255
static const tools::Long MaxTwips
#define DESKTOP_DLLPUBLIC
Definition: dllapi.h:19
std::unique_ptr< sal_Int32[]> pData
long Long
tools::Rectangle m_aRectangle
Definition: init.hxx:42
InteractionHandler is an interface that provides the user with various dialogs / error messages...
std::vector< CallbackData > queue_type2
Definition: init.hxx:178
void setViewId(int viewId)
Definition: init.hxx:112
bool isInfinite() const
Infinite Rectangle is both sides are equal or longer than SfxLokHelper::MaxTwips. ...
Definition: init.hxx:72
OString toString() const
Definition: init.hxx:61
Definition: app.cxx:164
CallbackData(const char *payload, int viewId)
Definition: init.hxx:129
std::vector< bool > m_updatedTypes
Definition: init.hxx:209
bool callbacksDisabled() const
Returns true iff callbacks are disabled.
Definition: init.hxx:107
std::shared_ptr< LibreOfficeKitClass > m_pOfficeClass
Definition: init.hxx:250
static constexpr tools::Rectangle emptyAllRectangle
Definition: init.hxx:48
static tools::Rectangle SanitizedRectangle(tools::Long nLeft, tools::Long nTop, tools::Long nWidth, tools::Long nHeight)
Makes sure a rectangle is valid (apparently some code does not like negative coordinates for example)...
Definition: init.cxx:458
std::unordered_map< int, std::unordered_map< int, std::string > > m_viewStates
Definition: init.hxx:197
constexpr tools::Long GetWidth() const
css::uno::Reference< css::lang::XComponent > mxComponent
Definition: init.hxx:237
constexpr bool IsEmpty() const
std::map< size_t, std::shared_ptr< CallbackFlushHandler > > mpCallbackFlushHandlers
Definition: init.hxx:239
LibreOfficeKitCallback mpCallback
Definition: init.hxx:252
void enableCallbacks()
Enables callbacks on this handler.
Definition: init.hxx:105
CallbackFlushHandler * mHandler
Definition: init.hxx:230
CallbackData(const tools::Rectangle *pRect, int viewId)
Definition: init.hxx:135
exports com.sun.star.chart2. data
LibreOfficeKitDocument * m_pDocument
Definition: init.hxx:218
static RectangleAndPart Create(const std::string &rPayload)
Definition: init.cxx:412
bool isEmpty() const
Empty Rectangle is when it has zero dimensions.
Definition: init.hxx:79
bool hasOptionalFeature(LibreOfficeKitOptionalFeatures const feature)
Definition: init.hxx:260
boost::variant< boost::blank, RectangleAndPart, boost::property_tree::ptree, int > PayloadObject
The parsed payload cache. Update validate() when changing this.
Definition: init.hxx:174
std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass
Definition: init.hxx:238
Represents an invalidated rectangle inside a given document part.
Definition: init.hxx:40
boost::container::flat_map< int, std::vector< PerViewIdData > > m_updatedTypesPerViewId
Definition: init.hxx:216
DESKTOP_DLLPUBLIC OUString extractParameter(OUString &aOptions, std::u16string_view rName)
Helper function to extract the value from parameters delimited by comma, like: Name1=Value1,Name2=Value2,Name3=Value3.
Definition: init.cxx:905
bool isCached() const
Returns true iff there is cached data.
Definition: init.hxx:168
LibreOfficeKitCallback m_pCallback
Definition: init.hxx:220
std::vector< int > queue_type1
Definition: init.hxx:177
std::unordered_map< std::string, std::string > m_lastStateChange
Definition: init.hxx:196
ResultType type
rtl::OString toString() const
DESKTOP_DLLPUBLIC std::vector< com::sun::star::beans::PropertyValue > jsonToPropertyValuesVector(const char *pJSON)
Helper function to convert JSON to a vector of PropertyValues.
Definition: init.cxx:371
RectangleAndPart(const tools::Rectangle *pRect, int nPart)
Definition: init.hxx:55
std::map< int, std::string > m_states
Definition: init.hxx:195
void set(css::uno::UnoInterfaceReference const &value)
constexpr tools::Long GetHeight() const