[Solved] Having problems with hasFocus()

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
UnklDonald418
Volunteer
Posts: 1544
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

[Solved] Having problems with hasFocus()

Post by UnklDonald418 »

While doing data entry on a Base Form Grid I have a macro that is invoked by a key press. For it to do its task I need to determine whether MainForm_Grid or a SubForm_Grid on the Base Form has the active cursor. I thought maybe the function hasFocus() would provide the answer. The Developers Guide says:
boolean
hasFocus();
Description
returns the focus state of the window
from
http://www.openoffice.org/api/docs/comm ... l#hasFocus

I wrote the following test macro which when bound to a key press (Tools->Customize->Keyboard) displays the names of the form/subform where hasFocus() returns TRUE. The problem I am having is that it works as long as I select an entire row on a form/subform grid, but if I only select a single cell on a grid, which is where I need it, hasFocus() always returns FALSE.

Code: Select all

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

Sub CheckFocus()
Dim oDoc as object
Dim fname as string
oDoc = ThisComponent.DrawPage.Forms
fname = FocusNameListRec(oDoc)
print fname
end Sub



REM =============================================

function FocusNameListRec(oDoc as object) as string 

DIM  oForm as object, oController as object, oGridControlView as object, oGCMP as object 
Dim fName as string
Dim i as integer, j as integer, n as integer 
' Globalscope.BasicLibraries.LoadLibrary( "MRILib" )
' oMRI = CreateUnoService( "mytools.Mri" )

oController = ThisComponent.CurrentController
FocusNameListRec = "Not Found" 
n = oDoc.Count  'get number of elements on the form
For i=0 to n-1    'i = element counter
  If  oDoc.hasElements()  then
      oForm  = oDoc.getByIndex(i)
      if oForm.ServiceName = "stardiv.one.form.component.Form" then
          fName = FocusNameListRec(oForm)
          if fName <> "Not Found" then
             FocusNameListRec = fName  'get return name
          end if
      else
        if  oForm.ServiceName = "stardiv.one.form.component.Grid"  then
           oGridControlView = oController.GetControl(oForm)
          if oGridControlView.hasFocus() then   ' isActive()  then
'             print "Control has Focus"
             oGCMP = oGridControlView.Model.Parent
             fName = ""       
             do
               fName = oGCMP.getName() + " : " + fName 
'               fName = oGCMP.getName() + Chr$(10) + fName
               oGCMP = oGCMP.Parent
               test = oGCMP.ServiceName            
             loop Until test <> "stardiv.one.form.component.Form"
             fName = left(fName,Len(fName)-3)
             FocusNameListRec = fName     
          end if
          if oGridControlView.Context.hasFocus() then  
             print "Context has Focus"
             fName = oGridControlView.Model.Parent.getName()
          end if
       end if 
      end if 
  end if          
next i
end function    'FocusNameListRec
I did find a page at
https://wiki.openoffice.org/wiki/Framew ... Tookit_API
which I don't fully understand but it makes me wonder if perhaps hasFocus() hasn't been fully implemented.

Anyway, does anyone have any advice on how I might solve this problem?
Last edited by RoryOF on Sun Feb 21, 2016 9:31 pm, edited 2 times in total.
Reason: Added green tick [RoryOF, Moderator]
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Having problems with hasFocus()

Post by RPG »

Hello
UnklDonald418 wrote:While doing data entry on a Base Form Grid I have a macro that is invoked by a key press.
I think this give you the focus. Be aware , as far I understand, a control in a grid does never get focus. The grid control can have the focus. You can play with an event of the grid-control or with a control in a grid. It is possible that LibreOffice does have other and more events then AOO.

For the view of the grid control
We have selection and this is for the row in the dataform.
we have the get- set-CurrentColumnPosition what is for the column in the grid for input

for the model of the gridcontrol
We have selection and this is for the selected columns in the gridcontrol. As far I remember it does not work with a number but with something else.

Code: Select all

sub Moveingrid(oEvent)
dim oGrid
oGrid=oEvent.source
oGrid.setCurrentColumnPosition(oGrid.getCurrentColumnPosition+1)
end sub
Romke
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
UnklDonald418
Volunteer
Posts: 1544
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Having problems with hasFocus()

Post by UnklDonald418 »

Thanks Romke for your response. I am investigating your suggestion.

It just seems odd that selecting the entire row has Focus, but not a single grid element which also knows the row. I noticed that selecting an entire column sometimes has Focus.
For the XFocusListener to work oO must internally keep track of which grid element has Focus, but apparently the programmers decided not to share that information with the outside world.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Having problems with hasFocus()

Post by RPG »

Hello
UnklDonald418 wrote:but apparently the programmers decided not to share that information with the outside world.
I think this is not true.

The view of the grid export a service what export: CurrentColumnPosition.

When you want work with the API and want write macro's then you really need to understand the service with which you want work. I think the programming language is not so important.

The complete Grid control can have the focus. When you select rows or columns or a single cell then the complete grid does have the focus and in an other way you have to discover what you want do.

I do really not understand the reason of this thread. You start a macro with an event. It start with a key press. Then you have the control what does have focus!

Romke
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Having problems with hasFocus()

Post by RPG »

Hello

I have now done some test on a control in a grid control. A textbox does have the methode setFocus but not hasfocus. I did not remember it. But it make also clear it is not possible to remember all things of all object. It is better to have an idea how it works.

https://www.openoffice.org/api/docs/com ... indow.html

https://www.openoffice.org/api/docs/com ... XGrid.html


Romke
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
UnklDonald418
Volunteer
Posts: 1544
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Having problems with hasFocus()

Post by UnklDonald418 »

Thanks again Romke
Yes, if I had an event on that control to tie to then finding the control would be easy.
You start a macro with an event.
If I run the macro Moveingrid from for example Ctrl-X ( a Key press) it generates an error message “Message: wrong number of parameters!”. It appears Key press does not trigger an Event.

My comments relate to the fact that if I select a row on a grid control that control hasFocus, but if I select a grid element from that same row the control appears to lose focus. Perhaps the problem is with my understanding of the definition of Focus. I've not found anywhere in the Developers Guide where it actually defines Focus.

If I attach a simple macro

Code: Select all

REM  ***Basic***
sub LosingFocus(oEvent)

'print "losing Focus"

end Sub
to “Control->Event->When losing focus” each time I move to a different different cell the macro runs despite the fact that
A textbox does have the methode setFocus but not hasfocus.
So, the grid cell can lose focus but doesn't support hasFocus. Where is the logic?
you really need to understand the service with which you want work.
Apparently, I don't understand, which is the reason I posted the question.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Having problems with hasFocus()

Post by RPG »

Hello

MoveIngrid
When you want use that macro then bind it to the grid control and to an event what give the view of the grid and not the model of the grid.

All parts of a form do have view of the control and a model of the control. When you have a understanding of the difference between the view and the model then it is more easy to understand the code but still real difficult.

I think built up your form in a way that you do not need macros. I think it is also good to spent your study time to SQL and forms and controls.

When you select a row in a grid control then you want some thing knew of the row, more the complete record. You can get a value what is a record number or bookmark. I think the gridcontrol does have the focus when you select the row. I do not know the real answer there I never use the combination hasfocus and selecting a row. The same is true for selecting a column in a gridcontrol.

You can bind events to the controls in a gridcontrol. A gridcontrol does contain other control. Be aware that controls in a gridcontrol are not the same as controls in a form.

When I start with macros I did study all the things exported by an event. Now you can do it with MRI or Xray. I did also learn which services and interfaces are exported by the event. I did learn which method or property belongs to which interfaces. Be aware you have to study hundreds of line and have to discover what means all the combinations. There is nearly no explanation. This means you have to understand how OOo- forms are working.

The logic
The logic comes clear when you understand the normal working of forms and all the properties of the control which can be set in design mode. When you can bring that in combination with the macros then slowly the logic comes clear.

When you cannot stop then see here. It is pointing to the Base tutorials and examples. I have placed there examples with macros but there are also other real good examples to study.

Romke
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
UnklDonald418
Volunteer
Posts: 1544
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Having problems with hasFocus()

Post by UnklDonald418 »

Romke, thanks for your response.
I have a working macro (actually, a few months ago you supplied the bones as CopyFieldAbove). That macro works fine on a simple form with a single grid, but when there are multiple grids it needs to know which one to use. Currently I have two working versions, in one a majority of the code is spent on locating and building an array of available grid controls and then setting up a dialog to ask the user which one to use. I was hoping that hasFocus() would be able to supply the information needed to eliminate the dialog. That was the ultimate goal of the test macro I posted with my question here. Since the function hasFocus() doesn't work when I need it I'll have to look at alternatives.

The other version I have been testing uses the following:

Code: Select all

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

Global oFocusdGrid as object
Global FocFormName as string

sub FindFocusdgrid(oEvent)
dim oGrid
dim stest as string

oGrid=oEvent.source
stest = oGrid.model.parent.getName()

if stest = FocFormName  then 
  exit sub
else
   oFocusdGrid = oGrid
   FocFormName = oFocusdGrid.model.parent.getName()
end if
'  print FocFormName    
end sub
The advantage is that it does eliminate much of the code devoted to building and processing a dialog. The drawback is that before I can use this macro I have to bind it to “Control->Event->When receiving focus” for each grid control on a form.

I suppose the next step will be to look for a way to eliminate the need to modify the Control->Properties for each form grid before it can be used.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: [Solved] Having problems with hasFocus()

Post by RPG »

Hello

I think it must be real easy to it with the macro I did give.
The original macro can work with one button if the grid are in the same data-form as you see in the form navigator. When the two grids are not in the same data-form then you need a button for each data-form.

When you work with the event get focus bound to a control in a grid-control then you have to modify the macro. But you have only to modify a little of the macro not the real body.

I think the event from getfocus give:
oEvent.source.model.parent.parent 'Give you the formmodel
I think you can delete or out comment the parts for the button.

I have not test the it. I have installed a new version of openSUSE with a new version of LibreOffice and that does not work good.

Romke
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: [Solved] Having problems with hasFocus()

Post by RPG »

Hello

I think the code I did give in the post just before can not work. The original macro is jumping between record and it will fire much more event then you want. It give also a problem with your idea.

Romke
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: [Solved] Having problems with hasFocus()

Post by RPG »

Hello

What is the best solutions is always a choice. In this case I think working with focus is not such a good idea but it is possible other people do have a good solution. I now have a solution with a keyreleased event. This is bind to a gridcontrol.
This event returns a keyevent
https://www.openoffice.org/api/docs/com ... Event.html
We need only a little modifications of the original code and it works. It is real well possible that there other methods to do the same even maybe better methods. I have not test it a lot.

Romke

Code: Select all

Sub CopyFieldabove(oEvent)
' We get an event from the gridcontrol.
' The event is: keyreleased
' First we drill up from the event to the form-model and the form view
dim oKeyreleased
oKeyreleased=oEvent
if oKeyreleased.KeyChar="c" and oKeyreleased.KeyFunc=9 then
	' Do it only with Control-C
	
	dim oformmodel2
	dim oFormView2
	dim sValue
	dim oControlViewwewantchange
	dim Operation as object
	dim oSelection
	Operation =com.sun.star.form.runtime.FormFeature
	
	
	oformmodel2=oEvent.source.model.parent 
	
	' Be aware that a textbox in a gridcontrol is not the same as a stand alone textbox.
	' This works for a text I Have it not test for big text and also a lot.
	
	
	oFormView2=thiscomponent.getcurrentcontroller.getformcontroller(oFormmodel2) ' We have now the form controller
	if  oFormView2.FormOperations.isEnabled(Operation.MoveToFirst) then
	' We are not on the first record
	'Now we drill down from the form view to the currentcontrol.
	'We do also test: if it is a gridcontrol.
	   ' Test for the good control we need special for a grid
	   oControlViewwewantchange=oFormView2.currentcontrol
	   if oControlViewwewantchange.implementationname= "com.sun.star.comp.dbu.SbaXGridControl" then
	      oControlViewwewantchange=oControlViewwewantchange.getbyindex(oControlViewwewantchange.currentcolumnposition)
	   end if
	
	   if  hasunointerfaces(oControlViewwewantchange.model,"com.sun.star.form.XBoundComponent") then
	   ' Now we have the control    and we know it does has a bound field
	      oSelection=oControlViewwewantchange.getselection ' Store the selection
	      'oFormView2.FormOperations.execute(Operation.SaveRecordChanges) '
	      oFormView2.FormOperations.execute(Operation.MoveToPrevious) 'Move to previous record
	      sValue=oControlViewwewantchange.model.boundfield.getstring ' Take the value
	      oFormView2.FormOperations.execute(Operation.MoveToNext) 'Move to Next record
	
	      oControlViewwewantchange.setselection(oSelection) ' Set the selection again
	      oControlViewwewantchange.insertText(oSelection,sValue) ' Bring in the value
	      oSelection=oControlViewwewantchange.getselection 'Get the new selection
	      oControlViewwewantchange.model.text=oControlViewwewantchange.gettext  ' This is also real strange we need it
	      oControlViewwewantchange.model.commit ' Strange we need it
	      oFormView2.FormOperations.execute(Operation.SaveRecordChanges)
	      oControlViewwewantchange.setSelection(oSelection)
	   else Print "We cannot work on this control"
	   end if
	end if
end if
end sub
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
Post Reply