diff options
Diffstat (limited to 'desktop/inc/lib/init.hxx')
-rw-r--r-- | desktop/inc/lib/init.hxx | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx index b8918729cff9..614ef404ddd2 100644 --- a/desktop/inc/lib/init.hxx +++ b/desktop/inc/lib/init.hxx @@ -13,6 +13,7 @@ #include <unordered_map> #include <memory> #include <mutex> +#include <set> #include <string_view> #include <boost/property_tree/ptree.hpp> @@ -21,6 +22,7 @@ #include <osl/thread.h> #include <rtl/ref.hxx> +#include <rtl/strbuf.hxx> #include <vcl/idle.hxx> #include <LibreOfficeKit/LibreOfficeKit.h> #include <LibreOfficeKit/LibreOfficeKitEnums.h> @@ -41,24 +43,33 @@ namespace desktop { { tools::Rectangle m_aRectangle; int m_nPart; + int m_nMode; + + // This is the "EMPTY" rectangle, which somewhat confusingly actually means + // to drop all rectangles (see LOK_CALLBACK_INVALIDATE_TILES documentation), + // and so it is actually an infinite rectangle and not an empty one. + constexpr static tools::Rectangle emptyAllRectangle = {0, 0, SfxLokHelper::MaxTwips, SfxLokHelper::MaxTwips}; RectangleAndPart() : m_nPart(INT_MIN) // -1 is reserved to mean "all parts". + , m_nMode(0) { } - RectangleAndPart(const tools::Rectangle* pRect, int nPart) - : m_aRectangle( pRect ? *pRect : tools::Rectangle(0, 0, SfxLokHelper::MaxTwips, SfxLokHelper::MaxTwips)) + RectangleAndPart(const tools::Rectangle* pRect, int nPart, int nMode) + : m_aRectangle( pRect ? SanitizedRectangle(*pRect) : emptyAllRectangle) , m_nPart(nPart) + , m_nMode(nMode) { } OString toString() const { if (m_nPart >= -1) - return m_aRectangle.toString() + ", " + OString::number(m_nPart); + return (isInfinite() ? "EMPTY"_ostr : m_aRectangle.toString()) + + ", " + OString::number(m_nPart) + ", " + OString::number(m_nMode); else - return m_aRectangle.toString(); + return (isInfinite() ? "EMPTY"_ostr : m_aRectangle.toString()); } /// Infinite Rectangle is both sides are @@ -75,17 +86,21 @@ namespace desktop { return m_aRectangle.IsEmpty(); } - static RectangleAndPart Create(const std::string& rPayload); + static RectangleAndPart Create(const OString& rPayload); + /// Makes sure a rectangle is valid (apparently some code does not like negative coordinates for example). + static tools::Rectangle SanitizedRectangle(tools::Long nLeft, tools::Long nTop, tools::Long nWidth, tools::Long nHeight); + static tools::Rectangle SanitizedRectangle(const tools::Rectangle& rect); }; - class DESKTOP_DLLPUBLIC CallbackFlushHandler final : public Idle, public SfxLokCallbackInterface + /// One instance of this per view, handles flushing callbacks + class SAL_DLLPUBLIC_RTTI CallbackFlushHandler final : public Idle, public SfxLokCallbackInterface { public: - explicit CallbackFlushHandler(LibreOfficeKitDocument* pDocument, LibreOfficeKitCallback pCallback, void* pData); - virtual ~CallbackFlushHandler() override; + DESKTOP_DLLPUBLIC explicit CallbackFlushHandler(LibreOfficeKitDocument* pDocument, LibreOfficeKitCallback pCallback, void* pData); + DESKTOP_DLLPUBLIC virtual ~CallbackFlushHandler() override; virtual void Invoke() override; // TODO This should be dropped and the binary libreOfficeKitViewCallback() variants should be called? - void queue(const int type, const char* data); + DESKTOP_DLLPUBLIC void queue(const int type, const OString& data); /// Disables callbacks on this handler. Must match with identical count /// of enableCallbacks. Used during painting and changing views. @@ -102,32 +117,39 @@ namespace desktop { void setViewId( int viewId ) { m_viewId = viewId; } // SfxLockCallbackInterface - virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) override; - virtual void libreOfficeKitViewCallbackWithViewId(int nType, const char* pPayload, int nViewId) override; - virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart) override; + virtual void libreOfficeKitViewCallback(int nType, const OString& pPayload) override; + virtual void libreOfficeKitViewCallbackWithViewId(int nType, const OString& pPayload, int nViewId) override; + DESKTOP_DLLPUBLIC virtual void libreOfficeKitViewInvalidateTilesCallback(const tools::Rectangle* pRect, int nPart, int nMode) override; virtual void libreOfficeKitViewUpdatedCallback(int nType) override; virtual void libreOfficeKitViewUpdatedCallbackPerViewId(int nType, int nViewId, int nSourceViewId) override; + virtual void libreOfficeKitViewAddPendingInvalidateTiles() override; + virtual void dumpState(rtl::OStringBuffer &rState) override; private: struct CallbackData { - CallbackData(const char* payload) - : PayloadString(payload ? payload : "(nil)") + CallbackData(OString payload) + : PayloadString(std::move(payload)) { } - CallbackData(const char* payload, int viewId) - : PayloadString(payload ? payload : "(nil)") + CallbackData(OString payload, int viewId) + : PayloadString(std::move(payload)) , PayloadObject(viewId) { } CallbackData(const tools::Rectangle* pRect, int viewId) - : PayloadObject(RectangleAndPart(pRect, viewId)) + : PayloadObject(RectangleAndPart(pRect, viewId, 0)) { // PayloadString will be done on demand } - const std::string& getPayload() const; + CallbackData(const tools::Rectangle* pRect, int part, int mode) + : PayloadObject(RectangleAndPart(pRect, part, mode)) + { // PayloadString will be done on demand + } + + const OString& getPayload() const; /// Update a RectangleAndPart object and update PayloadString if necessary. void updateRectangleAndPart(const RectangleAndPart& rRectAndPart); /// Return the parsed RectangleAndPart instance. @@ -143,7 +165,7 @@ namespace desktop { bool isEmpty() const { - return PayloadString.empty() && PayloadObject.which() == 0; + return PayloadString.isEmpty() && PayloadObject.which() == 0; } void clear() { @@ -158,7 +180,7 @@ namespace desktop { bool isCached() const { return PayloadObject.which() != 0; } private: - mutable std::string PayloadString; + mutable OString PayloadString; /// The parsed payload cache. Update validate() when changing this. mutable boost::variant<boost::blank, RectangleAndPart, boost::property_tree::ptree, int> PayloadObject; @@ -167,6 +189,7 @@ namespace desktop { typedef std::vector<int> queue_type1; typedef std::vector<CallbackData> queue_type2; + void startTimer(); bool removeAll(int type); bool removeAll(int type, const std::function<bool (const CallbackData&)>& rTestFunc); bool processInvalidateTilesEvent(int type, CallbackData& aCallbackData); @@ -181,8 +204,9 @@ namespace desktop { so we split the queue in 2 to make the scanning cache friendly. */ queue_type1 m_queue1; queue_type2 m_queue2; - std::map<int, std::string> m_states; - std::unordered_map<int, std::unordered_map<int, std::string>> m_viewStates; + std::map<int, OString> m_states; + std::unordered_map<OString, OString> m_lastStateChange; + std::unordered_map<int, std::unordered_map<int, OString>> m_viewStates; // For some types only the last message matters (see isUpdatedType()) or only the last message // per each viewId value matters (see isUpdatedTypePerViewId()), so instead of using push model @@ -197,7 +221,7 @@ namespace desktop { std::vector<bool> m_updatedTypes; // index is type, value is if set struct PerViewIdData { - bool set; // value is if set + bool set = false; // value is if set int sourceViewId; }; // Flat_map is used in preference to unordered_map because the map is accessed very often. @@ -208,7 +232,7 @@ namespace desktop { LibreOfficeKitCallback m_pCallback; void *m_pData; int m_nDisableCallbacks; - std::mutex m_mutex; + std::recursive_mutex m_mutex; class TimeoutIdle : public Timer { public: @@ -226,8 +250,9 @@ namespace desktop { std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; std::map<size_t, std::shared_ptr<CallbackFlushHandler>> mpCallbackFlushHandlers; const int mnDocumentId; + std::set<OUString> maFontsMissing; - explicit LibLODocument_Impl(const css::uno::Reference<css::lang::XComponent>& xComponent, + explicit LibLODocument_Impl(css::uno::Reference<css::lang::XComponent> xComponent, int nDocumentId); ~LibLODocument_Impl(); }; @@ -249,6 +274,8 @@ namespace desktop { { return (mOptionalFeatures & feature) != 0; } + + void dumpState(rtl::OStringBuffer &aState); }; /// Helper function to extract the value from parameters delimited by |