[Solved] Write access to generic statusbar item

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
ah8
Posts: 3
Joined: Sat Mar 23, 2024 2:46 pm

[Solved] Write access to generic statusbar item

Post by ah8 »

Hi there,

I'm currently working on an extension (OpenOffice Basic, AOO 4.x, Linux+Windows), that will change some keyboard bindings. The user shall have the option to switch these binding on and off at any time, choosing between the customising feature and the standard behaviour. I need a way to display the current status of that switch, i.e. the user shall be able to see at one glance, if the feature is currently active or not.

The natural choice seems to be to add a custom item to the statusbar, displaying a string like 'Feature On' or 'Feature Off'. I did manage to add a generic item to the statusbar in two ways, either by adding an entry to .openoffice/4/user/config/soffice.cfg/modules/swriter/statusbar/statusbar.xml

Code: Select all

<statusbar:statusbaritem xlink:href="::com::sun::star::statusbar" statusbar:width="100" statusbar:style="in"/>
or by modifying the settings of the the statusbar:

Code: Select all

Sub createStatusBarEntry()
	Dim aSetting(3) as New com.sun.star.beans.PropertyValue
	aSetting(0).name = "CommandURL"
	aSetting(0).value = "vnd.sun.star.script:StatusBar.StatusBar.onDoubleClick?language=Basic&location=application"
	aSetting(1).name = "Width"
	aSetting(1).value = 100
	aSetting(2).name = "Offset"
	aSetting(2).value = 5
	aSetting(3).name = "Style"
	aSetting(3).value = 10
	
	oStatusBar = ThisComponent.currentcontroller.frame.layoutmanager.getElement("private:resource/statusbar/statusbar")
	aSettings = oStatusBar.getSettings(True)
	aSettings.insertByIndex(0,aSetting)
	oStatusBar.setSettings(aSettings)
	oStatusBar.updateSettings()
End Sub 
However, I could not find a way to place a string into it. I could add some attributes to both ways, but in both cases they seem to be ignored:

Code: Select all

 <statusbar:statusbaritem xlink:href="::com::sun::star::statusbar" statusbar:width="100" statusbar:style="in" text="Feature On" AccessibleName="Feature On" TitledBorderText="Feature On"/>

Code: Select all

Sub createStatusBarEntry()
	Dim aSetting(6) as New com.sun.star.beans.PropertyValue
	aSetting(0).name = "CommandURL"
	aSetting(0).value = "vnd.sun.star.script:StatusBar.StatusBar.onDoubleClick?language=Basic&location=application"
	aSetting(1).name = "Width"
	aSetting(1).value = 100
	aSetting(2).name = "Offset"
	aSetting(2).value = 5
	aSetting(3).name = "Style"
	aSetting(3).value = 10
	aSetting(4).name = "Text"
	aSetting(4).value = "Feature On"
	aSetting(5).name = "AccessibleName"
	aSetting(5).value = "Feature On"
	aSetting(6).name = "TitledBorderText"
	aSetting(6).value = "Feature On"

	oStatusBar = ThisComponent.currentcontroller.frame.layoutmanager.getElement("private:resource/statusbar/statusbar")
	aSettings = oStatusBar.getSettings(True)
	aSettings.insertByIndex(0,aSetting)
	oStatusBar.setSettings(aSettings)
	oStatusBar.updateSettings()

End Sub
There is another way to access the items of the statusbar via the AccessibleContext like in

Code: Select all

oStatusBar.realinterface.accessiblecontext.getaccessiblechild(0).Text
but all attributes accessible that way seem to be read only, so no chance there.

The documentation https://wiki.openoffice.org/wiki/Framew ... Controller says, that a generic item is a text field, so there must be a way to fill it.

I browsed through all methods of all reported interfaces, but I couldn't find a suitable candidate to set the text. I also could not find a way to retrieve an object, that supports the XStatusbarItem interface, an interface that, according to the documentation, should allow to set the item text.

Does anybody have idea what I'm missing?
Is it possible, that I have to implement some event handler to set the text for the passed event object? In that case, what would be the correct handler?

Thanks, and best regards,
ah8
Last edited by MrProgrammer on Wed Apr 24, 2024 7:38 pm, edited 1 time in total.
Reason: Tagged ✓ [Solved] Not possible in StarBasic -- MrProgrammer, forum moderator
OpenOffice 4.x on Debian 10+
JeJe
Volunteer
Posts: 2785
Joined: Wed Mar 09, 2016 2:40 pm

Re: Write access to generic statusbar item

Post by JeJe »

My understanding is:

Its not possible to write a statusbar controller in Basic and you'd need to use a different language.

You can replace the status bar with a progress bar and some text, but then you lose the status bar features

You can create a clickable blank item on the status bar in Basic. And you can add your own dialog over that blank item to display information.

You can change the color of the status bar - which you might use to indicate something running.

Or you could just use a toolbar like full screen does.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
RoryOF
Moderator
Posts: 34619
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Write access to generic statusbar item

Post by RoryOF »

The Word Count status bar controller at

https://extensions.openoffice.org/en/pr ... controller

writes a word count for a Writer document to the Status Bar. Careful examination of its code may be of assistance.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
ah8
Posts: 3
Joined: Sat Mar 23, 2024 2:46 pm

Re: Write access to generic statusbar item

Post by ah8 »

@ JeJe
Thanks for your answer. I‘m afraid you made my worst fears come true :-). No, not really. I was almost expecting it. At least I can stop searching now.

Actually I was hoping for a chance to set the text without a status bar controller (the documentation says, an item can have a controller), or for the existence of a generic controller that does the job

Hiding all existing status bar items for unpredictable period of time is not an option, so that rules out the progress bar, and creating a dialogue above an empty status bar item is an interesting thought, but it sounds a bit like a nasty hack to me.

However, changing the colour is a cute idea. It’s probably not a long term solution, since it would be not such a good idea to hijack global resource for a single extension, but for the time being it should do pretty well; I think I’ll try that.

As a log term solution I’m thinking of writing an extension (presumably in C++) that provides a simple controller for a simple text field. It wouldn’t display anything itself and not really belong to the stuff I’m currently working on; it would be more like a library function, a controller that can be used something like:

Code: Select all

<statusbar:statusbaritem xlink:href=".uno.statusbarTextItem" statusbar:width="100”/>
Would that be possible? The only problem I see right now is the fact, that I would have to extend the interface of the item being created and then to be retrieved by one of the possible ways described above. No clue how this is going to work, after all I have never written C++ code for OO yet and I’m not sure when I’ll find the time to dive into this.

@RoryOF

If seen that site too. Unfortunately I could only find the binaries, not the source code. However, I found this https://svn.apache.org/viewvc?view=revi ... on=1417873. But as I said, I was hoping to get away without writing a controller.
OpenOffice 4.x on Debian 10+
JeJe
Volunteer
Posts: 2785
Joined: Wed Mar 09, 2016 2:40 pm

Re: Write access to generic statusbar item

Post by JeJe »

I just use Basic so don't know anything about creating a controller.

My code to create a blank clickable status bar item in Basic is here.

viewtopic.php?t=110487

It is indeed a bit like a nasty hack, but attached is a rudimentary extension for
adding a dialog to the Status bar.

Install the extension, then open the document (it just has a setting to call a macro in the extension on the view created event), and you should see the result in the status bar.

Creating a toolbar and showing it, or changing a toolbar button (edit: eg making it selected) to show your extension is in use, is still my best suggestion.

Edit:
slight updates/fixes to oxt
Attachments
JeStatusBar.oxt
(3.63 KiB) Downloaded 17 times
status bar dialog test.odt
(8.44 KiB) Downloaded 17 times
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
ah8
Posts: 3
Joined: Sat Mar 23, 2024 2:46 pm

Re: Write access to generic statusbar item

Post by ah8 »

@ JeJe,

thanks for your efforts and sorry to keep you waiting. It took me a while to find the time to continue with this project, but I don't want to keep my results from you.

Changing the colour of the status bar was a pretty neat idea and works really well with some very simple code; it’s a way I can live with for now. Here is the function that essentially does the job:

Code: Select all

REM  *****  BASIC  *****

Global vFeatureDocViews as Variant


Private Type DocViewsEntry
	oController as Object
'	oHandler as Object
End Type


Function featureColor()	as Long	: featureColor = rgb(153, 204, 255)	: End Function
Function defaultColor()	as Long	: defaultColor = rgb(238, 238, 238)	: End Function


Sub toggleFeature()
	Dim oController, oHandler, oStatusBar, oEntry as Object
	oController = ThisComponent.CurrentController
	If isEmpty(vFeatureDocViews) Then
		vFeatureDocViews = New Collection
	Else
		For i = 1 To vFeatureDocViews.count
			oEntry = vFeatureDocViews.item(i)
			If equalUnoObjects(oEntry.oController, oController) Then
				' oEntry.oController.removeKeyHandler(oEntry.oHandler)
				oStatusBar = oController.Frame.LayoutManager.getElement("private:resource/statusbar/statusbar")
				oStatusBar.getRealInterface().setBackground(defaultColor())
				oStatusBar.getRealInterface().invalidate(com.sun.star.awt.InvalidateStyle.UPDATE)
				' Collection.remove(i) keeps chrashing, so let's try to create a new collection instead
				newCollection = New Collection
				For j = 1 To vFeatureDocViews.count
					If i <> j Then
						newCollection.add(vFeatureDocViews.item(j))
					End If
				Next j
				vFeatureDocViews = newCollection
				Exit Sub
			End If
		Next i
	End If
	oStatusBar = oController.Frame.LayoutManager.getElement("private:resource/statusbar/statusbar")
	' oHandler = createUnoListener("Feature_", "com.sun.star.awt.XKeyHandler")
	' oController.addKeyHandler(oHandler)
	oEntry = New DocViewsEntry
	oEntry.oController = oController
	' oEntry.oHandler = oHandler
	vFeatureDocViews.add(oEntry)
	oStatusBar.getRealInterface().setBackground(featureColor())
	oStatusBar.getRealInterface().invalidate(com.sun.star.awt.InvalidateStyle.UPDATE)
End Sub

Switching the feature on and off just involves installing and removing a keyboard handler. I've left that code in the comments, it’s not needed for testing but might help to understand the purpose of the function. The only problem I had was removing an entry from the collection, it kept crashing OpenOffice. However, by creating a new collection and copying the remaining items over I could get around this.

There is definitely room for improvement, especially the hardcoding of the colours is a hack I really don’t like. The feature colour should be configurable and the default colour should be reset to whatever it was before. I managed to read some colours from OpenOffice’s schemes, which could be used for configuration, but schemes are not really used to control the appearance of the user interface. This seems to come somehow from the desktop settings of the window server (I’m using Xfce on Debian, by the way) and I have no clue how to read that.

I also experimented with placing a dialogue over the status bar, but I tried to create the dialogue on the fly, rather than using a predefined one. I thought it would be more natural to make the dialogue the size it needs staright from the start, but I got stuck when creating a container window, i.e. in the line

Code: Select all

CreateUnoService("com.sun.star.awt.ContainerWindowProvider").createContainerWindow("vnd.sun.star.script:JeStatusBar.StatusBarD?location=application", "", oParent, nothing)
where I have an object instead of a URL.
OpenOffice 4.x on Debian 10+
JeJe
Volunteer
Posts: 2785
Joined: Wed Mar 09, 2016 2:40 pm

Re: Write access to generic statusbar item

Post by JeJe »

createContainerWindow requires a URL. If you want to create a window without one you can use createWindow but then, my understanding is, you need to do a lot more work involving attaching the dialog model etc if needed. Resizing after creating the dialog seems a non-issue to me - you can resize it before making it visible. You can make a blank dialog in the IDE as a starting point if you just want to add controls at runtime.
https://www.openoffice.org/api/docs/com ... eateWindow
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Post Reply