17#include "DevToolsStrings.hrc"
19#include <com/sun/star/beans/theIntrospection.hpp>
20#include <com/sun/star/beans/XIntrospection.hpp>
21#include <com/sun/star/beans/XIntrospectionAccess.hpp>
22#include <com/sun/star/beans/PropertyConcept.hpp>
23#include <com/sun/star/beans/PropertyAttribute.hpp>
24#include <com/sun/star/beans/MethodConcept.hpp>
26#include <com/sun/star/reflection/theCoreReflection.hpp>
27#include <com/sun/star/reflection/XIdlReflection.hpp>
28#include <com/sun/star/reflection/XIdlMethod.hpp>
29#include <com/sun/star/reflection/XIdlArray.hpp>
30#include <com/sun/star/reflection/XEnumTypeDescription.hpp>
32#include <com/sun/star/container/XNamed.hpp>
33#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
34#include <com/sun/star/container/XIndexAccess.hpp>
35#include <com/sun/star/container/XNameAccess.hpp>
36#include <com/sun/star/container/XEnumerationAccess.hpp>
38#include <com/sun/star/script/Invocation.hpp>
39#include <com/sun/star/script/XInvocation2.hpp>
40#include <com/sun/star/script/MemberType.hpp>
42#include <com/sun/star/lang/XServiceInfo.hpp>
43#include <com/sun/star/lang/XTypeProvider.hpp>
55constexpr OUStringLiteral constTypeDescriptionManagerSingletonName
56 =
u"/singletons/com.sun.star.reflection.theTypeDescriptionManager";
58OUString enumValueToEnumName(
uno::Any const& aValue,
59 uno::Reference<uno::XComponentContext>
const& xContext)
61 sal_Int32 nIntValue = 0;
65 uno::Reference<container::XHierarchicalNameAccess> xManager;
66 xManager.set(xContext->getValueByName(constTypeDescriptionManagerSingletonName),
69 uno::Reference<reflection::XEnumTypeDescription> xTypeDescription;
70 xTypeDescription.set(xManager->getByHierarchicalName(aValue.getValueType().getTypeName()),
73 const uno::Sequence<sal_Int32> aValues = xTypeDescription->getEnumValues();
74 sal_Int32 nValuesIndex = std::find(aValues.begin(), aValues.end(), nIntValue) - aValues.begin();
75 uno::Sequence<OUString> aNames = xTypeDescription->getEnumNames();
76 return aNames[nValuesIndex];
79OUString getInterfaceImplementationClass(uno::Reference<uno::XInterface>
const& xInterface)
81 auto xServiceInfo = uno::Reference<lang::XServiceInfo>(xInterface, uno::UNO_QUERY);
82 if (xServiceInfo.is())
83 return xServiceInfo->getImplementationName();
88OUString convertBasicValueToString(
const uno::Any& aValue,
89 const uno::Reference<uno::XComponentContext>& xContext)
97 uno::TypeClass
eType = aValue.getValueTypeClass();
101 case uno::TypeClass_BOOLEAN:
103 bool bBool = aValue.get<
bool>();
104 aRetStr = bBool ?
SfxResId(STR_ANY_VALUE_TRUE) :
SfxResId(STR_ANY_VALUE_FALSE);
107 case uno::TypeClass_CHAR:
110 aRetStr = OUString::number(aChar);
113 case uno::TypeClass_STRING:
115 aRetStr =
u"\"" + aValue.get<OUString>() + u
"\"";
118 case uno::TypeClass_FLOAT:
120 auto aNumber = aValue.get<
float>();
121 aRetStr = OUString::number(aNumber);
124 case uno::TypeClass_DOUBLE:
126 auto aNumber = aValue.get<
double>();
127 aRetStr = OUString::number(aNumber);
130 case uno::TypeClass_BYTE:
132 auto aNumber = aValue.get<
sal_Int8>();
133 aRetStr = OUString::number(aNumber);
136 case uno::TypeClass_SHORT:
138 auto aNumber = aValue.get<sal_Int16>();
139 aRetStr = OUString::number(aNumber);
142 case uno::TypeClass_LONG:
144 auto aNumber = aValue.get<sal_Int32>();
145 aRetStr = OUString::number(aNumber);
148 case uno::TypeClass_HYPER:
150 auto aNumber = aValue.get<sal_Int64>();
151 aRetStr = OUString::number(aNumber);
154 case uno::TypeClass_UNSIGNED_SHORT:
156 auto aNumber = aValue.get<sal_uInt16>();
157 aRetStr = OUString::number(aNumber);
160 case uno::TypeClass_UNSIGNED_LONG:
162 auto aNumber = aValue.get<sal_uInt32>();
163 aRetStr = OUString::number(aNumber);
166 case uno::TypeClass_UNSIGNED_HYPER:
168 auto aNumber = aValue.get<sal_uInt64>();
169 aRetStr = OUString::number(aNumber);
172 case uno::TypeClass_TYPE:
175 aRetStr = aType.getTypeName();
178 case uno::TypeClass_ENUM:
180 aRetStr = enumValueToEnumName(aValue, xContext);
191OUString getInterfaceName(uno::Reference<uno::XInterface>
const& xInterface,
192 const uno::Reference<uno::XComponentContext>& xContext)
194 uno::Reference<container::XNamed> xNamed(xInterface, uno::UNO_QUERY);
196 return xNamed->getName();
198 auto xInvocationFactory = css::script::Invocation::create(xContext);
199 uno::Sequence<uno::Any> aParameters = {
uno::Any(xInterface) };
200 auto xInvocationInterface = xInvocationFactory->createInstanceWithArguments(aParameters);
201 if (xInvocationInterface.is())
203 uno::Reference<script::XInvocation2>
xInvocation(xInvocationInterface, uno::UNO_QUERY);
207 if (aAny.
hasValue() && aAny.getValueTypeClass() == uno::TypeClass_STRING)
208 return aAny.get<OUString>();
214OUString convertAnyToString(
const uno::Any& aValue,
215 const uno::Reference<uno::XComponentContext>& xContext)
219 return SfxResId(STR_ANY_VALUE_NULL);
223 uno::TypeClass
eType = aValue.getValueTypeClass();
227 case uno::TypeClass_INTERFACE:
229 uno::Reference<uno::XInterface> xInterface(aValue, uno::UNO_QUERY);
230 if (!xInterface.is())
231 aRetStr =
SfxResId(STR_ANY_VALUE_NULL);
234 OUString aImplementationClass = getInterfaceImplementationClass(xInterface);
235 if (aImplementationClass.isEmpty())
236 aImplementationClass =
SfxResId(STR_CLASS_UNKNOWN);
238 =
SfxResId(STR_PROPERTY_VALUE_OBJECT).replaceFirst(
"%1", aImplementationClass);
240 OUString aString = getInterfaceName(xInterface, xContext);
241 if (!aString.isEmpty())
242 aRetStr +=
" {" + aString +
"}";
246 case uno::TypeClass_STRUCT:
248 aRetStr =
SfxResId(STR_PROPERTY_VALUE_STRUCT);
253 aRetStr = convertBasicValueToString(aValue, xContext);
260OUString convertAnyToShortenedString(
const uno::Any& aValue,
261 const uno::Reference<uno::XComponentContext>& xContext)
265 return SfxResId(STR_ANY_VALUE_NULL);
269 uno::TypeClass
eType = aValue.getValueTypeClass();
271 constexpr const sal_Int32 constMaxStringLength = 60;
275 case uno::TypeClass_INTERFACE:
277 aRetStr = convertAnyToString(aValue, xContext);
279 if (aRetStr.getLength() > constMaxStringLength + 3)
280 aRetStr = OUString::Concat(aRetStr.subView(0, constMaxStringLength)) +
u"...";
283 case uno::TypeClass_STRING:
285 OUString aString = convertAnyToString(aValue, xContext);
286 if (aString.getLength() > constMaxStringLength + 4)
287 aString = OUString::Concat(aString.subView(0, constMaxStringLength)) +
u"\"...";
288 aRetStr = aString.replaceAll(
"\n",
" ");
293 aRetStr = convertAnyToString(aValue, xContext);
301OUString getAnyType(
const uno::Any& aValue)
303 OUString aTypeName = aValue.getValueType().getTypeName();
304 return aTypeName.replaceAll(
"com.sun.star",
"css");
308uno::Reference<reflection::XIdlClass>
309convertTypeToIdlClass(
const uno::Type& rType,
310 const uno::Reference<uno::XComponentContext>& xContext)
312 auto xReflection = reflection::theCoreReflection::get(xContext);
313 return xReflection->forName(rType.getTypeName());
327class ObjectInspectorNodeInterface
330 ObjectInspectorNodeInterface() =
default;
332 virtual ~ObjectInspectorNodeInterface() {}
335 virtual OUString getObjectName() = 0;
338 virtual bool shouldShowExpander() {
return false; }
341 virtual void fillChildren(std::unique_ptr<weld::TreeView>& rTree,
const weld::TreeIter* pParent)
345 virtual std::vector<std::pair<sal_Int32, OUString>> getColumnValues()
347 return std::vector<std::pair<sal_Int32, OUString>>();
352OUString lclAppendNode(
const std::unique_ptr<weld::TreeView>& pTree,
353 ObjectInspectorNodeInterface* pEntry)
355 OUString
sName = pEntry->getObjectName();
357 std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
358 pTree->insert(
nullptr, -1, &sName, &sId,
nullptr,
nullptr, pEntry->shouldShowExpander(),
360 pTree->set_text_emphasis(*pCurrent,
true, 0);
362 for (
auto const& rPair : pEntry->getColumnValues())
364 pTree->set_text(*pCurrent, rPair.second, rPair.first);
371OUString lclAppendNodeToParent(
const std::unique_ptr<weld::TreeView>& pTree,
372 const weld::TreeIter* pParent, ObjectInspectorNodeInterface* pEntry)
374 OUString
sName = pEntry->getObjectName();
376 std::unique_ptr<weld::TreeIter> pCurrent = pTree->make_iterator();
377 pTree->insert(pParent, -1, &sName, &sId,
nullptr,
nullptr, pEntry->shouldShowExpander(),
379 pTree->set_text_emphasis(*pCurrent,
true, 0);
381 for (
auto const& rPair : pEntry->getColumnValues())
383 pTree->set_text(*pCurrent, rPair.second, rPair.first);
390class SimpleStringNode :
public ObjectInspectorNodeInterface
396 SimpleStringNode(OUString sName)
401 void fillChildren(std::unique_ptr<weld::TreeView>& ,
406 OUString getObjectName()
override {
return msName; }
410class MethodNode :
public ObjectInspectorNodeInterface
413 uno::Reference<reflection::XIdlMethod> mxMethod;
416 MethodNode(uno::Reference<reflection::XIdlMethod> xMethod)
421 OUString getObjectName()
override {
return mxMethod->getName(); }
423 static OUString simpleTypeName(uno::Reference<reflection::XIdlClass>
const& xClass)
425 switch (xClass->getTypeClass())
427 case uno::TypeClass_INTERFACE:
428 return SfxResId(STR_METHOD_TYPE_OBJECT);
429 case uno::TypeClass_STRUCT:
430 return SfxResId(STR_METHOD_TYPE_STRUCT);
431 case uno::TypeClass_ENUM:
432 return SfxResId(STR_METHOD_TYPE_ENUM);
433 case uno::TypeClass_SEQUENCE:
434 return SfxResId(STR_METHOD_TYPE_SEQUENCE);
438 return xClass->getName();
441 std::vector<std::pair<sal_Int32, OUString>> getColumnValues()
override
444 auto xClass = mxMethod->getReturnType();
445 aOutString = simpleTypeName(xClass);
448 const auto aParameters = mxMethod->getParameterInfos();
450 for (
auto const& rParameterInfo : aParameters)
457 switch (rParameterInfo.aMode)
459 case reflection::ParamMode_IN:
460 aInString +=
SfxResId(STR_PARMETER_MODE_IN) +
" ";
462 case reflection::ParamMode_OUT:
463 aInString +=
SfxResId(STR_PARMETER_MODE_OUT) +
" ";
465 case reflection::ParamMode_INOUT:
466 aInString +=
SfxResId(STR_PARMETER_MODE_IN_AND_OUT) +
" ";
472 aInString += rParameterInfo.aName +
" : " + simpleTypeName(rParameterInfo.aType);
475 OUString aImplementationClass = mxMethod->getDeclaringClass()->getName();
480 { 3, aImplementationClass },
484 void fillChildren(std::unique_ptr<weld::TreeView>& ,
496class ClassNode :
public ObjectInspectorNodeInterface
499 uno::Reference<reflection::XIdlClass> mxClass;
501 static bool isXInterface(uno::Reference<reflection::XIdlClass>
const& xClass)
503 return xClass->getName() ==
"com.sun.star.uno.XInterface";
507 ClassNode(uno::Reference<reflection::XIdlClass> xClass)
508 : mxClass(
std::move(xClass))
512 bool shouldShowExpander()
override
514 auto const& xSuperClasses = mxClass->getSuperclasses();
515 return xSuperClasses.getLength() > 2
516 || (xSuperClasses.getLength() == 1 && !isXInterface(xSuperClasses[0]));
519 OUString getObjectName()
override {
return mxClass->getName(); }
522 void fillChildren(std::unique_ptr<weld::TreeView>& rTree,
525 auto const& xSuperClasses = mxClass->getSuperclasses();
526 for (
auto const& xSuper : xSuperClasses)
528 if (!isXInterface(xSuper))
529 lclAppendNodeToParent(rTree, pParent,
new ClassNode(xSuper));
535class BasicValueNode :
public SimpleStringNode
540 uno::Reference<uno::XComponentContext>
mxContext;
542 ObjectInspectorNodeInterface*
543 createNodeObjectForAny(OUString
const& rName,
const uno::Any& rAny, OUString
const& mrInfo);
546 BasicValueNode(OUString
const& rName,
uno::Any aAny, OUString aInfo,
547 uno::Reference<uno::XComponentContext> xContext)
548 : SimpleStringNode(rName)
549 , maAny(
std::move(aAny))
550 , mrInfo(
std::move(aInfo))
555 const uno::Any& getAny()
const {
return maAny; }
557 bool shouldShowExpander()
override
561 switch (maAny.getValueType().getTypeClass())
563 case uno::TypeClass_INTERFACE:
565 uno::Reference<uno::XInterface> xInterface(maAny, uno::UNO_QUERY);
566 return xInterface.is();
568 case uno::TypeClass_SEQUENCE:
577 std::vector<std::pair<sal_Int32, OUString>> getColumnValues()
override
579 OUString aValue = convertAnyToShortenedString(maAny, mxContext);
580 OUString aType = getAnyType(maAny);
582 return { { 1, aValue }, { 2, aType }, { 3, mrInfo } };
587class GenericPropertiesNode :
public BasicValueNode
590 GenericPropertiesNode(OUString
const& rName,
uno::Any const& rAny, OUString
const& rInfo,
591 uno::Reference<uno::XComponentContext>
const& xContext)
592 : BasicValueNode(rName, rAny, rInfo, xContext)
596 void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
601class StructNode :
public BasicValueNode
604 StructNode(OUString
const& rName,
uno::Any const& rAny, OUString
const& rInfo,
605 uno::Reference<uno::XComponentContext>
const& xContext)
606 : BasicValueNode(rName, rAny, rInfo, xContext)
610 bool shouldShowExpander()
override {
return true; }
612 void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
617class SequenceNode :
public BasicValueNode
619 uno::Reference<reflection::XIdlArray> mxIdlArray;
622 SequenceNode(OUString
const& rName,
uno::Any const& rAny, OUString
const& rInfo,
623 uno::Reference<uno::XComponentContext>
const& xContext)
624 : BasicValueNode(rName, rAny, rInfo, xContext)
626 auto xClass = convertTypeToIdlClass(maAny.getValueType(), mxContext);
627 mxIdlArray = xClass->getArray();
630 bool shouldShowExpander()
override
633 int nLength = mxIdlArray->getLen(maAny);
637 void fillChildren(std::unique_ptr<weld::TreeView>& pTree,
640 int nLength = mxIdlArray->getLen(maAny);
644 uno::Any aArrayValue = mxIdlArray->get(maAny, i);
646 auto* pObjectInspectorNode
647 = createNodeObjectForAny(OUString::number(i), aArrayValue,
"");
648 if (pObjectInspectorNode)
649 lclAppendNodeToParent(pTree, pParent, pObjectInspectorNode);
653 std::vector<std::pair<sal_Int32, OUString>> getColumnValues()
override
655 int nLength = mxIdlArray->getLen(maAny);
658 = getAnyType(maAny).replaceAll(u
"[]", u
"") +
u"[" + OUString::number(nLength) +
u"]";
661 =
SfxResId(STR_PROPERTY_VALUE_SEQUENCE).replaceFirst(
"%1", OUString::number(nLength));
670void GenericPropertiesNode::fillChildren(std::unique_ptr<weld::TreeView>& pTree,
678 const auto xNameAccess = uno::Reference<container::XNameAccess>(maAny, uno::UNO_QUERY);
679 if (xNameAccess.is())
681 const uno::Sequence<OUString> aNames = xNameAccess->getElementNames();
682 for (OUString
const& rName : aNames)
684 uno::Any aAny = xNameAccess->getByName(rName);
685 auto* pObjectInspectorNode = createNodeObjectForAny(
686 u
"@" + rName, aAny,
SfxResId(STR_PROPERTY_TYPE_IS_NAMED_CONTAINER));
687 lclAppendNodeToParent(pTree, pParent, pObjectInspectorNode);
697 const auto xIndexAccess = uno::Reference<container::XIndexAccess>(maAny, uno::UNO_QUERY);
698 if (xIndexAccess.is())
700 for (sal_Int32 nIndex = 0;
nIndex < xIndexAccess->getCount(); ++
nIndex)
702 uno::Any aAny = xIndexAccess->getByIndex(nIndex);
703 auto* pObjectInspectorNode
704 = createNodeObjectForAny(u
"@" + OUString::number(nIndex), aAny,
705 SfxResId(STR_PROPERTY_TYPE_IS_INDEX_CONTAINER));
706 lclAppendNodeToParent(pTree, pParent, pObjectInspectorNode);
716 const auto xEnumAccess
717 = uno::Reference<container::XEnumerationAccess>(maAny, uno::UNO_QUERY);
718 if (xEnumAccess.is())
720 uno::Reference<container::XEnumeration> xEnumeration = xEnumAccess->createEnumeration();
721 if (xEnumeration.is())
723 for (sal_Int32 nIndex = 0; xEnumeration->hasMoreElements();
nIndex++)
725 uno::Any aAny = xEnumeration->nextElement();
726 auto* pObjectInspectorNode
727 = createNodeObjectForAny(u
"@" + OUString::number(nIndex), aAny,
728 SfxResId(STR_PROPERTY_TYPE_IS_ENUMERATION));
729 lclAppendNodeToParent(pTree, pParent, pObjectInspectorNode);
738 auto xInvocationFactory = css::script::Invocation::create(mxContext);
739 uno::Sequence<uno::Any> aParameters = { maAny };
740 auto xInvocationInterface = xInvocationFactory->createInstanceWithArguments(aParameters);
741 if (!xInvocationInterface.is())
744 uno::Reference<script::XInvocation2>
xInvocation(xInvocationInterface, uno::UNO_QUERY);
748 auto const& xInvocationAccess =
xInvocation->getIntrospection();
749 if (!xInvocationAccess.is())
752 uno::Sequence<script::InvocationInfo> aInvocationInfoSequence;
761 for (
auto const& aInvocationInfo : std::as_const(aInvocationInfoSequence))
763 if (aInvocationInfo.eMemberType == script::MemberType_PROPERTY)
766 auto const& aPropertyName = aInvocationInfo.aName;
768 bool bIsAttribute =
false;
769 bool bIsGetSetMethod =
false;
770 bool bMethodGet =
false;
771 bool bMethodSet =
false;
772 bool bMethodIs =
false;
775 aCurrentAny =
xInvocation->getValue(aPropertyName);
776 bIsAttribute = xInvocationAccess->hasProperty(aPropertyName,
777 beans::PropertyConcept::ATTRIBUTES);
778 bIsGetSetMethod = xInvocationAccess->hasProperty(aPropertyName,
779 beans::PropertyConcept::METHODS);
782 bMethodGet = xInvocationAccess->hasMethod(u
"get" + aPropertyName,
783 beans::MethodConcept::PROPERTY);
784 bMethodSet = xInvocationAccess->hasMethod(u
"set" + aPropertyName,
785 beans::MethodConcept::PROPERTY);
786 bMethodIs = xInvocationAccess->hasMethod(u
"is" + aPropertyName,
787 beans::MethodConcept::PROPERTY);
794 std::vector<OUString> aInfoCollection;
796 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_IS_ATTRIBUTE));
799 bool bHasGet =
false;
801 if (bMethodGet || bMethodIs)
803 aString +=
SfxResId(STR_PROPERTY_ATTRIBUTE_GET);
810 aString +=
SfxResId(STR_PROPERTY_ATTRIBUTE_SET);
812 aInfoCollection.push_back(aString);
813 if (bMethodSet && !bHasGet)
814 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_WRITEONLY));
816 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::MAYBEVOID)
817 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_MAYBEVOID));
818 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::READONLY)
819 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_READONLY));
820 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::REMOVABLE)
821 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_REMOVABLE));
822 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::BOUND)
823 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_BOUND));
824 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::CONSTRAINED)
825 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_CONSTRAINED));
826 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::TRANSIENT)
827 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_TRANSIENT));
828 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::MAYBEAMBIGUOUS)
829 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_MAYBEAMBIGUOUS));
830 if (aInvocationInfo.PropertyAttribute & beans::PropertyAttribute::MAYBEDEFAULT)
831 aInfoCollection.push_back(
SfxResId(STR_PROPERTY_ATTRIBUTE_MAYBEDEFAULT));
834 OUString aInfoString;
835 for (
auto const& rString : aInfoCollection)
842 aInfoString += rString;
845 auto* pObjectInspectorNode
846 = createNodeObjectForAny(aPropertyName, aCurrentAny, aInfoString);
847 if (pObjectInspectorNode)
848 lclAppendNodeToParent(pTree, pParent, pObjectInspectorNode);
853void StructNode::fillChildren(std::unique_ptr<weld::TreeView>& pTree,
const weld::TreeIter* pParent)
855 auto xReflection = reflection::theCoreReflection::get(mxContext);
856 uno::Reference<reflection::XIdlClass> xClass
857 = xReflection->forName(maAny.getValueType().getTypeName());
859 const auto xFields = xClass->getFields();
861 for (
auto const& xField : xFields)
863 OUString aFieldName = xField->getName();
864 uno::Any aFieldValue = xField->get(maAny);
866 auto* pObjectInspectorNode = createNodeObjectForAny(aFieldName, aFieldValue,
"");
867 if (pObjectInspectorNode)
869 lclAppendNodeToParent(pTree, pParent, pObjectInspectorNode);
874ObjectInspectorNodeInterface* BasicValueNode::createNodeObjectForAny(OUString
const& rName,
876 OUString
const& rInfo)
878 switch (rAny.getValueType().getTypeClass())
880 case uno::TypeClass_INTERFACE:
881 return new GenericPropertiesNode(rName, rAny, rInfo, mxContext);
883 case uno::TypeClass_SEQUENCE:
884 return new SequenceNode(rName, rAny, rInfo, mxContext);
886 case uno::TypeClass_STRUCT:
887 return new StructNode(rName, rAny, rInfo, mxContext);
893 return new BasicValueNode(rName, rAny, rInfo, mxContext);
901ObjectInspectorNodeInterface* getSelectedNode(
weld::TreeView const& rTreeView)
907 if (
auto* pNode = weld::fromId<ObjectInspectorNodeInterface*>(sID))
913uno::Reference<uno::XInterface> getSelectedXInterface(
weld::TreeView const& rTreeView)
915 uno::Reference<uno::XInterface> xInterface;
917 if (
auto* pNode = getSelectedNode(rTreeView))
919 if (
auto* pBasicValueNode =
dynamic_cast<BasicValueNode*
>(pNode))
921 uno::Any aAny = pBasicValueNode->getAny();
922 xInterface.set(aAny, uno::UNO_QUERY);
932 std::unique_ptr<ObjectInspectorWidgets>& pObjectInspectorWidgets)
933 : mpObjectInspectorWidgets(pObjectInspectorWidgets)
987 auto nPropertiesDigitWidth
989 std::vector<int> aPropertiesWidths(4, nPropertiesDigitWidth * 30);
992 auto nMethodsDigitWidth
994 std::vector<int> aMethodsWidths{
static_cast<int>(nMethodsDigitWidth * 30),
995 static_cast<int>(nMethodsDigitWidth * 15),
996 static_cast<int>(nMethodsDigitWidth * 30),
997 static_cast<int>(nMethodsDigitWidth * 50) };
1005 pTreeView->set_sort_func(
1007 return compare(pTreeView, rLeft, rRight);
1015 int nSortColumn = pTreeView->get_sort_column();
1017 OUString sLeft = pTreeView->get_text(rLeft, nSortColumn);
1018 OUString sRight = pTreeView->get_text(rRight, nSortColumn);
1026 OUString sID = pTreeView->get_id(rParent);
1031 auto* pNode = weld::fromId<ObjectInspectorNodeInterface*>(sID);
1032 pNode->fillChildren(pTreeView, &rParent);
1038 handleExpanding(mpObjectInspectorWidgets->mpInterfacesTreeView, rParent);
1045 handleExpanding(mpObjectInspectorWidgets->mpServicesTreeView, rParent);
1052 handleExpanding(mpObjectInspectorWidgets->mpPropertiesTreeView, rParent);
1058 handleExpanding(mpObjectInspectorWidgets->mpMethodsTreeView, rParent);
1064 bool bHaveNodeWithObject =
false;
1065 mpObjectInspectorWidgets->mpTextView->set_text(
"");
1066 if (mpObjectInspectorWidgets->mpPropertiesTreeView.get() == &rTreeView)
1068 auto* pNode = getSelectedNode(rTreeView);
1069 if (
auto* pBasicValueNode =
dynamic_cast<BasicValueNode*
>(pNode))
1071 uno::Any aAny = pBasicValueNode->getAny();
1072 uno::Reference<uno::XInterface> xInterface(aAny, uno::UNO_QUERY);
1073 bHaveNodeWithObject = xInterface.is();
1074 mpObjectInspectorWidgets->mpTextView->set_text(convertAnyToString(aAny,
mxContext));
1078 mpObjectInspectorWidgets->mpToolbar->set_item_sensitive(
"inspect", bHaveNodeWithObject);
1081static void updateOrder(
const std::unique_ptr<weld::TreeView>& pTreeView, sal_Int32 nColumn)
1083 pTreeView->set_sort_column(nColumn);
1085 bool bSortAtoZ = pTreeView->get_sort_order();
1086 pTreeView->set_sort_order(!bSortAtoZ);
1092 auto rPageId = mpObjectInspectorWidgets->mpNotebook->get_current_page_ident();
1094 if (rPageId ==
"object_inspector_interfaces_tab")
1095 updateOrder(mpObjectInspectorWidgets->mpInterfacesTreeView, nColumn);
1096 else if (rPageId ==
"object_inspector_services_tab")
1097 updateOrder(mpObjectInspectorWidgets->mpServicesTreeView, nColumn);
1098 else if (rPageId ==
"object_inspector_properties_tab")
1099 updateOrder(mpObjectInspectorWidgets->mpPropertiesTreeView, nColumn);
1100 else if (rPageId ==
"object_inspector_methods_tab")
1101 updateOrder(mpObjectInspectorWidgets->mpMethodsTreeView, nColumn);
1106 if (rCommandEvent.GetCommand() != CommandEventId::ContextMenu)
1109 auto xInterface = getSelectedXInterface(*mpObjectInspectorWidgets->mpPropertiesTreeView);
1110 if (xInterface.is())
1113 mpObjectInspectorWidgets->mpPropertiesTreeView.get(),
"sfx/ui/devtoolsmenu.ui"));
1114 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(
"inspect_menu"));
1117 xMenu->popup_at_rect(mpObjectInspectorWidgets->mpPropertiesTreeView.get(),
1120 if (sCommand ==
"inspect")
1123 inspectObject(xInterface);
1131 if (rSelectionId ==
"inspect")
1133 auto xInterface = getSelectedXInterface(*mpObjectInspectorWidgets->mpPropertiesTreeView);
1134 if (xInterface.is())
1137 inspectObject(xInterface);
1140 else if (rSelectionId ==
"back")
1145 uno::Reference<uno::XInterface> xInterface(aAny, uno::UNO_QUERY);
1146 inspectObject(xInterface);
1149 else if (rSelectionId ==
"refresh")
1151 auto rPageId = mpObjectInspectorWidgets->mpNotebook->get_current_page_ident();
1152 NotebookEnterPage(rPageId);
1158 uno::Any aAny = maInspectionStack.back();
1162 uno::Reference<uno::XInterface> xInterface(aAny, uno::UNO_QUERY);
1163 if (rPageId ==
"object_inspector_interfaces_tab")
1165 mpObjectInspectorWidgets->mpInterfacesTreeView->freeze();
1166 clearAll(mpObjectInspectorWidgets->mpInterfacesTreeView);
1167 appendInterfaces(xInterface);
1168 mpObjectInspectorWidgets->mpInterfacesTreeView->thaw();
1170 else if (rPageId ==
"object_inspector_services_tab")
1172 mpObjectInspectorWidgets->mpServicesTreeView->freeze();
1173 clearAll(mpObjectInspectorWidgets->mpServicesTreeView);
1174 appendServices(xInterface);
1175 mpObjectInspectorWidgets->mpServicesTreeView->thaw();
1177 else if (rPageId ==
"object_inspector_properties_tab")
1179 mpObjectInspectorWidgets->mpPropertiesTreeView->freeze();
1180 clearAll(mpObjectInspectorWidgets->mpPropertiesTreeView);
1181 appendProperties(xInterface);
1182 mpObjectInspectorWidgets->mpPropertiesTreeView->thaw();
1184 else if (rPageId ==
"object_inspector_methods_tab")
1186 mpObjectInspectorWidgets->mpMethodsTreeView->freeze();
1187 clearAll(mpObjectInspectorWidgets->mpMethodsTreeView);
1188 appendMethods(xInterface);
1189 mpObjectInspectorWidgets->mpMethodsTreeView->thaw();
1195 if (rPageId ==
"object_inspector_interfaces_tab")
1197 mpObjectInspectorWidgets->mpInterfacesTreeView->freeze();
1198 clearAll(mpObjectInspectorWidgets->mpInterfacesTreeView);
1199 mpObjectInspectorWidgets->mpInterfacesTreeView->thaw();
1201 else if (rPageId ==
"object_inspector_services_tab")
1203 mpObjectInspectorWidgets->mpServicesTreeView->freeze();
1204 clearAll(mpObjectInspectorWidgets->mpServicesTreeView);
1205 mpObjectInspectorWidgets->mpServicesTreeView->thaw();
1207 else if (rPageId ==
"object_inspector_properties_tab")
1209 mpObjectInspectorWidgets->mpPropertiesTreeView->freeze();
1210 clearAll(mpObjectInspectorWidgets->mpPropertiesTreeView);
1211 mpObjectInspectorWidgets->mpPropertiesTreeView->thaw();
1213 else if (rPageId ==
"object_inspector_methods_tab")
1215 mpObjectInspectorWidgets->mpMethodsTreeView->freeze();
1216 clearAll(mpObjectInspectorWidgets->mpMethodsTreeView);
1217 mpObjectInspectorWidgets->mpMethodsTreeView->thaw();
1223 std::unique_ptr<weld::TreeView>& pTreeView,
weld::TreeIter const& rParent)
1225 bool bChild =
false;
1228 bChild = pTreeView->iter_has_child(rParent);
1231 std::unique_ptr<weld::TreeIter> pChild = pTreeView->make_iterator(&rParent);
1232 bChild = pTreeView->iter_children(*pChild);
1236 OUString sID = pTreeView->get_id(*pChild);
1237 auto* pEntry = weld::fromId<ObjectInspectorNodeInterface*>(sID);
1239 pTreeView->remove(*pChild);
1250 OUString sID = pTreeView->get_id(rEntry);
1251 auto* pEntry = weld::fromId<ObjectInspectorNodeInterface*>(sID);
1261 if (!xInterface.is())
1264 uno::Reference<lang::XTypeProvider> xTypeProvider(xInterface, uno::UNO_QUERY);
1265 if (xTypeProvider.is())
1267 const auto xSequenceTypes = xTypeProvider->getTypes();
1268 for (
auto const& xType : xSequenceTypes)
1270 auto xClass = convertTypeToIdlClass(xType,
mxContext);
1279 if (!xInterface.is())
1282 auto xServiceInfo = uno::Reference<lang::XServiceInfo>(xInterface, uno::UNO_QUERY);
1283 const uno::Sequence<OUString>
aServiceNames(xServiceInfo->getSupportedServiceNames());
1287 new SimpleStringNode(aServiceName));
1294 if (!xInterface.is())
1303 if (!xInterface.is())
1309 const auto xMethods = xIntrospectionAccess->getMethods(beans::MethodConcept::ALL);
1310 for (
auto const&
xMethod : xMethods)
1348 if (!xInterface.is())
1355 sal_Int32 nDigitWidth
1363 NotebookEnterPage(rPageId);
static void updateOrder(const std::unique_ptr< weld::TreeView > &pTreeView, sal_Int32 nColumn)
IMPL_LINK(ObjectInspectorTreeHandler, ExpandingHandlerInterfaces, weld::TreeIter const &, rParent, bool)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
Object inspector tree handler.
std::deque< css::uno::Any > maInspectionStack
void inspectObject(css::uno::Reference< css::uno::XInterface > const &xInterface)
static void handleExpanding(std::unique_ptr< weld::TreeView > &pTreeView, weld::TreeIter const &rParent)
css::uno::Reference< css::uno::XComponentContext > mxContext
void appendProperties(css::uno::Reference< css::uno::XInterface > const &xInterface)
Append properties to the "properties" tree view.
void introspect(css::uno::Reference< css::uno::XInterface > const &xInterface)
void updateBackButtonState()
std::unique_ptr< ObjectInspectorWidgets > & mpObjectInspectorWidgets
static void clearAll(std::unique_ptr< weld::TreeView > &pTreeView)
Deletes all the node objects in a tree view.
css::uno::Any popFromStack()
void appendMethods(css::uno::Reference< css::uno::XInterface > const &xInterface)
Append methods to the "methods" tree view.
sal_Int32 compare(std::unique_ptr< weld::TreeView > &pTreeView, const weld::TreeIter &rLeft, const weld::TreeIter &rRight)
ObjectInspectorTreeHandler(std::unique_ptr< ObjectInspectorWidgets > &pObjectInspectorWidgets)
comphelper::string::NaturalStringSorter mxSorter
void appendInterfaces(css::uno::Reference< css::uno::XInterface > const &xInterface)
Append interfaces to the "interfaces" tree view.
void setSortFunction(std::unique_ptr< weld::TreeView > &pTreeView)
void appendServices(css::uno::Reference< css::uno::XInterface > const &xInterface)
Append services to the "services" tree view.
static void clearObjectInspectorChildren(std::unique_ptr< weld::TreeView > &pTreeView, weld::TreeIter const &rParent)
void addToStack(css::uno::Any const &rAny)
sal_Int32 compare(const OUString &rLHS, const OUString &rRHS) const
virtual OUString get_selected_id() const=0
Sequence< OUString > aServiceNames
OUString aImplementationName
Reference< XIntrospection > xIntrospection
#define LINK(Instance, Class, Member)
const LanguageTag & getLocale()
Reference< XComponentContext > getProcessComponentContext()
bool enum2int(sal_Int32 &rnEnum, const css::uno::Any &rAny)
OUString toId(const void *pValue)
Reference< XInvocation2 > xInvocation
OUString SfxResId(TranslateId aId)