[Libreoffice-commits] core.git: include/vcl vcl/inc vcl/jsdialog vcl/source

Szymon KÅ‚os (via logerrit) logerrit at kemper.freedesktop.org
Wed Jul 28 12:33:07 UTC 2021


 include/vcl/toolkit/menubtn.hxx      |    1 
 vcl/inc/jsdialog/enabled.hxx         |    1 
 vcl/inc/jsdialog/jsdialogbuilder.hxx |   18 +++++++++-
 vcl/jsdialog/enabled.cxx             |    9 +++++
 vcl/jsdialog/executor.cxx            |   20 +++++++++++
 vcl/jsdialog/jsdialogbuilder.cxx     |   59 ++++++++++++++++++++++++++++++++++-
 vcl/source/control/menubtn.cxx       |   18 ++++++++++
 vcl/source/window/builder.cxx        |    4 +-
 8 files changed, 126 insertions(+), 4 deletions(-)

New commits:
commit 79eab8450b3a9db343a082e6d450764643340a3e
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Tue Jun 15 13:10:00 2021 +0200
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Wed Jul 28 14:32:30 2021 +0200

    jsdialog: dump and activate popup windows
    
    Change-Id: I4eb49a81d12ac37f50c6595eeec6d472fdbe6d82
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117251
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119581
    Tested-by: Szymon Kłos <szymon.klos at collabora.com>

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);
     }
 


More information about the Libreoffice-commits mailing list