2021-01-08 22:41:56 +09:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
|
|
|
* 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 <memory>
|
|
|
|
|
|
|
|
#include <svx/devtools/DevelopmentToolDockingWindow.hxx>
|
|
|
|
|
2020-12-24 17:12:48 +09:00
|
|
|
#include <com/sun/star/uno/XComponentContext.hpp>
|
2021-01-17 20:45:12 +09:00
|
|
|
#include <com/sun/star/lang/XServiceInfo.hpp>
|
2020-12-24 17:12:48 +09:00
|
|
|
|
|
|
|
#include <com/sun/star/beans/theIntrospection.hpp>
|
|
|
|
#include <com/sun/star/beans/XIntrospection.hpp>
|
|
|
|
#include <com/sun/star/beans/XIntrospectionAccess.hpp>
|
|
|
|
#include <com/sun/star/beans/Property.hpp>
|
|
|
|
#include <com/sun/star/beans/PropertyConcept.hpp>
|
|
|
|
#include <com/sun/star/beans/MethodConcept.hpp>
|
|
|
|
#include <com/sun/star/reflection/XIdlMethod.hpp>
|
|
|
|
|
|
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
|
2021-01-08 22:41:56 +09:00
|
|
|
#include <sfx2/dispatch.hxx>
|
|
|
|
#include <sfx2/sfxmodelfactory.hxx>
|
|
|
|
#include <svx/svxids.hrc>
|
|
|
|
|
2020-12-24 17:12:48 +09:00
|
|
|
#include <sfx2/objsh.hxx>
|
|
|
|
|
|
|
|
#include <sfx2/viewfrm.hxx>
|
|
|
|
|
|
|
|
#include <com/sun/star/frame/XController.hpp>
|
2021-01-29 15:09:59 +09:00
|
|
|
#include <com/sun/star/view/XSelectionSupplier.hpp>
|
2020-12-24 17:12:48 +09:00
|
|
|
|
|
|
|
#include <cppuhelper/compbase.hxx>
|
|
|
|
#include <cppuhelper/basemutex.hxx>
|
|
|
|
|
|
|
|
using namespace css;
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
typedef cppu::WeakComponentImplHelper<css::view::XSelectionChangeListener>
|
|
|
|
SelectionChangeHandlerInterfaceBase;
|
|
|
|
|
|
|
|
class SelectionChangeHandler final : private ::cppu::BaseMutex,
|
|
|
|
public SelectionChangeHandlerInterfaceBase
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
css::uno::Reference<css::frame::XController> mxController;
|
2021-01-06 15:58:13 +09:00
|
|
|
VclPtr<DevelopmentToolDockingWindow> mpDockingWindow;
|
2020-12-24 17:12:48 +09:00
|
|
|
|
|
|
|
public:
|
2021-01-06 15:58:13 +09:00
|
|
|
SelectionChangeHandler(const css::uno::Reference<css::frame::XController>& rxController,
|
|
|
|
DevelopmentToolDockingWindow* pDockingWindow)
|
2020-12-24 17:12:48 +09:00
|
|
|
: SelectionChangeHandlerInterfaceBase(m_aMutex)
|
|
|
|
, mxController(rxController)
|
2021-01-06 15:58:13 +09:00
|
|
|
, mpDockingWindow(pDockingWindow)
|
2020-12-24 17:12:48 +09:00
|
|
|
{
|
2021-01-29 15:09:59 +09:00
|
|
|
connect();
|
2020-12-24 17:12:48 +09:00
|
|
|
}
|
|
|
|
|
2021-01-06 15:58:13 +09:00
|
|
|
~SelectionChangeHandler() { mpDockingWindow.disposeAndClear(); }
|
|
|
|
|
2020-12-24 17:12:48 +09:00
|
|
|
virtual void SAL_CALL selectionChanged(const css::lang::EventObject& /*rEvent*/) override
|
|
|
|
{
|
|
|
|
uno::Reference<view::XSelectionSupplier> xSupplier(mxController, uno::UNO_QUERY);
|
|
|
|
if (xSupplier.is())
|
|
|
|
{
|
|
|
|
uno::Any aAny = xSupplier->getSelection();
|
2021-01-27 21:35:47 +09:00
|
|
|
auto xInterface = aAny.get<uno::Reference<uno::XInterface>>();
|
|
|
|
mpDockingWindow->selectionChanged(xInterface);
|
2020-12-24 17:12:48 +09:00
|
|
|
}
|
|
|
|
}
|
2021-01-29 15:09:59 +09:00
|
|
|
|
|
|
|
void connect()
|
|
|
|
{
|
|
|
|
uno::Reference<view::XSelectionSupplier> xSupplier(mxController, uno::UNO_QUERY);
|
|
|
|
xSupplier->addSelectionChangeListener(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void disconnect()
|
|
|
|
{
|
|
|
|
uno::Reference<view::XSelectionSupplier> xSupplier(mxController, uno::UNO_QUERY);
|
|
|
|
xSupplier->removeSelectionChangeListener(this);
|
|
|
|
}
|
|
|
|
|
2020-12-24 17:12:48 +09:00
|
|
|
virtual void SAL_CALL disposing(const css::lang::EventObject& /*rEvent*/) override {}
|
|
|
|
virtual void SAL_CALL disposing() override {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
SelectionChangeHandler(const SelectionChangeHandler&) = delete;
|
|
|
|
SelectionChangeHandler& operator=(const SelectionChangeHandler&) = delete;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2021-01-17 20:32:13 +09:00
|
|
|
DevelopmentToolDockingWindow::DevelopmentToolDockingWindow(SfxBindings* pInputBindings,
|
|
|
|
SfxChildWindow* pChildWindow,
|
|
|
|
vcl::Window* pParent)
|
|
|
|
: SfxDockingWindow(pInputBindings, pChildWindow, pParent, "DevelopmentTool",
|
|
|
|
"svx/ui/developmenttool.ui")
|
|
|
|
, mpClassNameLabel(m_xBuilder->weld_label("class_name_value_id"))
|
|
|
|
, mpClassListBox(m_xBuilder->weld_tree_view("class_listbox_id"))
|
|
|
|
, mpLeftSideTreeView(m_xBuilder->weld_tree_view("leftside_treeview_id"))
|
2021-01-29 14:51:56 +09:00
|
|
|
, mpSelectionToggle(m_xBuilder->weld_toggle_button("selection_toggle"))
|
2021-01-17 20:32:13 +09:00
|
|
|
, maDocumentModelTreeHandler(
|
|
|
|
mpLeftSideTreeView,
|
|
|
|
pInputBindings->GetDispatcher()->GetFrame()->GetObjectShell()->GetBaseModel())
|
|
|
|
{
|
|
|
|
mpLeftSideTreeView->connect_changed(LINK(this, DevelopmentToolDockingWindow, LeftSideSelected));
|
2021-01-29 14:51:56 +09:00
|
|
|
mpSelectionToggle->connect_toggled(LINK(this, DevelopmentToolDockingWindow, SelectionToggled));
|
2021-01-14 23:34:24 +09:00
|
|
|
|
2021-01-17 20:32:13 +09:00
|
|
|
auto* pViewFrame = pInputBindings->GetDispatcher()->GetFrame();
|
|
|
|
|
|
|
|
uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
|
|
|
|
|
|
|
|
mxRoot = pInputBindings->GetDispatcher()->GetFrame()->GetObjectShell()->GetBaseModel();
|
|
|
|
|
|
|
|
introspect(mxRoot);
|
|
|
|
maDocumentModelTreeHandler.inspectDocument();
|
2021-01-29 15:09:59 +09:00
|
|
|
mxSelectionListener.set(new SelectionChangeHandler(xController, this));
|
2021-01-11 09:57:57 +09:00
|
|
|
}
|
|
|
|
|
2021-01-18 08:17:01 +09:00
|
|
|
IMPL_LINK(DevelopmentToolDockingWindow, LeftSideSelected, weld::TreeView&, rView, void)
|
2021-01-17 20:32:13 +09:00
|
|
|
{
|
2021-01-29 14:51:56 +09:00
|
|
|
if (mpSelectionToggle->get_state() == TRISTATE_TRUE)
|
|
|
|
return;
|
|
|
|
|
2021-01-18 08:17:01 +09:00
|
|
|
OUString sID = rView.get_selected_id();
|
|
|
|
auto xObject = DocumentModelTreeHandler::getObjectByID(sID);
|
2021-01-17 20:32:13 +09:00
|
|
|
if (xObject.is())
|
|
|
|
introspect(xObject);
|
|
|
|
}
|
|
|
|
|
2021-01-29 14:51:56 +09:00
|
|
|
IMPL_LINK_NOARG(DevelopmentToolDockingWindow, SelectionToggled, weld::ToggleButton&, void)
|
|
|
|
{
|
|
|
|
updateSelection();
|
|
|
|
}
|
|
|
|
|
2021-01-08 22:41:56 +09:00
|
|
|
DevelopmentToolDockingWindow::~DevelopmentToolDockingWindow() { disposeOnce(); }
|
|
|
|
|
2021-01-08 20:09:01 +09:00
|
|
|
void DevelopmentToolDockingWindow::dispose()
|
|
|
|
{
|
2021-01-29 15:09:59 +09:00
|
|
|
auto* pSelectionChangeHandler
|
|
|
|
= dynamic_cast<SelectionChangeHandler*>(mxSelectionListener.get());
|
|
|
|
if (pSelectionChangeHandler)
|
|
|
|
pSelectionChangeHandler->disconnect();
|
|
|
|
|
|
|
|
mxSelectionListener = uno::Reference<view::XSelectionChangeListener>();
|
|
|
|
maDocumentModelTreeHandler.dispose();
|
|
|
|
|
2021-01-08 20:09:01 +09:00
|
|
|
mpClassNameLabel.reset();
|
|
|
|
mpClassListBox.reset();
|
2021-01-29 14:51:56 +09:00
|
|
|
mpSelectionToggle.reset();
|
2021-01-08 20:09:01 +09:00
|
|
|
mpLeftSideTreeView.reset();
|
|
|
|
|
|
|
|
SfxDockingWindow::dispose();
|
|
|
|
}
|
|
|
|
|
2021-01-29 14:51:56 +09:00
|
|
|
void DevelopmentToolDockingWindow::updateSelection()
|
|
|
|
{
|
|
|
|
TriState eTriState = mpSelectionToggle->get_state();
|
|
|
|
if (eTriState == TRISTATE_TRUE)
|
|
|
|
{
|
|
|
|
introspect(mxCurrentSelection);
|
|
|
|
mpLeftSideTreeView->set_sensitive(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mpLeftSideTreeView->set_sensitive(true);
|
|
|
|
LeftSideSelected(*mpLeftSideTreeView);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-08 22:41:56 +09:00
|
|
|
void DevelopmentToolDockingWindow::ToggleFloatingMode()
|
|
|
|
{
|
|
|
|
SfxDockingWindow::ToggleFloatingMode();
|
|
|
|
|
|
|
|
if (GetFloatingWindow())
|
|
|
|
GetFloatingWindow()->SetMinOutputSizePixel(Size(300, 300));
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
}
|
|
|
|
|
2021-01-27 21:35:47 +09:00
|
|
|
void DevelopmentToolDockingWindow::selectionChanged(
|
|
|
|
uno::Reference<uno::XInterface> const& xInterface)
|
|
|
|
{
|
2021-01-29 14:51:56 +09:00
|
|
|
mxCurrentSelection = xInterface;
|
|
|
|
updateSelection();
|
2021-01-27 21:35:47 +09:00
|
|
|
}
|
|
|
|
|
2021-01-06 15:58:13 +09:00
|
|
|
void DevelopmentToolDockingWindow::introspect(uno::Reference<uno::XInterface> const& xInterface)
|
|
|
|
{
|
|
|
|
if (!xInterface.is())
|
|
|
|
return;
|
|
|
|
|
|
|
|
uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
|
|
|
|
if (!xContext.is())
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto xServiceInfo = uno::Reference<lang::XServiceInfo>(xInterface, uno::UNO_QUERY);
|
|
|
|
OUString aImplementationName = xServiceInfo->getImplementationName();
|
|
|
|
|
|
|
|
mpClassNameLabel->set_label(aImplementationName);
|
|
|
|
|
|
|
|
mpClassListBox->freeze();
|
|
|
|
mpClassListBox->clear();
|
|
|
|
|
|
|
|
std::unique_ptr<weld::TreeIter> pParent = mpClassListBox->make_iterator();
|
|
|
|
OUString aServicesString("Services");
|
|
|
|
mpClassListBox->insert(nullptr, -1, &aServicesString, nullptr, nullptr, nullptr, false,
|
|
|
|
pParent.get());
|
|
|
|
mpClassListBox->set_text_emphasis(*pParent, true, 0);
|
|
|
|
|
|
|
|
std::unique_ptr<weld::TreeIter> pResult = mpClassListBox->make_iterator();
|
|
|
|
const uno::Sequence<OUString> aServiceNames(xServiceInfo->getSupportedServiceNames());
|
|
|
|
for (auto const& aServiceName : aServiceNames)
|
|
|
|
{
|
|
|
|
mpClassListBox->insert(pParent.get(), -1, &aServiceName, nullptr, nullptr, nullptr, false,
|
|
|
|
pResult.get());
|
2021-01-26 15:29:20 +00:00
|
|
|
mpClassListBox->set_text_emphasis(*pResult, false, 0);
|
2021-01-06 15:58:13 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
uno::Reference<beans::XIntrospection> xIntrospection;
|
|
|
|
xIntrospection = beans::theIntrospection::get(xContext);
|
|
|
|
|
|
|
|
uno::Reference<beans::XIntrospectionAccess> xIntrospectionAccess;
|
|
|
|
xIntrospectionAccess = xIntrospection->inspect(uno::makeAny(xInterface));
|
|
|
|
|
|
|
|
OUString aPropertiesString("Properties");
|
|
|
|
mpClassListBox->insert(nullptr, -1, &aPropertiesString, nullptr, nullptr, nullptr, false,
|
|
|
|
pParent.get());
|
|
|
|
mpClassListBox->set_text_emphasis(*pParent, true, 0);
|
|
|
|
|
|
|
|
const auto xProperties = xIntrospectionAccess->getProperties(
|
|
|
|
beans::PropertyConcept::ALL - beans::PropertyConcept::DANGEROUS);
|
|
|
|
for (auto const& xProperty : xProperties)
|
|
|
|
{
|
|
|
|
mpClassListBox->insert(pParent.get(), -1, &xProperty.Name, nullptr, nullptr, nullptr, false,
|
|
|
|
pResult.get());
|
2021-01-26 15:29:20 +00:00
|
|
|
mpClassListBox->set_text_emphasis(*pResult, false, 0);
|
2021-01-06 15:58:13 +09:00
|
|
|
}
|
|
|
|
|
2021-01-27 21:58:24 +09:00
|
|
|
{
|
|
|
|
uno::Reference<lang::XTypeProvider> xTypeProvider(xInterface, uno::UNO_QUERY);
|
|
|
|
if (xTypeProvider.is())
|
|
|
|
{
|
|
|
|
OUString aTypesString("Interfaces");
|
|
|
|
mpClassListBox->insert(nullptr, -1, &aTypesString, nullptr, nullptr, nullptr, false,
|
|
|
|
pParent.get());
|
|
|
|
mpClassListBox->set_text_emphasis(*pParent, true, 0);
|
|
|
|
|
|
|
|
const auto xSequenceTypes = xTypeProvider->getTypes();
|
|
|
|
for (auto const& xType : xSequenceTypes)
|
|
|
|
{
|
|
|
|
OUString aName = xType.getTypeName();
|
|
|
|
mpClassListBox->insert(pParent.get(), -1, &aName, nullptr, nullptr, nullptr, false,
|
|
|
|
pResult.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-06 15:58:13 +09:00
|
|
|
OUString aMethodsString("Methods");
|
|
|
|
mpClassListBox->insert(nullptr, -1, &aMethodsString, nullptr, nullptr, nullptr, false,
|
|
|
|
pParent.get());
|
|
|
|
mpClassListBox->set_text_emphasis(*pParent, true, 0);
|
|
|
|
|
|
|
|
const auto xMethods = xIntrospectionAccess->getMethods(beans::MethodConcept::ALL);
|
|
|
|
for (auto const& xMethod : xMethods)
|
|
|
|
{
|
|
|
|
OUString aMethodName = xMethod->getName();
|
|
|
|
mpClassListBox->insert(pParent.get(), -1, &aMethodName, nullptr, nullptr, nullptr, false,
|
|
|
|
pResult.get());
|
2021-01-26 15:29:20 +00:00
|
|
|
mpClassListBox->set_text_emphasis(*pResult, false, 0);
|
2021-01-06 15:58:13 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
mpClassListBox->thaw();
|
|
|
|
}
|
2021-01-08 22:41:56 +09:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|