This will help us to reduce payload and fix bug where in Chrome regenerated spin field always focused "arrow down" button after click on the "arrow up". Use value from formatter - the same as generated in widget update JSON. Change-Id: I6ace90eb532e894daacb563bc9fb93332fd755ce Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138700 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Rashesh Padia <rashesh.padia@collabora.com> Reviewed-by: Szymon Kłos <szymon.klos@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140579 Tested-by: Jenkins
1881 lines
58 KiB
C++
1881 lines
58 KiB
C++
/* -*- 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/jsdialogbuilder.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <comphelper/lok.hxx>
|
|
#include <utility>
|
|
#include <vcl/tabpage.hxx>
|
|
#include <vcl/toolkit/button.hxx>
|
|
#include <vcl/toolkit/dialog.hxx>
|
|
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
|
|
#include <vcl/toolkit/combobox.hxx>
|
|
#include <messagedialog.hxx>
|
|
#include <tools/json_writer.hxx>
|
|
#include <o3tl/deleter.hxx>
|
|
#include <memory>
|
|
#include <vcl/toolbox.hxx>
|
|
#include <vcl/toolkit/vclmedit.hxx>
|
|
#include <boost/property_tree/json_parser.hpp>
|
|
#include <vcl/toolkit/treelistentry.hxx>
|
|
#include <vcl/jsdialog/executor.hxx>
|
|
#include <cppuhelper/supportsservice.hxx>
|
|
|
|
static std::map<std::string, vcl::Window*>& GetLOKPopupsMap()
|
|
{
|
|
// Map to remember the LOKWindowId <-> vcl popup binding.
|
|
static std::map<std::string, vcl::Window*> s_aLOKPopupsMap;
|
|
|
|
return s_aLOKPopupsMap;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
void response_help(vcl::Window* pWindow)
|
|
{
|
|
::Dialog* pDialog = dynamic_cast<::Dialog*>(pWindow);
|
|
if (!pDialog)
|
|
return;
|
|
|
|
vcl::Window* pButtonWindow = pDialog->get_widget_for_response(RET_HELP);
|
|
::Button* pButton = dynamic_cast<::Button*>(pButtonWindow);
|
|
if (!pButton)
|
|
return;
|
|
|
|
pButton->Click();
|
|
}
|
|
}
|
|
|
|
JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow,
|
|
VclPtr<vcl::Window> aContentWindow, std::string sTypeOfJSON)
|
|
: Idle("JSDialog notify")
|
|
, m_aNotifierWindow(std::move(aNotifierWindow))
|
|
, m_aContentWindow(std::move(aContentWindow))
|
|
, m_sTypeOfJSON(std::move(sTypeOfJSON))
|
|
, m_bForce(false)
|
|
{
|
|
SetPriority(TaskPriority::POST_PAINT);
|
|
}
|
|
|
|
void JSDialogNotifyIdle::forceUpdate() { m_bForce = true; }
|
|
|
|
void JSDialogNotifyIdle::send(tools::JsonWriter& aJsonWriter)
|
|
{
|
|
if (!m_aNotifierWindow)
|
|
{
|
|
free(aJsonWriter.extractData());
|
|
return;
|
|
}
|
|
|
|
const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier();
|
|
if (pNotifier)
|
|
{
|
|
if (m_bForce || !aJsonWriter.isDataEquals(m_LastNotificationMessage))
|
|
{
|
|
m_bForce = false;
|
|
m_LastNotificationMessage = aJsonWriter.extractAsStdString();
|
|
pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG,
|
|
m_LastNotificationMessage.c_str());
|
|
}
|
|
else
|
|
{
|
|
free(aJsonWriter.extractData());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
free(aJsonWriter.extractData());
|
|
}
|
|
}
|
|
|
|
namespace
|
|
{
|
|
OUString extractActionType(const jsdialog::ActionDataMap& rData)
|
|
{
|
|
auto it = rData.find(ACTION_TYPE);
|
|
if (it != rData.end())
|
|
return it->second;
|
|
return "";
|
|
}
|
|
};
|
|
|
|
void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow,
|
|
std::unique_ptr<jsdialog::ActionDataMap> pData)
|
|
{
|
|
std::scoped_lock aGuard(m_aQueueMutex);
|
|
|
|
// 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();
|
|
|
|
while (it != m_aMessageQueue.end())
|
|
{
|
|
if (it->m_eType == eType && it->m_pWindow == pWindow)
|
|
{
|
|
if (it->m_pData && pData
|
|
&& extractActionType(*it->m_pData) != extractActionType(*pData))
|
|
{
|
|
it++;
|
|
continue;
|
|
}
|
|
it = m_aMessageQueue.erase(it);
|
|
}
|
|
else
|
|
it++;
|
|
}
|
|
|
|
JSDialogMessageInfo aMessage(eType, pWindow, std::move(pData));
|
|
m_aMessageQueue.push_back(aMessage);
|
|
}
|
|
|
|
std::unique_ptr<tools::JsonWriter> JSDialogNotifyIdle::generateFullUpdate() const
|
|
{
|
|
std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
|
|
|
|
if (!m_aContentWindow || !m_aNotifierWindow)
|
|
return aJsonWriter;
|
|
|
|
m_aContentWindow->DumpAsPropertyTree(*aJsonWriter);
|
|
aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
|
|
aJsonWriter->put("jsontype", m_sTypeOfJSON);
|
|
|
|
return aJsonWriter;
|
|
}
|
|
|
|
std::unique_ptr<tools::JsonWriter>
|
|
JSDialogNotifyIdle::generateWidgetUpdate(VclPtr<vcl::Window> pWindow) const
|
|
{
|
|
std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
|
|
|
|
if (!pWindow || !m_aNotifierWindow)
|
|
return aJsonWriter;
|
|
|
|
aJsonWriter->put("jsontype", m_sTypeOfJSON);
|
|
aJsonWriter->put("action", "update");
|
|
aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
|
|
{
|
|
auto aEntries = aJsonWriter->startNode("control");
|
|
pWindow->DumpAsPropertyTree(*aJsonWriter);
|
|
}
|
|
|
|
return aJsonWriter;
|
|
}
|
|
|
|
std::unique_ptr<tools::JsonWriter> JSDialogNotifyIdle::generateCloseMessage() const
|
|
{
|
|
std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
|
|
if (m_aNotifierWindow)
|
|
aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
|
|
aJsonWriter->put("jsontype", m_sTypeOfJSON);
|
|
aJsonWriter->put("action", "close");
|
|
|
|
return aJsonWriter;
|
|
}
|
|
|
|
std::unique_ptr<tools::JsonWriter>
|
|
JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow,
|
|
std::unique_ptr<jsdialog::ActionDataMap> pData) const
|
|
{
|
|
std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
|
|
|
|
aJsonWriter->put("jsontype", m_sTypeOfJSON);
|
|
aJsonWriter->put("action", "action");
|
|
aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
|
|
|
|
{
|
|
auto aDataNode = aJsonWriter->startNode("data");
|
|
aJsonWriter->put("control_id", pWindow->get_id());
|
|
|
|
for (auto it = pData->begin(); it != pData->end(); it++)
|
|
aJsonWriter->put(it->first.c_str(), it->second);
|
|
}
|
|
|
|
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;
|
|
|
|
if (!pWindow->GetParentWithLOKNotifier())
|
|
return aJsonWriter;
|
|
|
|
{
|
|
auto aChildren = aJsonWriter->startArray("children");
|
|
{
|
|
auto aStruct = aJsonWriter->startStruct();
|
|
pWindow->DumpAsPropertyTree(*aJsonWriter);
|
|
}
|
|
}
|
|
|
|
// try to get the position eg. for the autofilter
|
|
{
|
|
vcl::Window* pVclWindow = pWindow.get();
|
|
DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pVclWindow);
|
|
while (pVclWindow && !pDockingWindow)
|
|
{
|
|
pVclWindow = pVclWindow->GetParent();
|
|
pDockingWindow = dynamic_cast<DockingWindow*>(pVclWindow);
|
|
}
|
|
|
|
if (pDockingWindow)
|
|
{
|
|
Point aPos = pDockingWindow->GetFloatingPos();
|
|
aJsonWriter->put("posx", aPos.getX());
|
|
aJsonWriter->put("posy", aPos.getY());
|
|
if (!pDockingWindow->IsVisible())
|
|
aJsonWriter->put("visible", "false");
|
|
}
|
|
}
|
|
|
|
aJsonWriter->put("jsontype", "dialog");
|
|
aJsonWriter->put("type", "modalpopup");
|
|
aJsonWriter->put("cancellable", true);
|
|
aJsonWriter->put("popupParent", sParentId);
|
|
aJsonWriter->put("clickToClose", sCloseId);
|
|
aJsonWriter->put("id", pWindow->GetParentWithLOKNotifier()->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("type", "modalpopup");
|
|
aJsonWriter->put("action", "close");
|
|
aJsonWriter->put("id", sWindowId);
|
|
|
|
return aJsonWriter;
|
|
}
|
|
|
|
void JSDialogNotifyIdle::Invoke()
|
|
{
|
|
std::deque<JSDialogMessageInfo> aMessageQueue;
|
|
{
|
|
std::scoped_lock aGuard(m_aQueueMutex);
|
|
|
|
std::swap(aMessageQueue, m_aMessageQueue);
|
|
}
|
|
|
|
for (auto& rMessage : aMessageQueue)
|
|
{
|
|
jsdialog::MessageType eType = rMessage.m_eType;
|
|
|
|
if (m_sTypeOfJSON == "formulabar" && eType != jsdialog::MessageType::Action)
|
|
continue;
|
|
|
|
switch (eType)
|
|
{
|
|
case jsdialog::MessageType::FullUpdate:
|
|
send(*generateFullUpdate());
|
|
break;
|
|
|
|
case jsdialog::MessageType::WidgetUpdate:
|
|
send(*generateWidgetUpdate(rMessage.m_pWindow));
|
|
break;
|
|
|
|
case jsdialog::MessageType::Close:
|
|
send(*generateCloseMessage());
|
|
break;
|
|
|
|
case jsdialog::MessageType::Action:
|
|
send(*generateActionMessage(rMessage.m_pWindow, std::move(rMessage.m_pData)));
|
|
break;
|
|
|
|
case jsdialog::MessageType::Popup:
|
|
send(*generatePopupMessage(rMessage.m_pWindow, (*rMessage.m_pData)[PARENT_ID],
|
|
(*rMessage.m_pData)[CLOSE_ID]));
|
|
break;
|
|
|
|
case jsdialog::MessageType::PopupClose:
|
|
send(*generateClosePopupMessage((*rMessage.m_pData)[WINDOW_ID]));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void JSDialogNotifyIdle::clearQueue() { m_aMessageQueue.clear(); }
|
|
|
|
JSDialogSender::~JSDialogSender() COVERITY_NOEXCEPT_FALSE
|
|
{
|
|
sendClose();
|
|
|
|
if (mpIdleNotify)
|
|
mpIdleNotify->Stop();
|
|
}
|
|
|
|
void JSDialogSender::sendFullUpdate(bool bForce)
|
|
{
|
|
if (!mpIdleNotify)
|
|
return;
|
|
|
|
if (bForce)
|
|
mpIdleNotify->forceUpdate();
|
|
|
|
mpIdleNotify->sendMessage(jsdialog::MessageType::FullUpdate, nullptr);
|
|
mpIdleNotify->Start();
|
|
}
|
|
|
|
void JSDialogSender::sendClose()
|
|
{
|
|
if (!mpIdleNotify || !m_bCanClose)
|
|
return;
|
|
|
|
mpIdleNotify->clearQueue();
|
|
mpIdleNotify->sendMessage(jsdialog::MessageType::Close, nullptr);
|
|
flush();
|
|
}
|
|
|
|
void JSDialogSender::sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce)
|
|
{
|
|
if (!mpIdleNotify)
|
|
return;
|
|
|
|
if (bForce)
|
|
mpIdleNotify->forceUpdate();
|
|
|
|
mpIdleNotify->sendMessage(jsdialog::MessageType::WidgetUpdate, pWindow);
|
|
mpIdleNotify->Start();
|
|
}
|
|
|
|
void JSDialogSender::sendAction(VclPtr<vcl::Window> pWindow,
|
|
std::unique_ptr<jsdialog::ActionDataMap> pData)
|
|
{
|
|
if (!mpIdleNotify)
|
|
return;
|
|
|
|
mpIdleNotify->sendMessage(jsdialog::MessageType::Action, pWindow, std::move(pData));
|
|
mpIdleNotify->Start();
|
|
}
|
|
|
|
void JSDialogSender::sendPopup(VclPtr<vcl::Window> pWindow, OUString sParentId, OUString sCloseId)
|
|
{
|
|
if (!mpIdleNotify)
|
|
return;
|
|
|
|
std::unique_ptr<jsdialog::ActionDataMap> pData = std::make_unique<jsdialog::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)
|
|
{
|
|
if (!mpIdleNotify)
|
|
return;
|
|
|
|
std::unique_ptr<jsdialog::ActionDataMap> pData = std::make_unique<jsdialog::ActionDataMap>();
|
|
(*pData)[WINDOW_ID] = OUString::number(nWindowId);
|
|
mpIdleNotify->sendMessage(jsdialog::MessageType::PopupClose, nullptr, std::move(pData));
|
|
flush();
|
|
}
|
|
|
|
namespace
|
|
{
|
|
vcl::Window* extract_sal_widget(weld::Widget* pParent)
|
|
{
|
|
SalInstanceWidget* pInstanceWidget = dynamic_cast<SalInstanceWidget*>(pParent);
|
|
return pInstanceWidget ? pInstanceWidget->getWidget() : nullptr;
|
|
}
|
|
}
|
|
|
|
// Drag and drop
|
|
|
|
namespace
|
|
{
|
|
class JSDropTargetDropContext
|
|
: public cppu::WeakImplHelper<css::datatransfer::dnd::XDropTargetDropContext>
|
|
{
|
|
public:
|
|
JSDropTargetDropContext() {}
|
|
|
|
// XDropTargetDropContext
|
|
virtual void SAL_CALL acceptDrop(sal_Int8 /*dragOperation*/) override {}
|
|
|
|
virtual void SAL_CALL rejectDrop() override {}
|
|
|
|
virtual void SAL_CALL dropComplete(sal_Bool /*bSuccess*/) override {}
|
|
};
|
|
}
|
|
|
|
static JSTreeView* g_DragSource;
|
|
|
|
JSDropTarget::JSDropTarget() {}
|
|
|
|
void JSDropTarget::initialize(const css::uno::Sequence<css::uno::Any>& /*rArgs*/) {}
|
|
|
|
void JSDropTarget::addDropTargetListener(
|
|
const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener)
|
|
{
|
|
std::unique_lock aGuard(m_aMutex);
|
|
|
|
m_aListeners.push_back(xListener);
|
|
}
|
|
|
|
void JSDropTarget::removeDropTargetListener(
|
|
const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener)
|
|
{
|
|
std::unique_lock aGuard(m_aMutex);
|
|
|
|
m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), xListener),
|
|
m_aListeners.end());
|
|
}
|
|
|
|
sal_Bool JSDropTarget::isActive() { return false; }
|
|
|
|
void JSDropTarget::setActive(sal_Bool /*active*/) {}
|
|
|
|
sal_Int8 JSDropTarget::getDefaultActions() { return 0; }
|
|
|
|
void JSDropTarget::setDefaultActions(sal_Int8 /*actions*/) {}
|
|
|
|
OUString JSDropTarget::getImplementationName()
|
|
{
|
|
return "com.sun.star.datatransfer.dnd.JSDropTarget";
|
|
}
|
|
|
|
sal_Bool JSDropTarget::supportsService(OUString const& ServiceName)
|
|
{
|
|
return cppu::supportsService(this, ServiceName);
|
|
}
|
|
|
|
css::uno::Sequence<OUString> JSDropTarget::getSupportedServiceNames()
|
|
{
|
|
css::uno::Sequence<OUString> aRet{ "com.sun.star.datatransfer.dnd.JSDropTarget" };
|
|
return aRet;
|
|
}
|
|
|
|
void JSDropTarget::fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde)
|
|
{
|
|
std::unique_lock aGuard(m_aMutex);
|
|
std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
|
|
m_aListeners);
|
|
aGuard.unlock();
|
|
|
|
for (auto const& listener : aListeners)
|
|
{
|
|
listener->drop(dtde);
|
|
}
|
|
}
|
|
|
|
void JSDropTarget::fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent& dtde)
|
|
{
|
|
std::unique_lock aGuard(m_aMutex);
|
|
std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
|
|
m_aListeners);
|
|
aGuard.unlock();
|
|
|
|
for (auto const& listener : aListeners)
|
|
{
|
|
listener->dragEnter(dtde);
|
|
}
|
|
}
|
|
|
|
std::string JSInstanceBuilder::getMapIdFromWindowId() const
|
|
{
|
|
if (m_sTypeOfJSON == "sidebar" || m_sTypeOfJSON == "notebookbar"
|
|
|| m_sTypeOfJSON == "formulabar")
|
|
return std::to_string(m_nWindowId) + m_sTypeOfJSON;
|
|
else
|
|
return std::to_string(m_nWindowId);
|
|
}
|
|
|
|
// used for dialogs
|
|
JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot,
|
|
const OUString& rUIFile, bool bPopup)
|
|
: SalInstanceBuilder(extract_sal_widget(pParent), rUIRoot, rUIFile)
|
|
, m_nWindowId(0)
|
|
, m_aParentDialog(nullptr)
|
|
, m_aContentWindow(nullptr)
|
|
, 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)
|
|
{
|
|
m_sTypeOfJSON = "popup";
|
|
return;
|
|
}
|
|
|
|
vcl::Window* pRoot = m_xBuilder->get_widget_root();
|
|
|
|
if (pRoot && pRoot->GetParent())
|
|
{
|
|
m_aParentDialog = pRoot->GetParent()->GetParentWithLOKNotifier();
|
|
if (m_aParentDialog)
|
|
m_nWindowId = m_aParentDialog->GetLOKWindowId();
|
|
InsertWindowToMap(getMapIdFromWindowId());
|
|
}
|
|
|
|
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
|
}
|
|
|
|
// used for sidebar panels
|
|
JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot,
|
|
const OUString& rUIFile, sal_uInt64 nLOKWindowId)
|
|
: SalInstanceBuilder(extract_sal_widget(pParent), rUIRoot, rUIFile)
|
|
, m_nWindowId(nLOKWindowId)
|
|
, m_aParentDialog(nullptr)
|
|
, m_aContentWindow(nullptr)
|
|
, m_sTypeOfJSON("sidebar")
|
|
, m_bHasTopLevelDialog(false)
|
|
, m_bIsNotebookbar(false)
|
|
, m_aWindowToRelease(nullptr)
|
|
{
|
|
vcl::Window* pRoot = m_xBuilder->get_widget_root();
|
|
|
|
m_aParentDialog = pRoot->GetParentWithLOKNotifier();
|
|
|
|
if (rUIFile == "sfx/ui/panel.ui")
|
|
{
|
|
// builder for Panel, get SidebarDockingWindow as m_aContentWindow
|
|
m_aContentWindow = pRoot;
|
|
for (int i = 0; i < 7 && m_aContentWindow; i++)
|
|
m_aContentWindow = m_aContentWindow->GetParent();
|
|
}
|
|
else
|
|
{
|
|
// embedded fragments cannot send close message for whole sidebar
|
|
if (rUIFile == "modules/simpress/ui/customanimationfragment.ui")
|
|
m_bCanClose = false;
|
|
|
|
// builder for PanelLayout, get SidebarDockingWindow as m_aContentWindow
|
|
m_aContentWindow = pRoot;
|
|
for (int i = 0; i < 9 && m_aContentWindow; i++)
|
|
m_aContentWindow = m_aContentWindow->GetParent();
|
|
}
|
|
|
|
InsertWindowToMap(getMapIdFromWindowId());
|
|
|
|
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
|
}
|
|
|
|
// used for notebookbar
|
|
JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot,
|
|
const OUString& rUIFile,
|
|
const css::uno::Reference<css::frame::XFrame>& rFrame,
|
|
sal_uInt64 nWindowId)
|
|
: SalInstanceBuilder(pParent, rUIRoot, rUIFile, rFrame)
|
|
, m_nWindowId(0)
|
|
, m_aParentDialog(nullptr)
|
|
, m_aContentWindow(nullptr)
|
|
, m_sTypeOfJSON("notebookbar")
|
|
, m_bHasTopLevelDialog(false)
|
|
, m_bIsNotebookbar(false)
|
|
, m_aWindowToRelease(nullptr)
|
|
{
|
|
vcl::Window* pRoot = m_xBuilder->get_widget_root();
|
|
if (pRoot && pRoot->GetParent())
|
|
{
|
|
m_aParentDialog = pRoot->GetParent()->GetParentWithLOKNotifier();
|
|
if (m_aParentDialog)
|
|
m_nWindowId = m_aParentDialog->GetLOKWindowId();
|
|
if (!m_nWindowId && nWindowId)
|
|
{
|
|
m_nWindowId = nWindowId;
|
|
m_bIsNotebookbar = true;
|
|
}
|
|
InsertWindowToMap(getMapIdFromWindowId());
|
|
}
|
|
|
|
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
|
}
|
|
|
|
// used for formulabar
|
|
JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot,
|
|
const OUString& rUIFile, sal_uInt64 nLOKWindowId)
|
|
: SalInstanceBuilder(pParent, rUIRoot, rUIFile)
|
|
, m_nWindowId(nLOKWindowId)
|
|
, m_aParentDialog(nullptr)
|
|
, m_aContentWindow(nullptr)
|
|
, m_sTypeOfJSON("formulabar")
|
|
, m_bHasTopLevelDialog(false)
|
|
, m_bIsNotebookbar(false)
|
|
, m_aWindowToRelease(nullptr)
|
|
{
|
|
vcl::Window* pRoot = m_xBuilder->get_widget_root();
|
|
m_aContentWindow = pParent;
|
|
if (pRoot && pRoot->GetParent())
|
|
{
|
|
m_aParentDialog = pRoot->GetParent()->GetParentWithLOKNotifier();
|
|
InsertWindowToMap(getMapIdFromWindowId());
|
|
}
|
|
|
|
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
|
}
|
|
|
|
std::unique_ptr<JSInstanceBuilder> JSInstanceBuilder::CreateDialogBuilder(weld::Widget* pParent,
|
|
const OUString& rUIRoot,
|
|
const OUString& rUIFile)
|
|
{
|
|
return std::make_unique<JSInstanceBuilder>(pParent, rUIRoot, rUIFile);
|
|
}
|
|
|
|
std::unique_ptr<JSInstanceBuilder> JSInstanceBuilder::CreateNotebookbarBuilder(
|
|
vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile,
|
|
const css::uno::Reference<css::frame::XFrame>& rFrame, sal_uInt64 nWindowId)
|
|
{
|
|
return std::make_unique<JSInstanceBuilder>(pParent, rUIRoot, rUIFile, rFrame, nWindowId);
|
|
}
|
|
|
|
std::unique_ptr<JSInstanceBuilder> JSInstanceBuilder::CreateSidebarBuilder(weld::Widget* pParent,
|
|
const OUString& rUIRoot,
|
|
const OUString& rUIFile,
|
|
sal_uInt64 nLOKWindowId)
|
|
{
|
|
return std::make_unique<JSInstanceBuilder>(pParent, rUIRoot, rUIFile, nLOKWindowId);
|
|
}
|
|
|
|
std::unique_ptr<JSInstanceBuilder> JSInstanceBuilder::CreatePopupBuilder(weld::Widget* pParent,
|
|
const OUString& rUIRoot,
|
|
const OUString& rUIFile)
|
|
{
|
|
return std::make_unique<JSInstanceBuilder>(pParent, rUIRoot, rUIFile, true);
|
|
}
|
|
|
|
std::unique_ptr<JSInstanceBuilder>
|
|
JSInstanceBuilder::CreateFormulabarBuilder(vcl::Window* pParent, const OUString& rUIRoot,
|
|
const OUString& rUIFile, sal_uInt64 nLOKWindowId)
|
|
{
|
|
return std::make_unique<JSInstanceBuilder>(pParent, rUIRoot, rUIFile, nLOKWindowId);
|
|
}
|
|
|
|
JSInstanceBuilder::~JSInstanceBuilder()
|
|
{
|
|
if (m_sTypeOfJSON == "popup")
|
|
sendClosePopup(m_nWindowId);
|
|
|
|
if (m_aWindowToRelease)
|
|
{
|
|
m_aWindowToRelease->ReleaseLOKNotifier();
|
|
m_aWindowToRelease.clear();
|
|
}
|
|
|
|
if (m_nWindowId && (m_bHasTopLevelDialog || m_bIsNotebookbar))
|
|
{
|
|
GetLOKWeldWidgetsMap().erase(getMapIdFromWindowId());
|
|
}
|
|
else
|
|
{
|
|
auto it = GetLOKWeldWidgetsMap().find(getMapIdFromWindowId());
|
|
if (it != GetLOKWeldWidgetsMap().end())
|
|
{
|
|
std::for_each(m_aRememberedWidgets.begin(), m_aRememberedWidgets.end(),
|
|
[it](std::string& sId) { it->second.erase(sId.c_str()); });
|
|
}
|
|
}
|
|
|
|
GetLOKPopupsMap().erase(std::to_string(m_nWindowId));
|
|
}
|
|
|
|
std::map<std::string, WidgetMap>& JSInstanceBuilder::GetLOKWeldWidgetsMap()
|
|
{
|
|
// Map to remember the LOKWindowId <-> weld widgets binding.
|
|
static std::map<std::string, WidgetMap> s_aLOKWeldBuildersMap;
|
|
|
|
return s_aLOKWeldBuildersMap;
|
|
}
|
|
|
|
weld::Widget* JSInstanceBuilder::FindWeldWidgetsMap(const std::string& nWindowId,
|
|
const OString& 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 std::string& nWindowId)
|
|
{
|
|
WidgetMap map;
|
|
auto it = GetLOKWeldWidgetsMap().find(nWindowId);
|
|
if (it == GetLOKWeldWidgetsMap().end())
|
|
GetLOKWeldWidgetsMap().insert(std::map<std::string, WidgetMap>::value_type(nWindowId, map));
|
|
}
|
|
|
|
void JSInstanceBuilder::RememberWidget(OString 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 + OString::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.getStr());
|
|
}
|
|
|
|
void JSInstanceBuilder::RememberWidget(const std::string& nWindowId, const OString& 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 std::string& nWindowId, const OString& 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 std::string& nWindowId)
|
|
{
|
|
auto it = JSInstanceBuilder::GetLOKWeldWidgetsMap().find(nWindowId);
|
|
if (it != JSInstanceBuilder::GetLOKWeldWidgetsMap().end())
|
|
{
|
|
JSInstanceBuilder::GetLOKWeldWidgetsMap().erase(it);
|
|
}
|
|
}
|
|
|
|
void JSInstanceBuilder::RememberPopup(const std::string& nWindowId, VclPtr<vcl::Window> pWidget)
|
|
{
|
|
GetLOKPopupsMap()[nWindowId] = pWidget;
|
|
}
|
|
|
|
void JSInstanceBuilder::ForgetPopup(const std::string& nWindowId)
|
|
{
|
|
auto it = GetLOKPopupsMap().find(nWindowId);
|
|
if (it != GetLOKPopupsMap().end())
|
|
GetLOKPopupsMap().erase(it);
|
|
}
|
|
|
|
vcl::Window* JSInstanceBuilder::FindPopup(const std::string& nWindowId)
|
|
{
|
|
const auto it = GetLOKPopupsMap().find(nWindowId);
|
|
|
|
if (it != GetLOKPopupsMap().end())
|
|
return it->second;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
const std::string& JSInstanceBuilder::GetTypeOfJSON() const { return m_sTypeOfJSON; }
|
|
|
|
VclPtr<vcl::Window>& JSInstanceBuilder::GetContentWindow()
|
|
{
|
|
if (m_aContentWindow)
|
|
return m_aContentWindow;
|
|
else
|
|
return m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog;
|
|
}
|
|
|
|
VclPtr<vcl::Window>& JSInstanceBuilder::GetNotifierWindow()
|
|
{
|
|
return m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog;
|
|
}
|
|
|
|
std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id)
|
|
{
|
|
std::unique_ptr<weld::Dialog> pRet;
|
|
::Dialog* pDialog = m_xBuilder->get<::Dialog>(id);
|
|
|
|
if (pDialog)
|
|
{
|
|
m_nWindowId = pDialog->GetLOKWindowId();
|
|
pDialog->SetLOKTunnelingState(false);
|
|
|
|
InsertWindowToMap(getMapIdFromWindowId());
|
|
|
|
assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
|
|
m_aOwnedToplevel.set(pDialog);
|
|
m_xBuilder->drop_ownership(pDialog);
|
|
m_bHasTopLevelDialog = true;
|
|
|
|
pRet.reset(new JSDialog(this, pDialog, this, false));
|
|
|
|
RememberWidget("__DIALOG__", pRet.get());
|
|
|
|
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
|
sendFullUpdate();
|
|
}
|
|
|
|
return pRet;
|
|
}
|
|
|
|
std::unique_ptr<weld::MessageDialog> JSInstanceBuilder::weld_message_dialog(const OString& id)
|
|
{
|
|
std::unique_ptr<weld::MessageDialog> pRet;
|
|
::MessageDialog* pMessageDialog = m_xBuilder->get<::MessageDialog>(id);
|
|
|
|
if (pMessageDialog)
|
|
{
|
|
m_nWindowId = pMessageDialog->GetLOKWindowId();
|
|
pMessageDialog->SetLOKTunnelingState(false);
|
|
|
|
InsertWindowToMap(getMapIdFromWindowId());
|
|
|
|
assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
|
|
m_aOwnedToplevel.set(pMessageDialog);
|
|
m_xBuilder->drop_ownership(pMessageDialog);
|
|
m_bHasTopLevelDialog = true;
|
|
|
|
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
|
}
|
|
|
|
pRet.reset(pMessageDialog ? new JSMessageDialog(this, pMessageDialog, this, false) : nullptr);
|
|
|
|
if (pRet)
|
|
RememberWidget("__DIALOG__", pRet.get());
|
|
|
|
return pRet;
|
|
}
|
|
|
|
std::unique_ptr<weld::Container> JSInstanceBuilder::weld_container(const OString& id)
|
|
{
|
|
vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
|
|
auto pWeldWidget = std::make_unique<JSContainer>(this, pContainer, this, false);
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Label> JSInstanceBuilder::weld_label(const OString& id)
|
|
{
|
|
Control* pLabel = m_xBuilder->get<Control>(id);
|
|
auto pWeldWidget = std::make_unique<JSLabel>(this, pLabel, this, false);
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Button> JSInstanceBuilder::weld_button(const OString& id)
|
|
{
|
|
::Button* pButton = m_xBuilder->get<::Button>(id);
|
|
auto pWeldWidget = pButton ? std::make_unique<JSButton>(this, pButton, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Entry> JSInstanceBuilder::weld_entry(const OString& id)
|
|
{
|
|
Edit* pEntry = m_xBuilder->get<Edit>(id);
|
|
auto pWeldWidget = pEntry ? std::make_unique<JSEntry>(this, pEntry, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::ComboBox> JSInstanceBuilder::weld_combo_box(const OString& id)
|
|
{
|
|
vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
|
|
::ComboBox* pComboBox = dynamic_cast<::ComboBox*>(pWidget);
|
|
std::unique_ptr<weld::ComboBox> pWeldWidget;
|
|
|
|
if (pComboBox)
|
|
{
|
|
pWeldWidget = std::make_unique<JSComboBox>(this, pComboBox, this, false);
|
|
}
|
|
else
|
|
{
|
|
ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
|
|
pWeldWidget = pListBox ? std::make_unique<JSListBox>(this, pListBox, this, false) : nullptr;
|
|
}
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Notebook> JSInstanceBuilder::weld_notebook(const OString& id)
|
|
{
|
|
TabControl* pNotebook = m_xBuilder->get<TabControl>(id);
|
|
auto pWeldWidget
|
|
= pNotebook ? std::make_unique<JSNotebook>(this, pNotebook, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::SpinButton> JSInstanceBuilder::weld_spin_button(const OString& id)
|
|
{
|
|
FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
|
|
auto pWeldWidget
|
|
= pSpinButton ? std::make_unique<JSSpinButton>(this, pSpinButton, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::CheckButton> JSInstanceBuilder::weld_check_button(const OString& id)
|
|
{
|
|
CheckBox* pCheckButton = m_xBuilder->get<CheckBox>(id);
|
|
auto pWeldWidget
|
|
= pCheckButton ? std::make_unique<JSCheckButton>(this, pCheckButton, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::DrawingArea>
|
|
JSInstanceBuilder::weld_drawing_area(const OString& id, const a11yref& rA11yImpl,
|
|
FactoryFunction pUITestFactoryFunction, void* pUserData)
|
|
{
|
|
VclDrawingArea* pArea = m_xBuilder->get<VclDrawingArea>(id);
|
|
auto pWeldWidget = pArea ? std::make_unique<JSDrawingArea>(this, pArea, this, rA11yImpl,
|
|
pUITestFactoryFunction, pUserData)
|
|
: nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Toolbar> JSInstanceBuilder::weld_toolbar(const OString& id)
|
|
{
|
|
ToolBox* pToolBox = m_xBuilder->get<ToolBox>(id);
|
|
auto pWeldWidget
|
|
= pToolBox ? std::make_unique<JSToolbar>(this, pToolBox, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::TextView> JSInstanceBuilder::weld_text_view(const OString& id)
|
|
{
|
|
VclMultiLineEdit* pTextView = m_xBuilder->get<VclMultiLineEdit>(id);
|
|
auto pWeldWidget
|
|
= pTextView ? std::make_unique<JSTextView>(this, pTextView, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::TreeView> JSInstanceBuilder::weld_tree_view(const OString& id)
|
|
{
|
|
SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id);
|
|
auto pWeldWidget
|
|
= pTreeView ? std::make_unique<JSTreeView>(this, pTreeView, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Expander> JSInstanceBuilder::weld_expander(const OString& id)
|
|
{
|
|
VclExpander* pExpander = m_xBuilder->get<VclExpander>(id);
|
|
auto pWeldWidget
|
|
= pExpander ? std::make_unique<JSExpander>(this, pExpander, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::IconView> JSInstanceBuilder::weld_icon_view(const OString& id)
|
|
{
|
|
::IconView* pIconView = m_xBuilder->get<::IconView>(id);
|
|
auto pWeldWidget
|
|
= pIconView ? std::make_unique<JSIconView>(this, pIconView, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::RadioButton> JSInstanceBuilder::weld_radio_button(const OString& id)
|
|
{
|
|
::RadioButton* pRadioButton = m_xBuilder->get<::RadioButton>(id);
|
|
auto pWeldWidget
|
|
= pRadioButton ? std::make_unique<JSRadioButton>(this, pRadioButton, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Frame> JSInstanceBuilder::weld_frame(const OString& id)
|
|
{
|
|
::VclFrame* pFrame = m_xBuilder->get<::VclFrame>(id);
|
|
auto pWeldWidget = pFrame ? std::make_unique<JSFrame>(this, pFrame, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::MenuButton> JSInstanceBuilder::weld_menu_button(const OString& id)
|
|
{
|
|
::MenuButton* pMenuButton = m_xBuilder->get<::MenuButton>(id);
|
|
auto pWeldWidget
|
|
= pMenuButton ? std::make_unique<JSMenuButton>(this, pMenuButton, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Popover> JSInstanceBuilder::weld_popover(const OString& id)
|
|
{
|
|
DockingWindow* pDockingWindow = m_xBuilder->get<DockingWindow>(id);
|
|
JSPopover* pPopover
|
|
= pDockingWindow ? new JSPopover(this, pDockingWindow, this, false) : nullptr;
|
|
std::unique_ptr<weld::Popover> pWeldWidget(pPopover);
|
|
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())
|
|
{
|
|
vcl::Window* pPopupRoot = pDockingWindow->GetChild(0);
|
|
pPopupRoot->SetLOKNotifier(pWin->GetLOKNotifier());
|
|
m_aParentDialog = pPopupRoot;
|
|
m_aWindowToRelease = pPopupRoot;
|
|
m_nWindowId = m_aParentDialog->GetLOKWindowId();
|
|
|
|
pPopover->set_window_id(m_nWindowId);
|
|
JSInstanceBuilder::RememberPopup(std::to_string(m_nWindowId), pDockingWindow);
|
|
|
|
InsertWindowToMap(getMapIdFromWindowId());
|
|
initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
|
|
}
|
|
}
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget("__POPOVER__", pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Box> JSInstanceBuilder::weld_box(const OString& id)
|
|
{
|
|
VclBox* pContainer = m_xBuilder->get<VclBox>(id);
|
|
auto pWeldWidget
|
|
= pContainer ? std::make_unique<JSBox>(this, pContainer, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Widget> JSInstanceBuilder::weld_widget(const OString& id)
|
|
{
|
|
vcl::Window* pWidget = m_xBuilder->get(id);
|
|
auto pWeldWidget
|
|
= pWidget ? std::make_unique<JSWidgetInstance>(this, pWidget, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
std::unique_ptr<weld::Image> JSInstanceBuilder::weld_image(const OString& id)
|
|
{
|
|
FixedImage* pImage = m_xBuilder->get<FixedImage>(id);
|
|
|
|
auto pWeldWidget = pImage ? std::make_unique<JSImage>(this, pImage, this, false) : nullptr;
|
|
|
|
if (pWeldWidget)
|
|
RememberWidget(id, pWeldWidget.get());
|
|
|
|
return pWeldWidget;
|
|
}
|
|
|
|
weld::MessageDialog* JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent,
|
|
VclMessageType eMessageType,
|
|
VclButtonsType eButtonType,
|
|
const OUString& rPrimaryMessage)
|
|
{
|
|
SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
|
|
SystemWindow* pParentWidget = pParentInstance ? pParentInstance->getSystemWindow() : nullptr;
|
|
VclPtrInstance<::MessageDialog> xMessageDialog(pParentWidget, rPrimaryMessage, eMessageType,
|
|
eButtonType);
|
|
|
|
const vcl::ILibreOfficeKitNotifier* pNotifier = xMessageDialog->GetLOKNotifier();
|
|
if (pNotifier)
|
|
{
|
|
tools::JsonWriter aJsonWriter;
|
|
xMessageDialog->DumpAsPropertyTree(aJsonWriter);
|
|
aJsonWriter.put("id", xMessageDialog->GetLOKWindowId());
|
|
aJsonWriter.put("jsontype", "dialog");
|
|
std::unique_ptr<char[], o3tl::free_delete> message(aJsonWriter.extractData());
|
|
pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.get());
|
|
|
|
std::string sWindowId = std::to_string(xMessageDialog->GetLOKWindowId());
|
|
InsertWindowToMap(sWindowId);
|
|
}
|
|
|
|
xMessageDialog->SetLOKTunnelingState(false);
|
|
|
|
return new JSMessageDialog(xMessageDialog, nullptr, true);
|
|
}
|
|
|
|
JSDialog::JSDialog(JSDialogSender* pSender, ::Dialog* pDialog, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceDialog, ::Dialog>(pSender, pDialog, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSDialog::collapse(weld::Widget* pEdit, weld::Widget* pButton)
|
|
{
|
|
SalInstanceDialog::collapse(pEdit, pButton);
|
|
sendFullUpdate();
|
|
}
|
|
|
|
void JSDialog::undo_collapse()
|
|
{
|
|
SalInstanceDialog::undo_collapse();
|
|
sendFullUpdate();
|
|
}
|
|
|
|
void JSDialog::response(int response)
|
|
{
|
|
if (response == RET_HELP)
|
|
{
|
|
response_help(m_xWidget.get());
|
|
return;
|
|
}
|
|
|
|
sendClose();
|
|
SalInstanceDialog::response(response);
|
|
}
|
|
|
|
JSContainer::JSContainer(JSDialogSender* pSender, vcl::Window* pContainer,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceContainer, vcl::Window>(pSender, pContainer, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
JSLabel::JSLabel(JSDialogSender* pSender, Control* pLabel, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceLabel, Control>(pSender, pLabel, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSLabel::set_label(const OUString& rText)
|
|
{
|
|
SalInstanceLabel::set_label(rText);
|
|
sendUpdate();
|
|
};
|
|
|
|
JSButton::JSButton(JSDialogSender* pSender, ::Button* pButton, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceButton, ::Button>(pSender, pButton, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
JSEntry::JSEntry(JSDialogSender* pSender, ::Edit* pEntry, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceEntry, ::Edit>(pSender, pEntry, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSEntry::set_text(const OUString& rText)
|
|
{
|
|
SalInstanceEntry::set_text(rText);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSEntry::set_text_without_notify(const OUString& rText) { SalInstanceEntry::set_text(rText); }
|
|
|
|
JSListBox::JSListBox(JSDialogSender* pSender, ::ListBox* pListBox, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceComboBoxWithoutEdit, ::ListBox>(pSender, pListBox, pBuilder,
|
|
bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSListBox::insert(int pos, const OUString& rStr, const OUString* pId,
|
|
const OUString* pIconName, VirtualDevice* pImageSurface)
|
|
{
|
|
SalInstanceComboBoxWithoutEdit::insert(pos, rStr, pId, pIconName, pImageSurface);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSListBox::remove(int pos)
|
|
{
|
|
SalInstanceComboBoxWithoutEdit::remove(pos);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSListBox::set_active(int pos)
|
|
{
|
|
SalInstanceComboBoxWithoutEdit::set_active(pos);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSComboBox::JSComboBox(JSDialogSender* pSender, ::ComboBox* pComboBox, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceComboBoxWithEdit, ::ComboBox>(pSender, pComboBox, pBuilder,
|
|
bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSComboBox::insert(int pos, const OUString& rStr, const OUString* pId,
|
|
const OUString* pIconName, VirtualDevice* pImageSurface)
|
|
{
|
|
SalInstanceComboBoxWithEdit::insert(pos, rStr, pId, pIconName, pImageSurface);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSComboBox::remove(int pos)
|
|
{
|
|
SalInstanceComboBoxWithEdit::remove(pos);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSComboBox::set_entry_text_without_notify(const OUString& rText)
|
|
{
|
|
SalInstanceComboBoxWithEdit::set_entry_text(rText);
|
|
}
|
|
|
|
void JSComboBox::set_entry_text(const OUString& rText)
|
|
{
|
|
SalInstanceComboBoxWithEdit::set_entry_text(rText);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSComboBox::set_active(int pos)
|
|
{
|
|
SalInstanceComboBoxWithEdit::set_active(pos);
|
|
sendUpdate();
|
|
}
|
|
|
|
bool JSComboBox::changed_by_direct_pick() const { return true; }
|
|
|
|
JSNotebook::JSNotebook(JSDialogSender* pSender, ::TabControl* pControl,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceNotebook, ::TabControl>(pSender, pControl, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSNotebook::set_current_page(int nPage)
|
|
{
|
|
bool bForce = false;
|
|
int nCurrent = get_current_page();
|
|
if (nCurrent == nPage)
|
|
bForce = true;
|
|
|
|
SalInstanceNotebook::set_current_page(nPage);
|
|
sendFullUpdate(bForce);
|
|
|
|
m_aEnterPageHdl.Call(get_current_page_ident());
|
|
}
|
|
|
|
void JSNotebook::set_current_page(const OString& rIdent)
|
|
{
|
|
bool bForce = false;
|
|
OString sCurrent = get_current_page_ident();
|
|
if (sCurrent == rIdent)
|
|
bForce = true;
|
|
|
|
SalInstanceNotebook::set_current_page(rIdent);
|
|
sendFullUpdate(bForce);
|
|
|
|
m_aEnterPageHdl.Call(get_current_page_ident());
|
|
}
|
|
|
|
void JSNotebook::remove_page(const OString& rIdent)
|
|
{
|
|
SalInstanceNotebook::remove_page(rIdent);
|
|
sendFullUpdate();
|
|
}
|
|
|
|
void JSNotebook::insert_page(const OString& rIdent, const OUString& rLabel, int nPos)
|
|
{
|
|
SalInstanceNotebook::insert_page(rIdent, rLabel, nPos);
|
|
sendFullUpdate();
|
|
}
|
|
|
|
JSSpinButton::JSSpinButton(JSDialogSender* pSender, ::FormattedField* pSpin,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceSpinButton, ::FormattedField>(pSender, pSpin, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSSpinButton::set_value(sal_Int64 value)
|
|
{
|
|
SalInstanceSpinButton::set_value(value);
|
|
|
|
std::unique_ptr<jsdialog::ActionDataMap> pMap = std::make_unique<jsdialog::ActionDataMap>();
|
|
(*pMap)[ACTION_TYPE] = "setText";
|
|
(*pMap)["text"] = OUString::number(m_rFormatter.GetValue());
|
|
sendAction(std::move(pMap));
|
|
}
|
|
|
|
JSMessageDialog::JSMessageDialog(JSDialogSender* pSender, ::MessageDialog* pDialog,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceMessageDialog, ::MessageDialog>(pSender, pDialog, pBuilder,
|
|
bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
JSMessageDialog::JSMessageDialog(::MessageDialog* pDialog, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceMessageDialog, ::MessageDialog>(nullptr, pDialog, pBuilder,
|
|
bTakeOwnership)
|
|
, m_pOwnedSender(new JSDialogSender(pDialog, pDialog, "dialog"))
|
|
{
|
|
m_pSender = m_pOwnedSender.get();
|
|
|
|
if (pBuilder)
|
|
return;
|
|
|
|
m_sWindowId = std::to_string(m_xMessageDialog->GetLOKWindowId());
|
|
|
|
if (::OKButton* pOKBtn
|
|
= 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().toUtf8(), m_pOK.get());
|
|
m_pOK->connect_clicked(LINK(this, JSMessageDialog, OKHdl));
|
|
}
|
|
|
|
if (::CancelButton* pCancelBtn
|
|
= 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().toUtf8(),
|
|
m_pCancel.get());
|
|
m_pCancel->connect_clicked(LINK(this, JSMessageDialog, CancelHdl));
|
|
}
|
|
}
|
|
|
|
JSMessageDialog::~JSMessageDialog()
|
|
{
|
|
if (m_pOK || m_pCancel)
|
|
JSInstanceBuilder::RemoveWindowWidget(m_sWindowId);
|
|
}
|
|
|
|
void JSMessageDialog::RememberMessageDialog()
|
|
{
|
|
static OStringLiteral sWidgetName = "__DIALOG__";
|
|
std::string sWindowId = std::to_string(m_xMessageDialog->GetLOKWindowId());
|
|
if (JSInstanceBuilder::FindWeldWidgetsMap(sWindowId, sWidgetName) != nullptr)
|
|
return;
|
|
|
|
JSInstanceBuilder::InsertWindowToMap(sWindowId);
|
|
JSInstanceBuilder::RememberWidget(sWindowId, sWidgetName, this);
|
|
}
|
|
|
|
bool JSMessageDialog::runAsync(std::shared_ptr<weld::DialogController> aOwner,
|
|
const std::function<void(sal_Int32)>& rEndDialogFn)
|
|
{
|
|
bool bRet = SalInstanceMessageDialog::runAsync(aOwner, rEndDialogFn);
|
|
|
|
RememberMessageDialog();
|
|
sendFullUpdate();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
bool JSMessageDialog::runAsync(std::shared_ptr<Dialog> const& rxSelf,
|
|
const std::function<void(sal_Int32)>& rEndDialogFn)
|
|
{
|
|
bool bRet = SalInstanceMessageDialog::runAsync(rxSelf, rEndDialogFn);
|
|
|
|
RememberMessageDialog();
|
|
sendFullUpdate();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
IMPL_LINK_NOARG(JSMessageDialog, OKHdl, weld::Button&, void) { response(RET_OK); }
|
|
|
|
IMPL_LINK_NOARG(JSMessageDialog, CancelHdl, weld::Button&, void) { response(RET_CANCEL); }
|
|
|
|
void JSMessageDialog::set_primary_text(const OUString& rText)
|
|
{
|
|
SalInstanceMessageDialog::set_primary_text(rText);
|
|
sendFullUpdate();
|
|
}
|
|
|
|
void JSMessageDialog::set_secondary_text(const OUString& rText)
|
|
{
|
|
SalInstanceMessageDialog::set_secondary_text(rText);
|
|
sendFullUpdate();
|
|
}
|
|
|
|
void JSMessageDialog::response(int response)
|
|
{
|
|
if (response == RET_HELP)
|
|
{
|
|
response_help(m_xWidget.get());
|
|
return;
|
|
}
|
|
|
|
sendClose();
|
|
SalInstanceMessageDialog::response(response);
|
|
}
|
|
|
|
JSCheckButton::JSCheckButton(JSDialogSender* pSender, ::CheckBox* pCheckBox,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceCheckButton, ::CheckBox>(pSender, pCheckBox, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSCheckButton::set_active(bool active)
|
|
{
|
|
bool bWasActive = get_active();
|
|
SalInstanceCheckButton::set_active(active);
|
|
if (bWasActive != active)
|
|
sendUpdate();
|
|
}
|
|
|
|
JSDrawingArea::JSDrawingArea(JSDialogSender* pSender, VclDrawingArea* pDrawingArea,
|
|
SalInstanceBuilder* pBuilder, const a11yref& rAlly,
|
|
FactoryFunction pUITestFactoryFunction, void* pUserData)
|
|
: JSWidget<SalInstanceDrawingArea, VclDrawingArea>(pSender, pDrawingArea, pBuilder, rAlly,
|
|
std::move(pUITestFactoryFunction), pUserData,
|
|
false)
|
|
{
|
|
}
|
|
|
|
void JSDrawingArea::queue_draw()
|
|
{
|
|
SalInstanceDrawingArea::queue_draw();
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSDrawingArea::queue_draw_area(int x, int y, int width, int height)
|
|
{
|
|
SalInstanceDrawingArea::queue_draw_area(x, y, width, height);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSToolbar::JSToolbar(JSDialogSender* pSender, ::ToolBox* pToolbox, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceToolbar, ::ToolBox>(pSender, pToolbox, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSToolbar::set_menu_item_active(const OString& rIdent, bool bActive)
|
|
{
|
|
bool bWasActive = get_menu_item_active(rIdent);
|
|
SalInstanceToolbar::set_menu_item_active(rIdent, bActive);
|
|
|
|
ToolBoxItemId nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
|
|
VclPtr<vcl::Window> pFloat = m_aFloats[nItemId];
|
|
|
|
if (!pFloat)
|
|
return;
|
|
|
|
// 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)
|
|
{
|
|
JSInstanceBuilder::RememberPopup(std::to_string(pPopupRoot->GetLOKWindowId()), pFloat);
|
|
sendPopup(pPopupRoot, m_xToolBox->get_id(),
|
|
OStringToOUString(rIdent, RTL_TEXTENCODING_ASCII_US));
|
|
}
|
|
else if (bWasActive)
|
|
{
|
|
JSInstanceBuilder::ForgetPopup(std::to_string(pPopupRoot->GetLOKWindowId()));
|
|
sendClosePopup(pPopupRoot->GetLOKWindowId());
|
|
}
|
|
}
|
|
}
|
|
|
|
void JSToolbar::set_item_sensitive(const OString& rIdent, bool bSensitive)
|
|
{
|
|
SalInstanceToolbar::set_item_sensitive(rIdent, bSensitive);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSToolbar::set_item_icon_name(const OString& rIdent, const OUString& rIconName)
|
|
{
|
|
SalInstanceToolbar::set_item_icon_name(rIdent, rIconName);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSTextView::JSTextView(JSDialogSender* pSender, ::VclMultiLineEdit* pTextView,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceTextView, ::VclMultiLineEdit>(pSender, pTextView, pBuilder,
|
|
bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSTextView::set_text(const OUString& rText)
|
|
{
|
|
SalInstanceTextView::set_text(rText);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSTreeView::JSTreeView(JSDialogSender* pSender, ::SvTabListBox* pTreeView,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceTreeView, ::SvTabListBox>(pSender, pTreeView, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSTreeView::set_toggle(int pos, TriState eState, int col)
|
|
{
|
|
SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0);
|
|
|
|
while (pEntry && pos--)
|
|
pEntry = m_xTreeView->Next(pEntry);
|
|
|
|
if (pEntry)
|
|
{
|
|
SalInstanceTreeView::set_toggle(pEntry, eState, col);
|
|
signal_toggled(iter_col(SalInstanceTreeIter(pEntry), col));
|
|
|
|
sendUpdate();
|
|
}
|
|
}
|
|
|
|
void JSTreeView::set_toggle(const weld::TreeIter& rIter, TriState bOn, int col)
|
|
{
|
|
SalInstanceTreeView::set_toggle(rIter, bOn, col);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::select(int pos)
|
|
{
|
|
assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
|
|
disable_notify_events();
|
|
if (pos == -1 || (pos == 0 && n_children() == 0))
|
|
m_xTreeView->SelectAll(false);
|
|
else
|
|
{
|
|
SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0);
|
|
|
|
while (pEntry && pos--)
|
|
pEntry = m_xTreeView->Next(pEntry);
|
|
|
|
if (pEntry)
|
|
{
|
|
m_xTreeView->Select(pEntry, true);
|
|
m_xTreeView->MakeVisible(pEntry);
|
|
}
|
|
}
|
|
enable_notify_events();
|
|
sendUpdate();
|
|
}
|
|
|
|
weld::TreeView* JSTreeView::get_drag_source() const { return g_DragSource; }
|
|
|
|
void JSTreeView::drag_start() { g_DragSource = this; }
|
|
|
|
void JSTreeView::drag_end()
|
|
{
|
|
css::datatransfer::dnd::XDropTarget* xDropTarget = m_xDropTarget.get();
|
|
if (xDropTarget)
|
|
{
|
|
css::datatransfer::dnd::DropTargetDropEvent aEvent;
|
|
aEvent.Source = xDropTarget;
|
|
aEvent.Context = new JSDropTargetDropContext();
|
|
// dummy values
|
|
aEvent.LocationX = 50;
|
|
aEvent.LocationY = 50;
|
|
aEvent.DropAction = css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
|
|
aEvent.SourceActions = css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
|
|
|
|
m_xDropTarget->fire_drop(aEvent);
|
|
|
|
sendUpdate();
|
|
if (g_DragSource)
|
|
g_DragSource->sendUpdate();
|
|
}
|
|
|
|
g_DragSource = nullptr;
|
|
}
|
|
|
|
void JSTreeView::insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
|
|
const OUString* pId, const OUString* pIconName,
|
|
VirtualDevice* pImageSurface, bool bChildrenOnDemand, weld::TreeIter* pRet)
|
|
{
|
|
SalInstanceTreeView::insert(pParent, pos, pStr, pId, pIconName, pImageSurface,
|
|
bChildrenOnDemand, pRet);
|
|
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::set_text(int row, const OUString& rText, int col)
|
|
{
|
|
SalInstanceTreeView::set_text(row, rText, col);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::set_text(const weld::TreeIter& rIter, const OUString& rStr, int col)
|
|
{
|
|
SalInstanceTreeView::set_text(rIter, rStr, col);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::remove(int pos)
|
|
{
|
|
SalInstanceTreeView::remove(pos);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::remove(const weld::TreeIter& rIter)
|
|
{
|
|
SalInstanceTreeView::remove(rIter);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::clear()
|
|
{
|
|
SalInstanceTreeView::clear();
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::expand_row(const weld::TreeIter& rIter)
|
|
{
|
|
SalInstanceTreeView::expand_row(rIter);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSTreeView::collapse_row(const weld::TreeIter& rIter)
|
|
{
|
|
SalInstanceTreeView::collapse_row(rIter);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSExpander::JSExpander(JSDialogSender* pSender, ::VclExpander* pExpander,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceExpander, ::VclExpander>(pSender, pExpander, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSExpander::set_expanded(bool bExpand)
|
|
{
|
|
SalInstanceExpander::set_expanded(bExpand);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSIconView::JSIconView(JSDialogSender* pSender, ::IconView* pIconView, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceIconView, ::IconView>(pSender, pIconView, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSIconView::insert(int pos, const OUString* pStr, const OUString* pId,
|
|
const OUString* pIconName, weld::TreeIter* pRet)
|
|
{
|
|
SalInstanceIconView::insert(pos, pStr, pId, pIconName, pRet);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSIconView::insert(int pos, const OUString* pStr, const OUString* pId,
|
|
const VirtualDevice* pIcon, weld::TreeIter* pRet)
|
|
{
|
|
SalInstanceIconView::insert(pos, pStr, pId, pIcon, pRet);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSIconView::insert_separator(int pos, const OUString* pId)
|
|
{
|
|
SalInstanceIconView::insert_separator(pos, pId);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSIconView::clear()
|
|
{
|
|
SalInstanceIconView::clear();
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSIconView::select(int pos)
|
|
{
|
|
SalInstanceIconView::select(pos);
|
|
|
|
std::unique_ptr<jsdialog::ActionDataMap> pMap = std::make_unique<jsdialog::ActionDataMap>();
|
|
(*pMap)[ACTION_TYPE] = "select";
|
|
(*pMap)["position"] = OUString::number(pos);
|
|
sendAction(std::move(pMap));
|
|
}
|
|
|
|
void JSIconView::unselect(int pos)
|
|
{
|
|
SalInstanceIconView::unselect(pos);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSRadioButton::JSRadioButton(JSDialogSender* pSender, ::RadioButton* pRadioButton,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceRadioButton, ::RadioButton>(pSender, pRadioButton, pBuilder,
|
|
bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSRadioButton::set_active(bool active)
|
|
{
|
|
SalInstanceRadioButton::set_active(active);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSFrame::JSFrame(JSDialogSender* pSender, ::VclFrame* pFrame, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceFrame, ::VclFrame>(pSender, pFrame, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
JSMenuButton::JSMenuButton(JSDialogSender* pSender, ::MenuButton* pMenuButton,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstanceMenuButton, ::MenuButton>(pSender, pMenuButton, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSMenuButton::set_label(const OUString& rText)
|
|
{
|
|
OUString aPreviousLabel = get_label();
|
|
SalInstanceMenuButton::set_label(rText);
|
|
if (aPreviousLabel != rText)
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSMenuButton::set_image(VirtualDevice* pDevice)
|
|
{
|
|
SalInstanceMenuButton::set_image(pDevice);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSMenuButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
|
|
{
|
|
SalInstanceMenuButton::set_image(rImage);
|
|
sendUpdate();
|
|
}
|
|
|
|
void JSMenuButton::set_active(bool bActive)
|
|
{
|
|
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,
|
|
SalInstanceBuilder* pBuilder, bool bTakeOwnership)
|
|
: JSWidget<SalInstancePopover, DockingWindow>(pSender, pDockingWindow, pBuilder, bTakeOwnership)
|
|
, mnWindowId(0)
|
|
{
|
|
}
|
|
|
|
void JSPopover::popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect,
|
|
weld::Placement ePlace)
|
|
{
|
|
SalInstancePopover::popup_at_rect(pParent, rRect, ePlace);
|
|
sendPopup(getWidget()->GetChild(0), "_POPOVER_", "_POPOVER_");
|
|
}
|
|
|
|
void JSPopover::popdown()
|
|
{
|
|
vcl::Window* pPopup = JSInstanceBuilder::FindPopup(std::to_string(mnWindowId));
|
|
|
|
if (pPopup)
|
|
{
|
|
sendClosePopup(mnWindowId);
|
|
vcl::Window::GetDockingManager()->EndPopupMode(pPopup);
|
|
}
|
|
|
|
if (getWidget() && getWidget()->GetChild(0))
|
|
sendClosePopup(getWidget()->GetChild(0)->GetLOKWindowId());
|
|
|
|
SalInstancePopover::popdown();
|
|
}
|
|
|
|
JSBox::JSBox(JSDialogSender* pSender, VclBox* pBox, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceBox, VclBox>(pSender, pBox, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
void JSBox::reorder_child(weld::Widget* pWidget, int nNewPosition)
|
|
{
|
|
SalInstanceBox::reorder_child(pWidget, nNewPosition);
|
|
sendUpdate();
|
|
}
|
|
|
|
JSImage::JSImage(JSDialogSender* pSender, FixedImage* pImage, SalInstanceBuilder* pBuilder,
|
|
bool bTakeOwnership)
|
|
: JSWidget<SalInstanceImage, FixedImage>(pSender, pImage, pBuilder, bTakeOwnership)
|
|
{
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|