jsdialog: share code for widget registry
- move all helpers for widgets registration into separate file - share code for Widgets, Menu and Popup register Change-Id: I3449721d7e436ff4459edb7990c1af860b78054f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177738 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178205 Tested-by: Jenkins Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
This commit is contained in:
@@ -208,8 +208,11 @@ public:
|
||||
|| (loplugin::DeclCheck(pVarDecl).Var("maThreadSpecific")
|
||||
.Class("ScDocument").GlobalNamespace()) // not owning
|
||||
|| name == "s_aLOKWindowsMap" // LOK only, guarded by assert, and LOK never tries to perform a VCL cleanup
|
||||
|| name == "s_aLOKWeldBuildersMap" // LOK only, similar case as above
|
||||
|| name == "s_aLOKPopupsMap" // LOK only, similar case as above
|
||||
// vcl/inc/jsdialog/jsdialogbuilder.hxx
|
||||
|| name == "m_aWidgets" // LOK only, similar case as above
|
||||
|| name == "m_aPopups" // LOK only, similar case as above
|
||||
|| name == "m_aMenus" // LOK only, similar case as above
|
||||
//
|
||||
|| name == "gNotebookBarManager" // LOK only case, when notebookbar is closed - VclPtr instance is removed
|
||||
|| name == "gStaticManager" // vcl/source/graphic/Manager.cxx - stores non-owning pointers
|
||||
|| name == "aThreadedInterpreterPool" // ScInterpreterContext(Pool), not owning
|
||||
|
@@ -540,6 +540,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
|
||||
vcl/backendtest/GraphicsRenderTests \
|
||||
vcl/jsdialog/enabled \
|
||||
vcl/jsdialog/jsdialogbuilder \
|
||||
vcl/jsdialog/jsdialogregister \
|
||||
vcl/jsdialog/executor \
|
||||
))
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jsdialog/jsdialogregister.hxx>
|
||||
#include <utility>
|
||||
#include <vcl/weld.hxx>
|
||||
#include <vcl/jsdialog/executor.hxx>
|
||||
@@ -44,8 +45,6 @@ namespace vcl
|
||||
class ILibreOfficeKitNotifier;
|
||||
}
|
||||
|
||||
typedef std::map<OUString, weld::Widget*> WidgetMap;
|
||||
|
||||
namespace jsdialog
|
||||
{
|
||||
enum MessageType
|
||||
@@ -59,6 +58,8 @@ enum MessageType
|
||||
};
|
||||
}
|
||||
|
||||
typedef jsdialog::WidgetRegister<weld::Widget*> WidgetMap;
|
||||
|
||||
/// Class with the message description for storing in the queue
|
||||
class JSDialogMessageInfo
|
||||
{
|
||||
@@ -211,6 +212,10 @@ public:
|
||||
|
||||
class JSInstanceBuilder final : public SalInstanceBuilder, public JSDialogSender
|
||||
{
|
||||
static jsdialog::WidgetRegister<std::shared_ptr<WidgetMap>> m_aWidgets;
|
||||
static jsdialog::WidgetRegister<VclPtr<vcl::Window>> m_aPopups;
|
||||
static jsdialog::WidgetRegister<weld::Menu*> m_aMenus;
|
||||
|
||||
sal_uInt64 m_nWindowId;
|
||||
/// used in case of tab pages where dialog is not a direct top level
|
||||
VclPtr<vcl::Window> m_aParentDialog;
|
||||
@@ -238,12 +243,10 @@ class JSInstanceBuilder final : public SalInstanceBuilder, public JSDialogSender
|
||||
const OUString& rWidget,
|
||||
std::unique_ptr<jsdialog::ActionDataMap> pData);
|
||||
|
||||
static std::map<OUString, WidgetMap>& GetLOKWeldWidgetsMap();
|
||||
static void InsertWindowToMap(const OUString& nWindowId);
|
||||
void RememberWidget(OUString id, weld::Widget* pWidget);
|
||||
static void RememberWidget(const OUString& nWindowId, const OUString& id,
|
||||
weld::Widget* pWidget);
|
||||
static weld::Widget* FindWeldWidgetsMap(const OUString& nWindowId, const OUString& rWidget);
|
||||
|
||||
OUString getMapIdFromWindowId() const;
|
||||
|
||||
@@ -322,19 +325,14 @@ public:
|
||||
VclButtonsType eButtonType, const OUString& rPrimaryMessage,
|
||||
const vcl::ILibreOfficeKitNotifier* pNotifier = nullptr);
|
||||
|
||||
static void AddChildWidget(const OUString& nWindowId, const OUString& id,
|
||||
weld::Widget* pWidget);
|
||||
static void RemoveWindowWidget(const OUString& nWindowId);
|
||||
// regular widgets
|
||||
static jsdialog::WidgetRegister<std::shared_ptr<WidgetMap>>& Widgets() { return m_aWidgets; };
|
||||
|
||||
// we need to remember original popup window to close it properly (its handled by vcl)
|
||||
static void RememberPopup(const OUString& nWindowId, const VclPtr<vcl::Window>& pWidget);
|
||||
static void ForgetPopup(const OUString& nWindowId);
|
||||
static vcl::Window* FindPopup(const OUString& nWindowId);
|
||||
static jsdialog::WidgetRegister<VclPtr<vcl::Window>>& Popups() { return m_aPopups; }
|
||||
|
||||
// menus in separate container as they don't share base class with weld::Widget
|
||||
static void RememberMenu(const OUString& nWindowId, weld::Menu* pMenu);
|
||||
static void ForgetMenu(const OUString& nWindowId);
|
||||
static weld::Menu* FindMenu(const OUString& nWindowId);
|
||||
static jsdialog::WidgetRegister<weld::Menu*>& Menus() { return m_aMenus; }
|
||||
|
||||
private:
|
||||
const OUString& GetTypeOfJSON() const;
|
||||
|
52
vcl/inc/jsdialog/jsdialogregister.hxx
Normal file
52
vcl/inc/jsdialog/jsdialogregister.hxx
Normal file
@@ -0,0 +1,52 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <rtl/ustring.hxx>
|
||||
|
||||
namespace jsdialog
|
||||
{
|
||||
template <class T> class WidgetRegister
|
||||
{
|
||||
// Map to remember the LOKWindowId <-> widget binding.
|
||||
std::map<OUString, T> m_aWidgetMap;
|
||||
std::map<OUString, T>& Map() { return m_aWidgetMap; }
|
||||
|
||||
public:
|
||||
void Remember(const OUString& rId, T pWidget);
|
||||
void Forget(const OUString& rId);
|
||||
T Find(const OUString& rId);
|
||||
};
|
||||
|
||||
template <class T> void WidgetRegister<T>::Remember(const OUString& nWindowId, T pMenu)
|
||||
{
|
||||
Map()[nWindowId] = pMenu;
|
||||
}
|
||||
|
||||
template <class T> void WidgetRegister<T>::Forget(const OUString& nWindowId)
|
||||
{
|
||||
auto it = Map().find(nWindowId);
|
||||
if (it != Map().end())
|
||||
Map().erase(it);
|
||||
}
|
||||
|
||||
template <class T> T WidgetRegister<T>::Find(const OUString& nWindowId)
|
||||
{
|
||||
const auto it = Map().find(nWindowId);
|
||||
|
||||
if (it != Map().end())
|
||||
return it->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
@@ -37,7 +37,8 @@ StringMap jsonToStringMap(const char* pJSON)
|
||||
|
||||
void SendFullUpdate(const OUString& nWindowId, const OUString& rWidget)
|
||||
{
|
||||
weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, rWidget);
|
||||
auto aWidgetMap = JSInstanceBuilder::Widgets().Find(nWindowId);
|
||||
weld::Widget* pWidget = aWidgetMap ? aWidgetMap->Find(rWidget) : nullptr;
|
||||
if (auto pJSWidget = dynamic_cast<BaseJSWidget*>(pWidget))
|
||||
pJSWidget->sendFullUpdate();
|
||||
}
|
||||
@@ -45,14 +46,16 @@ void SendFullUpdate(const OUString& nWindowId, const OUString& rWidget)
|
||||
void SendAction(const OUString& nWindowId, const OUString& rWidget,
|
||||
std::unique_ptr<ActionDataMap> pData)
|
||||
{
|
||||
weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, rWidget);
|
||||
auto aWidgetMap = JSInstanceBuilder::Widgets().Find(nWindowId);
|
||||
weld::Widget* pWidget = aWidgetMap ? aWidgetMap->Find(rWidget) : nullptr;
|
||||
if (auto pJSWidget = dynamic_cast<BaseJSWidget*>(pWidget))
|
||||
pJSWidget->sendAction(std::move(pData));
|
||||
}
|
||||
|
||||
bool ExecuteAction(const OUString& nWindowId, const OUString& rWidget, StringMap& rData)
|
||||
{
|
||||
weld::Widget* pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, rWidget);
|
||||
auto aWidgetMap = JSInstanceBuilder::Widgets().Find(nWindowId);
|
||||
weld::Widget* pWidget = aWidgetMap ? aWidgetMap->Find(rWidget) : nullptr;
|
||||
|
||||
OUString sControlType = rData[u"type"_ustr];
|
||||
OUString sAction = rData[u"cmd"_ustr];
|
||||
@@ -63,7 +66,8 @@ bool ExecuteAction(const OUString& nWindowId, const OUString& rWidget, StringMap
|
||||
if (pWidget == nullptr || (pButton && !pButton->is_custom_handler_set()))
|
||||
{
|
||||
// welded wrapper not found - use response code instead
|
||||
pWidget = JSInstanceBuilder::FindWeldWidgetsMap(nWindowId, u"__DIALOG__"_ustr);
|
||||
auto aWindowMap = JSInstanceBuilder::Widgets().Find(nWindowId);
|
||||
pWidget = aWindowMap ? aWindowMap->Find(u"__DIALOG__"_ustr) : nullptr;
|
||||
sControlType = "dialog";
|
||||
sAction = "response";
|
||||
}
|
||||
@@ -79,7 +83,7 @@ bool ExecuteAction(const OUString& nWindowId, const OUString& rWidget, StringMap
|
||||
// weld::Menu doesn't have base of weld::Widget
|
||||
if (sControlType == "menu")
|
||||
{
|
||||
weld::Menu* pMenu = JSInstanceBuilder::FindMenu(nWindowId);
|
||||
weld::Menu* pMenu = JSInstanceBuilder::Menus().Find(nWindowId);
|
||||
if (pMenu && sAction == "activated")
|
||||
{
|
||||
LOKTrigger::trigger_activated(*pMenu, rData["data"]);
|
||||
|
@@ -32,22 +32,6 @@
|
||||
#include <vcl/cvtgrf.hxx>
|
||||
#include <wizdlg.hxx>
|
||||
|
||||
static std::map<OUString, vcl::Window*>& GetLOKPopupsMap()
|
||||
{
|
||||
// Map to remember the LOKWindowId <-> vcl popup binding.
|
||||
static std::map<OUString, vcl::Window*> s_aLOKPopupsMap;
|
||||
|
||||
return s_aLOKPopupsMap;
|
||||
}
|
||||
|
||||
static std::map<OUString, weld::Menu*>& GetLOKMenusMap()
|
||||
{
|
||||
// Map to remember the LOKWindowId <-> weld menu binding.
|
||||
static std::map<OUString, weld::Menu*> s_aLOKMenusMap;
|
||||
|
||||
return s_aLOKMenusMap;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void response_help(vcl::Window* pWindow)
|
||||
@@ -495,15 +479,6 @@ void JSDropTarget::fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEn
|
||||
}
|
||||
}
|
||||
|
||||
OUString JSInstanceBuilder::getMapIdFromWindowId() const
|
||||
{
|
||||
if (m_sTypeOfJSON == "sidebar" || m_sTypeOfJSON == "notebookbar"
|
||||
|| m_sTypeOfJSON == "formulabar")
|
||||
return OUString::number(m_nWindowId) + m_sTypeOfJSON;
|
||||
else
|
||||
return OUString::number(m_nWindowId);
|
||||
}
|
||||
|
||||
// used for dialogs
|
||||
JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const std::u16string_view sUIRoot,
|
||||
const OUString& rUIFile, bool bPopup)
|
||||
@@ -693,153 +668,19 @@ JSInstanceBuilder::~JSInstanceBuilder()
|
||||
|
||||
if (m_nWindowId && (m_bHasTopLevelDialog || m_bIsNotebookbar))
|
||||
{
|
||||
GetLOKWeldWidgetsMap().erase(getMapIdFromWindowId());
|
||||
JSInstanceBuilder::Widgets().Forget(getMapIdFromWindowId());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = GetLOKWeldWidgetsMap().find(getMapIdFromWindowId());
|
||||
if (it != GetLOKWeldWidgetsMap().end())
|
||||
auto aWindowMap = JSInstanceBuilder::Widgets().Find(getMapIdFromWindowId());
|
||||
if (aWindowMap)
|
||||
{
|
||||
std::for_each(m_aRememberedWidgets.begin(), m_aRememberedWidgets.end(),
|
||||
[it](const OUString& sId) { it->second.erase(sId); });
|
||||
[&aWindowMap](const OUString& sId) { aWindowMap->Forget(sId); });
|
||||
}
|
||||
}
|
||||
|
||||
GetLOKPopupsMap().erase(OUString::number(m_nWindowId));
|
||||
}
|
||||
|
||||
std::map<OUString, WidgetMap>& JSInstanceBuilder::GetLOKWeldWidgetsMap()
|
||||
{
|
||||
// Map to remember the LOKWindowId <-> weld widgets binding.
|
||||
static std::map<OUString, WidgetMap> s_aLOKWeldBuildersMap;
|
||||
|
||||
return s_aLOKWeldBuildersMap;
|
||||
}
|
||||
|
||||
weld::Widget* JSInstanceBuilder::FindWeldWidgetsMap(const OUString& nWindowId,
|
||||
const OUString& rWidget)
|
||||
{
|
||||
const auto it = GetLOKWeldWidgetsMap().find(nWindowId);
|
||||
|
||||
if (it != GetLOKWeldWidgetsMap().end())
|
||||
{
|
||||
auto widgetIt = it->second.find(rWidget);
|
||||
if (widgetIt != it->second.end())
|
||||
return widgetIt->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::InsertWindowToMap(const OUString& nWindowId)
|
||||
{
|
||||
WidgetMap map;
|
||||
auto it = GetLOKWeldWidgetsMap().find(nWindowId);
|
||||
if (it == GetLOKWeldWidgetsMap().end())
|
||||
GetLOKWeldWidgetsMap().insert({ nWindowId, map });
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::RememberWidget(OUString sId, weld::Widget* pWidget)
|
||||
{
|
||||
// do not use the same id for two widgets inside one builder
|
||||
// exception is sidebar where we base our full invalidation on that "Panel" id sharing
|
||||
if (m_sTypeOfJSON != "sidebar")
|
||||
{
|
||||
static std::atomic<unsigned long long int> nNotRepeatIndex = 0;
|
||||
auto aWindowIt = GetLOKWeldWidgetsMap().find(getMapIdFromWindowId());
|
||||
if (aWindowIt != GetLOKWeldWidgetsMap().end())
|
||||
{
|
||||
auto aWidgetIt = aWindowIt->second.find(sId);
|
||||
if (aWidgetIt != aWindowIt->second.end())
|
||||
{
|
||||
unsigned long long int nIndex = nNotRepeatIndex++;
|
||||
// found duplicated it -> add some number to the id and apply to the widget
|
||||
sId = sId + OUString::number(nIndex);
|
||||
SalInstanceWidget* pSalWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
|
||||
assert(pSalWidget && "can only be a SalInstanceWidget");
|
||||
vcl::Window* pVclWidget = pSalWidget->getWidget();
|
||||
pVclWidget->set_id(pVclWidget->get_id() + OUString::number(nIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RememberWidget(getMapIdFromWindowId(), sId, pWidget);
|
||||
m_aRememberedWidgets.push_back(sId);
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::RememberWidget(const OUString& nWindowId, const OUString& id,
|
||||
weld::Widget* pWidget)
|
||||
{
|
||||
auto it = GetLOKWeldWidgetsMap().find(nWindowId);
|
||||
if (it != GetLOKWeldWidgetsMap().end())
|
||||
{
|
||||
it->second.erase(id);
|
||||
it->second.insert(WidgetMap::value_type(id, pWidget));
|
||||
}
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::AddChildWidget(const OUString& nWindowId, const OUString& id,
|
||||
weld::Widget* pWidget)
|
||||
{
|
||||
auto it = GetLOKWeldWidgetsMap().find(nWindowId);
|
||||
if (it != GetLOKWeldWidgetsMap().end())
|
||||
{
|
||||
it->second.erase(id);
|
||||
it->second.insert(WidgetMap::value_type(id, pWidget));
|
||||
}
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::RemoveWindowWidget(const OUString& nWindowId)
|
||||
{
|
||||
auto it = JSInstanceBuilder::GetLOKWeldWidgetsMap().find(nWindowId);
|
||||
if (it != JSInstanceBuilder::GetLOKWeldWidgetsMap().end())
|
||||
{
|
||||
JSInstanceBuilder::GetLOKWeldWidgetsMap().erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::RememberPopup(const OUString& nWindowId, const VclPtr<vcl::Window>& pWidget)
|
||||
{
|
||||
GetLOKPopupsMap()[nWindowId] = pWidget;
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::ForgetPopup(const OUString& nWindowId)
|
||||
{
|
||||
auto it = GetLOKPopupsMap().find(nWindowId);
|
||||
if (it != GetLOKPopupsMap().end())
|
||||
GetLOKPopupsMap().erase(it);
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::RememberMenu(const OUString& nWindowId, weld::Menu* pMenu)
|
||||
{
|
||||
GetLOKMenusMap()[nWindowId] = pMenu;
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::ForgetMenu(const OUString& nWindowId)
|
||||
{
|
||||
auto it = GetLOKMenusMap().find(nWindowId);
|
||||
if (it != GetLOKMenusMap().end())
|
||||
GetLOKMenusMap().erase(it);
|
||||
}
|
||||
|
||||
weld::Menu* JSInstanceBuilder::FindMenu(const OUString& nWindowId)
|
||||
{
|
||||
const auto it = GetLOKMenusMap().find(nWindowId);
|
||||
|
||||
if (it != GetLOKMenusMap().end())
|
||||
return it->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
vcl::Window* JSInstanceBuilder::FindPopup(const OUString& nWindowId)
|
||||
{
|
||||
const auto it = GetLOKPopupsMap().find(nWindowId);
|
||||
|
||||
if (it != GetLOKPopupsMap().end())
|
||||
return it->second;
|
||||
|
||||
return nullptr;
|
||||
JSInstanceBuilder::Popups().Forget(OUString::number(m_nWindowId));
|
||||
}
|
||||
|
||||
const OUString& JSInstanceBuilder::GetTypeOfJSON() const { return m_sTypeOfJSON; }
|
||||
@@ -961,8 +802,13 @@ std::unique_ptr<weld::Container> JSInstanceBuilder::weld_container(const OUStrin
|
||||
// use parent builder to send update - avoid multiple calls from many builders
|
||||
vcl::Window* pParent = pContainer->GetParent();
|
||||
OUString sId = OUString::number(m_nWindowId);
|
||||
while (pParent && !FindWeldWidgetsMap(sId, pParent->get_id()))
|
||||
while (pParent)
|
||||
{
|
||||
auto aWidgetMap = Widgets().Find(sId);
|
||||
if (!aWidgetMap || !aWidgetMap->Find(pParent->get_id()))
|
||||
break;
|
||||
pParent = pParent->GetParent();
|
||||
}
|
||||
|
||||
if (pParent)
|
||||
jsdialog::SendFullUpdate(sId, pParent->get_id());
|
||||
@@ -1244,7 +1090,7 @@ std::unique_ptr<weld::Menu> JSInstanceBuilder::weld_menu(const OUString& id)
|
||||
std::unique_ptr<weld::Menu> pWeldWidget(pMenu);
|
||||
|
||||
if (pWeldWidget)
|
||||
RememberMenu(getMapIdFromWindowId(), pWeldWidget.get());
|
||||
JSInstanceBuilder::Menus().Remember(getMapIdFromWindowId(), pWeldWidget.get());
|
||||
|
||||
return pWeldWidget;
|
||||
}
|
||||
@@ -1270,7 +1116,7 @@ std::unique_ptr<weld::Popover> JSInstanceBuilder::weld_popover(const OUString& i
|
||||
m_nWindowId = m_aParentDialog->GetLOKWindowId();
|
||||
|
||||
pPopover->set_window_id(m_nWindowId);
|
||||
JSInstanceBuilder::RememberPopup(OUString::number(m_nWindowId), pDockingWindow);
|
||||
JSInstanceBuilder::Popups().Remember(OUString::number(m_nWindowId), pDockingWindow);
|
||||
|
||||
InsertWindowToMap(getMapIdFromWindowId());
|
||||
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
||||
@@ -1869,7 +1715,7 @@ JSMessageDialog::JSMessageDialog(::MessageDialog* pDialog, SalInstanceBuilder* p
|
||||
= dynamic_cast<::OKButton*>(m_xMessageDialog->get_widget_for_response(RET_OK)))
|
||||
{
|
||||
m_pOK.reset(new JSButton(m_pSender, pOKBtn, nullptr, false));
|
||||
JSInstanceBuilder::AddChildWidget(m_sWindowId, pOKBtn->get_id(), m_pOK.get());
|
||||
JSInstanceBuilder::RememberWidget(m_sWindowId, pOKBtn->get_id(), m_pOK.get());
|
||||
m_pOK->connect_clicked(LINK(this, JSMessageDialog, OKHdl));
|
||||
}
|
||||
|
||||
@@ -1877,7 +1723,7 @@ JSMessageDialog::JSMessageDialog(::MessageDialog* pDialog, SalInstanceBuilder* p
|
||||
= dynamic_cast<::CancelButton*>(m_xMessageDialog->get_widget_for_response(RET_CANCEL)))
|
||||
{
|
||||
m_pCancel.reset(new JSButton(m_pSender, pCancelBtn, nullptr, false));
|
||||
JSInstanceBuilder::AddChildWidget(m_sWindowId, pCancelBtn->get_id(), m_pCancel.get());
|
||||
JSInstanceBuilder::RememberWidget(m_sWindowId, pCancelBtn->get_id(), m_pCancel.get());
|
||||
m_pCancel->connect_clicked(LINK(this, JSMessageDialog, CancelHdl));
|
||||
}
|
||||
}
|
||||
@@ -1889,7 +1735,7 @@ JSMessageDialog::~JSMessageDialog()
|
||||
// For Message Dialogs created from Application::CreateMessageDialog
|
||||
// (where there is no builder to take care of this for us) explicitly
|
||||
// remove this window id on tear down
|
||||
JSInstanceBuilder::RemoveWindowWidget(m_sWindowId);
|
||||
JSInstanceBuilder::Widgets().Forget(m_sWindowId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1897,7 +1743,8 @@ void JSMessageDialog::RememberMessageDialog()
|
||||
{
|
||||
static constexpr OUString sWidgetName = u"__DIALOG__"_ustr;
|
||||
OUString sWindowId = OUString::number(m_xMessageDialog->GetLOKWindowId());
|
||||
if (JSInstanceBuilder::FindWeldWidgetsMap(sWindowId, sWidgetName) != nullptr)
|
||||
auto aWidgetMap = JSInstanceBuilder::Widgets().Find(sWindowId);
|
||||
if (!aWidgetMap || !aWidgetMap->Find(sWidgetName))
|
||||
return;
|
||||
|
||||
JSInstanceBuilder::InsertWindowToMap(sWindowId);
|
||||
@@ -2028,13 +1875,13 @@ void JSToolbar::set_menu_item_active(const OUString& rIdent, bool bActive)
|
||||
{
|
||||
if (bActive)
|
||||
{
|
||||
JSInstanceBuilder::RememberPopup(OUString::number(pPopupRoot->GetLOKWindowId()),
|
||||
pFloat);
|
||||
JSInstanceBuilder::Popups().Remember(OUString::number(pPopupRoot->GetLOKWindowId()),
|
||||
pFloat);
|
||||
sendPopup(pPopupRoot, m_xToolBox->get_id(), rIdent);
|
||||
}
|
||||
else if (bWasActive)
|
||||
{
|
||||
JSInstanceBuilder::ForgetPopup(OUString::number(pPopupRoot->GetLOKWindowId()));
|
||||
JSInstanceBuilder::Popups().Forget(OUString::number(pPopupRoot->GetLOKWindowId()));
|
||||
sendClosePopup(pPopupRoot->GetLOKWindowId());
|
||||
}
|
||||
}
|
||||
@@ -2428,7 +2275,7 @@ void JSPopover::popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRe
|
||||
|
||||
void JSPopover::popdown()
|
||||
{
|
||||
vcl::Window* pPopup = JSInstanceBuilder::FindPopup(OUString::number(mnWindowId));
|
||||
VclPtr<vcl::Window> pPopup = JSInstanceBuilder::Popups().Find(OUString::number(mnWindowId));
|
||||
|
||||
if (pPopup)
|
||||
{
|
||||
|
74
vcl/jsdialog/jsdialogregister.cxx
Normal file
74
vcl/jsdialog/jsdialogregister.cxx
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <jsdialog/jsdialogregister.hxx>
|
||||
#include <jsdialog/jsdialogbuilder.hxx>
|
||||
|
||||
jsdialog::WidgetRegister<std::shared_ptr<WidgetMap>> JSInstanceBuilder::m_aWidgets;
|
||||
jsdialog::WidgetRegister<VclPtr<vcl::Window>> JSInstanceBuilder::m_aPopups;
|
||||
jsdialog::WidgetRegister<weld::Menu*> JSInstanceBuilder::m_aMenus;
|
||||
|
||||
OUString JSInstanceBuilder::getMapIdFromWindowId() const
|
||||
{
|
||||
if (m_sTypeOfJSON == "sidebar" || m_sTypeOfJSON == "notebookbar"
|
||||
|| m_sTypeOfJSON == "formulabar" || m_sTypeOfJSON == "addressinputfield")
|
||||
{
|
||||
return OUString::number(m_nWindowId) + m_sTypeOfJSON;
|
||||
}
|
||||
else
|
||||
return OUString::number(m_nWindowId);
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::InsertWindowToMap(const OUString& nWindowId)
|
||||
{
|
||||
auto aWidgetMap = JSInstanceBuilder::Widgets().Find(nWindowId);
|
||||
if (!aWidgetMap)
|
||||
JSInstanceBuilder::Widgets().Remember(nWindowId, std::make_shared<WidgetMap>());
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::RememberWidget(OUString sId, weld::Widget* pWidget)
|
||||
{
|
||||
// do not use the same id for two widgets inside one builder
|
||||
// exception is sidebar where we base our full invalidation on that "Panel" id sharing
|
||||
if (m_sTypeOfJSON != "sidebar")
|
||||
{
|
||||
static std::atomic<unsigned long long int> nNotRepeatIndex = 0;
|
||||
auto aWindowIt = JSInstanceBuilder::Widgets().Find(getMapIdFromWindowId());
|
||||
if (aWindowIt)
|
||||
{
|
||||
auto aWidgetIt = aWindowIt->Find(sId);
|
||||
if (aWidgetIt)
|
||||
{
|
||||
unsigned long long int nIndex = nNotRepeatIndex++;
|
||||
// found duplicated it -> add some number to the id and apply to the widget
|
||||
sId = sId + OUString::number(nIndex);
|
||||
SalInstanceWidget* pSalWidget = dynamic_cast<SalInstanceWidget*>(pWidget);
|
||||
assert(pSalWidget && "can only be a SalInstanceWidget");
|
||||
vcl::Window* pVclWidget = pSalWidget->getWidget();
|
||||
pVclWidget->set_id(pVclWidget->get_id() + OUString::number(nIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSInstanceBuilder::RememberWidget(getMapIdFromWindowId(), sId, pWidget);
|
||||
m_aRememberedWidgets.push_back(sId);
|
||||
}
|
||||
|
||||
void JSInstanceBuilder::RememberWidget(const OUString& nWindowId, const OUString& id,
|
||||
weld::Widget* pWidget)
|
||||
{
|
||||
auto aWindowMap = JSInstanceBuilder::Widgets().Find(nWindowId);
|
||||
if (aWindowMap)
|
||||
{
|
||||
aWindowMap->Forget(id);
|
||||
aWindowMap->Remember(id, pWidget);
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
Reference in New Issue
Block a user