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")
|
|| (loplugin::DeclCheck(pVarDecl).Var("maThreadSpecific")
|
||||||
.Class("ScDocument").GlobalNamespace()) // not owning
|
.Class("ScDocument").GlobalNamespace()) // not owning
|
||||||
|| name == "s_aLOKWindowsMap" // LOK only, guarded by assert, and LOK never tries to perform a VCL cleanup
|
|| 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
|
// vcl/inc/jsdialog/jsdialogbuilder.hxx
|
||||||
|| name == "s_aLOKPopupsMap" // LOK only, similar case as above
|
|| 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 == "gNotebookBarManager" // LOK only case, when notebookbar is closed - VclPtr instance is removed
|
||||||
|| name == "gStaticManager" // vcl/source/graphic/Manager.cxx - stores non-owning pointers
|
|| name == "gStaticManager" // vcl/source/graphic/Manager.cxx - stores non-owning pointers
|
||||||
|| name == "aThreadedInterpreterPool" // ScInterpreterContext(Pool), not owning
|
|| name == "aThreadedInterpreterPool" // ScInterpreterContext(Pool), not owning
|
||||||
|
@@ -540,6 +540,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
|
|||||||
vcl/backendtest/GraphicsRenderTests \
|
vcl/backendtest/GraphicsRenderTests \
|
||||||
vcl/jsdialog/enabled \
|
vcl/jsdialog/enabled \
|
||||||
vcl/jsdialog/jsdialogbuilder \
|
vcl/jsdialog/jsdialogbuilder \
|
||||||
|
vcl/jsdialog/jsdialogregister \
|
||||||
vcl/jsdialog/executor \
|
vcl/jsdialog/executor \
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <jsdialog/jsdialogregister.hxx>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vcl/weld.hxx>
|
#include <vcl/weld.hxx>
|
||||||
#include <vcl/jsdialog/executor.hxx>
|
#include <vcl/jsdialog/executor.hxx>
|
||||||
@@ -44,8 +45,6 @@ namespace vcl
|
|||||||
class ILibreOfficeKitNotifier;
|
class ILibreOfficeKitNotifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::map<OUString, weld::Widget*> WidgetMap;
|
|
||||||
|
|
||||||
namespace jsdialog
|
namespace jsdialog
|
||||||
{
|
{
|
||||||
enum MessageType
|
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 with the message description for storing in the queue
|
||||||
class JSDialogMessageInfo
|
class JSDialogMessageInfo
|
||||||
{
|
{
|
||||||
@@ -211,6 +212,10 @@ public:
|
|||||||
|
|
||||||
class JSInstanceBuilder final : public SalInstanceBuilder, public JSDialogSender
|
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;
|
sal_uInt64 m_nWindowId;
|
||||||
/// used in case of tab pages where dialog is not a direct top level
|
/// used in case of tab pages where dialog is not a direct top level
|
||||||
VclPtr<vcl::Window> m_aParentDialog;
|
VclPtr<vcl::Window> m_aParentDialog;
|
||||||
@@ -238,12 +243,10 @@ class JSInstanceBuilder final : public SalInstanceBuilder, public JSDialogSender
|
|||||||
const OUString& rWidget,
|
const OUString& rWidget,
|
||||||
std::unique_ptr<jsdialog::ActionDataMap> pData);
|
std::unique_ptr<jsdialog::ActionDataMap> pData);
|
||||||
|
|
||||||
static std::map<OUString, WidgetMap>& GetLOKWeldWidgetsMap();
|
|
||||||
static void InsertWindowToMap(const OUString& nWindowId);
|
static void InsertWindowToMap(const OUString& nWindowId);
|
||||||
void RememberWidget(OUString id, weld::Widget* pWidget);
|
void RememberWidget(OUString id, weld::Widget* pWidget);
|
||||||
static void RememberWidget(const OUString& nWindowId, const OUString& id,
|
static void RememberWidget(const OUString& nWindowId, const OUString& id,
|
||||||
weld::Widget* pWidget);
|
weld::Widget* pWidget);
|
||||||
static weld::Widget* FindWeldWidgetsMap(const OUString& nWindowId, const OUString& rWidget);
|
|
||||||
|
|
||||||
OUString getMapIdFromWindowId() const;
|
OUString getMapIdFromWindowId() const;
|
||||||
|
|
||||||
@@ -322,19 +325,14 @@ public:
|
|||||||
VclButtonsType eButtonType, const OUString& rPrimaryMessage,
|
VclButtonsType eButtonType, const OUString& rPrimaryMessage,
|
||||||
const vcl::ILibreOfficeKitNotifier* pNotifier = nullptr);
|
const vcl::ILibreOfficeKitNotifier* pNotifier = nullptr);
|
||||||
|
|
||||||
static void AddChildWidget(const OUString& nWindowId, const OUString& id,
|
// regular widgets
|
||||||
weld::Widget* pWidget);
|
static jsdialog::WidgetRegister<std::shared_ptr<WidgetMap>>& Widgets() { return m_aWidgets; };
|
||||||
static void RemoveWindowWidget(const OUString& nWindowId);
|
|
||||||
|
|
||||||
// we need to remember original popup window to close it properly (its handled by vcl)
|
// 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 jsdialog::WidgetRegister<VclPtr<vcl::Window>>& Popups() { return m_aPopups; }
|
||||||
static void ForgetPopup(const OUString& nWindowId);
|
|
||||||
static vcl::Window* FindPopup(const OUString& nWindowId);
|
|
||||||
|
|
||||||
// menus in separate container as they don't share base class with weld::Widget
|
// menus in separate container as they don't share base class with weld::Widget
|
||||||
static void RememberMenu(const OUString& nWindowId, weld::Menu* pMenu);
|
static jsdialog::WidgetRegister<weld::Menu*>& Menus() { return m_aMenus; }
|
||||||
static void ForgetMenu(const OUString& nWindowId);
|
|
||||||
static weld::Menu* FindMenu(const OUString& nWindowId);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const OUString& GetTypeOfJSON() const;
|
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)
|
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))
|
if (auto pJSWidget = dynamic_cast<BaseJSWidget*>(pWidget))
|
||||||
pJSWidget->sendFullUpdate();
|
pJSWidget->sendFullUpdate();
|
||||||
}
|
}
|
||||||
@@ -45,14 +46,16 @@ void SendFullUpdate(const OUString& nWindowId, const OUString& rWidget)
|
|||||||
void SendAction(const OUString& nWindowId, const OUString& rWidget,
|
void SendAction(const OUString& nWindowId, const OUString& rWidget,
|
||||||
std::unique_ptr<ActionDataMap> pData)
|
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))
|
if (auto pJSWidget = dynamic_cast<BaseJSWidget*>(pWidget))
|
||||||
pJSWidget->sendAction(std::move(pData));
|
pJSWidget->sendAction(std::move(pData));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExecuteAction(const OUString& nWindowId, const OUString& rWidget, StringMap& rData)
|
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 sControlType = rData[u"type"_ustr];
|
||||||
OUString sAction = rData[u"cmd"_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()))
|
if (pWidget == nullptr || (pButton && !pButton->is_custom_handler_set()))
|
||||||
{
|
{
|
||||||
// welded wrapper not found - use response code instead
|
// 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";
|
sControlType = "dialog";
|
||||||
sAction = "response";
|
sAction = "response";
|
||||||
}
|
}
|
||||||
@@ -79,7 +83,7 @@ bool ExecuteAction(const OUString& nWindowId, const OUString& rWidget, StringMap
|
|||||||
// weld::Menu doesn't have base of weld::Widget
|
// weld::Menu doesn't have base of weld::Widget
|
||||||
if (sControlType == "menu")
|
if (sControlType == "menu")
|
||||||
{
|
{
|
||||||
weld::Menu* pMenu = JSInstanceBuilder::FindMenu(nWindowId);
|
weld::Menu* pMenu = JSInstanceBuilder::Menus().Find(nWindowId);
|
||||||
if (pMenu && sAction == "activated")
|
if (pMenu && sAction == "activated")
|
||||||
{
|
{
|
||||||
LOKTrigger::trigger_activated(*pMenu, rData["data"]);
|
LOKTrigger::trigger_activated(*pMenu, rData["data"]);
|
||||||
|
@@ -32,22 +32,6 @@
|
|||||||
#include <vcl/cvtgrf.hxx>
|
#include <vcl/cvtgrf.hxx>
|
||||||
#include <wizdlg.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
|
namespace
|
||||||
{
|
{
|
||||||
void response_help(vcl::Window* pWindow)
|
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
|
// used for dialogs
|
||||||
JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const std::u16string_view sUIRoot,
|
JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const std::u16string_view sUIRoot,
|
||||||
const OUString& rUIFile, bool bPopup)
|
const OUString& rUIFile, bool bPopup)
|
||||||
@@ -693,153 +668,19 @@ JSInstanceBuilder::~JSInstanceBuilder()
|
|||||||
|
|
||||||
if (m_nWindowId && (m_bHasTopLevelDialog || m_bIsNotebookbar))
|
if (m_nWindowId && (m_bHasTopLevelDialog || m_bIsNotebookbar))
|
||||||
{
|
{
|
||||||
GetLOKWeldWidgetsMap().erase(getMapIdFromWindowId());
|
JSInstanceBuilder::Widgets().Forget(getMapIdFromWindowId());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto it = GetLOKWeldWidgetsMap().find(getMapIdFromWindowId());
|
auto aWindowMap = JSInstanceBuilder::Widgets().Find(getMapIdFromWindowId());
|
||||||
if (it != GetLOKWeldWidgetsMap().end())
|
if (aWindowMap)
|
||||||
{
|
{
|
||||||
std::for_each(m_aRememberedWidgets.begin(), m_aRememberedWidgets.end(),
|
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));
|
JSInstanceBuilder::Popups().Forget(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const OUString& JSInstanceBuilder::GetTypeOfJSON() const { return m_sTypeOfJSON; }
|
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
|
// use parent builder to send update - avoid multiple calls from many builders
|
||||||
vcl::Window* pParent = pContainer->GetParent();
|
vcl::Window* pParent = pContainer->GetParent();
|
||||||
OUString sId = OUString::number(m_nWindowId);
|
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();
|
pParent = pParent->GetParent();
|
||||||
|
}
|
||||||
|
|
||||||
if (pParent)
|
if (pParent)
|
||||||
jsdialog::SendFullUpdate(sId, pParent->get_id());
|
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);
|
std::unique_ptr<weld::Menu> pWeldWidget(pMenu);
|
||||||
|
|
||||||
if (pWeldWidget)
|
if (pWeldWidget)
|
||||||
RememberMenu(getMapIdFromWindowId(), pWeldWidget.get());
|
JSInstanceBuilder::Menus().Remember(getMapIdFromWindowId(), pWeldWidget.get());
|
||||||
|
|
||||||
return pWeldWidget;
|
return pWeldWidget;
|
||||||
}
|
}
|
||||||
@@ -1270,7 +1116,7 @@ std::unique_ptr<weld::Popover> JSInstanceBuilder::weld_popover(const OUString& i
|
|||||||
m_nWindowId = m_aParentDialog->GetLOKWindowId();
|
m_nWindowId = m_aParentDialog->GetLOKWindowId();
|
||||||
|
|
||||||
pPopover->set_window_id(m_nWindowId);
|
pPopover->set_window_id(m_nWindowId);
|
||||||
JSInstanceBuilder::RememberPopup(OUString::number(m_nWindowId), pDockingWindow);
|
JSInstanceBuilder::Popups().Remember(OUString::number(m_nWindowId), pDockingWindow);
|
||||||
|
|
||||||
InsertWindowToMap(getMapIdFromWindowId());
|
InsertWindowToMap(getMapIdFromWindowId());
|
||||||
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
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)))
|
= dynamic_cast<::OKButton*>(m_xMessageDialog->get_widget_for_response(RET_OK)))
|
||||||
{
|
{
|
||||||
m_pOK.reset(new JSButton(m_pSender, pOKBtn, nullptr, false));
|
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));
|
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)))
|
= dynamic_cast<::CancelButton*>(m_xMessageDialog->get_widget_for_response(RET_CANCEL)))
|
||||||
{
|
{
|
||||||
m_pCancel.reset(new JSButton(m_pSender, pCancelBtn, nullptr, false));
|
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));
|
m_pCancel->connect_clicked(LINK(this, JSMessageDialog, CancelHdl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1889,7 +1735,7 @@ JSMessageDialog::~JSMessageDialog()
|
|||||||
// For Message Dialogs created from Application::CreateMessageDialog
|
// For Message Dialogs created from Application::CreateMessageDialog
|
||||||
// (where there is no builder to take care of this for us) explicitly
|
// (where there is no builder to take care of this for us) explicitly
|
||||||
// remove this window id on tear down
|
// 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;
|
static constexpr OUString sWidgetName = u"__DIALOG__"_ustr;
|
||||||
OUString sWindowId = OUString::number(m_xMessageDialog->GetLOKWindowId());
|
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;
|
return;
|
||||||
|
|
||||||
JSInstanceBuilder::InsertWindowToMap(sWindowId);
|
JSInstanceBuilder::InsertWindowToMap(sWindowId);
|
||||||
@@ -2028,13 +1875,13 @@ void JSToolbar::set_menu_item_active(const OUString& rIdent, bool bActive)
|
|||||||
{
|
{
|
||||||
if (bActive)
|
if (bActive)
|
||||||
{
|
{
|
||||||
JSInstanceBuilder::RememberPopup(OUString::number(pPopupRoot->GetLOKWindowId()),
|
JSInstanceBuilder::Popups().Remember(OUString::number(pPopupRoot->GetLOKWindowId()),
|
||||||
pFloat);
|
pFloat);
|
||||||
sendPopup(pPopupRoot, m_xToolBox->get_id(), rIdent);
|
sendPopup(pPopupRoot, m_xToolBox->get_id(), rIdent);
|
||||||
}
|
}
|
||||||
else if (bWasActive)
|
else if (bWasActive)
|
||||||
{
|
{
|
||||||
JSInstanceBuilder::ForgetPopup(OUString::number(pPopupRoot->GetLOKWindowId()));
|
JSInstanceBuilder::Popups().Forget(OUString::number(pPopupRoot->GetLOKWindowId()));
|
||||||
sendClosePopup(pPopupRoot->GetLOKWindowId());
|
sendClosePopup(pPopupRoot->GetLOKWindowId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2428,7 +2275,7 @@ void JSPopover::popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRe
|
|||||||
|
|
||||||
void JSPopover::popdown()
|
void JSPopover::popdown()
|
||||||
{
|
{
|
||||||
vcl::Window* pPopup = JSInstanceBuilder::FindPopup(OUString::number(mnWindowId));
|
VclPtr<vcl::Window> pPopup = JSInstanceBuilder::Popups().Find(OUString::number(mnWindowId));
|
||||||
|
|
||||||
if (pPopup)
|
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