summaryrefslogtreecommitdiff
path: root/vcl/jsdialog
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2021-06-24 14:31:45 +0200
committerSzymon Kłos <szymon.klos@collabora.com>2021-07-29 11:04:29 +0200
commitcf9baa91a3c15fb798639c96f2fee6a5bd4975ff (patch)
tree698ea280f7e49c32064e870f1ba6d3a13b18cbc9 /vcl/jsdialog
parente1fe04f117030400f07d207e0a3e35161ac464fa (diff)
jsdialog: toolbox popups
unify menubutton popups and toolbox dropdowns Change-Id: I61c0c33a17d96f03d6513507bda6d5c8edbc55dd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117786 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Szymon Kłos <szymon.klos@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119608 Tested-by: Szymon Kłos <szymon.klos@collabora.com>
Diffstat (limited to 'vcl/jsdialog')
-rw-r--r--vcl/jsdialog/enabled.cxx2
-rw-r--r--vcl/jsdialog/jsdialogbuilder.cxx132
2 files changed, 124 insertions, 10 deletions
diff --git a/vcl/jsdialog/enabled.cxx b/vcl/jsdialog/enabled.cxx
index b0ef018c16c0..67a7cb90c1f0 100644
--- a/vcl/jsdialog/enabled.cxx
+++ b/vcl/jsdialog/enabled.cxx
@@ -61,7 +61,7 @@ bool isBuilderEnabled(std::u16string_view rUIFile, bool bMobile)
bool isBuilderEnabledForPopup(std::u16string_view rUIFile)
{
- if (rUIFile == u"svx/ui/colorwindow.ui")
+ if (rUIFile == u"svx/ui/colorwindow.ui" || rUIFile == u"modules/scalc/ui/floatinglinestyle.ui")
return true;
return false;
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 65414c46ed5f..9526b9e020fa 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -101,6 +101,8 @@ OUString extractActionType(const ActionDataMap& rData)
void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow,
std::unique_ptr<ActionDataMap> pData)
{
+ m_aQueueMutex.acquire();
+
// we want only the latest update of same type
// TODO: also if we met full update - previous updates are not valid
auto it = m_aMessageQueue.begin();
@@ -123,6 +125,8 @@ void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Wi
JSDialogMessageInfo aMessage(eType, pWindow, std::move(pData));
m_aMessageQueue.push_back(aMessage);
+
+ m_aQueueMutex.release();
}
std::unique_ptr<tools::JsonWriter> JSDialogNotifyIdle::generateFullUpdate() const
@@ -210,9 +214,56 @@ JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow,
return aJsonWriter;
}
+std::unique_ptr<tools::JsonWriter>
+JSDialogNotifyIdle::generatePopupMessage(VclPtr<vcl::Window> pWindow, OUString sParentId,
+ OUString sCloseId) const
+{
+ std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
+
+ if (!pWindow || !m_aNotifierWindow)
+ return aJsonWriter;
+
+ pWindow->DumpAsPropertyTree(*aJsonWriter);
+
+ aJsonWriter->put("jsontype", "dialog");
+ aJsonWriter->put("type", "modalpopup");
+ aJsonWriter->put("cancellable", true);
+ aJsonWriter->put("popupParent", sParentId);
+ aJsonWriter->put("clickToClose", sCloseId);
+ aJsonWriter->put("id", pWindow->GetLOKWindowId());
+
+ return aJsonWriter;
+}
+
+std::unique_ptr<tools::JsonWriter>
+JSDialogNotifyIdle::generateClosePopupMessage(OUString sWindowId) const
+{
+ std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
+
+ if (!m_aNotifierWindow)
+ return aJsonWriter;
+
+ aJsonWriter->put("jsontype", "dialog");
+ aJsonWriter->put("action", "close");
+ aJsonWriter->put("id", sWindowId);
+
+ return aJsonWriter;
+}
+
void JSDialogNotifyIdle::Invoke()
{
- for (auto& rMessage : m_aMessageQueue)
+ bool bAcquired = m_aQueueMutex.acquire();
+
+ if (!bAcquired)
+ SAL_WARN("vcl", "JSDialogNotifyIdle::Invoke : mutex cannot be acquired");
+
+ std::deque<JSDialogMessageInfo> aMessageQueue(std::move(m_aMessageQueue));
+ m_aMessageQueue = std::deque<JSDialogMessageInfo>();
+ clearQueue();
+
+ m_aQueueMutex.release();
+
+ for (auto& rMessage : aMessageQueue)
{
jsdialog::MessageType eType = rMessage.m_eType;
@@ -233,10 +284,21 @@ void JSDialogNotifyIdle::Invoke()
case jsdialog::MessageType::Action:
send(*generateActionMessage(rMessage.m_pWindow, std::move(rMessage.m_pData)));
break;
+
+ case jsdialog::MessageType::Popup:
+ {
+ OUString sParentId = (*rMessage.m_pData)[PARENT_ID];
+ OUString sWindowId = (*rMessage.m_pData)[WINDOW_ID];
+ OUString sCloseId = (*rMessage.m_pData)[CLOSE_ID];
+
+ if (!sParentId.isEmpty())
+ send(*generatePopupMessage(rMessage.m_pWindow, sParentId, sCloseId));
+ else if (!sWindowId.isEmpty())
+ send(*generateClosePopupMessage(sWindowId));
+ break;
+ }
}
}
-
- clearQueue();
}
void JSDialogNotifyIdle::clearQueue() { m_aMessageQueue.clear(); }
@@ -278,6 +340,23 @@ void JSDialogSender::sendAction(VclPtr<vcl::Window> pWindow, std::unique_ptr<Act
mpIdleNotify->Start();
}
+void JSDialogSender::sendPopup(VclPtr<vcl::Window> pWindow, OUString sParentId, OUString sCloseId)
+{
+ std::unique_ptr<ActionDataMap> pData = std::make_unique<ActionDataMap>();
+ (*pData)[PARENT_ID] = sParentId;
+ (*pData)[CLOSE_ID] = sCloseId;
+ mpIdleNotify->sendMessage(jsdialog::MessageType::Popup, pWindow, std::move(pData));
+ mpIdleNotify->Start();
+}
+
+void JSDialogSender::sendClosePopup(vcl::LOKWindowId nWindowId)
+{
+ std::unique_ptr<ActionDataMap> pData = std::make_unique<ActionDataMap>();
+ (*pData)[WINDOW_ID] = OUString::number(nWindowId);
+ mpIdleNotify->sendMessage(jsdialog::MessageType::Popup, nullptr, std::move(pData));
+ mpIdleNotify->Start();
+}
+
namespace
{
vcl::Window* extract_sal_widget(weld::Widget* pParent)
@@ -919,9 +998,10 @@ std::unique_ptr<weld::Popover> JSInstanceBuilder::weld_popover(const OString& id
if (VclPtr<vcl::Window> pWin = pDockingWindow->GetParentWithLOKNotifier())
{
- pDockingWindow->SetLOKNotifier(pWin->GetLOKNotifier());
- m_aParentDialog = pDockingWindow;
- m_aWindowToRelease = pDockingWindow;
+ vcl::Window* pPopupRoot = pDockingWindow->GetChild(0);
+ pPopupRoot->SetLOKNotifier(pWin->GetLOKNotifier());
+ m_aParentDialog = pPopupRoot;
+ m_aWindowToRelease = pPopupRoot;
m_nWindowId = m_aParentDialog->GetLOKWindowId();
InsertWindowToMap(m_nWindowId);
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
@@ -1251,6 +1331,32 @@ JSToolbar::JSToolbar(JSDialogSender* pSender, ::ToolBox* pToolbox, SalInstanceBu
{
}
+void JSToolbar::set_menu_item_active(const OString& rIdent, bool bActive)
+{
+ SalInstanceToolbar::set_menu_item_active(rIdent, bActive);
+
+ ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
+ VclPtr<vcl::Window> pFloat = m_aFloats[nItemId];
+
+ if (pFloat)
+ {
+ // See WeldToolbarPopup : include/svtools/toolbarmenu.hxx
+ // TopLevel (Popover) -> Container -> main container of the popup
+ vcl::Window* pPopupRoot = pFloat->GetChild(0);
+ if (pPopupRoot)
+ pPopupRoot = pPopupRoot->GetChild(0);
+
+ if (pPopupRoot)
+ {
+ if (bActive)
+ sendPopup(pPopupRoot, m_xToolBox->get_id(),
+ OStringToOUString(rIdent, RTL_TEXTENCODING_ASCII_US));
+ else
+ sendClosePopup(pPopupRoot->GetLOKWindowId());
+ }
+ }
+}
+
JSTextView::JSTextView(JSDialogSender* pSender, ::VclMultiLineEdit* pTextView,
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
: JSWidget<SalInstanceTextView, ::VclMultiLineEdit>(pSender, pTextView, pBuilder,
@@ -1494,10 +1600,18 @@ void JSMenuButton::set_image(const css::uno::Reference<css::graphic::XGraphic>&
sendUpdate();
}
-void JSMenuButton::set_active(bool active)
+void JSMenuButton::set_active(bool bActive)
{
- SalInstanceMenuButton::set_active(active);
- sendUpdate();
+ SalInstanceMenuButton::set_active(bActive);
+
+ VclPtr<vcl::Window> pPopup = m_xMenuButton->GetPopover();
+ if (pPopup)
+ {
+ if (bActive)
+ sendPopup(pPopup->GetChild(0), m_xMenuButton->get_id(), m_xMenuButton->get_id());
+ else
+ sendClosePopup(pPopup->GetChild(0)->GetLOKWindowId());
+ }
}
JSPopover::JSPopover(JSDialogSender* pSender, DockingWindow* pDockingWindow,