summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2021-06-15 13:10:00 +0200
committerSzymon Kłos <szymon.klos@collabora.com>2021-07-28 14:32:30 +0200
commit79eab8450b3a9db343a082e6d450764643340a3e (patch)
tree67fda50220aff3af58fe3e86eb834b449a392509
parent3ed7511eca99819012fc1baa490ef85963a9472e (diff)
jsdialog: dump and activate popup windows
Change-Id: I4eb49a81d12ac37f50c6595eeec6d472fdbe6d82 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117251 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Szymon Kłos <szymon.klos@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119581 Tested-by: Szymon Kłos <szymon.klos@collabora.com>
-rw-r--r--include/vcl/toolkit/menubtn.hxx1
-rw-r--r--vcl/inc/jsdialog/enabled.hxx1
-rw-r--r--vcl/inc/jsdialog/jsdialogbuilder.hxx18
-rw-r--r--vcl/jsdialog/enabled.cxx9
-rw-r--r--vcl/jsdialog/executor.cxx20
-rw-r--r--vcl/jsdialog/jsdialogbuilder.cxx59
-rw-r--r--vcl/source/control/menubtn.cxx18
-rw-r--r--vcl/source/window/builder.cxx4
8 files changed, 126 insertions, 4 deletions
diff --git a/include/vcl/toolkit/menubtn.hxx b/include/vcl/toolkit/menubtn.hxx
index db4f9f44f5d6..95d8a65d4769 100644
--- a/include/vcl/toolkit/menubtn.hxx
+++ b/include/vcl/toolkit/menubtn.hxx
@@ -92,6 +92,7 @@ public:
void SetCurItemId();
+ void DumpAsPropertyTree(tools::JsonWriter& rJsonWriter) override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/jsdialog/enabled.hxx b/vcl/inc/jsdialog/enabled.hxx
index 50586cf3bb13..0f37301d0c0d 100644
--- a/vcl/inc/jsdialog/enabled.hxx
+++ b/vcl/inc/jsdialog/enabled.hxx
@@ -14,6 +14,7 @@
namespace jsdialog
{
bool isBuilderEnabled(std::u16string_view rUIFile, bool bMobile);
+bool isBuilderEnabledForPopup(std::u16string_view rUIFile);
bool isBuilderEnabledForSidebar(std::u16string_view rUIFile);
bool isInterimBuilderEnabledForNotebookbar(std::u16string_view rUIFile);
}
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index 78534ea8c29a..7c6ce7be45e1 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -195,6 +195,8 @@ class JSInstanceBuilder final : public SalInstanceBuilder, public JSDialogSender
std::string m_sTypeOfJSON;
bool m_bHasTopLevelDialog;
bool m_bIsNotebookbar;
+ /// When LOKNotifier is set by jsdialogs code we need to release it
+ VclPtr<vcl::Window> m_aWindowToRelease;
friend VCL_DLLPUBLIC bool jsdialog::ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget,
StringMap& rData);
@@ -206,8 +208,9 @@ class JSInstanceBuilder final : public SalInstanceBuilder, public JSDialogSender
void RememberWidget(const OString& id, weld::Widget* pWidget);
static weld::Widget* FindWeldWidgetsMap(sal_uInt64 nWindowId, const OString& rWidget);
- /// used for dialogs
- JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile);
+ /// used for dialogs or popups
+ JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile,
+ bool bPopup = false);
/// used for sidebar panels
JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile,
sal_uInt64 nLOKWindowId);
@@ -231,6 +234,8 @@ public:
static JSInstanceBuilder* CreateSidebarBuilder(weld::Widget* pParent, const OUString& rUIRoot,
const OUString& rUIFile,
sal_uInt64 nLOKWindowId = 0);
+ static JSInstanceBuilder* CreatePopupBuilder(weld::Widget* pParent, const OUString& rUIRoot,
+ const OUString& rUIFile);
virtual ~JSInstanceBuilder() override;
virtual std::unique_ptr<weld::MessageDialog> weld_message_dialog(const OString& id) override;
@@ -255,6 +260,7 @@ public:
virtual std::unique_ptr<weld::RadioButton> weld_radio_button(const OString& id) override;
virtual std::unique_ptr<weld::Frame> weld_frame(const OString& id) override;
virtual std::unique_ptr<weld::MenuButton> weld_menu_button(const OString& id) override;
+ virtual std::unique_ptr<weld::Popover> weld_popover(const OString& id) override;
static weld::MessageDialog* CreateMessageDialog(weld::Widget* pParent,
VclMessageType eMessageType,
@@ -627,6 +633,14 @@ public:
virtual void set_label(const OUString& rText) override;
virtual void set_image(VirtualDevice* pDevice) override;
virtual void set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage) override;
+ virtual void set_active(bool active) override;
+};
+
+class JSPopover : public JSWidget<SalInstancePopover, DockingWindow>
+{
+public:
+ JSPopover(JSDialogSender* pSender, DockingWindow* pPopover, SalInstanceBuilder* pBuilder,
+ bool bTakeOwnership);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/vcl/jsdialog/enabled.cxx b/vcl/jsdialog/enabled.cxx
index 7160b8bcc38d..b0ef018c16c0 100644
--- a/vcl/jsdialog/enabled.cxx
+++ b/vcl/jsdialog/enabled.cxx
@@ -13,6 +13,7 @@ namespace jsdialog
{
bool isBuilderEnabled(std::u16string_view rUIFile, bool bMobile)
{
+ // mobile only dialogs
if (bMobile)
{
if (rUIFile == u"modules/swriter/ui/wordcount-mobile.ui"
@@ -58,6 +59,14 @@ bool isBuilderEnabled(std::u16string_view rUIFile, bool bMobile)
return false;
}
+bool isBuilderEnabledForPopup(std::u16string_view rUIFile)
+{
+ if (rUIFile == u"svx/ui/colorwindow.ui")
+ return true;
+
+ return false;
+}
+
bool isBuilderEnabledForSidebar(std::u16string_view rUIFile)
{
if (rUIFile == u"sfx/ui/panel.ui" || rUIFile == u"svx/ui/sidebartextpanel.ui"
diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx
index d35ae301be66..5675ec0b56f0 100644
--- a/vcl/jsdialog/executor.cxx
+++ b/vcl/jsdialog/executor.cxx
@@ -120,6 +120,26 @@ bool ExecuteAction(sal_uInt64 nWindowId, const OString& rWidget, StringMap& rDat
}
}
}
+ else if (sControlType == "menubutton")
+ {
+ auto pButton = dynamic_cast<weld::MenuButton*>(pWidget);
+ if (pButton)
+ {
+ if (sAction == "toggle")
+ {
+ if (pButton->get_active())
+ pButton->set_active(false);
+ else
+ pButton->set_active(true);
+
+ BaseJSWidget* pMenuButton = dynamic_cast<BaseJSWidget*>(pButton);
+ if (pMenuButton)
+ pMenuButton->sendUpdate(true);
+
+ return true;
+ }
+ }
+ }
else if (sControlType == "checkbox")
{
auto pCheckButton = dynamic_cast<weld::CheckButton*>(pWidget);
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 02e794808c78..a0b17f23bf08 100644
--- a/vcl/jsdialog/jsdialogbuilder.cxx
+++ b/vcl/jsdialog/jsdialogbuilder.cxx
@@ -384,7 +384,7 @@ void JSDropTarget::fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEn
// used for dialogs
JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot,
- const OUString& rUIFile)
+ const OUString& rUIFile, bool bPopup)
: SalInstanceBuilder(extract_sal_widget(pParent), rUIRoot, rUIFile)
, m_nWindowId(0)
, m_aParentDialog(nullptr)
@@ -392,7 +392,12 @@ JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIR
, m_sTypeOfJSON("dialog")
, m_bHasTopLevelDialog(false)
, m_bIsNotebookbar(false)
+ , m_aWindowToRelease(nullptr)
{
+ // when it is a popup we initialize sender in weld_popover
+ if (bPopup)
+ return;
+
vcl::Window* pRoot = m_xBuilder->get_widget_root();
if (pRoot && pRoot->GetParent())
@@ -416,6 +421,7 @@ JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIR
, m_sTypeOfJSON("sidebar")
, m_bHasTopLevelDialog(false)
, m_bIsNotebookbar(false)
+ , m_aWindowToRelease(nullptr)
{
vcl::Window* pRoot = m_xBuilder->get_widget_root();
@@ -453,6 +459,7 @@ JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, const OUString& rUIRo
, m_sTypeOfJSON("notebookbar")
, m_bHasTopLevelDialog(false)
, m_bIsNotebookbar(false)
+ , m_aWindowToRelease(nullptr)
{
vcl::Window* pRoot = m_xBuilder->get_widget_root();
if (pRoot && pRoot->GetParent())
@@ -481,6 +488,7 @@ JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, const OUString& rUIRo
, m_sTypeOfJSON("autofilter")
, m_bHasTopLevelDialog(false)
, m_bIsNotebookbar(false)
+ , m_aWindowToRelease(nullptr)
{
vcl::Window* pRoot = m_xBuilder->get_widget_root();
m_aContentWindow = pParent;
@@ -524,8 +532,21 @@ JSInstanceBuilder* JSInstanceBuilder::CreateSidebarBuilder(weld::Widget* pParent
return new JSInstanceBuilder(pParent, rUIRoot, rUIFile, nLOKWindowId);
}
+JSInstanceBuilder* JSInstanceBuilder::CreatePopupBuilder(weld::Widget* pParent,
+ const OUString& rUIRoot,
+ const OUString& rUIFile)
+{
+ return new JSInstanceBuilder(pParent, rUIRoot, rUIFile, true);
+}
+
JSInstanceBuilder::~JSInstanceBuilder()
{
+ if (m_aWindowToRelease)
+ {
+ m_aWindowToRelease->ReleaseLOKNotifier();
+ m_aWindowToRelease.clear();
+ }
+
if (m_nWindowId && (m_bHasTopLevelDialog || m_bIsNotebookbar))
{
GetLOKWeldWidgetsMap().erase(m_nWindowId);
@@ -885,6 +906,30 @@ std::unique_ptr<weld::MenuButton> JSInstanceBuilder::weld_menu_button(const OStr
return pWeldWidget;
}
+std::unique_ptr<weld::Popover> JSInstanceBuilder::weld_popover(const OString& id)
+{
+ DockingWindow* pDockingWindow = m_xBuilder->get<DockingWindow>(id);
+ std::unique_ptr<weld::Popover> pRet(
+ pDockingWindow ? new JSPopover(this, pDockingWindow, this, false) : nullptr);
+ if (pDockingWindow)
+ {
+ assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
+ m_aOwnedToplevel.set(pDockingWindow);
+ m_xBuilder->drop_ownership(pDockingWindow);
+
+ if (VclPtr<vcl::Window> pWin = pDockingWindow->GetParentWithLOKNotifier())
+ {
+ pDockingWindow->SetLOKNotifier(pWin->GetLOKNotifier());
+ m_aParentDialog = pDockingWindow;
+ m_aWindowToRelease = pDockingWindow;
+ m_nWindowId = m_aParentDialog->GetLOKWindowId();
+ InsertWindowToMap(m_nWindowId);
+ initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
+ }
+ }
+ return pRet;
+}
+
weld::MessageDialog* JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent,
VclMessageType eMessageType,
VclButtonsType eButtonType,
@@ -1445,4 +1490,16 @@ void JSMenuButton::set_image(const css::uno::Reference<css::graphic::XGraphic>&
sendUpdate();
}
+void JSMenuButton::set_active(bool active)
+{
+ SalInstanceMenuButton::set_active(active);
+ sendUpdate();
+}
+
+JSPopover::JSPopover(JSDialogSender* pSender, DockingWindow* pDockingWindow,
+ SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+ : JSWidget<SalInstancePopover, DockingWindow>(pSender, pDockingWindow, pBuilder, bTakeOwnership)
+{
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/vcl/source/control/menubtn.cxx b/vcl/source/control/menubtn.cxx
index 33401186fc36..a46b6bab6789 100644
--- a/vcl/source/control/menubtn.cxx
+++ b/vcl/source/control/menubtn.cxx
@@ -28,6 +28,7 @@
#include <vcl/uitest/logger.hxx>
#include <vcl/uitest/eventdescription.hxx>
#include <menutogglebutton.hxx>
+#include <tools/json_writer.hxx>
namespace
{
@@ -264,6 +265,23 @@ void MenuButton::SetCurItemId(){
msCurItemIdent = mpMenu->GetCurItemIdent();
}
+void MenuButton::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
+{
+ Button::DumpAsPropertyTree(rJsonWriter);
+ if (mpFloatingWindow)
+ {
+ auto aPopup = rJsonWriter.startNode("popup");
+ if (InPopupMode())
+ mpFloatingWindow->DumpAsPropertyTree(rJsonWriter);
+ else
+ rJsonWriter.put("action", "close");
+
+ VclPtr<vcl::Window> pParentWithNotifier = mpFloatingWindow->GetParentWithLOKNotifier();
+ if (pParentWithNotifier)
+ rJsonWriter.put("id", pParentWithNotifier->GetLOKWindowId());
+ }
+}
+
//class MenuToggleButton ----------------------------------------------------
MenuToggleButton::MenuToggleButton( vcl::Window* pParent, WinBits nWinBits )
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 5b20c550eab9..2c34c47b1d95 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -184,7 +184,9 @@ weld::Builder* Application::CreateBuilder(weld::Widget* pParent, const OUString
{
if (jsdialog::isBuilderEnabledForSidebar(rUIFile))
return JSInstanceBuilder::CreateSidebarBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, nLOKWindowId);
- if (jsdialog::isBuilderEnabled(rUIFile, bMobile))
+ else if (jsdialog::isBuilderEnabledForPopup(rUIFile))
+ return JSInstanceBuilder::CreatePopupBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile);
+ else if (jsdialog::isBuilderEnabled(rUIFile, bMobile))
return JSInstanceBuilder::CreateDialogBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile);
}