OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

Determine which button fired an event

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API
View previous topic :: View next topic  
Author Message
Laird
Guest





PostPosted: Wed Dec 03, 2003 7:12 am    Post subject: Determine which button fired an event Reply with quote

Hi,

I'm new to OOo macros, although I am a long-time programmer.

How do I determine from within an event, which button caused that event to fire? I have several buttons in a spreadsheet, some on the same sheet, others in different sheets, all with a mouseup event set to the same event. I want the event to operate on different cells depending on which button was pressed. It isn't going to be good enough to have different events because some of the buttons are going to be created dynamically and I'm not going to even venture into the territory of trying to create dynamic events...

Thanks,
Laird
Back to top
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Wed Dec 03, 2003 8:27 am    Post subject: Reply with quote

See this thread....

http://www.oooforum.org/forum/viewtopic.php?t=3130

The thread talks about creating CheckBox controls on the fly, and assigning event listeners to them. You can create one event listener and assign it to multiple controls. From within the event listener, determine which control created the event.

I am not talking about the "events" that you can assign in the user interface by picking Tools --> Configure.

Hope this helps.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Laird
General User
General User


Joined: 03 Dec 2003
Posts: 9

PostPosted: Wed Dec 03, 2003 9:27 am    Post subject: Reply with quote

Thanks, that's given me a start.

Now I can determine the name of the button. The problem is that the buttons on different worksheets could have the same name. I would like to know the name of the worksheet that the button comes from as well as the button's name. I have the following test code:

sub HandlerAddRows(oEvent)
msgbox(oEvent.Source.getModel().Name)
msgbox(oEvent.Source.getModel().Parent.Name)
msgbox(oEvent.ActionCommand)
end sub

The first msgbox prints the name of the button. The second one prints 'Standard' - I was hoping it would print the worksheet name. The third one, surprisingly, gives an error:
'BASIC Runtime Error. Property or method not found.' Why is this?

I have a second problem. I would like to use the same handler to check whether the user pressed enter or space when the button was focussed. I can hook the key pressed handler, but how do I tell which key was pressed?

The documentation for macros seems to be very disjointed - and the object model doesn't seem to be very fully documented either. It's a bit frustrating.

Thanks,
Laird
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Wed Dec 03, 2003 11:24 am    Post subject: Reply with quote

Laird wrote:
Now I can determine the name of the button. The problem is that the buttons on different worksheets could have the same name. I would like to know the name of the worksheet that the button comes from as well as the button's name. I have the following test code:


From the oEvent parameter, you can get the Source, that is the object which is the source of the event. This is the control obejct itself. From there, you can call getModel(), and then examine the Name property to see the control model's name -- but it is not necessary to do this.

From the control object, before getting the model, it should be possible to find which form this control is in, and then from the form discover the sheet. It is probably just a few function calls and dots, but I am not an expert on Calc. A quick look in the developer's guide reveals that each sheet has its own single DrawPage. From the chapter on Forms, the forms are on the DrawPage.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Wed Dec 03, 2003 12:00 pm    Post subject: Reply with quote

Looking at the API, I would say that it seems that if you get the control Model, then you should be able to get to the form, and then to the drawpage.

From the control, we do

oControlModel = oEvent.Source.getModel()

Now looking in the Developer's Guide....
http://api.openoffice.org/docs/DevelopersGuide/Forms/Forms.htm#1+3+2+Control+Models+and+Shapes

It seems from the diagram that we can get from the control model to the draw page.

The control model is a com.sun.star.form.FormControlModel, as illustrated.

This service is documented here.
http://api.openoffice.org/docs/common/ref/com/sun/star/form/FormControlModel.html

From there we can see that any FormControlModel is also a FormComponent, which is documented here.
http://api.openoffice.org/docs/common/ref/com/sun/star/form/FormComponent.html

Every FormComponent, as can be seen by the previous link, has the XFormComponent interface, which is described here...
http://api.openoffice.org/docs/common/ref/com/sun/star/form/XFormComponent.html

XFormComponent interface inherits from the XChild interface described here...
http://api.openoffice.org/docs/common/ref/com/sun/star/container/XChild.html

which has the getParent() method.
http://api.openoffice.org/docs/common/ref/com/sun/star/container/XChild.html#getParent

So if you are still with me, surfing the api docs, we should from the control model be able to call getParent() to get us the form.

oForm = oControlModel.getParent()

The XFormComponent interface said to See Also: XForm, which is here...
http://api.openoffice.org/docs/common/ref/com/sun/star/form/XForm.html

So the returned form is an XForm. You can see that it also conveniently inherits from XChild (which is its grandparent interface). So you can call getParent again.

oForms = oForm.getParent()

So now we have the form collection that was shown in the illustration on the developer's guide. From the Forms, we have to get to the DrawPage. (The chapter on Spreadsheets says that every sheet has its own DrawPage, but I won't go into that.)

Note that the Forms service
http://api.openoffice.org/docs/common/ref/com/sun/star/form/Forms.html

includes the FormComponents service
http://api.openoffice.org/docs/common/ref/com/sun/star/form/FormComponents.html

I am not seeing a way to move from Forms to the DrawPage. From the DrawPage you can just call getForms() to get the Forms. Every sheet has one drawpage. Every drawpage has one Forms. So let's try this....

For each sheet on the document, get it's drawpage. Then call getForms, and see if the forms object returned is the same as oForms that you get from the control above. You should now be able to identify which sheet the control was on.

Something roughly like...

Code:

oControlModel = oEvent.Source.getModel()
oForm = oControlModel.getParent()
oForms = oForm.getParent()

oSheets = oCalcDoc.getSheets()
For i = 0 to oSheets.getCount() - 1
   oSheet = oSheets.getByIndex( i )
   oDrawPage = oSheet.getDrawPage()
   oDPForms = oDrawPage.getForms()
   
   If EqualUnoObjects( oForms, oDPForms ) Then
      ... we've found the forms collection,
      ... therefore, the drawpage,
      ... therefore which sheet the oForm was on.
   EndIf
Next


I have not tested this. I am just surfing through the API links (as shown above) and making it up as I go along, as usual.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Laird
General User
General User


Joined: 03 Dec 2003
Posts: 9

PostPosted: Wed Dec 03, 2003 9:49 pm    Post subject: Thanks Reply with quote

Thanks DannyB, much appreciated.

I understand the documentation a little better now, although I still think it could be done a lot better, but anyway I gotta work with it the way it is.

Your code worked a treat.

Cheers,
Laird
Back to top
View user's profile Send private message
Laird
General User
General User


Joined: 03 Dec 2003
Posts: 9

PostPosted: Thu Dec 04, 2003 2:02 am    Post subject: More problems Reply with quote

OK I'm having more problems now.

I have a dialog, and it has several Numeric fields on it. Each field has assigned to its on text changed event the event handler 'sub HandlerDlg(oEvent)'. Now I want from within this handler to (1) determine which field triggered it and (2) be able to access and change the values of the other fields.

I manage (1) with the line: if oEvent.Source.getModel().Name = "[Control Name]" then
and (2) I thought I could manage with the code you showed me, so I tried these lines:
oControlModel = oEvent.Source.getModel()
oForm = oControlModel.getParent()
Unfortunately I get an error saying Property or Method Not Found. I have tried again with the documentation, but to no avail.

In your post you state: "The control model is a com.sun.star.form.FormControlModel, as illustrated. " How did you know that the Event.Source.getModel() method would return this object? I've navigated the docs to death and I can't see it documented anywhere. For that matter, how do you even konw which Event structure is passed into the handler? There seem to be two, but I can't see the handlers documented anywhere.

Any help greatly appreciated - frustration is eating me away,
Laird
Back to top
View user's profile Send private message
DannyB
Moderator
Moderator


Joined: 02 Apr 2003
Posts: 3991
Location: Lawrence, Kansas, USA

PostPosted: Thu Dec 04, 2003 7:06 am    Post subject: Re: More problems Reply with quote

Laird wrote:
I have a dialog, and it has several Numeric fields on it. Each field has assigned to its on text changed event the event handler 'sub HandlerDlg(oEvent)'. Now I want from within this handler to (1) determine which field triggered it and (2) be able to access and change the values of the other fields.


Dialogs work somewhat differently than document forms.

If you look at Danny's Draw Power Tools (available from OOoMacros.org) you can find within it many dialog boxes. In the FlowerGears tool, in particular, there I enable/disable controls, get the value of text boxes, etc.

About the only thing I don't do in DDPT is to attach event listeners to any dialog box controls. If you do, when the event fires, it works like we've discussed previously. The event object parameter will contain the event. It's Source will have either the control, or the control's model -- I can't be sure which without testing or digging in the docs. (BTW, the Xray tool, available at OOoMacros.org, is invaluable to quickly answer questions like this.)

As I said, DDPT will show you examples of getting the values of other controls, numeric fields, or text boxes. Setting the values of controls is very similar.

From the event object's Source, you have the control or its model. (If given the control, then call getModel() to get the model.) From the control model you should be able to get the control's name, and know which control fired the event. Then alter the values of other controls.

DDPT also shows how to enable/disable controls in dialogs.


Laird wrote:

I manage (1) with the line: if oEvent.Source.getModel().Name = "[Control Name]"


It may be the case that the event from a dialog is giving you the control model already, so you couldn't call getModel() on it. I'm not sure as stated above.



Laird wrote:
I thought I could manage with the code you showed me, so I tried these lines:
oControlModel = oEvent.Source.getModel()
oForm = oControlModel.getParent()
Unfortunately I get an error saying Property or Method Not Found. I have tried again with the documentation, but to no avail.


Which line gives you the "Method not found"? If it is the call to getModel(), then you probably already have the model in the event source.

If it is the getParent(), then this is because the control model is not the model of a form component.

Dialog boxes work differently than forms.




Laird wrote:
In your post you state: "The control model is a com.sun.star.form.FormControlModel, as illustrated. " How did you know that the Event.Source.getModel() method would return this object?


The chapter on Forms discusses the View / Model paradigm. All controls have two parts:
1. the *control*, that is the widget you see on the screen
2. the *model*, the thing you manipulate within the program that is affected by, and affects the control (1).
The reason for this distinction, I'm sure, is NOT to make the API simpler, but to make porting to other platforms simpler. I'm sure that the Control is one object, and the Model is another object internally. The Control may be derrived from different internal classes, if they change the widgets, say to Qt widgets for KDE, for instance. But the model would remain the same. The internal separation of the control and model is simply brought out in the API, which was probably easier to implement than to make the API represent the control and model as a single object.

From a control you can call getModel() to get the model.

The answer to your question is that I looked at the diagram we linked above. Also, I have "surfed" around the Form controls enough to know that all of the form controls inherit from (or include?) a single service, and all form control models have a single common service FormControlModel.




Laird wrote:

I've navigated the docs to death and I can't see it documented anywhere. For that matter, how do you even konw which Event structure is passed into the handler? There seem to be two, but I can't see the handlers documented anywhere.

Any help greatly appreciated - frustration is eating me away,
Laird


Believe me, I've been there. Smile It is frustrating to be an experienced programmer, versed in many languages over many many years. Having even used punched cards! OOo is just complex. That complexity is overwhelming when you first approach it. There is just no other way to say it than that it is complex. On some level, I found that the complexity appealed to me. Complex systems of rules are what I seem to thrive on, rather than knowing how to interact with humans.

Earlier this year, I didn't know my way around. And I did not have all of the examples that I have posted here on OOoForum.

At some point, you just have to read the Developer's Guide and try to understand it. The DevGuide gives the "big picture". The online API gives the "microscopic" picture of individual services. The DevGuide shows a bird's eye view of how a document has multiple interfaces. How a document supports a variety of services, and then discusses the various aspects of a document. There are separate chapters on generic topics like Forms, Basic, Configuration Manager, and Universal Content Broker.

I remember how cryptic all of this seemed at first. In time, I managed to pick it up. If you go back through my posts you can clearly see where certian thigns were a mystery to me, and later I mastered them. At one point, I did not know how to print or save a document. Now I do. At one point, I did not know the configuration manager.

If you are persistent you'll get it.

I absolutely agree that the API docs could be done better. The automatic generator which generates that html from the IDL specification files should show you all of the methods and properties that are available on one single service. The Developer's Guide has improved steadily and continues to improve.
_________________
Want to make OOo Drawings like the colored flower design to the left?
Back to top
View user's profile Send private message
Laird
General User
General User


Joined: 03 Dec 2003
Posts: 9

PostPosted: Thu Dec 04, 2003 8:39 am    Post subject: Reply with quote

The solution to my problems was one word: 'object'.

I tried creating a private global variable to store my dialog in so I could access it through the event handlers, however I got errors whenever I tried to set it. This was because I had declared it: "private dlg as variant" instead of "private dlg as object". Your source code set me straight.

I still don't know how to access the dialog given one of its controls, which I would like to know how to do, but nevermind, I have enough to work it now.

You wrote:
---Start quote---
Which line gives you the "Method not found"? If it is the call to getModel(), then you probably already have the model in the event source.

If it is the getParent(), then this is because the control model is not the model of a form component.

Dialog boxes work differently than forms.
---End quote---

It was getParent(). No doubt there is an equivalent to get the dialog box from the control, but blow me down if I can work out what it is!

Thanks again,
Laird
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Macros and API All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group