You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openoffice.apache.org by fabian <fm...@netempire.de> on 2012/01/23 09:51:27 UTC

[EXT] disable/enable toolbar functions

Hi, 

I am trying to disable/enable toolbar buttons in my java oo-extension. I managed to use the addStatusListener method to use an additional dropdownbutton and know how to enable/disable buttons at startup. 
My problem is that I can't safe a reference to com.sun.star.frame.XStatusListener xControl to enable/disable a button at wish, since the reference is set back to null after xControl.statusChanged() was called. 
But looking at the c++ example of the SDK,  keeping a copy of xControl is what I have to do to recall statusChanged.

Can someone point me to the solution?
Thanks!

best,
Fabian 





Re: [EXT] disable/enable toolbar functions

Posted by fabian <fm...@netempire.de>.
Gruß
Fabian Hoffmann
Software-Entwickler

. Netempire AG | Lüghauser Straße 16 | D - 51503 Rösrath
. Fon: 0221 99 11 12 - 19 | Fax: 0221 99 11 12 - 99
. mailto:fmh@netempire.de | http://www.netempire.de
__________________________________________________________

. Vorstandsvorsitzender: Andreas Nettesheim
. Vorstand: Dr. Guido Gimmler | Johannes Krause
. Vorsitzender des Aufsichtsrates: Madjid Salimi

. Handelsregister: Amtsgericht Köln, HRB 35407
. USt-IdNr.: DE 215404683
__________________________________________________________





On Jan 31, 2012, at 1:37 PM, Ariel Constenla-Haile wrote:

> On Sun, Jan 29, 2012 at 06:04:44PM +0100, fabian wrote:
>> Right now I am trying to also disable the controls in the menubar but
>> I think there is a good example for that in the SDK
>> (DisableCommandsTest.java).
> 
> yes, this is disabling commands by configuration:
> http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Disable_Commands
> 
> If you want something more dynamic, the status of menu items is also
> controlled by dispatch objects, just like in the toolbar case.

>>> Right, that's what I actually want. Since my menu commands are named equally as my toolbar commands (in addons.xcu) I thought disabling a toolbar command will also disable the corresponding menu command but that wasn't the case.
>>> I did rename the menu commands to see if that way the addStatusListener method is called by them but that's not happening and therefore I have no listeners to disable the commands. I did expect it works the same as for the toolbar?
>>>  
>>> 
>> I would like to ask one more thing related to using an external
>> graphics library for dialogs. I am using Swing to build dialogs since
>> I need to build more complex dialogs than possible with UNO/AWT. Since
>> I am working on a mac I got to learn pretty fast that I have to run
>> AWT/Swing in its own Thread in order to avoid the error: "Apple AWT
>> Java VM was loaded on first thread -- can't start AWT."
>> 
>> Naturally this causes that OpenOffice is still accessible while the
>> dialog pops up. So the question is, is there anything like putting
>> OpenOffice to sleep while a dialog is open?
> 
> I know nothing about MacOS, I'm a Linux user, and I develop on that
> platform. Though I know there is an issue:
> https://issues.apache.org/ooo/show_bug.cgi?id=92926
> This is CLOSED FIXED, but according to
> https://issues.apache.org/ooo/show_bug.cgi?id=92926#c51 the fix applied
> only solves the issue with beanshell and javascript with AOO, not the
> problem itself:
> http://hg.services.openoffice.org/OOO340/rev/43bea9e7a54b
> Look at that code, see if you can apply the same approach in your
> extension. If it does not work, then the issue should be reopened.
>>> I I read that thread when I faced the problem the first time and from it I know that I need to run AWT/Swing in its own thread. But the javascript code might teach me how to deal with the main office thread while my awt thread is running.
> 

Regards,
Fabian


Re: [EXT] disable/enable toolbar functions

Posted by Ariel Constenla-Haile <ar...@apache.org>.
On Sun, Jan 29, 2012 at 06:04:44PM +0100, fabian wrote:
> Right now I am trying to also disable the controls in the menubar but
> I think there is a good example for that in the SDK
> (DisableCommandsTest.java).

yes, this is disabling commands by configuration:
http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Disable_Commands

If you want something more dynamic, the status of menu items is also
controlled by dispatch objects, just like in the toolbar case.


> I would like to ask one more thing related to using an external
> graphics library for dialogs. I am using Swing to build dialogs since
> I need to build more complex dialogs than possible with UNO/AWT. Since
> I am working on a mac I got to learn pretty fast that I have to run
> AWT/Swing in its own Thread in order to avoid the error: "Apple AWT
> Java VM was loaded on first thread -- can't start AWT."
> 
> Naturally this causes that OpenOffice is still accessible while the
> dialog pops up. So the question is, is there anything like putting
> OpenOffice to sleep while a dialog is open?

I know nothing about MacOS, I'm a Linux user, and I develop on that
platform. Though I know there is an issue:
https://issues.apache.org/ooo/show_bug.cgi?id=92926
This is CLOSED FIXED, but according to
https://issues.apache.org/ooo/show_bug.cgi?id=92926#c51 the fix applied
only solves the issue with beanshell and javascript with AOO, not the
problem itself:
http://hg.services.openoffice.org/OOO340/rev/43bea9e7a54b
Look at that code, see if you can apply the same approach in your
extension. If it does not work, then the issue should be reopened.


Regards
-- 
Ariel Constenla-Haile
La Plata, Argentina

Re: [EXT] disable/enable toolbar functions

Posted by fabian <fm...@netempire.de>.
Hi Ariel,

thx again for the example, it gave me a way better understanding for the concept of listeners and dispatch objects.

In my case I used only a base dispatch class (as created by netbeans) and an instance of it, for each control command. All I actually needed yet was a listener helper with correct synchronization and a static map/list combo to store the listeners. 

Right now I am trying to also disable the controls in the menubar but  I think there is a good example for that in the SDK (DisableCommandsTest.java).

I would like to ask one more thing related to using an external graphics library for dialogs. I am using Swing to build dialogs since I need to build more complex dialogs than possible with UNO/AWT. Since I am working on a mac I got to learn pretty fast that I have to run AWT/Swing in its own Thread in order to avoid the error:
"Apple AWT Java VM was loaded on first thread -- can't start AWT."

Naturally this causes that OpenOffice is still accessible while the dialog pops up. So the question is, is there anything like putting OpenOffice to sleep while a dialog is open?

best,
Fabian 


On Jan 26, 2012, at 5:29 PM, fabian wrote:

> Hi Ariel,
> 
> wow thx for the java example, I appreciate it very much!  I will go through it and figure out what I am doing wrong. 
> 
> best,
> Fabian
> 
> On Jan 26, 2012, at 2:56 PM, Ariel Constenla-Haile wrote:
> 
>> Hi Fabian,
>> 
>> On Tue, Jan 24, 2012 at 10:04:35PM -0300, Ariel Constenla-Haile wrote:
>>> It looks as if you had some issues translating the code from C++ to
>>> Java, on the other hand the C++ has some issues if you want to implement
>>> it in a real-world use case (where you send status updates according to
>>> the current selection, etc).
>>> I see if I can write some simple example, real-world oriented.
>> 
>> 
>> See http://people.apache.org/~arielch/api/ShapeComplexToolbarControl/
>> 
>> In a lack of imagination, I took the dummy shape example. The extensions
>> add a toolbar in Writer with two edit fields, displaying the Title and
>> Description of the currently selected shape. Of course, when no shape is
>> selected in the current view, the controls are disabled.
>> 
>> Notice that I wrote it fast and without much testing, so be warned.
>> 
>> This is a complex subject, so the better way to understand it is to
>> select "Debug Extension in Target OpenOffice.org" inside NetBeans, set
>> break point on the ProtocolHandler implementation, and start debugging
>> specially from queryDispatch().
>> 
>> 
>> Regards
>> -- 
>> Ariel Constenla-Haile
>> La Plata, Argentina
> 


Re: [EXT] disable/enable toolbar functions

Posted by fabian <fm...@netempire.de>.
Hi Ariel,

wow thx for the java example, I appreciate it very much!  I will go through it and figure out what I am doing wrong. 

best,
Fabian

On Jan 26, 2012, at 2:56 PM, Ariel Constenla-Haile wrote:

> Hi Fabian,
> 
> On Tue, Jan 24, 2012 at 10:04:35PM -0300, Ariel Constenla-Haile wrote:
>> It looks as if you had some issues translating the code from C++ to
>> Java, on the other hand the C++ has some issues if you want to implement
>> it in a real-world use case (where you send status updates according to
>> the current selection, etc).
>> I see if I can write some simple example, real-world oriented.
> 
> 
> See http://people.apache.org/~arielch/api/ShapeComplexToolbarControl/
> 
> In a lack of imagination, I took the dummy shape example. The extensions
> add a toolbar in Writer with two edit fields, displaying the Title and
> Description of the currently selected shape. Of course, when no shape is
> selected in the current view, the controls are disabled.
> 
> Notice that I wrote it fast and without much testing, so be warned.
> 
> This is a complex subject, so the better way to understand it is to
> select "Debug Extension in Target OpenOffice.org" inside NetBeans, set
> break point on the ProtocolHandler implementation, and start debugging
> specially from queryDispatch().
> 
> 
> Regards
> -- 
> Ariel Constenla-Haile
> La Plata, Argentina


Re: [EXT] disable/enable toolbar functions

Posted by Ariel Constenla-Haile <ar...@apache.org>.
Hi Fabian,

On Tue, Jan 24, 2012 at 10:04:35PM -0300, Ariel Constenla-Haile wrote:
> It looks as if you had some issues translating the code from C++ to
> Java, on the other hand the C++ has some issues if you want to implement
> it in a real-world use case (where you send status updates according to
> the current selection, etc).
> I see if I can write some simple example, real-world oriented.
 

See http://people.apache.org/~arielch/api/ShapeComplexToolbarControl/

In a lack of imagination, I took the dummy shape example. The extensions
add a toolbar in Writer with two edit fields, displaying the Title and
Description of the currently selected shape. Of course, when no shape is
selected in the current view, the controls are disabled.

Notice that I wrote it fast and without much testing, so be warned.

This is a complex subject, so the better way to understand it is to
select "Debug Extension in Target OpenOffice.org" inside NetBeans, set
break point on the ProtocolHandler implementation, and start debugging
specially from queryDispatch().


Regards
-- 
Ariel Constenla-Haile
La Plata, Argentina

Re: [EXT] disable/enable toolbar functions

Posted by Ariel Constenla-Haile <ar...@apache.org>.
Hi Fabian,

On Wed, Jan 25, 2012 at 12:51:39AM +0100, fabian wrote:
> Hi Ariel,
> 
> thanks again for helping me out!
> 
> I did what you described and tried to adapt the cpp example.  my
> extended toolbar has 3 controls (ImageButtons):  control1, control2,
> control3 Each  registers at startup by calling addStatusListener(
> aURL, aListener). 
> 
> Don't I need to put each of these listeners in a collection to be
> later able to send a event to the according control?

that's what I meant. When the control wants to register itself as
a status listener, add it to a collection and send it an status update.
When the listener wants to stop listening for updates, remove it from
the collection.

addStatusListener -> add it to the collection and send an status update
to this control

removeStatusListener -> remove it from the collection


Then, when you need to update the feature state, you have to loop
through the listeners collection and send an statusChanged to each
element in the collection.


> I am only able to safe a reference to the XStatusListener which was
> provided by the last call of addStatusListener(). I don't seem to
> understand why I can't keep a reference to the XStatusListeners of the

do you mean by holding a reference in a member variable?
This is not possible, among other reasons, because it violates the
notion of a listener that adds and *removes* itself at will. Besides,
several listener can register themselves, so you need a collection.


> previous calls of addStatusListener() ( has each control its own
> thread and the calls happen in parallel ?) If I do something like
> Collection.put(xController) each time addStatusListener is called, the
> collection will only contain one element in the end.

this shouldn't be the case. It looks like an issue with your collection.
Depending on how you implemented the XDispatchProvider you may need to
implement a simple listeners container or a complex map of URL-key with
listeners-contaniner-value.


> What I try then is to click on controll1 in my toolbar. This triggers
> in the dispatch method the code above to disable control2. But instead
> of control2 I can only use the XStatusListener of the last call of
> addStatusListener().
> 
> As a result control1 gets disabled instead control2 as I would expect.

It seems you are using the same dispatch object instance for different
commands, if so, you need a map collection:

key        value
control1 - listeners collection
control2 - listeners collection
control3 - listeners collection

The key is a string, representing the URL.Complete or URL.Path.
Something similar is done in the C++ example.

When you want to update the status of control2, you get the listeners
collection from the map and send an statusChanged to each listener in
it.

> So to me it seems that my problem is that I can't keep the references
> to the according XStatusListener.
> 
> I hope this wasn't too confusing and makes any sense to you, thanks
> again for the help!

It looks as if you had some issues translating the code from C++ to
Java, on the other hand the C++ has some issues if you want to implement
it in a real-world use case (where you send status updates according to
the current selection, etc).
I see if I can write some simple example, real-world oriented.


Regards
-- 
Ariel Constenla-Haile
La Plata, Argentina

Re: [EXT] disable/enable toolbar functions

Posted by fabian <fm...@netempire.de>.
Hi Ariel,

thanks again for helping me out!

I did what you described and tried to adapt the cpp example.
my extended toolbar has 3 controls (ImageButtons):  control1, control2, control3
Each  registers at startup by calling addStatusListener( aURL, aListener). 

Don't I need to put each of these listeners in a collection to be later able to send a event to the according control?

like e.g. 

 com.sun.star.util.URL mURL = new com.sun.star.util.URL();
                    mURL.Path = "control2";
                    mURL.Protocol  = "de.addon.addonstarter:";
                    buttonEditEPorto.Complete = "de.addon.addonstarter:control2";
                    FeatureStateEvent fsStateEvent = new FeatureStateEvent();
                    fsStateEvent.FeatureURL = mURL;
                    fsStateEvent.Source = this;    // is called from within dispatch Method
                    fsStateEvent.IsEnabled = controlEnabled;   // controlEnabled = false or true
                    fsStateEvent.Requery = false;

control2.statusChanged(fsStatusEvent);  

I am only able to safe a reference to the XStatusListener which was provided by the last call of addStatusListener(). I don't seem to understand why I can't keep a reference to the XStatusListeners of the previous calls of addStatusListener() ( has each control its own thread and the calls happen in parallel ?) 
If I do something like Collection.put(xController) each time addStatusListener is called, the collection will only contain one element in the end.

What I try then is to click on controll1 in my toolbar. This triggers in the dispatch method the code above to disable control2. But instead of control2 I can only use the XStatusListener of the last call of addStatusListener().

As a result control1 gets disabled instead control2 as I would expect.

So to me it seems that my problem is that I can't keep the references to the according XStatusListener.

I hope this wasn't too confusing and makes any sense to you,
thanks again for the help!

regards,
Fabian


On Jan 23, 2012, at 9:26 PM, Ariel Constenla-Haile wrote:

> Hi Fabian,
> 
> On Mon, Jan 23, 2012 at 09:51:27AM +0100, fabian wrote:
>> Hi, 
>> 
>> I am trying to disable/enable toolbar buttons in my java oo-extension.
> 
> I guess you're using the so called "Complex Toolbar Controls" feature,
> aren't you?
> 
>> I managed to use the addStatusListener method to use an additional
>> dropdownbutton and know how to enable/disable buttons at startup.  My
>> problem is that I can't safe a reference to
>> com.sun.star.frame.XStatusListener xControl to enable/disable a button
>> at wish, since the reference is set back to null after
>> xControl.statusChanged() was called.  But looking at the c++ example
>> of the SDK,  keeping a copy of xControl is what I have to do to recall
>> statusChanged.
>> 
>> Can someone point me to the solution?  Thanks!
> 
> The toolbar control registers itself as listener at the Dispatch object
> you return in queryDispatch in order to get status updates. This is done
> in the Dispatch object's addStatusListener().
> 
> Your Dispatch object should have a collection of listeners:
> 
> * when addStatusListener() is invoked, the Dispatch object should:
>  * add the listener (the toolbar control) to the collection
>  * send to this listener an status update invoking the listener's
>    statusChanges() method
> 
> * when removeStatusListener() is invoked, the Dispatch object should
>  remove the listener from the collection
> 
> 
> To Enable/Disable a toolbar control is simply sending it a 
> FeatureStateEvent with IsEnabled set to false.
> 
> 
> Now let's suppose that your toolbar control provides functionality for
> drawing shapes; so you want it enabled only when a shape is selected.
> You will have to implement an XSelectionChangeListener that, when the
> selection changes:
> 
> * if the selected object is a drawing shape, send a feature update to
>  all the status listeners in the collection that were registered for
>  the command URL. Here FeatureStateEvent.IsEnabled = true
> 
> * if the selected object is not a drawing shape, then you want to
>  disable your toolbar control; just send an status update to all the
>  status listeners in the collection with IsEnable set to false.
> 
> In general this is how context-sensitivity is implemented by sending
> status updates to the user interface element, then the UI element
> updates its representation to reflect the feature state.
> 
> 
> Regards
> -- 
> Ariel Constenla-Haile
> La Plata, Argentina


Re: [EXT] disable/enable toolbar functions

Posted by Ariel Constenla-Haile <ar...@apache.org>.
Hi Fabian,

On Mon, Jan 23, 2012 at 09:51:27AM +0100, fabian wrote:
> Hi, 
> 
> I am trying to disable/enable toolbar buttons in my java oo-extension.

I guess you're using the so called "Complex Toolbar Controls" feature,
aren't you?

> I managed to use the addStatusListener method to use an additional
> dropdownbutton and know how to enable/disable buttons at startup.  My
> problem is that I can't safe a reference to
> com.sun.star.frame.XStatusListener xControl to enable/disable a button
> at wish, since the reference is set back to null after
> xControl.statusChanged() was called.  But looking at the c++ example
> of the SDK,  keeping a copy of xControl is what I have to do to recall
> statusChanged.
> 
> Can someone point me to the solution?  Thanks!

The toolbar control registers itself as listener at the Dispatch object
you return in queryDispatch in order to get status updates. This is done
in the Dispatch object's addStatusListener().

Your Dispatch object should have a collection of listeners:

* when addStatusListener() is invoked, the Dispatch object should:
  * add the listener (the toolbar control) to the collection
  * send to this listener an status update invoking the listener's
    statusChanges() method

* when removeStatusListener() is invoked, the Dispatch object should
  remove the listener from the collection


To Enable/Disable a toolbar control is simply sending it a 
FeatureStateEvent with IsEnabled set to false.


Now let's suppose that your toolbar control provides functionality for
drawing shapes; so you want it enabled only when a shape is selected.
You will have to implement an XSelectionChangeListener that, when the
selection changes:

* if the selected object is a drawing shape, send a feature update to
  all the status listeners in the collection that were registered for
  the command URL. Here FeatureStateEvent.IsEnabled = true

* if the selected object is not a drawing shape, then you want to
  disable your toolbar control; just send an status update to all the
  status listeners in the collection with IsEnable set to false.

In general this is how context-sensitivity is implemented by sending
status updates to the user interface element, then the UI element
updates its representation to reflect the feature state.


Regards
-- 
Ariel Constenla-Haile
La Plata, Argentina