Base Macro to Determine Control Type

Is there a property or method of a control that reliably reveals its type? For example, can I determine if a given object is a form, table control, list box or text box? I am trying to simplify some of my subroutines and functions so that inside them, they can determine the control type and take different actions accordingly. Or better yet, write a function that receives a control object, and returns a string telling the type of the control so I could reuse the function throughout my code. I’m particularly interested at the moment to determine if a given object is a table control, but the other types would be useful to determine as well.

I did finally figure out how to use MRI, so I can generally view the methods and properties of any object. I’m just not sure how to test for the type of a control. I suppose I could find some property that is unique to a table control or list box and check whether those methods/properties exist or something like that.

It would also be cool if there was a way to determine the format of the data in a control (kind of the same as the first question/paragraph). For example, is it numerical, currency, text, date, time, etc.? In some of my functions I pass a string parameter that tells the type in advance, like sFormat = “string”, “currency”, “long”, “integer”, “double”, “float”, “listbox”, “null”, etc. If there was a way to determine the data type programmatically, I could skip having to tell the functions what the type is, which would be nice.

Reliably; Funny guy.
Of course there is.

Each control model has a service name property. That is what you want

Here is an example routine which will walk down every control on a form looking for certain types of controls.
And then go over what is happening. (actually it should be fairly self explanatory)

sub setNativeWidgetLook( aDataForm as variant, aYesNo as Boolean )
	dim enControlModels
	dim oControlModel as object
	
	'thisComponent.LockControllers    '

	enControlModels = aDataForm.CreateEnumeration
	if enControlModels.hasMoreElements then
		do
	  		oControlModel = enControlModels.nextElement
	  		if oControlModel.ServiceName = "stardiv.one.form.component.Form" then
	  			setNativeWidgetLook( oControlModel, aYesNo )
	  		else
	  			if oControlModel.ServiceName <> "stardiv.one.form.component.Grid" then
	  				if oControlModel.ServiceName <> "stardiv.one.form.component.Hidden" then
	  					oControlModel.NativeWidgetLook = aYesNo
	  				end if
	  			else
	  				setNativeWidgetLook( oControlModel, aYesNo )
	  			end if
	  		end if
		loop while enControlModels.hasMoreElements = True
	end if

	'thisComponent.UnLockControllers    '	
end sub

Of course a dataform can nest include other dataforms (ie. for a master/slave type form) so in these lines:

if oControlModel.ServiceName = "stardiv.one.form.component.Form" then
    	  			setNativeWidgetLook( oControlModel, aYesNo )

if the current control is another dataform the routine uses recursion to walk down the controls on this sub-dataform first.

Then it looks it checks that the control model is neither a grid control nor a hidden control (which is not just any control hidden, it is separate type of control) and if not then it sets the property NativeWidetLook (yes for OS, no for LO).

If the current control was a grid, that again has a collection of controls so again it uses recursion to call itself and walk down those also.

You will want to get a copy of SDK from the LO download site, with that is the documentation that will give you the needed ServiceNames, etc and this document can be linked to from MRI so you can use it to get details while you are working.

When you say datatype of the control are you actually asking to find the dataytpe of the database field the control is linked to? (I’ll assume you are)

so here is an example of another working routine which uses that:

sub PrettyControl( aControl as variant, aReqColor as double, setDisplaySize as boolean )
	if 	aControl.ServiceName = "stardiv.one.form.component.Edit" _
		or	aControl.ServiceName = "stardiv.one.form.component.TimeField" _
		or	aControl.ServiceName = "stardiv.one.form.component.DateField" _
		then
		if aControl.BoundField.isNullable = 0  and aReqColor <> -1 then
			aControl.BackgroundColor = aReqColor
		end if
		aControl.ReadOnly = aControl.BoundField.IsAutoIncrement
		if aControl.BoundField.TypeName = "VARCHAR"_
			OR aControl.BoundField.TypeName = "CHAR"_
			then
			if setDisplaySize then
				aControl.MaxTextLen = aControl.BoundField.DisplaySize
			end if
		end if
		if aControl.HelpText = "" then
			aControl.HelpText = aControl.BoundField.Helptext
		end if
	end if
end sub

Each data awara UI control has a property BoundField which is the database column and here the routine checks that for certain things like whether is can be null and if not colors the UI controls background, the only thing that might need explaining are the last lines:

if aControl.HelpText = "" then
			aControl.HelpText = aControl.BoundField.Helptext
		end if

In the table edit dialog there is the ability to add a description to a column, that string can be accessed through the Helptext property and this copies that string into the UI controls HelpText property.

Hope that helps.

Golden. While some of this is a bit above my head, I can perceive the answer is here if I slowly parse through. I like that there is a “service name property.” All the stuff about recursion and whatnot is great additional info too. More than likely my situation will only require a subset of what you have offered as an answer, but for those who want to go deeper, you’ve provided them fodder as well. Thanks a lot!

.hasMoreElements… nooice!

My question concerned the Base control type. As in, when I “replace with” and choose text field, numerical, currency, etc. Obviously I don’t have to use “replace with” to make new controls, but it’s faster to CTRL+drag an existing control (to copy it), replace with to change its type, and change its properties. Then all the size, font and color stuff is consistent. Knowing the underlying type of the MySQL column is just as good or better, as long as I use the roughly matching control in Base.

That help text thing is cool. Since I’m using MySQL, I wonder if it would grab the MySQL field descriptions. That would be kinda cool. Though most of my stuff doesn’t require much user instruction. “This is an address field, so type an address in it.” Heh heh.

One of the reasons I want to know the type is so I can know which .updateXXX() method to use. For example .updateString(), .updateLong(). Same goes for .getXXX methods. Also, list boxes are unique & need .commit & not .boundField. I pass an array of fieldnames to functions & a matching array of field types. It’s not terrible, and it works, but it would be cool if I didn’t have to pass that extra array. I think I’ll be able to write a function to determine the control types with your info. Sweet!

Ah, well some real over kill on my part then - but knowing how to work with the boundField property at runtime can have its advantages.

IIRC, you can not get to the MySQL table column descriptions at least not with this property. It would be nice if you could. Maybe there is a way, I’ll ponder that a bit.

One method to get MySQL field comments is through Information Schema:

SELECT column_name, column_comment
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name='YOUR_TABLE_NAME'

This will get you all columns with their comments for a particular table.

+1. Thanks! Also added a trailing ’ (single quote) on comment lines to work around bug in Ask.Libreoffice.org which diesplay’s comments wrong, so your code displays a bit better at this web site.