Get IDE line number

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
DavidHMcCracken
Posts: 44
Joined: Tue Apr 10, 2018 6:15 am

Get IDE line number

Post by DavidHMcCracken »

Does anyone know how to get the line number of the cursor position in the BASIC IDE; hopefully also a simple method of moving to a line number? The IDE only supports a few global methods, notably copy/paste and search but, it seems, nothing involving the cursor. However, as viewtopic.php?f=20&t=75031 shows, the line number is knowable-- it is one of the arguments to uno:BasicIDEAppear.
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

Try the window's accessible context

viewtopic.php?f=20&t=6458#p30769
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
DavidHMcCracken
Posts: 44
Joined: Tue Apr 10, 2018 6:15 am

Re: Get IDE line number

Post by DavidHMcCracken »

Je Je, thank you for your quick reply. The only accessible context I've been able to find is
StarDesktop.CurrentComponent.CurrentController.Frame.getContainerWindow().AccessibleContext
This doesn't seem to have any cursor position information. It has Location and LocationOnScreen properties but these don't change with cursor (caret or pointer) position.
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

If you look at the code by ms777 in that link it shows you how to go through all the paragraphs in the text in the IDE - if you adapt the getSelectedParas function and find the one where the caretposition isn't -1. Expect crashes.

Code: Select all



    for k=0 to iMaxPara


      oACP = oACTextFrame.AccessibleContext.getAccessibleChild(k)

if oAcp.CaretPosition <>-1 then
msgbox oAcp.CaretPosition
exit function

'etc

Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
DavidHMcCracken
Posts: 44
Joined: Tue Apr 10, 2018 6:15 am

Re: Get IDE line number

Post by DavidHMcCracken »

Thank you Je Je for that very helpful suggestion. Building on that, I am able to get the text of the line containing the caret, which will be a big help beyond my immediate problem.
The referenced example uses magic numbers for child indices and one of them fails in my system because the parent has no children. I wrote a more general recursive version that looks for the caret without a priori knowledge of the objects. As you warned, many of the objects don't have a CaretPosition, raising an exception. As you indicated, only one has value <> -1 and its value is the column index of the caret. The object in which this occurs is the line containing the cursor. This object's parent appears to represent a paragraph and its AccessibleIndexInParent appears to be the line's index in that paragraph. This seems to be approaching a solution but I can't figure out how many lines precede this paragraph. Its parent, i.e. the caret line's grandparent, does not contain any other paragraphs. Even it did, the DOM (Document Object Model) tree order is not related to text order and I don't see anything that is. To get a broader view of the situation, I rewrote my test to not stop upon finding the caret but to examine the entire DOM tree, counting all lines, which I assume are those objects that have CaretPosition. But my supposed line count is significantly less than the real line count. I instrumented the code a little more to also tell the number of objects examined and the recursion depth. This information is displayed when the caret is found and also when done to verify that the process didn't stop on finding the caret. All of the values on finding the caret are a little less than when done, reflecting the history of this code. I initially created it near the end of a large test library. Moving it to the beginning didn't change the DOM structure. Can you offer any further suggestions?

Code: Select all

dim lineCount as integer, depthR as integer, objCount as integer 
sub showResults
	print "lineCount=" & lineCount & ", depthR=" & depthR & ", objCount=" & objCount
end sub
sub countLinesR(this as object)
	depthR = depthR + 1
	objCount = ObjCount + 1
	dim cpi as integer, lidx as integer
	lidx = -1
	on error goto NotThis
	cpi = this.CaretPosition
	if cpi = -1 then
		lineCount = lineCount + 1
	else
		lidx = this.AccessibleIndexInParent
	endif
NotThis:
	on error goto 0
	if lidx >= 0 then
		showResults()
	else
		for idx = 0 to this.AccessibleContext.AccessibleChildCount - 1
			countLinesR(this.AccessibleContext.getAccessibleChild(idx))
		next idx
	endif
	depthR = depthR - 1
end sub
sub countLines
	lineCount = 0 : depthR = 0 : objCount = 0
	countLinesR(StarDesktop.CurrentComponent.CurrentController.Frame.ComponentWindow)
	showResults()
end sub
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

The accessible context gives the paragraphs in the visible window, not the lines from the start of the module. You can get the whole text of the module and compare the caret position with that. If you look at the code from the BasicAddonBuilder extension it may be helpful for getting the text of the module/nodes.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

In answering another question, I remembered this thread... you can get the line number and column from the accessible context of the status bar (Edit: or should be able to). And then change the line number at least using BasicIDEAppear (as mentioned in your initial post)
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
arfgh
Posts: 566
Joined: Tue Mar 05, 2013 6:44 pm

Re: Get IDE line number

Post by arfgh »

^^ i'm not sure what you mean with 'change the line number'... some example ?
OpenOffice last version | Mageia Linux x64 | Ubuntu Linux | Windows 8.1 Enterprise x64 | Java last version
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

Move the cursor to a new line - as in the OP's link

viewtopic.php?f=20&t=75031#p340819
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
DavidHMcCracken
Posts: 44
Joined: Tue Apr 10, 2018 6:15 am

Re: Get IDE line number

Post by DavidHMcCracken »

JeJe-- your suggestion to get the line number from the status bar is great in concept but I have not been able to find the status bar recursing the AccessibleContext tree with root StarDesktop.CurrentComponent.CurrentController.Frame.ComponentWindow. I examined each object's Text and AccessibleContext.AccessibleName for anything visible in the status bar and found no matches. I think my macro is working; it completely reveals Object Catalog, library source file, Watch, Variables, Calls, component tabs, etc.
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

Code: Select all

ac = StarDesktop.CurrentComponent.CurrentController.Frame.Containerwindow.accessiblecontext
with ac
for i = 0 to .accessiblechildcount - 1
if .getaccessiblechild(i).accessiblecontext.accessiblerole = 57 then
'you've got the status bar
end if
next
end with

Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
DavidHMcCracken
Posts: 44
Joined: Tue Apr 10, 2018 6:15 am

Re: Get IDE line number

Post by DavidHMcCracken »

Thank you so much for that JeJe. It works. I would like your opinion on one implementation issue. I am leery of using magic numbers but testing for 57 is certainly cheaper than testing supportsService. Do you think that the number is likely to be as stable as the text format (no need to ask it to be more stable than the format, which we have to parse)?

Code: Select all

function getIdeCur(optional col as integer) as integer
	ac = StarDesktop.CurrentComponent.CurrentController.Frame.Containerwindow.accessiblecontext
	with ac
	for i = 0 to .accessiblechildcount - 1
		cc = .getaccessiblechild(i).accessiblecontext
		'if cc.accessiblerole = 57 then
		if cc.supportsService("com.sun.star.awt.AccessibleStatusBar") then
			pos = split(cc.getAccessibleChild(2).Text)
			getIdeCur() = pos(1)
			if not IsMissing(col) then col = pos(3)
			exit for
		endif
	next i
	end with
end function
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

Its the constant for a scroll bar from here:

https://www.openoffice.org/api/docs/com ... eRole.html
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
arfgh
Posts: 566
Joined: Tue Mar 05, 2013 6:44 pm

Re: Get IDE line number

Post by arfgh »

but.. is it possible to write on that accesible bar ?
OpenOffice last version | Mageia Linux x64 | Ubuntu Linux | Windows 8.1 Enterprise x64 | Java last version
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Get IDE line number

Post by JeJe »

but.. is it possible to write on that accesible bar ?
to paraphrase someone else here: I don't know, I use MRI in these situations and go and have a look-see what's read only and what isn't.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
DavidHMcCracken
Posts: 44
Joined: Tue Apr 10, 2018 6:15 am

Re: Get IDE line number

Post by DavidHMcCracken »

That is an excellent answer JeJe. Those references not only justify using the number but also provide an ongoing means to track changes. The OO page also explains that constants are used instead of enums because that allows creating new cardinals, a strong hint that existing ordinals will not change, even if other values are deleted (unlike arbitrary manifest constants, enums cannot be sparse).
W10 Libre 6.1.5.2 and Ubuntu-Mate 18.04 Libre 6.0.7.3
Post Reply