Wednesday, March 24, 2021

Built-in "Xray" like UNO object inspector – Part 3

DevTools implementation has been completed and this is the third and final part of the mini-series. The focus of this part is on the object inspector, but I have also improved or changed other DevTools parts, so first I will briefly mention those.

New menu position


Figure 1: Development Tools location in the menu

The position in menu has changed from "Help / Development Tools" to "Tools / Development Tools". The new position fits better as it is near the position of macro editor and they go hand in hand with each-other.

Updates to the document model tree view



Figure 2: Document model tree view and "Current Selection" toggle button

The left-hand side document model tree view has been changed to use the same approach than the object inspector tree view uses, where the object attached tree view (in this case DocumentModelTreeEntry) has all the behavioural logic for a specific tree view node. This makes it easier to manipulate the tree view and add new nodes (if necessary).

In the document object tree view I have added a top toolbar with "Refresh" (icon) button and I changed the existing “Current Selection” button to a toolbar toggle button, so it looks more consistent as the is only the toolbar now (see figure 2).

In Writer, each paragraph tree view node now has text portion child nodes (as shown in figure 2), to make it possible to quickly inspect all the individual parts of a paragraph.

The object inspector tree view

Figure 3: Top toolbar and tab bar in object inspector


The object inspector shows various information about an object. Each object has a implementation class, which is always shown for the current object (see figure 3).

The other information that the object inspector shows are divided into four main categories:
  • "Interfaces" - the interfaces that the current object implements
  • "Services" - the services that the current object supports
  • "Properties" - the properties of the current object
  • "Methods" - the combined methods that can be called on the current object
On the user interface, the categories are divided with a tab bar (see figure 3). Each tab represents a different categories. The tabs are filled on "entry" - when the user clicks on the tab.

In the code the tabs and tree views are all handled by the ObjectInspectorTreeHandler and the hierarchy of objects attached the tree view that implement the ObjectInspectorNodeInterface (see include/sfx2/devtools/ObjectInspectorTreeHandler.hxx). 

The two major categories are "Properties" and "Methods", which I describe in more detail next.

Properties

Figure 4: Object inspector "Properties" tab


There are three types of properties of an object:
  • Properties accessible view XPropertySet.
  • Properties defined as an attribute (marked "[attribute]" in IDL). 
  • Pseudo properties defined by a get and set method. 
All the three types are represented in the properties tab and can be identified by the "Info" column. Attribute properties have an "attribute" flag, pseudo properties have either a "get", "set" or both flags. If neither flags exists, it represents a property that is from XPropertySet. 

In the tree view there are four columns for each property - "Name", "Value", "Type" and already mentioned "Info". The "Name" of the property is always available, but it is possible that two properties have the same name (because of multiple property types). The "Value" shows the value of the property, which is converted to the string, if this is possible (it should be if the property is basic), otherwise a representation string is created. The representation string for objects shows the implementation name ("<Object@SwXTextRange>"), for sequences it shows the size ("<Sequence [5]>") and for structs it just mentions the type ("<Struct>").

A node in the “Properties” tree view can be expanded (if offered) so it is possible to recursively inspect the the objects further. In case the property is a struct, it shows the struct members, and if it is a sequence, it shows the indices each object has in the sequence.

There are special properties, which names start with "@". This are added for convenience, so it is possible to inspect objects, that implement XIndexContainer, XNameContainer or XEnumeration interfaces. When such an object is found, the entries gathered using those interfaces are added to the tree view, and are prefixed with "@". For example "@3" (XIndexContainer)   "@PageStyles" (XNameContainer or XEnumeration). The type of the special property is written in the "Info" column ("index container", "name container" and "enumeration" flags). Note that this functionality is not present in Xray or the Macro editor's debugger, but was added for convenience.

Figure 5: "Properties" tab and the text view

On the bottom of the "Properties" tab there is a text view, which shows the full value of the current selected property. In the tree view, the value shown is always using a short form (shortened to 60 chars with new-line characters removed) to not make the tree view too wide. The full value therefor is written in the text view, where it can be inspected in full and has also a working copy/paste (see figure 5).

Object Stack

Related to the "Properties" is the object stack. It is possible to select an object in the tree view and inspect the object (either using the context menu or the toolbar "Inspect" action). In this case the object in the object inspector will change to the selected one. This is convenient when you are only interested in one object down in the tree view hierarchy and want to inspect only that. In that case the previous object will be added to the stack, and can be returned to with hitting the "Back" button in the toolbar.

Note that going to another object (not using "Inspect" action) will always remove the object stack. 

Methods

Figure 6: Object inspector "Methods" tab


The "Methods" tab contains a tree view that shows all the methods, that can be called for the current object. Each method is represented by four columns (see figure 6):
  • "Method" - name of the method
  • "Return type" - the return (simplified) type of the method
  • "Parameters" - list of input parameters, where each one lists the direction ("in", "out" or "in/out"), the parameter name and the simplified type 
  • "Implementation Class" - class/interface where the method is implemented
Currently the types of parameters and return types are simplified, with only basic types, "void", "any", "sequence" and "object" that represents all the objects and the type of the object isn't written. The reason for this is to make it easier to read. 

Future ideas

There are many improvements that can still be made, but aren't included in the current implementation. 

I think it would be quite convenient to have the ability to open a object inspector in mode-less dialog separate to the DevTools, just to quickly look up a property. 

Another big upgrade would also be the ability to change values of basic types for the properties and structs, so it is possible to quickly see what effect the change would have. Similar to changing property values is to call methods with defining the parameters, but only if the parameters are basic types.

My initial vision of DevTools was not that it will be only one tool (object inspector), but more tools just like the development tools in the browser, so I'm sure there will be more useful things integrated over time.

I think there are a lot of ideas you may also have, so please tell me if you have a good one. Of course if you find something that is not working as expected, please let me know.

Credits

Many thanks to TDF and users that support the foundation by providing donations, to make this work possible.

6 comments:

  1. Hi Tomaz,

    Great work you're achieving!

    Would it be possible to add an extra Tab next to Properties and Methods that details Events - names and signatures - to be listened to for a given UNO object?

    Such information is rather difficult to obtain from the SDK

    ReplyDelete
  2. great work, thank you so much! i'm a beginner, so i like it when i see help pages and references tightly integrated into an app and popping up here and there when i hover elements, and i'd be happy if this feature were implemented. Keep up the good work!

    ReplyDelete
  3. Wow, this is great! I wish I had this when I was developing a custom database.

    ReplyDelete
  4. I have version 7.4.2.1 running on manjaro linux and the menu seems to show in writer and presentations but not in calc?

    ReplyDelete
  5. It's disappointing it has no presence in Base.

    ReplyDelete
  6. hello,
    i discovered recently your UNO object inspector which seems very promising : thanks and congratulations for that great tool.

    Calc makes me crazy deleting randomly comments in complex sheets, so i want first to write macros that would save and restore comments of my sheets if some are deleted, and then to learn further.

    i made some development with Excel some years ago, and was pleased to use auto-completion to discover the object model : it was very handy.

    i was disappointed when i saw that Calc did not provide auto-completion, due to architecture reasons, so i searched on the net and discovered quite old tools (XRay and MRI) that seem helpful but a bit outdated in some aspects, and anymore maintained .

    I finally found your tool when updating to LibreOffice version 7.

    i know that this tool is recent so it's a first (great) step ; however, i didn't see how to use it in the macro environement : did i miss something ? or do you plan to this integration in the future?

    some XRay/MRI features would be needed to have a true development tool and not only an objet inspector as you say at the end or your article :

    - links to the API reference

    - help in writing code (as MRI) or at least copy the element syntax (as in MRI/Xray)

    - search tool to locate a specific string, when the inspected object has plenty of properties/methods (as MRI)

    - using it in macro environment : with LibreOffice integration, could it interact with the macro window to retrieve for example the current string (pointed by the cursor) and show new items in the contextual menu ?
    - in static mode to discover the object model : right click in the code => "inspect current selection" would open the inpector and list all relevant objects, properties or methods for the selected string (it could use the index needed for giving access to the API reference) => click on one item would give the entry point of the inspector ?

    - in running mode : right click in the code on a variable => "inspect current selection" would launch the inspector to browse this object variable (without having to write code explicitly to launch the inspector as in MRI/XRay)

    - the MRI File => diff menu option seems very handy to see what property was changed by a specific action on the sheet

    do you plan to implement some of them ?

    thanks in advance for your response

    eseb63




    ReplyDelete