OInterfaceContainerHelper3 needs to be thread-safe
[LibreOffice.git] / vcl / jsdialog / jsdialogbuilder.cxx
blob981ff5fb746a5fa6ebee6d50ab41685ecfa57807
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <jsdialog/jsdialogbuilder.hxx>
11 #include <sal/log.hxx>
12 #include <comphelper/lok.hxx>
13 #include <vcl/tabpage.hxx>
14 #include <vcl/toolkit/button.hxx>
15 #include <vcl/toolkit/dialog.hxx>
16 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
17 #include <vcl/toolkit/combobox.hxx>
18 #include <messagedialog.hxx>
19 #include <tools/json_writer.hxx>
20 #include <o3tl/deleter.hxx>
21 #include <memory>
22 #include <vcl/toolbox.hxx>
23 #include <vcl/toolkit/vclmedit.hxx>
24 #include <boost/property_tree/json_parser.hpp>
25 #include <vcl/toolkit/treelistentry.hxx>
26 #include <vcl/jsdialog/executor.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <utility>
30 namespace
32 void response_help(vcl::Window* pWindow)
34 ::Dialog* pDialog = dynamic_cast<::Dialog*>(pWindow);
35 if (!pDialog)
36 return;
38 vcl::Window* pButtonWindow = pDialog->get_widget_for_response(RET_HELP);
39 ::Button* pButton = dynamic_cast<::Button*>(pButtonWindow);
40 if (!pButton)
41 return;
43 pButton->Click();
47 JSDialogNotifyIdle::JSDialogNotifyIdle(VclPtr<vcl::Window> aNotifierWindow,
48 VclPtr<vcl::Window> aContentWindow, std::string sTypeOfJSON)
49 : Idle("JSDialog notify")
50 , m_aNotifierWindow(aNotifierWindow)
51 , m_aContentWindow(aContentWindow)
52 , m_sTypeOfJSON(sTypeOfJSON)
53 , m_LastNotificationMessage()
54 , m_bForce(false)
56 SetPriority(TaskPriority::POST_PAINT);
59 void JSDialogNotifyIdle::forceUpdate() { m_bForce = true; }
61 void JSDialogNotifyIdle::send(tools::JsonWriter& aJsonWriter)
63 if (!m_aNotifierWindow)
65 free(aJsonWriter.extractData());
66 return;
69 const vcl::ILibreOfficeKitNotifier* pNotifier = m_aNotifierWindow->GetLOKNotifier();
70 if (pNotifier)
72 if (m_bForce || !aJsonWriter.isDataEquals(m_LastNotificationMessage))
74 m_bForce = false;
75 m_LastNotificationMessage = aJsonWriter.extractAsStdString();
76 pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG,
77 m_LastNotificationMessage.c_str());
79 else
81 free(aJsonWriter.extractData());
84 else
86 free(aJsonWriter.extractData());
90 namespace
92 OUString extractActionType(const ActionDataMap& rData)
94 auto it = rData.find(ACTION_TYPE);
95 if (it != rData.end())
96 return it->second;
97 return "";
101 void JSDialogNotifyIdle::sendMessage(jsdialog::MessageType eType, VclPtr<vcl::Window> pWindow,
102 std::unique_ptr<ActionDataMap> pData)
104 m_aQueueMutex.acquire();
106 // we want only the latest update of same type
107 // TODO: also if we met full update - previous updates are not valid
108 auto it = m_aMessageQueue.begin();
110 while (it != m_aMessageQueue.end())
112 if (it->m_eType == eType && it->m_pWindow == pWindow)
114 if (it->m_pData && pData
115 && extractActionType(*it->m_pData) != extractActionType(*pData))
117 it++;
118 continue;
120 it = m_aMessageQueue.erase(it);
122 else
123 it++;
126 JSDialogMessageInfo aMessage(eType, pWindow, std::move(pData));
127 m_aMessageQueue.push_back(aMessage);
129 m_aQueueMutex.release();
132 std::unique_ptr<tools::JsonWriter> JSDialogNotifyIdle::generateFullUpdate() const
134 std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
136 if (!m_aContentWindow || !m_aNotifierWindow)
137 return aJsonWriter;
139 m_aContentWindow->DumpAsPropertyTree(*aJsonWriter);
140 aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
141 aJsonWriter->put("jsontype", m_sTypeOfJSON);
143 if (m_sTypeOfJSON == "autofilter")
145 vcl::Window* pWindow = m_aContentWindow.get();
146 DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pWindow);
147 while (pWindow && !pDockingWindow)
149 pWindow = pWindow->GetParent();
150 pDockingWindow = dynamic_cast<DockingWindow*>(pWindow);
153 if (pDockingWindow)
155 Point aPos = pDockingWindow->GetFloatingPos();
156 aJsonWriter->put("posx", aPos.getX());
157 aJsonWriter->put("posy", aPos.getY());
158 if (!pDockingWindow->IsVisible())
159 aJsonWriter->put("visible", "false");
163 return aJsonWriter;
166 std::unique_ptr<tools::JsonWriter>
167 JSDialogNotifyIdle::generateWidgetUpdate(VclPtr<vcl::Window> pWindow) const
169 std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
171 if (!pWindow || !m_aNotifierWindow)
172 return aJsonWriter;
174 aJsonWriter->put("jsontype", m_sTypeOfJSON);
175 aJsonWriter->put("action", "update");
176 aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
178 auto aEntries = aJsonWriter->startNode("control");
179 pWindow->DumpAsPropertyTree(*aJsonWriter);
182 return aJsonWriter;
185 std::unique_ptr<tools::JsonWriter> JSDialogNotifyIdle::generateCloseMessage() const
187 std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
188 if (m_aNotifierWindow)
189 aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
190 aJsonWriter->put("jsontype", m_sTypeOfJSON);
191 aJsonWriter->put("action", "close");
193 return aJsonWriter;
196 std::unique_ptr<tools::JsonWriter>
197 JSDialogNotifyIdle::generateActionMessage(VclPtr<vcl::Window> pWindow,
198 std::unique_ptr<ActionDataMap> pData) const
200 std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
202 aJsonWriter->put("jsontype", m_sTypeOfJSON);
203 aJsonWriter->put("action", "action");
204 aJsonWriter->put("id", m_aNotifierWindow->GetLOKWindowId());
207 auto aDataNode = aJsonWriter->startNode("data");
208 aJsonWriter->put("control_id", pWindow->get_id());
210 for (auto it = pData->begin(); it != pData->end(); it++)
211 aJsonWriter->put(it->first.c_str(), it->second);
214 return aJsonWriter;
217 std::unique_ptr<tools::JsonWriter>
218 JSDialogNotifyIdle::generatePopupMessage(VclPtr<vcl::Window> pWindow, OUString sParentId,
219 OUString sCloseId) const
221 std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
223 if (!pWindow || !m_aNotifierWindow)
224 return aJsonWriter;
226 if (!pWindow->GetParentWithLOKNotifier())
227 return aJsonWriter;
230 auto aChildren = aJsonWriter->startArray("children");
232 auto aStruct = aJsonWriter->startStruct();
233 pWindow->DumpAsPropertyTree(*aJsonWriter);
237 aJsonWriter->put("jsontype", "dialog");
238 aJsonWriter->put("type", "modalpopup");
239 aJsonWriter->put("cancellable", true);
240 aJsonWriter->put("popupParent", sParentId);
241 aJsonWriter->put("clickToClose", sCloseId);
242 aJsonWriter->put("id", pWindow->GetParentWithLOKNotifier()->GetLOKWindowId());
244 return aJsonWriter;
247 std::unique_ptr<tools::JsonWriter>
248 JSDialogNotifyIdle::generateClosePopupMessage(OUString sWindowId) const
250 std::unique_ptr<tools::JsonWriter> aJsonWriter(new tools::JsonWriter());
252 if (!m_aNotifierWindow)
253 return aJsonWriter;
255 aJsonWriter->put("jsontype", "dialog");
256 aJsonWriter->put("type", "modalpopup");
257 aJsonWriter->put("action", "close");
258 aJsonWriter->put("id", sWindowId);
260 return aJsonWriter;
263 void JSDialogNotifyIdle::Invoke()
265 bool bAcquired = m_aQueueMutex.acquire();
267 if (!bAcquired)
268 SAL_WARN("vcl", "JSDialogNotifyIdle::Invoke : mutex cannot be acquired");
270 std::deque<JSDialogMessageInfo> aMessageQueue(std::move(m_aMessageQueue));
271 m_aMessageQueue = std::deque<JSDialogMessageInfo>();
272 clearQueue();
274 m_aQueueMutex.release();
276 for (auto& rMessage : aMessageQueue)
278 jsdialog::MessageType eType = rMessage.m_eType;
280 switch (eType)
282 case jsdialog::MessageType::FullUpdate:
283 send(*generateFullUpdate());
284 break;
286 case jsdialog::MessageType::WidgetUpdate:
287 send(*generateWidgetUpdate(rMessage.m_pWindow));
288 break;
290 case jsdialog::MessageType::Close:
291 send(*generateCloseMessage());
292 break;
294 case jsdialog::MessageType::Action:
295 send(*generateActionMessage(rMessage.m_pWindow, std::move(rMessage.m_pData)));
296 break;
298 case jsdialog::MessageType::Popup:
299 send(*generatePopupMessage(rMessage.m_pWindow, (*rMessage.m_pData)[PARENT_ID],
300 (*rMessage.m_pData)[CLOSE_ID]));
301 break;
303 case jsdialog::MessageType::PopupClose:
304 send(*generateClosePopupMessage((*rMessage.m_pData)[WINDOW_ID]));
305 break;
310 void JSDialogNotifyIdle::clearQueue() { m_aMessageQueue.clear(); }
312 JSDialogSender::~JSDialogSender()
314 sendClose();
316 if (mpIdleNotify)
317 mpIdleNotify->Stop();
320 void JSDialogSender::sendFullUpdate(bool bForce)
322 if (!mpIdleNotify)
323 return;
325 if (bForce)
326 mpIdleNotify->forceUpdate();
328 mpIdleNotify->sendMessage(jsdialog::MessageType::FullUpdate, nullptr);
329 mpIdleNotify->Start();
332 void JSDialogSender::sendClose()
334 if (!mpIdleNotify || !m_bCanClose)
335 return;
337 mpIdleNotify->clearQueue();
338 mpIdleNotify->sendMessage(jsdialog::MessageType::Close, nullptr);
339 flush();
342 void JSDialogSender::sendUpdate(VclPtr<vcl::Window> pWindow, bool bForce)
344 if (!mpIdleNotify)
345 return;
347 if (bForce)
348 mpIdleNotify->forceUpdate();
350 mpIdleNotify->sendMessage(jsdialog::MessageType::WidgetUpdate, pWindow);
351 mpIdleNotify->Start();
354 void JSDialogSender::sendAction(VclPtr<vcl::Window> pWindow, std::unique_ptr<ActionDataMap> pData)
356 if (!mpIdleNotify)
357 return;
359 mpIdleNotify->sendMessage(jsdialog::MessageType::Action, pWindow, std::move(pData));
360 mpIdleNotify->Start();
363 void JSDialogSender::sendPopup(VclPtr<vcl::Window> pWindow, OUString sParentId, OUString sCloseId)
365 if (!mpIdleNotify)
366 return;
368 std::unique_ptr<ActionDataMap> pData = std::make_unique<ActionDataMap>();
369 (*pData)[PARENT_ID] = sParentId;
370 (*pData)[CLOSE_ID] = sCloseId;
371 mpIdleNotify->sendMessage(jsdialog::MessageType::Popup, pWindow, std::move(pData));
372 mpIdleNotify->Start();
375 void JSDialogSender::sendClosePopup(vcl::LOKWindowId nWindowId)
377 if (!mpIdleNotify)
378 return;
380 std::unique_ptr<ActionDataMap> pData = std::make_unique<ActionDataMap>();
381 (*pData)[WINDOW_ID] = OUString::number(nWindowId);
382 mpIdleNotify->sendMessage(jsdialog::MessageType::PopupClose, nullptr, std::move(pData));
383 flush();
386 namespace
388 vcl::Window* extract_sal_widget(weld::Widget* pParent)
390 SalInstanceWidget* pInstanceWidget = dynamic_cast<SalInstanceWidget*>(pParent);
391 return pInstanceWidget ? pInstanceWidget->getWidget() : nullptr;
395 // Drag and drop
397 namespace
399 class JSDropTargetDropContext
400 : public cppu::WeakImplHelper<css::datatransfer::dnd::XDropTargetDropContext>
402 public:
403 JSDropTargetDropContext() {}
405 // XDropTargetDropContext
406 virtual void SAL_CALL acceptDrop(sal_Int8 /*dragOperation*/) override {}
408 virtual void SAL_CALL rejectDrop() override {}
410 virtual void SAL_CALL dropComplete(sal_Bool /*bSuccess*/) override {}
414 static JSTreeView* g_DragSource;
416 JSDropTarget::JSDropTarget()
417 : WeakComponentImplHelper(m_aMutex)
421 void JSDropTarget::initialize(const css::uno::Sequence<css::uno::Any>& /*rArgs*/) {}
423 void JSDropTarget::addDropTargetListener(
424 const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener)
426 ::osl::Guard<::osl::Mutex> aGuard(m_aMutex);
428 m_aListeners.push_back(xListener);
431 void JSDropTarget::removeDropTargetListener(
432 const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>& xListener)
434 ::osl::Guard<::osl::Mutex> aGuard(m_aMutex);
436 m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), xListener),
437 m_aListeners.end());
440 sal_Bool JSDropTarget::isActive() { return false; }
442 void JSDropTarget::setActive(sal_Bool /*active*/) {}
444 sal_Int8 JSDropTarget::getDefaultActions() { return 0; }
446 void JSDropTarget::setDefaultActions(sal_Int8 /*actions*/) {}
448 OUString JSDropTarget::getImplementationName()
450 return "com.sun.star.datatransfer.dnd.JSDropTarget";
453 sal_Bool JSDropTarget::supportsService(OUString const& ServiceName)
455 return cppu::supportsService(this, ServiceName);
458 css::uno::Sequence<OUString> JSDropTarget::getSupportedServiceNames()
460 css::uno::Sequence<OUString> aRet{ "com.sun.star.datatransfer.dnd.JSDropTarget" };
461 return aRet;
464 void JSDropTarget::fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde)
466 osl::ClearableGuard<osl::Mutex> aGuard(m_aMutex);
467 std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
468 m_aListeners);
469 aGuard.clear();
471 for (auto const& listener : aListeners)
473 listener->drop(dtde);
477 void JSDropTarget::fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent& dtde)
479 osl::ClearableGuard<::osl::Mutex> aGuard(m_aMutex);
480 std::vector<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> aListeners(
481 m_aListeners);
482 aGuard.clear();
484 for (auto const& listener : aListeners)
486 listener->dragEnter(dtde);
490 std::string JSInstanceBuilder::getMapIdFromWindowId() const
492 if (m_sTypeOfJSON == "sidebar" || m_sTypeOfJSON == "notebookbar")
493 return std::to_string(m_nWindowId) + m_sTypeOfJSON;
494 else
495 return std::to_string(m_nWindowId);
498 // used for dialogs
499 JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot,
500 const OUString& rUIFile, bool bPopup)
501 : SalInstanceBuilder(extract_sal_widget(pParent), rUIRoot, rUIFile)
502 , m_nWindowId(0)
503 , m_aParentDialog(nullptr)
504 , m_aContentWindow(nullptr)
505 , m_sTypeOfJSON("dialog")
506 , m_bHasTopLevelDialog(false)
507 , m_bIsNotebookbar(false)
508 , m_aWindowToRelease(nullptr)
510 // when it is a popup we initialize sender in weld_popover
511 if (bPopup)
512 return;
514 vcl::Window* pRoot = m_xBuilder->get_widget_root();
516 if (pRoot && pRoot->GetParent())
518 m_aParentDialog = pRoot->GetParent()->GetParentWithLOKNotifier();
519 if (m_aParentDialog)
520 m_nWindowId = m_aParentDialog->GetLOKWindowId();
521 InsertWindowToMap(getMapIdFromWindowId());
524 initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
527 // used for sidebar panels
528 JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, const OUString& rUIRoot,
529 const OUString& rUIFile, sal_uInt64 nLOKWindowId)
530 : SalInstanceBuilder(extract_sal_widget(pParent), rUIRoot, rUIFile)
531 , m_nWindowId(nLOKWindowId)
532 , m_aParentDialog(nullptr)
533 , m_aContentWindow(nullptr)
534 , m_sTypeOfJSON("sidebar")
535 , m_bHasTopLevelDialog(false)
536 , m_bIsNotebookbar(false)
537 , m_aWindowToRelease(nullptr)
539 vcl::Window* pRoot = m_xBuilder->get_widget_root();
541 m_aParentDialog = pRoot->GetParentWithLOKNotifier();
543 if (rUIFile == "sfx/ui/panel.ui")
545 // builder for Panel, get SidebarDockingWindow as m_aContentWindow
546 m_aContentWindow = pRoot;
547 for (int i = 0; i < 7 && m_aContentWindow; i++)
548 m_aContentWindow = m_aContentWindow->GetParent();
550 else
552 // embedded fragments cannot send close message for whole sidebar
553 if (rUIFile == "modules/simpress/ui/customanimationfragment.ui")
554 m_bCanClose = false;
556 // builder for PanelLayout, get SidebarDockingWindow as m_aContentWindow
557 m_aContentWindow = pRoot;
558 for (int i = 0; i < 9 && m_aContentWindow; i++)
559 m_aContentWindow = m_aContentWindow->GetParent();
562 InsertWindowToMap(getMapIdFromWindowId());
564 initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
567 // used for notebookbar
568 JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot,
569 const OUString& rUIFile,
570 const css::uno::Reference<css::frame::XFrame>& rFrame,
571 sal_uInt64 nWindowId)
572 : SalInstanceBuilder(pParent, rUIRoot, rUIFile, rFrame)
573 , m_nWindowId(0)
574 , m_aParentDialog(nullptr)
575 , m_aContentWindow(nullptr)
576 , m_sTypeOfJSON("notebookbar")
577 , m_bHasTopLevelDialog(false)
578 , m_bIsNotebookbar(false)
579 , m_aWindowToRelease(nullptr)
581 vcl::Window* pRoot = m_xBuilder->get_widget_root();
582 if (pRoot && pRoot->GetParent())
584 m_aParentDialog = pRoot->GetParent()->GetParentWithLOKNotifier();
585 if (m_aParentDialog)
586 m_nWindowId = m_aParentDialog->GetLOKWindowId();
587 if (!m_nWindowId && nWindowId)
589 m_nWindowId = nWindowId;
590 m_bIsNotebookbar = true;
592 InsertWindowToMap(getMapIdFromWindowId());
595 initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
598 // used for autofilter dropdown
599 JSInstanceBuilder::JSInstanceBuilder(vcl::Window* pParent, const OUString& rUIRoot,
600 const OUString& rUIFile)
601 : SalInstanceBuilder(pParent, rUIRoot, rUIFile)
602 , m_nWindowId(0)
603 , m_aParentDialog(nullptr)
604 , m_aContentWindow(nullptr)
605 , m_sTypeOfJSON("autofilter")
606 , m_bHasTopLevelDialog(false)
607 , m_bIsNotebookbar(false)
608 , m_aWindowToRelease(nullptr)
610 vcl::Window* pRoot = m_xBuilder->get_widget_root();
611 m_aContentWindow = pParent;
612 if (pRoot && pRoot->GetParent())
614 m_aParentDialog = pRoot->GetParent()->GetParentWithLOKNotifier();
615 if (m_aParentDialog)
616 m_nWindowId = m_aParentDialog->GetLOKWindowId();
617 InsertWindowToMap(getMapIdFromWindowId());
620 initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
621 sendFullUpdate();
624 JSInstanceBuilder* JSInstanceBuilder::CreateDialogBuilder(weld::Widget* pParent,
625 const OUString& rUIRoot,
626 const OUString& rUIFile)
628 return new JSInstanceBuilder(pParent, rUIRoot, rUIFile);
631 JSInstanceBuilder* JSInstanceBuilder::CreateNotebookbarBuilder(
632 vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile,
633 const css::uno::Reference<css::frame::XFrame>& rFrame, sal_uInt64 nWindowId)
635 return new JSInstanceBuilder(pParent, rUIRoot, rUIFile, rFrame, nWindowId);
638 JSInstanceBuilder* JSInstanceBuilder::CreateAutofilterWindowBuilder(vcl::Window* pParent,
639 const OUString& rUIRoot,
640 const OUString& rUIFile)
642 return new JSInstanceBuilder(pParent, rUIRoot, rUIFile);
645 JSInstanceBuilder* JSInstanceBuilder::CreateSidebarBuilder(weld::Widget* pParent,
646 const OUString& rUIRoot,
647 const OUString& rUIFile,
648 sal_uInt64 nLOKWindowId)
650 return new JSInstanceBuilder(pParent, rUIRoot, rUIFile, nLOKWindowId);
653 JSInstanceBuilder* JSInstanceBuilder::CreatePopupBuilder(weld::Widget* pParent,
654 const OUString& rUIRoot,
655 const OUString& rUIFile)
657 return new JSInstanceBuilder(pParent, rUIRoot, rUIFile, true);
660 JSInstanceBuilder::~JSInstanceBuilder()
662 if (m_aWindowToRelease)
664 m_aWindowToRelease->ReleaseLOKNotifier();
665 m_aWindowToRelease.clear();
668 if (m_nWindowId && (m_bHasTopLevelDialog || m_bIsNotebookbar))
670 GetLOKWeldWidgetsMap().erase(getMapIdFromWindowId());
672 else
674 auto it = GetLOKWeldWidgetsMap().find(getMapIdFromWindowId());
675 if (it != GetLOKWeldWidgetsMap().end())
677 std::for_each(m_aRememberedWidgets.begin(), m_aRememberedWidgets.end(),
678 [it](std::string& sId) { it->second.erase(sId.c_str()); });
683 std::map<std::string, WidgetMap>& JSInstanceBuilder::GetLOKWeldWidgetsMap()
685 // Map to remember the LOKWindowId <-> weld widgets binding.
686 static std::map<std::string, WidgetMap> s_aLOKWeldBuildersMap;
688 return s_aLOKWeldBuildersMap;
691 weld::Widget* JSInstanceBuilder::FindWeldWidgetsMap(const std::string& nWindowId,
692 const OString& rWidget)
694 const auto it = GetLOKWeldWidgetsMap().find(nWindowId);
696 if (it != GetLOKWeldWidgetsMap().end())
698 auto widgetIt = it->second.find(rWidget);
699 if (widgetIt != it->second.end())
700 return widgetIt->second;
703 return nullptr;
706 void JSInstanceBuilder::InsertWindowToMap(const std::string& nWindowId)
708 WidgetMap map;
709 auto it = GetLOKWeldWidgetsMap().find(nWindowId);
710 if (it == GetLOKWeldWidgetsMap().end())
711 GetLOKWeldWidgetsMap().insert(std::map<std::string, WidgetMap>::value_type(nWindowId, map));
714 void JSInstanceBuilder::RememberWidget(const OString& id, weld::Widget* pWidget)
716 RememberWidget(getMapIdFromWindowId(), id, pWidget);
717 m_aRememberedWidgets.push_back(id.getStr());
720 void JSInstanceBuilder::RememberWidget(const std::string& nWindowId, const OString& id,
721 weld::Widget* pWidget)
723 auto it = GetLOKWeldWidgetsMap().find(nWindowId);
724 if (it != GetLOKWeldWidgetsMap().end())
726 it->second.erase(id);
727 it->second.insert(WidgetMap::value_type(id, pWidget));
731 void JSInstanceBuilder::AddChildWidget(const std::string& nWindowId, const OString& id,
732 weld::Widget* pWidget)
734 auto it = GetLOKWeldWidgetsMap().find(nWindowId);
735 if (it != GetLOKWeldWidgetsMap().end())
737 it->second.erase(id);
738 it->second.insert(WidgetMap::value_type(id, pWidget));
742 void JSInstanceBuilder::RemoveWindowWidget(const std::string& nWindowId)
744 auto it = JSInstanceBuilder::GetLOKWeldWidgetsMap().find(nWindowId);
745 if (it != JSInstanceBuilder::GetLOKWeldWidgetsMap().end())
747 JSInstanceBuilder::GetLOKWeldWidgetsMap().erase(it);
751 const std::string& JSInstanceBuilder::GetTypeOfJSON() { return m_sTypeOfJSON; }
753 VclPtr<vcl::Window>& JSInstanceBuilder::GetContentWindow()
755 if (m_aContentWindow)
756 return m_aContentWindow;
757 else
758 return m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog;
761 VclPtr<vcl::Window>& JSInstanceBuilder::GetNotifierWindow()
763 return m_bHasTopLevelDialog ? m_aOwnedToplevel : m_aParentDialog;
766 std::unique_ptr<weld::Dialog> JSInstanceBuilder::weld_dialog(const OString& id)
768 std::unique_ptr<weld::Dialog> pRet;
769 ::Dialog* pDialog = m_xBuilder->get<::Dialog>(id);
771 if (pDialog)
773 m_nWindowId = pDialog->GetLOKWindowId();
774 pDialog->SetLOKTunnelingState(false);
776 InsertWindowToMap(getMapIdFromWindowId());
778 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
779 m_aOwnedToplevel.set(pDialog);
780 m_xBuilder->drop_ownership(pDialog);
781 m_bHasTopLevelDialog = true;
783 pRet.reset(new JSDialog(this, pDialog, this, false));
785 RememberWidget("__DIALOG__", pRet.get());
787 initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
788 sendFullUpdate();
791 return pRet;
794 std::unique_ptr<weld::MessageDialog> JSInstanceBuilder::weld_message_dialog(const OString& id)
796 std::unique_ptr<weld::MessageDialog> pRet;
797 ::MessageDialog* pMessageDialog = m_xBuilder->get<::MessageDialog>(id);
799 if (pMessageDialog)
801 m_nWindowId = pMessageDialog->GetLOKWindowId();
802 pMessageDialog->SetLOKTunnelingState(false);
804 InsertWindowToMap(getMapIdFromWindowId());
806 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
807 m_aOwnedToplevel.set(pMessageDialog);
808 m_xBuilder->drop_ownership(pMessageDialog);
809 m_bHasTopLevelDialog = true;
811 initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
814 pRet.reset(pMessageDialog ? new JSMessageDialog(this, pMessageDialog, this, false) : nullptr);
816 if (pRet)
817 RememberWidget("__DIALOG__", pRet.get());
819 return pRet;
822 std::unique_ptr<weld::Container> JSInstanceBuilder::weld_container(const OString& id)
824 vcl::Window* pContainer = m_xBuilder->get<vcl::Window>(id);
825 auto pWeldWidget = std::make_unique<JSContainer>(this, pContainer, this, false);
827 if (pWeldWidget)
828 RememberWidget(id, pWeldWidget.get());
830 return pWeldWidget;
833 std::unique_ptr<weld::Label> JSInstanceBuilder::weld_label(const OString& id)
835 ::FixedText* pLabel = m_xBuilder->get<FixedText>(id);
836 auto pWeldWidget = std::make_unique<JSLabel>(this, pLabel, this, false);
838 if (pWeldWidget)
839 RememberWidget(id, pWeldWidget.get());
841 return pWeldWidget;
844 std::unique_ptr<weld::Button> JSInstanceBuilder::weld_button(const OString& id)
846 ::Button* pButton = m_xBuilder->get<::Button>(id);
847 auto pWeldWidget = pButton ? std::make_unique<JSButton>(this, pButton, this, false) : nullptr;
849 if (pWeldWidget)
850 RememberWidget(id, pWeldWidget.get());
852 return pWeldWidget;
855 std::unique_ptr<weld::Entry> JSInstanceBuilder::weld_entry(const OString& id)
857 Edit* pEntry = m_xBuilder->get<Edit>(id);
858 auto pWeldWidget = pEntry ? std::make_unique<JSEntry>(this, pEntry, this, false) : nullptr;
860 if (pWeldWidget)
861 RememberWidget(id, pWeldWidget.get());
863 return pWeldWidget;
866 std::unique_ptr<weld::ComboBox> JSInstanceBuilder::weld_combo_box(const OString& id)
868 vcl::Window* pWidget = m_xBuilder->get<vcl::Window>(id);
869 ::ComboBox* pComboBox = dynamic_cast<::ComboBox*>(pWidget);
870 std::unique_ptr<weld::ComboBox> pWeldWidget;
872 if (pComboBox)
874 pWeldWidget = std::make_unique<JSComboBox>(this, pComboBox, this, false);
876 else
878 ListBox* pListBox = dynamic_cast<ListBox*>(pWidget);
879 pWeldWidget = pListBox ? std::make_unique<JSListBox>(this, pListBox, this, false) : nullptr;
882 if (pWeldWidget)
883 RememberWidget(id, pWeldWidget.get());
885 return pWeldWidget;
888 std::unique_ptr<weld::Notebook> JSInstanceBuilder::weld_notebook(const OString& id)
890 TabControl* pNotebook = m_xBuilder->get<TabControl>(id);
891 auto pWeldWidget
892 = pNotebook ? std::make_unique<JSNotebook>(this, pNotebook, this, false) : nullptr;
894 if (pWeldWidget)
895 RememberWidget(id, pWeldWidget.get());
897 return pWeldWidget;
900 std::unique_ptr<weld::SpinButton> JSInstanceBuilder::weld_spin_button(const OString& id)
902 FormattedField* pSpinButton = m_xBuilder->get<FormattedField>(id);
903 auto pWeldWidget
904 = pSpinButton ? std::make_unique<JSSpinButton>(this, pSpinButton, this, false) : nullptr;
906 if (pWeldWidget)
907 RememberWidget(id, pWeldWidget.get());
909 return pWeldWidget;
912 std::unique_ptr<weld::CheckButton> JSInstanceBuilder::weld_check_button(const OString& id)
914 CheckBox* pCheckButton = m_xBuilder->get<CheckBox>(id);
915 auto pWeldWidget
916 = pCheckButton ? std::make_unique<JSCheckButton>(this, pCheckButton, this, false) : nullptr;
918 if (pWeldWidget)
919 RememberWidget(id, pWeldWidget.get());
921 return pWeldWidget;
924 std::unique_ptr<weld::DrawingArea>
925 JSInstanceBuilder::weld_drawing_area(const OString& id, const a11yref& rA11yImpl,
926 FactoryFunction pUITestFactoryFunction, void* pUserData)
928 VclDrawingArea* pArea = m_xBuilder->get<VclDrawingArea>(id);
929 auto pWeldWidget = pArea ? std::make_unique<JSDrawingArea>(this, pArea, this, rA11yImpl,
930 pUITestFactoryFunction, pUserData)
931 : nullptr;
933 if (pWeldWidget)
934 RememberWidget(id, pWeldWidget.get());
936 return pWeldWidget;
939 std::unique_ptr<weld::Toolbar> JSInstanceBuilder::weld_toolbar(const OString& id)
941 ToolBox* pToolBox = m_xBuilder->get<ToolBox>(id);
942 auto pWeldWidget
943 = pToolBox ? std::make_unique<JSToolbar>(this, pToolBox, this, false) : nullptr;
945 if (pWeldWidget)
946 RememberWidget(id, pWeldWidget.get());
948 return pWeldWidget;
951 std::unique_ptr<weld::TextView> JSInstanceBuilder::weld_text_view(const OString& id)
953 VclMultiLineEdit* pTextView = m_xBuilder->get<VclMultiLineEdit>(id);
954 auto pWeldWidget
955 = pTextView ? std::make_unique<JSTextView>(this, pTextView, this, false) : nullptr;
957 if (pWeldWidget)
958 RememberWidget(id, pWeldWidget.get());
960 return pWeldWidget;
963 std::unique_ptr<weld::TreeView> JSInstanceBuilder::weld_tree_view(const OString& id)
965 SvTabListBox* pTreeView = m_xBuilder->get<SvTabListBox>(id);
966 auto pWeldWidget
967 = pTreeView ? std::make_unique<JSTreeView>(this, pTreeView, this, false) : nullptr;
969 if (pWeldWidget)
970 RememberWidget(id, pWeldWidget.get());
972 return pWeldWidget;
975 std::unique_ptr<weld::Expander> JSInstanceBuilder::weld_expander(const OString& id)
977 VclExpander* pExpander = m_xBuilder->get<VclExpander>(id);
978 auto pWeldWidget
979 = pExpander ? std::make_unique<JSExpander>(this, pExpander, this, false) : nullptr;
981 if (pWeldWidget)
982 RememberWidget(id, pWeldWidget.get());
984 return pWeldWidget;
987 std::unique_ptr<weld::IconView> JSInstanceBuilder::weld_icon_view(const OString& id)
989 ::IconView* pIconView = m_xBuilder->get<::IconView>(id);
990 auto pWeldWidget
991 = pIconView ? std::make_unique<JSIconView>(this, pIconView, this, false) : nullptr;
993 if (pWeldWidget)
994 RememberWidget(id, pWeldWidget.get());
996 return pWeldWidget;
999 std::unique_ptr<weld::RadioButton> JSInstanceBuilder::weld_radio_button(const OString& id)
1001 ::RadioButton* pRadioButton = m_xBuilder->get<::RadioButton>(id);
1002 auto pWeldWidget
1003 = pRadioButton ? std::make_unique<JSRadioButton>(this, pRadioButton, this, false) : nullptr;
1005 if (pWeldWidget)
1006 RememberWidget(id, pWeldWidget.get());
1008 return pWeldWidget;
1011 std::unique_ptr<weld::Frame> JSInstanceBuilder::weld_frame(const OString& id)
1013 ::VclFrame* pFrame = m_xBuilder->get<::VclFrame>(id);
1014 auto pWeldWidget = pFrame ? std::make_unique<JSFrame>(this, pFrame, this, false) : nullptr;
1016 if (pWeldWidget)
1017 RememberWidget(id, pWeldWidget.get());
1019 return pWeldWidget;
1022 std::unique_ptr<weld::MenuButton> JSInstanceBuilder::weld_menu_button(const OString& id)
1024 ::MenuButton* pMenuButton = m_xBuilder->get<::MenuButton>(id);
1025 auto pWeldWidget
1026 = pMenuButton ? std::make_unique<JSMenuButton>(this, pMenuButton, this, false) : nullptr;
1028 if (pWeldWidget)
1029 RememberWidget(id, pWeldWidget.get());
1031 return pWeldWidget;
1034 std::unique_ptr<weld::Popover> JSInstanceBuilder::weld_popover(const OString& id)
1036 DockingWindow* pDockingWindow = m_xBuilder->get<DockingWindow>(id);
1037 std::unique_ptr<weld::Popover> pWeldWidget(
1038 pDockingWindow ? new JSPopover(this, pDockingWindow, this, false) : nullptr);
1039 if (pDockingWindow)
1041 assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
1042 m_aOwnedToplevel.set(pDockingWindow);
1043 m_xBuilder->drop_ownership(pDockingWindow);
1045 if (VclPtr<vcl::Window> pWin = pDockingWindow->GetParentWithLOKNotifier())
1047 vcl::Window* pPopupRoot = pDockingWindow->GetChild(0);
1048 pPopupRoot->SetLOKNotifier(pWin->GetLOKNotifier());
1049 m_aParentDialog = pPopupRoot;
1050 m_aWindowToRelease = pPopupRoot;
1051 m_nWindowId = m_aParentDialog->GetLOKWindowId();
1052 InsertWindowToMap(getMapIdFromWindowId());
1053 initializeSender(GetNotifierWindow(), GetContentWindow(), GetTypeOfJSON());
1057 if (pWeldWidget)
1058 RememberWidget("__POPOVER__", pWeldWidget.get());
1060 return pWeldWidget;
1063 std::unique_ptr<weld::Box> JSInstanceBuilder::weld_box(const OString& id)
1065 VclBox* pContainer = m_xBuilder->get<VclBox>(id);
1066 auto pWeldWidget
1067 = pContainer ? std::make_unique<JSBox>(this, pContainer, this, false) : nullptr;
1069 if (pWeldWidget)
1070 RememberWidget(id, pWeldWidget.get());
1072 return pWeldWidget;
1075 std::unique_ptr<weld::Widget> JSInstanceBuilder::weld_widget(const OString& id)
1077 vcl::Window* pWidget = m_xBuilder->get(id);
1078 auto pWeldWidget
1079 = pWidget ? std::make_unique<JSWidgetInstance>(this, pWidget, this, false) : nullptr;
1081 if (pWeldWidget)
1082 RememberWidget(id, pWeldWidget.get());
1084 return pWeldWidget;
1087 std::unique_ptr<weld::Image> JSInstanceBuilder::weld_image(const OString& id)
1089 FixedImage* pImage = m_xBuilder->get<FixedImage>(id);
1091 auto pWeldWidget = pImage ? std::make_unique<JSImage>(this, pImage, this, false) : nullptr;
1093 if (pWeldWidget)
1094 RememberWidget(id, pWeldWidget.get());
1096 return pWeldWidget;
1099 weld::MessageDialog* JSInstanceBuilder::CreateMessageDialog(weld::Widget* pParent,
1100 VclMessageType eMessageType,
1101 VclButtonsType eButtonType,
1102 const OUString& rPrimaryMessage)
1104 SalInstanceWidget* pParentInstance = dynamic_cast<SalInstanceWidget*>(pParent);
1105 SystemWindow* pParentWidget = pParentInstance ? pParentInstance->getSystemWindow() : nullptr;
1106 VclPtrInstance<::MessageDialog> xMessageDialog(pParentWidget, rPrimaryMessage, eMessageType,
1107 eButtonType);
1109 const vcl::ILibreOfficeKitNotifier* pNotifier = xMessageDialog->GetLOKNotifier();
1110 if (pNotifier)
1112 tools::JsonWriter aJsonWriter;
1113 xMessageDialog->DumpAsPropertyTree(aJsonWriter);
1114 aJsonWriter.put("id", xMessageDialog->GetLOKWindowId());
1115 aJsonWriter.put("jsontype", "dialog");
1116 std::unique_ptr<char[], o3tl::free_delete> message(aJsonWriter.extractData());
1117 pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.get());
1120 xMessageDialog->SetLOKTunnelingState(false);
1121 std::string sWindowId = std::to_string(xMessageDialog->GetLOKWindowId());
1122 InsertWindowToMap(sWindowId);
1124 weld::MessageDialog* pRet = new JSMessageDialog(xMessageDialog, nullptr, true);
1126 if (pRet)
1127 RememberWidget(sWindowId, "__DIALOG__", pRet);
1129 return pRet;
1132 JSDialog::JSDialog(JSDialogSender* pSender, ::Dialog* pDialog, SalInstanceBuilder* pBuilder,
1133 bool bTakeOwnership)
1134 : JSWidget<SalInstanceDialog, ::Dialog>(pSender, pDialog, pBuilder, bTakeOwnership)
1138 void JSDialog::collapse(weld::Widget* pEdit, weld::Widget* pButton)
1140 SalInstanceDialog::collapse(pEdit, pButton);
1141 sendFullUpdate();
1144 void JSDialog::undo_collapse()
1146 SalInstanceDialog::undo_collapse();
1147 sendFullUpdate();
1150 void JSDialog::response(int response)
1152 if (response == RET_HELP)
1154 response_help(m_xWidget.get());
1155 return;
1158 sendClose();
1159 SalInstanceDialog::response(response);
1162 JSContainer::JSContainer(JSDialogSender* pSender, vcl::Window* pContainer,
1163 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1164 : JSWidget<SalInstanceContainer, vcl::Window>(pSender, pContainer, pBuilder, bTakeOwnership)
1168 JSLabel::JSLabel(JSDialogSender* pSender, FixedText* pLabel, SalInstanceBuilder* pBuilder,
1169 bool bTakeOwnership)
1170 : JSWidget<SalInstanceLabel, FixedText>(pSender, pLabel, pBuilder, bTakeOwnership)
1174 void JSLabel::set_label(const OUString& rText)
1176 SalInstanceLabel::set_label(rText);
1177 sendUpdate();
1180 JSButton::JSButton(JSDialogSender* pSender, ::Button* pButton, SalInstanceBuilder* pBuilder,
1181 bool bTakeOwnership)
1182 : JSWidget<SalInstanceButton, ::Button>(pSender, pButton, pBuilder, bTakeOwnership)
1186 JSEntry::JSEntry(JSDialogSender* pSender, ::Edit* pEntry, SalInstanceBuilder* pBuilder,
1187 bool bTakeOwnership)
1188 : JSWidget<SalInstanceEntry, ::Edit>(pSender, pEntry, pBuilder, bTakeOwnership)
1192 void JSEntry::set_text(const OUString& rText)
1194 SalInstanceEntry::set_text(rText);
1195 sendUpdate();
1198 void JSEntry::set_text_without_notify(const OUString& rText) { SalInstanceEntry::set_text(rText); }
1200 JSListBox::JSListBox(JSDialogSender* pSender, ::ListBox* pListBox, SalInstanceBuilder* pBuilder,
1201 bool bTakeOwnership)
1202 : JSWidget<SalInstanceComboBoxWithoutEdit, ::ListBox>(pSender, pListBox, pBuilder,
1203 bTakeOwnership)
1207 void JSListBox::insert(int pos, const OUString& rStr, const OUString* pId,
1208 const OUString* pIconName, VirtualDevice* pImageSurface)
1210 SalInstanceComboBoxWithoutEdit::insert(pos, rStr, pId, pIconName, pImageSurface);
1211 sendUpdate();
1214 void JSListBox::remove(int pos)
1216 SalInstanceComboBoxWithoutEdit::remove(pos);
1217 sendUpdate();
1220 void JSListBox::set_active(int pos)
1222 SalInstanceComboBoxWithoutEdit::set_active(pos);
1223 sendUpdate();
1226 JSComboBox::JSComboBox(JSDialogSender* pSender, ::ComboBox* pComboBox, SalInstanceBuilder* pBuilder,
1227 bool bTakeOwnership)
1228 : JSWidget<SalInstanceComboBoxWithEdit, ::ComboBox>(pSender, pComboBox, pBuilder,
1229 bTakeOwnership)
1233 void JSComboBox::insert(int pos, const OUString& rStr, const OUString* pId,
1234 const OUString* pIconName, VirtualDevice* pImageSurface)
1236 SalInstanceComboBoxWithEdit::insert(pos, rStr, pId, pIconName, pImageSurface);
1237 sendUpdate();
1240 void JSComboBox::remove(int pos)
1242 SalInstanceComboBoxWithEdit::remove(pos);
1243 sendUpdate();
1246 void JSComboBox::set_entry_text(const OUString& rText)
1248 SalInstanceComboBoxWithEdit::set_entry_text(rText);
1249 sendUpdate();
1252 void JSComboBox::set_active(int pos)
1254 SalInstanceComboBoxWithEdit::set_active(pos);
1255 sendUpdate();
1258 bool JSComboBox::changed_by_direct_pick() const { return true; }
1260 JSNotebook::JSNotebook(JSDialogSender* pSender, ::TabControl* pControl,
1261 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1262 : JSWidget<SalInstanceNotebook, ::TabControl>(pSender, pControl, pBuilder, bTakeOwnership)
1266 void JSNotebook::set_current_page(int nPage)
1268 bool bForce = false;
1269 int nCurrent = get_current_page();
1270 if (nCurrent == nPage)
1271 bForce = true;
1273 SalInstanceNotebook::set_current_page(nPage);
1274 sendFullUpdate(bForce);
1276 m_aEnterPageHdl.Call(get_current_page_ident());
1279 void JSNotebook::set_current_page(const OString& rIdent)
1281 bool bForce = false;
1282 OString sCurrent = get_current_page_ident();
1283 if (sCurrent == rIdent)
1284 bForce = true;
1286 SalInstanceNotebook::set_current_page(rIdent);
1287 sendFullUpdate(bForce);
1289 m_aEnterPageHdl.Call(get_current_page_ident());
1292 void JSNotebook::remove_page(const OString& rIdent)
1294 SalInstanceNotebook::remove_page(rIdent);
1295 sendFullUpdate();
1298 void JSNotebook::insert_page(const OString& rIdent, const OUString& rLabel, int nPos)
1300 SalInstanceNotebook::insert_page(rIdent, rLabel, nPos);
1301 sendFullUpdate();
1304 JSSpinButton::JSSpinButton(JSDialogSender* pSender, ::FormattedField* pSpin,
1305 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1306 : JSWidget<SalInstanceSpinButton, ::FormattedField>(pSender, pSpin, pBuilder, bTakeOwnership)
1310 void JSSpinButton::set_value(int value)
1312 SalInstanceSpinButton::set_value(value);
1313 sendUpdate(true); // if input is limited we can receive the same JSON
1316 JSMessageDialog::JSMessageDialog(JSDialogSender* pSender, ::MessageDialog* pDialog,
1317 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1318 : JSWidget<SalInstanceMessageDialog, ::MessageDialog>(pSender, pDialog, pBuilder,
1319 bTakeOwnership)
1323 JSMessageDialog::JSMessageDialog(::MessageDialog* pDialog, SalInstanceBuilder* pBuilder,
1324 bool bTakeOwnership)
1325 : JSWidget<SalInstanceMessageDialog, ::MessageDialog>(nullptr, pDialog, pBuilder,
1326 bTakeOwnership)
1327 , m_pOwnedSender(new JSDialogSender(pDialog, pDialog, "dialog"))
1329 m_pSender = m_pOwnedSender.get();
1331 if (!pBuilder)
1333 m_sWindowId = std::to_string(m_xMessageDialog->GetLOKWindowId());
1335 if (::OKButton* pOKBtn
1336 = dynamic_cast<::OKButton*>(m_xMessageDialog->get_widget_for_response(RET_OK)))
1338 m_pOK.reset(new JSButton(m_pSender, pOKBtn, nullptr, false));
1339 JSInstanceBuilder::AddChildWidget(m_sWindowId, pOKBtn->get_id().toUtf8(), m_pOK.get());
1340 m_pOK->connect_clicked(LINK(this, JSMessageDialog, OKHdl));
1343 if (::CancelButton* pCancelBtn
1344 = dynamic_cast<::CancelButton*>(m_xMessageDialog->get_widget_for_response(RET_CANCEL)))
1346 m_pCancel.reset(new JSButton(m_pSender, pCancelBtn, nullptr, false));
1347 JSInstanceBuilder::AddChildWidget(m_sWindowId, pCancelBtn->get_id().toUtf8(),
1348 m_pCancel.get());
1349 m_pCancel->connect_clicked(LINK(this, JSMessageDialog, CancelHdl));
1354 JSMessageDialog::~JSMessageDialog()
1356 if (m_pOK || m_pCancel)
1357 JSInstanceBuilder::RemoveWindowWidget(m_sWindowId);
1360 IMPL_LINK_NOARG(JSMessageDialog, OKHdl, weld::Button&, void) { response(RET_OK); }
1362 IMPL_LINK_NOARG(JSMessageDialog, CancelHdl, weld::Button&, void) { response(RET_CANCEL); }
1364 void JSMessageDialog::set_primary_text(const OUString& rText)
1366 SalInstanceMessageDialog::set_primary_text(rText);
1367 sendFullUpdate();
1370 void JSMessageDialog::set_secondary_text(const OUString& rText)
1372 SalInstanceMessageDialog::set_secondary_text(rText);
1373 sendFullUpdate();
1376 void JSMessageDialog::response(int response)
1378 if (response == RET_HELP)
1380 response_help(m_xWidget.get());
1381 return;
1384 sendClose();
1385 SalInstanceMessageDialog::response(response);
1388 JSCheckButton::JSCheckButton(JSDialogSender* pSender, ::CheckBox* pCheckBox,
1389 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1390 : JSWidget<SalInstanceCheckButton, ::CheckBox>(pSender, pCheckBox, pBuilder, bTakeOwnership)
1394 void JSCheckButton::set_active(bool active)
1396 bool bWasActive = get_active();
1397 SalInstanceCheckButton::set_active(active);
1398 if (bWasActive != active)
1399 sendUpdate();
1402 JSDrawingArea::JSDrawingArea(JSDialogSender* pSender, VclDrawingArea* pDrawingArea,
1403 SalInstanceBuilder* pBuilder, const a11yref& rAlly,
1404 FactoryFunction pUITestFactoryFunction, void* pUserData)
1405 : JSWidget<SalInstanceDrawingArea, VclDrawingArea>(pSender, pDrawingArea, pBuilder, rAlly,
1406 pUITestFactoryFunction, pUserData, false)
1410 void JSDrawingArea::queue_draw()
1412 SalInstanceDrawingArea::queue_draw();
1413 sendUpdate();
1416 void JSDrawingArea::queue_draw_area(int x, int y, int width, int height)
1418 SalInstanceDrawingArea::queue_draw_area(x, y, width, height);
1419 sendUpdate();
1422 JSToolbar::JSToolbar(JSDialogSender* pSender, ::ToolBox* pToolbox, SalInstanceBuilder* pBuilder,
1423 bool bTakeOwnership)
1424 : JSWidget<SalInstanceToolbar, ::ToolBox>(pSender, pToolbox, pBuilder, bTakeOwnership)
1428 void JSToolbar::set_menu_item_active(const OString& rIdent, bool bActive)
1430 bool bWasActive = get_menu_item_active(rIdent);
1431 SalInstanceToolbar::set_menu_item_active(rIdent, bActive);
1433 sal_uInt16 nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent));
1434 VclPtr<vcl::Window> pFloat = m_aFloats[nItemId];
1436 if (pFloat)
1438 // See WeldToolbarPopup : include/svtools/toolbarmenu.hxx
1439 // TopLevel (Popover) -> Container -> main container of the popup
1440 vcl::Window* pPopupRoot = pFloat->GetChild(0);
1441 if (pPopupRoot)
1442 pPopupRoot = pPopupRoot->GetChild(0);
1444 if (pPopupRoot)
1446 if (bActive)
1447 sendPopup(pPopupRoot, m_xToolBox->get_id(),
1448 OStringToOUString(rIdent, RTL_TEXTENCODING_ASCII_US));
1449 else if (bWasActive)
1450 sendClosePopup(pPopupRoot->GetLOKWindowId());
1455 void JSToolbar::set_item_sensitive(const OString& rIdent, bool bSensitive)
1457 SalInstanceToolbar::set_item_sensitive(rIdent, bSensitive);
1458 sendUpdate();
1461 void JSToolbar::set_item_icon_name(const OString& rIdent, const OUString& rIconName)
1463 SalInstanceToolbar::set_item_icon_name(rIdent, rIconName);
1464 sendUpdate();
1467 JSTextView::JSTextView(JSDialogSender* pSender, ::VclMultiLineEdit* pTextView,
1468 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1469 : JSWidget<SalInstanceTextView, ::VclMultiLineEdit>(pSender, pTextView, pBuilder,
1470 bTakeOwnership)
1474 void JSTextView::set_text(const OUString& rText)
1476 SalInstanceTextView::set_text(rText);
1477 sendUpdate();
1480 JSTreeView::JSTreeView(JSDialogSender* pSender, ::SvTabListBox* pTreeView,
1481 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1482 : JSWidget<SalInstanceTreeView, ::SvTabListBox>(pSender, pTreeView, pBuilder, bTakeOwnership)
1486 void JSTreeView::set_toggle(int pos, TriState eState, int col)
1488 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0);
1490 while (pEntry && pos--)
1491 pEntry = m_xTreeView->Next(pEntry);
1493 if (pEntry)
1495 SalInstanceTreeView::set_toggle(pEntry, eState, col);
1496 signal_toggled(iter_col(SalInstanceTreeIter(pEntry), col));
1498 sendUpdate();
1502 void JSTreeView::set_toggle(const weld::TreeIter& rIter, TriState bOn, int col)
1504 SalInstanceTreeView::set_toggle(rIter, bOn, col);
1505 sendUpdate();
1508 void JSTreeView::select(int pos)
1510 assert(m_xTreeView->IsUpdateMode() && "don't select when frozen");
1511 disable_notify_events();
1512 if (pos == -1 || (pos == 0 && n_children() == 0))
1513 m_xTreeView->SelectAll(false);
1514 else
1516 SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, 0);
1518 while (pEntry && pos--)
1519 pEntry = m_xTreeView->Next(pEntry);
1521 if (pEntry)
1523 m_xTreeView->Select(pEntry, true);
1524 m_xTreeView->MakeVisible(pEntry);
1527 enable_notify_events();
1528 sendUpdate();
1531 weld::TreeView* JSTreeView::get_drag_source() const { return g_DragSource; }
1533 void JSTreeView::drag_start() { g_DragSource = this; }
1535 void JSTreeView::drag_end()
1537 css::datatransfer::dnd::XDropTarget* xDropTarget = m_xDropTarget.get();
1538 if (xDropTarget)
1540 css::datatransfer::dnd::DropTargetDropEvent aEvent;
1541 aEvent.Source = xDropTarget;
1542 aEvent.Context = new JSDropTargetDropContext();
1543 // dummy values
1544 aEvent.LocationX = 50;
1545 aEvent.LocationY = 50;
1546 aEvent.DropAction = css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
1547 aEvent.SourceActions = css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
1549 m_xDropTarget->fire_drop(aEvent);
1551 sendUpdate();
1552 if (g_DragSource)
1553 g_DragSource->sendUpdate();
1556 g_DragSource = nullptr;
1559 void JSTreeView::insert(const weld::TreeIter* pParent, int pos, const OUString* pStr,
1560 const OUString* pId, const OUString* pIconName,
1561 VirtualDevice* pImageSurface, bool bChildrenOnDemand, weld::TreeIter* pRet)
1563 SalInstanceTreeView::insert(pParent, pos, pStr, pId, pIconName, pImageSurface,
1564 bChildrenOnDemand, pRet);
1566 sendUpdate();
1569 void JSTreeView::set_text(int row, const OUString& rText, int col)
1571 SalInstanceTreeView::set_text(row, rText, col);
1572 sendUpdate();
1575 void JSTreeView::set_text(const weld::TreeIter& rIter, const OUString& rStr, int col)
1577 SalInstanceTreeView::set_text(rIter, rStr, col);
1578 sendUpdate();
1581 void JSTreeView::remove(int pos)
1583 SalInstanceTreeView::remove(pos);
1584 sendUpdate();
1587 void JSTreeView::remove(const weld::TreeIter& rIter)
1589 SalInstanceTreeView::remove(rIter);
1590 sendUpdate();
1593 void JSTreeView::clear()
1595 SalInstanceTreeView::clear();
1596 sendUpdate();
1599 void JSTreeView::expand_row(const weld::TreeIter& rIter)
1601 SalInstanceTreeView::expand_row(rIter);
1602 sendUpdate();
1605 void JSTreeView::collapse_row(const weld::TreeIter& rIter)
1607 SalInstanceTreeView::collapse_row(rIter);
1608 sendUpdate();
1611 JSExpander::JSExpander(JSDialogSender* pSender, ::VclExpander* pExpander,
1612 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1613 : JSWidget<SalInstanceExpander, ::VclExpander>(pSender, pExpander, pBuilder, bTakeOwnership)
1617 void JSExpander::set_expanded(bool bExpand)
1619 SalInstanceExpander::set_expanded(bExpand);
1620 sendUpdate();
1623 JSIconView::JSIconView(JSDialogSender* pSender, ::IconView* pIconView, SalInstanceBuilder* pBuilder,
1624 bool bTakeOwnership)
1625 : JSWidget<SalInstanceIconView, ::IconView>(pSender, pIconView, pBuilder, bTakeOwnership)
1629 void JSIconView::insert(int pos, const OUString* pStr, const OUString* pId,
1630 const OUString* pIconName, weld::TreeIter* pRet)
1632 SalInstanceIconView::insert(pos, pStr, pId, pIconName, pRet);
1633 sendUpdate();
1636 void JSIconView::insert(int pos, const OUString* pStr, const OUString* pId,
1637 const VirtualDevice* pIcon, weld::TreeIter* pRet)
1639 SalInstanceIconView::insert(pos, pStr, pId, pIcon, pRet);
1640 sendUpdate();
1643 void JSIconView::clear()
1645 SalInstanceIconView::clear();
1646 sendUpdate();
1649 void JSIconView::select(int pos)
1651 SalInstanceIconView::select(pos);
1653 std::unique_ptr<ActionDataMap> pMap = std::make_unique<ActionDataMap>();
1654 (*pMap)[ACTION_TYPE] = "select";
1655 (*pMap)["position"] = OUString::number(pos);
1656 sendAction(std::move(pMap));
1659 void JSIconView::unselect(int pos)
1661 SalInstanceIconView::unselect(pos);
1662 sendUpdate();
1665 JSRadioButton::JSRadioButton(JSDialogSender* pSender, ::RadioButton* pRadioButton,
1666 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1667 : JSWidget<SalInstanceRadioButton, ::RadioButton>(pSender, pRadioButton, pBuilder,
1668 bTakeOwnership)
1672 void JSRadioButton::set_active(bool active)
1674 SalInstanceRadioButton::set_active(active);
1675 sendUpdate();
1678 JSFrame::JSFrame(JSDialogSender* pSender, ::VclFrame* pFrame, SalInstanceBuilder* pBuilder,
1679 bool bTakeOwnership)
1680 : JSWidget<SalInstanceFrame, ::VclFrame>(pSender, pFrame, pBuilder, bTakeOwnership)
1684 JSMenuButton::JSMenuButton(JSDialogSender* pSender, ::MenuButton* pMenuButton,
1685 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1686 : JSWidget<SalInstanceMenuButton, ::MenuButton>(pSender, pMenuButton, pBuilder, bTakeOwnership)
1690 void JSMenuButton::set_label(const OUString& rText)
1692 OUString aPreviousLabel = get_label();
1693 SalInstanceMenuButton::set_label(rText);
1694 if (aPreviousLabel != rText)
1695 sendUpdate();
1698 void JSMenuButton::set_image(VirtualDevice* pDevice)
1700 SalInstanceMenuButton::set_image(pDevice);
1701 sendUpdate();
1704 void JSMenuButton::set_image(const css::uno::Reference<css::graphic::XGraphic>& rImage)
1706 SalInstanceMenuButton::set_image(rImage);
1707 sendUpdate();
1710 void JSMenuButton::set_active(bool bActive)
1712 SalInstanceMenuButton::set_active(bActive);
1714 VclPtr<vcl::Window> pPopup = m_xMenuButton->GetPopover();
1715 if (pPopup)
1717 if (bActive)
1718 sendPopup(pPopup->GetChild(0), m_xMenuButton->get_id(), m_xMenuButton->get_id());
1719 else
1720 sendClosePopup(pPopup->GetChild(0)->GetLOKWindowId());
1724 JSPopover::JSPopover(JSDialogSender* pSender, DockingWindow* pDockingWindow,
1725 SalInstanceBuilder* pBuilder, bool bTakeOwnership)
1726 : JSWidget<SalInstancePopover, DockingWindow>(pSender, pDockingWindow, pBuilder, bTakeOwnership)
1730 void JSPopover::popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect)
1732 SalInstancePopover::popup_at_rect(pParent, rRect);
1733 sendPopup(getWidget()->GetChild(0), "_POPOVER_", "_POPOVER_");
1736 void JSPopover::popdown()
1738 if (getWidget() && getWidget()->GetChild(0))
1739 sendClosePopup(getWidget()->GetChild(0)->GetLOKWindowId());
1740 SalInstancePopover::popdown();
1743 JSBox::JSBox(JSDialogSender* pSender, VclBox* pBox, SalInstanceBuilder* pBuilder,
1744 bool bTakeOwnership)
1745 : JSWidget<SalInstanceBox, VclBox>(pSender, pBox, pBuilder, bTakeOwnership)
1749 JSImage::JSImage(JSDialogSender* pSender, FixedImage* pImage, SalInstanceBuilder* pBuilder,
1750 bool bTakeOwnership)
1751 : JSWidget<SalInstanceImage, FixedImage>(pSender, pImage, pBuilder, bTakeOwnership)
1755 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */