summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-06-09 12:17:18 +0200
committerAshod Nakashian <ashod.nakashian@collabora.co.uk>2016-07-12 22:06:17 -0400
commit8e9799f4fb8bf4e98971c0b45dd5a1aa1b23d7c5 (patch)
treef7e82aaf5d8804db125a54a760eaa17c23a86c9d /desktop
parent59a9da5ba16561947fbd443bc5919cde901aecfe (diff)
desktop lok: move CallbackFlushHandler impl details out of header
To reduce the amount of rebuilt code when changing something there. Reviewed-on: https://gerrit.libreoffice.org/26088 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit de455afe5151d6e0bf89f3e4349f18cb42e752cf) Change-Id: I8f3c18c29d5c08d70910ee2b204cafb99d6b4011
Diffstat (limited to 'desktop')
-rw-r--r--desktop/inc/lib/init.hxx206
-rw-r--r--desktop/source/lib/init.cxx197
2 files changed, 209 insertions, 194 deletions
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index b47cdb2ecce3..3a5c5b7333c9 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -20,210 +20,28 @@
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/lang/XComponent.hpp>
-#include <memory>
-#include <map>
-#include "../../source/inc/desktopdllapi.h"
-#include <osl/thread.h>
+
+#include <desktop/dllapi.h>
class LOKInteractionHandler;
namespace desktop {
- class CallbackFlushHandler : public Idle
+ class DESKTOP_DLLPUBLIC CallbackFlushHandler : public Idle
{
public:
- explicit CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData)
- : Idle( "lokit timer callback" ),
- m_pCallback(pCallback),
- m_pData(pData),
- m_bPartTilePainting(false)
- {
- SetPriority(SchedulerPriority::POST_PAINT);
-
- // Add the states that are safe to skip duplicates on,
- // even when not consequent.
- m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_START, "NIL");
- m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_END, "NIL");
- m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL");
- m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL");
- m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL");
- m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL");
- m_states.emplace(LOK_CALLBACK_MOUSE_POINTER, "NIL");
- m_states.emplace(LOK_CALLBACK_CELL_CURSOR, "NIL");
- m_states.emplace(LOK_CALLBACK_CELL_FORMULA, "NIL");
- m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL");
- m_states.emplace(LOK_CALLBACK_SET_PART, "NIL");
-
- Start();
- }
-
- virtual ~CallbackFlushHandler()
- {
- Stop();
-
- // We might have important notification (.uno:save?).
- flush();
- }
-
- virtual void Invoke() override
- {
- flush();
- }
-
- static
- void callback(const int type, const char* payload, void* data)
- {
- CallbackFlushHandler* self = reinterpret_cast<CallbackFlushHandler*>(data);
- if (self)
- {
- self->queue(type, payload);
- }
- }
-
- void queue(const int type, const char* data)
- {
- const std::string payload(data ? data : "(nil)");
- if (m_bPartTilePainting)
- {
- // We drop notifications when this is set, except for important ones.
- // When we issue a complex command (such as .uno:InsertAnnotation)
- // there will be multiple notifications. On the first invalidation
- // we will start painting, but other events will get fired
- // while the complex command in question executes.
- // We don't want to supress everything here on the wrong assumption
- // that no new events are fired during painting.
- if (type != LOK_CALLBACK_STATE_CHANGED &&
- type != LOK_CALLBACK_INVALIDATE_TILES &&
- type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
- type != LOK_CALLBACK_CURSOR_VISIBLE &&
- type != LOK_CALLBACK_TEXT_SELECTION)
- {
- //SAL_WARN("lokevt", "Skipping while painting [" + std::to_string(type) + "]: [" + payload + "].");
- return;
- }
- }
-
- // Supress invalid payloads.
- if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
- payload.find(", 0, 0, ") != std::string::npos)
- {
- // The cursor position is often the relative coordinates of the widget
- // issueing it, instead of the absolute one that we expect.
- // This is temporary however, and, once the control is created and initialized
- // correctly, it eventually emits the correct absolute coordinates.
- //SAL_WARN("lokevt", "Skipping invalid event [" + std::to_string(type) + "]: [" + payload + "].");
- return;
- }
-
- std::unique_lock<std::mutex> lock(m_mutex);
-
- const auto stateIt = m_states.find(type);
- if (stateIt != m_states.end())
- {
- // If the state didn't change, it's safe to ignore.
- if (stateIt->second == payload)
- {
- //SAL_WARN("lokevt", "Skipping duplicate [" + std::to_string(type) + "]: [" + payload + "].");
- return;
- }
-
- stateIt->second = payload;
- }
-
- if (type == LOK_CALLBACK_TEXT_SELECTION && payload.empty())
- {
- // Removing text selection invalidates the start and end as well.
- m_states[LOK_CALLBACK_TEXT_SELECTION_START] = "";
- m_states[LOK_CALLBACK_TEXT_SELECTION_END] = "";
- }
-
- m_queue.emplace_back(type, payload);
-
- // These are safe to use the latest state and ignore previous
- // ones (if any) since the last overrides previous ones.
- switch (type)
- {
- case LOK_CALLBACK_TEXT_SELECTION_START:
- case LOK_CALLBACK_TEXT_SELECTION_END:
- case LOK_CALLBACK_TEXT_SELECTION:
- case LOK_CALLBACK_GRAPHIC_SELECTION:
- case LOK_CALLBACK_MOUSE_POINTER:
- case LOK_CALLBACK_CELL_CURSOR:
- case LOK_CALLBACK_CELL_FORMULA:
- case LOK_CALLBACK_CURSOR_VISIBLE:
- case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
- removeAllButLast(type, false);
- break;
-
- // These come with rects, so drop earlier
- // only when the latter includes former ones.
- case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
- case LOK_CALLBACK_INVALIDATE_TILES:
- if (payload.empty())
- {
- // Invalidating everything means previously
- // invalidated tiles can be dropped.
- removeAllButLast(type, false);
- }
- else
- {
- removeAllButLast(type, true);
- }
-
- break;
- }
-
- lock.unlock();
- if (!IsActive())
- {
- Start();
- }
- }
-
- void setPartTilePainting(const bool bPartPainting) { m_bPartTilePainting = bPartPainting; }
- bool isPartTilePainting() const { return m_bPartTilePainting; }
+ explicit CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData);
+ virtual ~CallbackFlushHandler();
+ virtual void Invoke() override;
+ static void callback(const int type, const char* payload, void* data);
+ void queue(const int type, const char* data);
+ void setPartTilePainting(const bool bPartPainting);
+ bool isPartTilePainting() const;
private:
- void flush()
- {
- if (m_pCallback)
- {
- std::unique_lock<std::mutex> lock(m_mutex);
- for (auto& pair : m_queue)
- {
- m_pCallback(pair.first, pair.second.c_str(), m_pData);
- }
-
- m_queue.clear();
- }
- }
+ void flush();
+ void removeAllButLast(const int type, const bool identical);
- void removeAllButLast(const int type, const bool identical)
- {
- int i = m_queue.size() - 1;
- std::string payload;
- for (; i >= 0; --i)
- {
- if (m_queue[i].first == type)
- {
- payload = m_queue[i].second;
- //SAL_WARN("lokevt", "Found [" + std::to_string(type) + "] at " + std::to_string(i) + ": [" + payload + "].");
- break;
- }
- }
-
- for (--i; i >= 0; --i)
- {
- if (m_queue[i].first == type &&
- (!identical || m_queue[i].second == payload))
- {
- //SAL_WARN("lokevt", "Removing [" + std::to_string(type) + "] at " + std::to_string(i) + ": " + m_queue[i].second + "].");
- m_queue.erase(m_queue.begin() + i);
- }
- }
- }
-
- private:
std::vector<std::pair<int, std::string>> m_queue;
std::map<int, std::string> m_states;
LibreOfficeKitCallback m_pCallback;
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 5f8b12953795..7c1e34ae10b2 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -445,6 +445,203 @@ LibLODocument_Impl::~LibLODocument_Impl()
mxComponent->dispose();
}
+CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData)
+ : Idle( "lokit timer callback" ),
+ m_pCallback(pCallback),
+ m_pData(pData),
+ m_bPartTilePainting(false)
+{
+ SetPriority(SchedulerPriority::POST_PAINT);
+
+ // Add the states that are safe to skip duplicates on,
+ // even when not consequent.
+ m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_START, "NIL");
+ m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_END, "NIL");
+ m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL");
+ m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL");
+ m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL");
+ m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL");
+ m_states.emplace(LOK_CALLBACK_MOUSE_POINTER, "NIL");
+ m_states.emplace(LOK_CALLBACK_CELL_CURSOR, "NIL");
+ m_states.emplace(LOK_CALLBACK_CELL_FORMULA, "NIL");
+ m_states.emplace(LOK_CALLBACK_CURSOR_VISIBLE, "NIL");
+ m_states.emplace(LOK_CALLBACK_SET_PART, "NIL");
+
+ Start();
+}
+
+CallbackFlushHandler::~CallbackFlushHandler()
+{
+ Stop();
+
+ // We might have important notification (.uno:save?).
+ flush();
+}
+
+void CallbackFlushHandler::Invoke()
+{
+ flush();
+}
+
+void CallbackFlushHandler::callback(const int type, const char* payload, void* data)
+{
+ CallbackFlushHandler* self = static_cast<CallbackFlushHandler*>(data);
+ if (self)
+ {
+ self->queue(type, payload);
+ }
+}
+
+void CallbackFlushHandler::queue(const int type, const char* data)
+{
+ const std::string payload(data ? data : "(nil)");
+ if (m_bPartTilePainting)
+ {
+ // We drop notifications when this is set, except for important ones.
+ // When we issue a complex command (such as .uno:InsertAnnotation)
+ // there will be multiple notifications. On the first invalidation
+ // we will start painting, but other events will get fired
+ // while the complex command in question executes.
+ // We don't want to supress everything here on the wrong assumption
+ // that no new events are fired during painting.
+ if (type != LOK_CALLBACK_STATE_CHANGED &&
+ type != LOK_CALLBACK_INVALIDATE_TILES &&
+ type != LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
+ type != LOK_CALLBACK_CURSOR_VISIBLE &&
+ type != LOK_CALLBACK_TEXT_SELECTION)
+ {
+ //SAL_WARN("lokevt", "Skipping while painting [" + std::to_string(type) + "]: [" + payload + "].");
+ return;
+ }
+ }
+
+ // Supress invalid payloads.
+ if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR &&
+ payload.find(", 0, 0, ") != std::string::npos)
+ {
+ // The cursor position is often the relative coordinates of the widget
+ // issueing it, instead of the absolute one that we expect.
+ // This is temporary however, and, once the control is created and initialized
+ // correctly, it eventually emits the correct absolute coordinates.
+ //SAL_WARN("lokevt", "Skipping invalid event [" + std::to_string(type) + "]: [" + payload + "].");
+ return;
+ }
+
+ std::unique_lock<std::mutex> lock(m_mutex);
+
+ const auto stateIt = m_states.find(type);
+ if (stateIt != m_states.end())
+ {
+ // If the state didn't change, it's safe to ignore.
+ if (stateIt->second == payload)
+ {
+ //SAL_WARN("lokevt", "Skipping duplicate [" + std::to_string(type) + "]: [" + payload + "].");
+ return;
+ }
+
+ stateIt->second = payload;
+ }
+
+ if (type == LOK_CALLBACK_TEXT_SELECTION && payload.empty())
+ {
+ // Removing text selection invalidates the start and end as well.
+ m_states[LOK_CALLBACK_TEXT_SELECTION_START] = "";
+ m_states[LOK_CALLBACK_TEXT_SELECTION_END] = "";
+ }
+
+ m_queue.emplace_back(type, payload);
+
+ // These are safe to use the latest state and ignore previous
+ // ones (if any) since the last overrides previous ones.
+ switch (type)
+ {
+ case LOK_CALLBACK_TEXT_SELECTION_START:
+ case LOK_CALLBACK_TEXT_SELECTION_END:
+ case LOK_CALLBACK_TEXT_SELECTION:
+ case LOK_CALLBACK_GRAPHIC_SELECTION:
+ case LOK_CALLBACK_MOUSE_POINTER:
+ case LOK_CALLBACK_CELL_CURSOR:
+ case LOK_CALLBACK_CELL_FORMULA:
+ case LOK_CALLBACK_CURSOR_VISIBLE:
+ case LOK_CALLBACK_SET_PART:
+ case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
+ removeAllButLast(type, false);
+ break;
+
+ // These come with rects, so drop earlier
+ // only when the latter includes former ones.
+ case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
+ case LOK_CALLBACK_INVALIDATE_TILES:
+ if (payload.empty())
+ {
+ // Invalidating everything means previously
+ // invalidated tiles can be dropped.
+ removeAllButLast(type, false);
+ }
+ else
+ {
+ removeAllButLast(type, true);
+ }
+
+ break;
+ }
+
+ lock.unlock();
+ if (!IsActive())
+ {
+ Start();
+ }
+}
+
+void CallbackFlushHandler::setPartTilePainting(const bool bPartPainting)
+{
+ m_bPartTilePainting = bPartPainting;
+}
+
+bool CallbackFlushHandler::isPartTilePainting() const
+{
+ return m_bPartTilePainting;
+}
+
+void CallbackFlushHandler::flush()
+{
+ if (m_pCallback)
+ {
+ std::unique_lock<std::mutex> lock(m_mutex);
+ for (auto& pair : m_queue)
+ {
+ m_pCallback(pair.first, pair.second.c_str(), m_pData);
+ }
+
+ m_queue.clear();
+ }
+}
+
+void CallbackFlushHandler::removeAllButLast(const int type, const bool identical)
+{
+ int i = m_queue.size() - 1;
+ std::string payload;
+ for (; i >= 0; --i)
+ {
+ if (m_queue[i].first == type)
+ {
+ payload = m_queue[i].second;
+ //SAL_WARN("lokevt", "Found [" + std::to_string(type) + "] at " + std::to_string(i) + ": [" + payload + "].");
+ break;
+ }
+ }
+
+ for (--i; i >= 0; --i)
+ {
+ if (m_queue[i].first == type &&
+ (!identical || m_queue[i].second == payload))
+ {
+ //SAL_WARN("lokevt", "Removing [" + std::to_string(type) + "] at " + std::to_string(i) + ": " + m_queue[i].second + "].");
+ m_queue.erase(m_queue.begin() + i);
+ }
+ }
+}
+
static void doc_destroy(LibreOfficeKitDocument *pThis)
{
LibLODocument_Impl *pDocument = static_cast<LibLODocument_Impl*>(pThis);