[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - include/vcl vcl/inc vcl/jsdialog vcl/source

Szymon KÅ‚os (via logerrit) logerrit at kemper.freedesktop.org
Mon Jun 28 08:13:08 UTC 2021


 include/vcl/menubtn.hxx              |    3 
 vcl/inc/jsdialog/jsdialogbuilder.hxx |   35 ++++++++-
 vcl/inc/salvtables.hxx               |    4 -
 vcl/jsdialog/enabled.cxx             |    2 
 vcl/jsdialog/jsdialogbuilder.cxx     |  132 ++++++++++++++++++++++++++++++++---
 vcl/source/control/menubtn.cxx       |   17 ----
 vcl/source/window/toolbox2.cxx       |    8 +-
 7 files changed, 166 insertions(+), 35 deletions(-)

New commits:
commit 59812ab6f584173596a4ec96cc29d5f0fa3b561f
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Thu Jun 24 14:31:45 2021 +0200
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Mon Jun 28 10:12:48 2021 +0200

    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 at gmail.com>
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

diff --git a/include/vcl/menubtn.hxx b/include/vcl/menubtn.hxx
index 8e7c259221c5..ccbd23a041f8 100644
--- a/include/vcl/menubtn.hxx
+++ b/include/vcl/menubtn.hxx
@@ -79,6 +79,7 @@ public:
     PopupMenu*      GetPopupMenu() const { return mpMenu; }
 
     void            SetPopover(Window* pWindow);
+    Window*         GetPopover() { return mpFloatingWindow.get(); }
 
     OString const & GetCurItemIdent() const { return msCurItemIdent; }
 
@@ -89,8 +90,6 @@ public:
 
     void SetCurItemId();
 
-    void DumpAsPropertyTree(tools::JsonWriter& rJsonWriter) override;
-
 };
 
 #endif // INCLUDED_VCL_MENUBTN_HXX
diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx
index 4e6324a15fcb..fdd952f93968 100644
--- a/vcl/inc/jsdialog/jsdialogbuilder.hxx
+++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx
@@ -9,9 +9,10 @@
 
 #pragma once
 
+#include <comphelper/string.hxx>
+#include <osl/mutex.hxx>
 #include <vcl/weld.hxx>
 #include <vcl/jsdialog/executor.hxx>
-#include <comphelper/string.hxx>
 #include <vcl/sysdata.hxx>
 #include <vcl/virdev.hxx>
 #include <vcl/builder.hxx>
@@ -28,6 +29,9 @@
 #include <unordered_map>
 
 #define ACTION_TYPE "action_type"
+#define PARENT_ID "parent_id"
+#define WINDOW_ID "id"
+#define CLOSE_ID "close_id"
 
 class ToolBox;
 class ComboBox;
@@ -45,7 +49,8 @@ enum MessageType
     FullUpdate,
     WidgetUpdate,
     Close,
-    Action
+    Action,
+    Popup
 };
 }
 
@@ -101,6 +106,7 @@ class JSDialogNotifyIdle : public Idle
     bool m_bForce;
 
     std::deque<JSDialogMessageInfo> m_aMessageQueue;
+    osl::Mutex m_aQueueMutex;
 
 public:
     JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow, VclPtr<vcl::Window> aContentWindow,
@@ -120,6 +126,9 @@ private:
     std::unique_ptr<tools::JsonWriter> generateCloseMessage() const;
     std::unique_ptr<tools::JsonWriter>
     generateActionMessage(VclPtr<vcl::Window> pWindow, std::unique_ptr<ActionDataMap> pData) const;
+    std::unique_ptr<tools::JsonWriter>
+    generatePopupMessage(VclPtr<vcl::Window> pWindow, OUString sParentId, OUString sCloseId) const;
+    std::unique_ptr<tools::JsonWriter> generateClosePopupMessage(OUString sWindowId) const;
 };
 
 class JSDialogSender
@@ -140,6 +149,8 @@ public:
     void sendClose();
     virtual void sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce = false);
     virtual void sendAction(VclPtr<vcl::Window> pWindow, std::unique_ptr<ActionDataMap> pData);
+    virtual void sendPopup(VclPtr<vcl::Window> pWindow, OUString sParentId, OUString sCloseId);
+    virtual void sendClosePopup(vcl::LOKWindowId nWindowId);
     void flush() { mpIdleNotify->Invoke(); }
 
 protected:
@@ -287,6 +298,10 @@ public:
     virtual void sendFullUpdate(bool bForce = false) = 0;
 
     virtual void sendAction(std::unique_ptr<ActionDataMap> pData) = 0;
+
+    virtual void sendPopup(vcl::Window* pPopup, OUString sParentId, OUString sCloseId) = 0;
+
+    virtual void sendClosePopup(vcl::LOKWindowId nWindowId) = 0;
 };
 
 template <class BaseInstanceClass, class VclClass>
@@ -394,6 +409,18 @@ public:
         if (!m_bIsFreezed && m_pSender && pData)
             m_pSender->sendAction(BaseInstanceClass::m_xWidget, std::move(pData));
     }
+
+    virtual void sendPopup(vcl::Window* pPopup, OUString sParentId, OUString sCloseId) override
+    {
+        if (!m_bIsFreezed && m_pSender)
+            m_pSender->sendPopup(pPopup, sParentId, sCloseId);
+    }
+
+    virtual void sendClosePopup(vcl::LOKWindowId nWindowId) override
+    {
+        if (!m_bIsFreezed && m_pSender)
+            m_pSender->sendClosePopup(nWindowId);
+    }
 };
 
 class JSDialog : public JSWidget<SalInstanceDialog, ::Dialog>
@@ -530,9 +557,13 @@ public:
 
 class JSToolbar : public JSWidget<SalInstanceToolbar, ::ToolBox>
 {
+    std::map<sal_uInt16, weld::Widget*> m_pPopovers;
+
 public:
     JSToolbar(JSDialogSender* pSender, ::ToolBox* pToolbox, SalInstanceBuilder* pBuilder,
               bool bTakeOwnership);
+
+    virtual void set_menu_item_active(const OString& rIdent, bool bActive) override;
 };
 
 class JSTextView : public JSWidget<SalInstanceTextView, ::VclMultiLineEdit>
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 0a7299af56bf..bbe49cdc0dd4 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1172,7 +1172,7 @@ public:
 
 class SalInstanceToolbar : public SalInstanceWidget, public virtual weld::Toolbar
 {
-private:
+protected:
     VclPtr<ToolBox> m_xToolBox;
     std::map<sal_uInt16, VclPtr<vcl::Window>> m_aFloats;
     std::map<sal_uInt16, VclPtr<PopupMenu>> m_aMenus;
@@ -1815,7 +1815,7 @@ public:
 
 class SalInstanceMenuButton : public SalInstanceButton, public virtual weld::MenuButton
 {
-private:
+protected:
     VclPtr<::MenuButton> m_xMenuButton;
     sal_uInt16 m_nLastId;
 
diff --git a/vcl/jsdialog/enabled.cxx b/vcl/jsdialog/enabled.cxx
index 92f29674d00e..fbb111f59289 100644
--- a/vcl/jsdialog/enabled.cxx
+++ b/vcl/jsdialog/enabled.cxx
@@ -62,7 +62,7 @@ bool isBuilderEnabled(const OUString& rUIFile, bool bMobile)
 
 bool isBuilderEnabledForPopup(const OUString& rUIFile)
 {
-    if (rUIFile == "svx/ui/colorwindow.ui")
+    if (rUIFile == "svx/ui/colorwindow.ui" || rUIFile == "modules/scalc/ui/floatinglinestyle.ui")
         return true;
 
     return false;
diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx
index 3dbbe8160976..c58eaf00e3fd 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);
+
+    sal_uInt16 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,
diff --git a/vcl/source/control/menubtn.cxx b/vcl/source/control/menubtn.cxx
index a6e809e558fe..bf59cad6c1d6 100644
--- a/vcl/source/control/menubtn.cxx
+++ b/vcl/source/control/menubtn.cxx
@@ -265,23 +265,6 @@ 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/toolbox2.cxx b/vcl/source/window/toolbox2.cxx
index 2e442923899b..cee2d7dfadbf 100644
--- a/vcl/source/window/toolbox2.cxx
+++ b/vcl/source/window/toolbox2.cxx
@@ -1747,11 +1747,15 @@ void ToolBox::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
             }
             else
             {
-                if (!IsItemVisible(nId))
-                    continue;
                 rJsonWriter.put("type", "toolitem");
                 rJsonWriter.put("text", GetItemText(nId));
                 rJsonWriter.put("command", GetItemCommand(nId));
+                if (!IsItemVisible(nId))
+                    rJsonWriter.put("visible", false);
+                if (GetItemBits(nId) & ToolBoxItemBits::DROPDOWN)
+                    rJsonWriter.put("dropdown", true);
+                if (!IsItemEnabled(nId))
+                    rJsonWriter.put("enabled", false);
             }
         }
     }


More information about the Libreoffice-commits mailing list