diff options
author | Szymon Kłos <szymon.klos@collabora.com> | 2021-03-01 19:27:04 +0100 |
---|---|---|
committer | Szymon Kłos <szymon.klos@collabora.com> | 2021-03-06 17:48:57 +0100 |
commit | ec195ae250c7be1b6e444e4173055cdf966dc48b (patch) | |
tree | 4f35466ee70627096228e467cab24ff3fd5d5b83 | |
parent | 3716699a96797f6f15c1f92ea03b9d8cb940420d (diff) |
jsdialog: send selection change for icon view
- add posibility to send additional actions
- send selection change for icon view as separate
command - optimization, no need for rendering
Change-Id: I02dd129068baf32c265612a1cfa2c2af20319ae9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111767
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112071
Tested-by: Jenkins
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
-rw-r--r-- | vcl/inc/jsdialog/jsdialogbuilder.hxx | 62 | ||||
-rw-r--r-- | vcl/jsdialog/jsdialogbuilder.cxx | 70 |
2 files changed, 123 insertions, 9 deletions
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index d87f230eafc3..2b6672b2da05 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -26,6 +26,7 @@ #include <deque> #include <list> +#include <unordered_map> class ToolBox; class ComboBox; @@ -34,6 +35,7 @@ class SvTabListBox; class IconView; typedef std::map<OString, weld::Widget*> WidgetMap; +typedef std::unordered_map<std::string, OUString> ActionDataMap; namespace jsdialog { @@ -41,10 +43,52 @@ enum MessageType { FullUpdate, WidgetUpdate, - Close + Close, + Action }; } +/// Class with the message description for storing in the queue +class JSDialogMessageInfo +{ +public: + jsdialog::MessageType m_eType; + VclPtr<vcl::Window> m_pWindow; + std::unique_ptr<ActionDataMap> m_pData; + +private: + void copy(const JSDialogMessageInfo& rInfo) + { + this->m_eType = rInfo.m_eType; + this->m_pWindow = rInfo.m_pWindow; + if (rInfo.m_pData) + { + std::unique_ptr<ActionDataMap> pData(new ActionDataMap(*rInfo.m_pData)); + this->m_pData = std::move(pData); + } + } + +public: + JSDialogMessageInfo(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow, + std::unique_ptr<ActionDataMap> pData) + : m_eType(eType) + , m_pWindow(pWindow) + , m_pData(std::move(pData)) + { + } + + JSDialogMessageInfo(const JSDialogMessageInfo& rInfo) { copy(rInfo); } + + JSDialogMessageInfo& operator=(JSDialogMessageInfo aInfo) + { + if (this == &aInfo) + return *this; + + copy(aInfo); + return *this; + } +}; + class JSDialogNotifyIdle : public Idle { // used to send message @@ -55,7 +99,7 @@ class JSDialogNotifyIdle : public Idle std::string m_LastNotificationMessage; bool m_bForce; - std::deque<std::pair<jsdialog::MessageType, VclPtr<vcl::Window>>> m_aMessageQueue; + std::deque<JSDialogMessageInfo> m_aMessageQueue; public: JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow, @@ -65,13 +109,16 @@ public: void clearQueue(); void forceUpdate(); - void sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow); + void sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow, + std::unique_ptr<ActionDataMap> pData = nullptr); private: void send(tools::JsonWriter& aJsonWriter); std::unique_ptr<tools::JsonWriter> generateFullUpdate() const; std::unique_ptr<tools::JsonWriter> generateWidgetUpdate(VclPtr<vcl::Window> pWindow) const; std::unique_ptr<tools::JsonWriter> generateCloseMessage() const; + std::unique_ptr<tools::JsonWriter> + generateActionMessage(VclPtr<vcl::Window> pWindow, std::unique_ptr<ActionDataMap> pData) const; }; class JSDialogSender @@ -91,6 +138,7 @@ public: virtual void sendFullUpdate(bool bForce = false); void sendClose(); void sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce = false); + virtual void sendAction(VclPtr<vcl::Window> pWindow, std::unique_ptr<ActionDataMap> pData); void flush() { mpIdleNotify->Invoke(); } protected: @@ -218,6 +266,8 @@ public: virtual void sendUpdate(bool bForce = false) = 0; virtual void sendFullUpdate(bool bForce = false) = 0; + + virtual void sendAction(std::unique_ptr<ActionDataMap> pData) = 0; }; template <class BaseInstanceClass, class VclClass> @@ -307,6 +357,12 @@ public: if ((!m_bIsFreezed || bForce) && m_pSender) m_pSender->sendFullUpdate(bForce); } + + virtual void sendAction(std::unique_ptr<ActionDataMap> pData) override + { + if (!m_bIsFreezed && m_pSender && pData) + m_pSender->sendAction(BaseInstanceClass::m_xWidget, std::move(pData)); + } }; class JSDialog : public JSWidget<SalInstanceDialog, ::Dialog> diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index b9d0a308e4bd..5c379952a634 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -27,6 +27,8 @@ #include <cppuhelper/supportsservice.hxx> #include <utility> +#define ACTION_TYPE "action_type" + namespace { void response_help(vcl::Window* pWindow) @@ -83,7 +85,19 @@ void JSDialogNotifyIdle::send(tools::JsonWriter& aJsonWriter) } } -void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow) +namespace +{ +OUString extractActionType(const ActionDataMap& rData) +{ + auto it = rData.find(ACTION_TYPE); + if (it != rData.end()) + return it->second; + return ""; +} +}; + +void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow, + std::unique_ptr<ActionDataMap> pData) { // we want only the latest update of same type // TODO: also if we met full update - previous updates are not valid @@ -91,13 +105,22 @@ void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Wi while (it != m_aMessageQueue.end()) { - if (it->first == eType && it->second == pWindow) + if (it->m_eType == eType && it->m_pWindow == pWindow) + { + if (it->m_pData && pData + && extractActionType(*it->m_pData) != extractActionType(*pData)) + { + it++; + continue; + } it = m_aMessageQueue.erase(it); + } else it++; } - m_aMessageQueue.push_back(std::make_pair(eType, pWindow)); + JSDialogMessageInfo aMessage(eType, pWindow, std::move(pData)); + m_aMessageQueue.push_back(aMessage); } std::unique_ptr<tools::JsonWriter> JSDialogNotifyIdle::generateFullUpdate() const @@ -161,11 +184,32 @@ std::unique_ptr<tools::JsonWriter> JSDialogNotifyIdle::generateCloseMessage() co return aJsonWriter; } +std::unique_ptr<tools::JsonWriter> +JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow, + std::unique_ptr<ActionDataMap> pData) const +{ + std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter()); + + aJsonWriter->put("jsontype", m_sTypeOfJSON); + aJsonWriter->put("action", "action"); + aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId()); + + { + auto aDataNode = aJsonWriter->startNode("data"); + aJsonWriter->put("control_id", pWindow->get_id()); + + for (auto it = pData->begin(); it != pData->end(); it++) + aJsonWriter->put(it->first.c_str(), it->second); + } + + return aJsonWriter; +} + void JSDialogNotifyIdle::Invoke() { for (auto& rMessage : m_aMessageQueue) { - jsdialog::MessageType eType = rMessage.first; + jsdialog::MessageType eType = rMessage.m_eType; switch (eType) { @@ -174,12 +218,16 @@ void JSDialogNotifyIdle::Invoke() break; case jsdialog::MessageType::WidgetUpdate: - send(*generateWidgetUpdate(rMessage.second)); + send(*generateWidgetUpdate(rMessage.m_pWindow)); break; case jsdialog::MessageType::Close: send(*generateCloseMessage()); break; + + case jsdialog::MessageType::Action: + send(*generateActionMessage(rMessage.m_pWindow, std::move(rMessage.m_pData))); + break; } } @@ -219,6 +267,12 @@ void JSDialogSender::sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce) mpIdleNotify->Start(); } +void JSDialogSender::sendAction(VclPtr<vcl::Window> pWindow, std::unique_ptr<ActionDataMap> pData) +{ + mpIdleNotify->sendMessage(jsdialog::MessageType::Action, pWindow, std::move(pData)); + mpIdleNotify->Start(); +} + namespace { vcl::Window* extract_sal_widget(weld::Widget* pParent) @@ -1186,7 +1240,11 @@ void JSIconView::clear() void JSIconView::select(int pos) { SalInstanceIconView::select(pos); - sendUpdate(); + + std::unique_ptr<ActionDataMap> pMap = std::make_unique<ActionDataMap>(); + (*pMap)[ACTION_TYPE] = "select"; + (*pMap)["position"] = OUString::number(pos); + sendAction(std::move(pMap)); } void JSIconView::unselect(int pos) |