summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2021-03-01 19:27:04 +0100
committerJan Holesovsky <kendy@collabora.com>2021-03-04 10:52:56 +0100
commit81e0a4a859d6f47cca9c54482e30be0b7d7355cc (patch)
treef6b68fdc108ab0f9c8b1b89f8d4302310dfd577b
parentbe688de877ad5e96836e7bd0a9d70b80d6dabdf2 (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>
-rw-r--r--vcl/inc/jsdialog/jsdialogbuilder.hxx61
-rw-r--r--vcl/jsdialog/jsdialogbuilder.cxx69
2 files changed, 121 insertions, 9 deletions
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index c228967eb0f5..13e9db2a178e 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -28,6 +28,7 @@
#include <boost/property_tree/ptree_fwd.hpp>
#include <deque>
+#include <unordered_map>
class ToolBox;
class SfxViewShell;
@@ -35,6 +36,7 @@ class VclMultiLineEdit;
class IconView;
typedef std::map<OString, weld::Widget*> WidgetMap;
+typedef std::unordered_map<std::string, OUString> ActionDataMap;
namespace jsdialog
{
@@ -42,10 +44,51 @@ enum MessageType
{
FullUpdate,
WidgetUpdate,
- Close
+ Close,
+ Action
};
}
+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
@@ -56,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,
@@ -66,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(const boost::property_tree::ptree& rTree);
boost::property_tree::ptree generateFullUpdate() const;
boost::property_tree::ptree generateWidgetUpdate(VclPtr<vcl::Window> pWindow) const;
boost::property_tree::ptree generateCloseMessage() const;
+ boost::property_tree::ptree generateActionMessage(VclPtr<vcl::Window> pWindow,
+ std::unique_ptr<ActionDataMap> pData) const;
};
class VCL_DLLPUBLIC JSDialogSender
@@ -92,6 +138,7 @@ public:
virtual void sendFullUpdate(bool bForce = false);
void sendClose();
virtual 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:
@@ -234,6 +281,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>
@@ -323,6 +372,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 VCL_DLLPUBLIC JSDialog : public JSWidget<SalInstanceDialog, ::Dialog>
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 573c9a817310..3fd84f281ef7 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -21,6 +21,7 @@
using namespace weld;
+#define ACTION_TYPE "action_type"
namespace
{
void response_help(vcl::Window* pWindow)
@@ -79,7 +80,19 @@ void JSDialogNotifyIdle::send(const boost::property_tree::ptree& rTree)
}
}
-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
@@ -87,13 +100,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);
}
boost::property_tree::ptree JSDialogNotifyIdle::generateFullUpdate() const
@@ -152,11 +174,32 @@ boost::property_tree::ptree JSDialogNotifyIdle::generateCloseMessage() const
return aTree;
}
+boost::property_tree::ptree
+JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow,
+ std::unique_ptr<ActionDataMap> pData) const
+{
+ boost::property_tree::ptree aTree;
+
+ aTree.put("jsontype", m_sTypeOfJSON);
+ aTree.put("action", "action");
+ aTree.put("id", m_aNotifierWindow->GetLOKWindowId());
+
+ boost::property_tree::ptree aDataTree;
+ aDataTree.put("control_id", pWindow->get_id());
+
+ for (auto it = pData->begin(); it != pData->end(); it++)
+ aDataTree.put(it->first, it->second);
+
+ aTree.add_child("data", aDataTree);
+
+ return aTree;
+}
+
void JSDialogNotifyIdle::Invoke()
{
for (auto& rMessage : m_aMessageQueue)
{
- jsdialog::MessageType eType = rMessage.first;
+ jsdialog::MessageType eType = rMessage.m_eType;
switch (eType)
{
@@ -165,12 +208,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;
}
}
@@ -210,6 +257,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();
+}
+
// Drag and drop
class JSDropTargetDropContext
@@ -1197,7 +1250,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)