| View previous topic :: View next topic |
| Author |
Message |
beiwen Guest
|
Posted: Mon Apr 05, 2004 12:02 am Post subject: Addin with GUI |
|
|
Hi,
I am trying to implement an add-in that adds functions to Calc and additionally adds a menu to the office bar, that can be used to call dialogs on the add-in. So far I was able to create a uno component that dows the GUI-stuff and an add-in to create the functions. However I don't know how to bring those two solutions together.
Any help is very much appreciated
Kind Regards |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
Posted: Mon Apr 05, 2004 7:13 am Post subject: |
|
|
If you've done that much, then you've done a lot already!
I'm not exactly sure what you're asking. Maybe you could provide additional information.
What language did you write your new Calc functions in?
Are you adding menus by altering the configuration manager via. the API?
What I would recommend is packaging your entire solution into a package that is deployed with pkgchk.
At first I didn't like pkgchk. But now I have changed my mind. Here is how an end user deploys a package....
1. Make sure OOo is not running.
2. Copy package file into the OOo\user\uno_packages folder.
3. Run the command... OOo\program\pkgchk.exe
An administrator can install the package for all users by....
1. Make sure OOo is not running.
2. Copy package file into the OOo\share\uno_packages folder.
3. Run the command... OOo\program\pkgchk -s
Uninstalling the component is similarly easy. Just remove your package from the folder in step 2, and then do step 3. Package is removed from OOo.
Step 3 can be done by simply double clicking on the pkgchk program, even though it is a command line tool. It does the right thing. If anything goes wrong, you can always look at the
OOo\user-or-share\uno_packages\cache\log.txt
file to see what went wrong.
Maybe I misunderstand your question?
The OOo developers really need to provide a simple GUI-fied version of pkgchk which can be double clicked by a user, which runs pkgchk, and then confirms to the user that it was installed/removed successfully -- or displays the OOo\user-or-share\uno_packages\cache\log.txt to show what went wrong. Such a gui front end to pkgchk would be analogous to the gui program OOo\program\jvmsetup that is already part of OOo. _________________ Want to make OOo Drawings like the colored flower design to the left? |
|
| Back to top |
|
 |
beiwen Guest
|
Posted: Mon Apr 05, 2004 11:01 am Post subject: Addin with GUI |
|
|
Thank you for the message. I have seen a lot of postings from you already and I think you have a very profound knowledge of OO.
I try to be more specific what my problem is:
I have written an addin in java. It adds a function to Calc. I can test that function in Calc and it behaves as expected. The addin is a package. I do deploy it with pkgchk - it gets unzipped into the cache directory and everything is just fine.
However, I can only use the function in Calc, when I type it into a cell. I so see some GUI when I use the function pilot. There I can see explanations of my parameters. All very neat but I need a way to call up a dialog, where I can adjust properties/preferences for my addin (i.e global properties, like defaults). I would like to have a menu item in the officebar, where I can call up a dialog to adjust these values for my addin. I haven't found a way to let my addin respond to menuitem-commands. I can add the menu and menuitems using xcu files. I have also implemented the interfaces XDispatchProvider and XDispatch. However, my dispatch-method gets never called.
I hope it's somewhat clearer what I try to achive.
Kind regards
Benno |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
Posted: Mon Apr 05, 2004 1:23 pm Post subject: |
|
|
| beiwen wrote: | | I have seen a lot of postings from you already and I think you have a very profound knowledge of OO. |
Thanks. But don't be fooled. I don't have any magic insight. It helps that I have been programming for 25 years. It helps that I have spent more than a year now studying the OOo API and conducting countless experiments using simple Basic programs.
Other people have been doing the same thing. Some even longer than I. Andrew Pitonyak's macro document for example, demonstrates a significant effort to study OOo programming for a long period of time. Andrew's macro document existed in some form in my early days of learning OOo last year.
Others here, like dfrench, are more expert than I in particular modules of OOo, such as Calc or Writer. My interest is Draw (and Impress).
If you've written a java component with calc add in functions, then you've jumped numerous hurdles, the same ones I've learned in the last year. You may just be impressed because I spend a lot of time answering questions and posting example code. That's probably just because I am passionate about OOo and seeing it succeed.
Mostly, I spend a lot of time playing with OOo. I have no commercial interest or motive. To me, OOo is a really cool toy that I have not yet become bored with.
| beiwen wrote: | | I have written an addin in java. .... |
Here is how I read your more elaborate description.
Your addin does describe all aspects of the function, its parameters, help strings, etc. Therefore, the function seems to truly fit into Calc, including the function autopilot.
You want your function to have some additional "configuration parameters" which are not parameters to the function.
For instance, if the function were called....
AddMyConstant( x )
then if I passed 5 for x, some magic configurable constant would be added to x (i.e. 5) and the result returned. You want to be able to go to the menu, bring up a dialog box, and tweak the constant that AddMyConstant adds to its parameter. If I go to the menu, bring up the custom dialog, and change the constant to 3, then AddMyConstant( x ) behaves as if it were "AddThree( x )".
If this is the correct interpretation, then here is what I would do....
Think of your add in as three distinct parts.
1. Some new configuration data, using your own custom schema.
2. The calc function addin, which accesses your custom configuration data and uses it in evaluating the function.
3. A component that brings up a dialog box and edits the custom configuration data. A menu command is added to the office which displays this dialog component.
Do you know how to access the Configuration Manager API?
The Configuration Manager edits the XCU files in OOo.
What is allowed into the XCU files is defined by the XCS files.
Simply put an XCU and an XCS file into your package, and pkgchk will property install it.
Here is an example custom configuration schema that I use.
DannyExample.xcs
| Code: | <?xml version='1.0' encoding='UTF-8'?>
<oor:component-schema oor:name="DannyExample" oor:package="nom.DannyBrewer.Example" xml:lang="en-US" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<templates>
<group oor:name="DannysSetting">
<prop oor:name="Setting" oor:type="xs:string"/>
<set oor:name="SubSettings" oor:node-type="DannysSetting"/>
</group>
</templates>
<component>
<group oor:name="DannysConfig">
<set oor:name="Settings" oor:node-type="DannysSetting"/>
</group>
</component>
</oor:component-schema>
|
Here is an example XCU file that stores data according to the above specification.
DannyExample.xcu
| Code: | <?xml version="1.0" encoding="UTF-8"?>
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="DannyExample" oor:package="nom.DannyBrewer.Example">
<node oor:name="DannysConfig">
<node oor:name="Settings">
<node oor:name="my.location" oor:op="replace">
<prop oor:name="Setting" oor:type="xs:string">
<value>%origin%</value>
</prop>
</node>
<node oor:name="my.thing1" oor:op="replace">
<prop oor:name="Setting" oor:type="xs:string">
<value>Thing1</value>
</prop>
</node>
<node oor:name="my.thing2" oor:op="replace">
<prop oor:name="Setting" oor:type="xs:string">
<value>Thing2</value>
</prop>
<node oor:name="SubSettings">
<node oor:name="sub1" oor:op="replace">
<prop oor:name="Setting" oor:type="xs:string">
<value>sub setting 1</value>
</prop>
</node>
<node oor:name="sub2" oor:op="replace">
<prop oor:name="Setting" oor:type="xs:string">
<value>sub setting 2</value>
</prop>
</node>
</node>
</node>
</node>
</node>
</oor:component-data>
|
PkgChk will install both of these files. Because of the oor:package property, pkgchk will create a folder called "nom" containing a folder called "DannyBrewer" containing a folder called "Example" containing a file called "DannyExample.xcs" and "DannyExample.xcu".
Now using the Configuration Manager API, you can access the DannysConfig node like this....
| Code: | Function GetMyLocation()
oConfigAccess = GetConfigAccess( "/nom.DannyBrewer.Example.DannyExample/DannysConfig" )
oElement = oConfigAccess.getByName( "Settings" )
if Not oElement.hasByName( "my.thing1" ) Then
MsgBox "my.thing1 not defined"
EndIf
if Not oElement.hasByName( "my.location" ) Then
MsgBox "my.location not defined"
Exit Function
EndIf
oLocation = oElement.getByName( "my.location" )
cMyLocation = oLocation.Setting
GetMyLocation() = cMyLocation
End Function
Function GetConfigAccess( ByVal cNodePath As String,_
ByVal bWriteAccess As Boolean,_
Optional bEnableSync,_
Optional bLazyWrite ) As Object
If IsMissing( bEnableSync ) Then
bEnableSync = True
EndIf
If IsMissing( bLazyWrite ) Then
bLazyWrite = False
EndIf
' If bWriteAccess And bEnableSync Then
oConfigProvider = GetProcessServiceManager().createInstanceWithArguments(_
"com.sun.star.configuration.ConfigurationProvider",_
Array( MakePropertyValue( "enableasync", bEnableSync ) ) )
' Else
' oConfigProvider = createUnoService( "com.sun.star.configuration.ConfigurationProvider" )
' EndIf
If bWriteAccess Then
cServiceName = "com.sun.star.configuration.ConfigurationUpdateAccess"
Else
cServiceName = "com.sun.star.configuration.ConfigurationAccess"
EndIf
oConfigAccess = oConfigProvider.createInstanceWithArguments( cServiceName,_
Array( MakePropertyValue( "nodepath", cNodePath ),_
MakePropertyValue( "lazywrite", bLazyWrite ) ) )
GetConfigAccess() = oConfigAccess
End Function
Function MakePropertyValue( Optional cName As String, Optional uValue ) As com.sun.star.beans.PropertyValue
Dim oPropertyValue As New com.sun.star.beans.PropertyValue
If Not IsMissing( cName ) Then
oPropertyValue.Name = cName
EndIf
If Not IsMissing( uValue ) Then
oPropertyValue.Value = uValue
EndIf
MakePropertyValue() = oPropertyValue
End Function
|
Each node, such as "my.thing1" and "my.thing2" has two properties....
1. Setting
2. SubSettings
Setting is a value of type string.
SubSettings is another node that contains named sets the above two items. So a node named "my.thing3" can have one Setting, and then have a named set of SubSettings, each SubSetting having a name, such as "Fred", "Joe", "John", and each of Fred, Joe and John are identically structured to the above, having both a Setting property, and a SubSettings property that has more named sub-sub-settings.
Since each node has a name, like "my.thing1" and "my.thing2", I can access a node by name, and get its setting. But that node can have SubSettings which have more nodes by name, accessed using hasByName(), getByName(), etc.
This is just one flexible configuration schema that I use. You can make up your own. I wanted to make my custom configuration schema recursive so that I could reuse the same xcu and xcs files in every component I create, yet store arbitrary tree structures of data.
Basically you store configuration data into an XCU file. Define the structure of it by an XCS file. Pkgchk installs both of those.
Your code must use the configuration manager, as I demonstrated above in Basic, to access your configuration settings. Your dialog box will get / display / edit / save the setting. Your add in function will get the setting and use its values.
Don't name your configuration schema "nom.DannyBrewer.Example.DannyExample". This may conflict with components that I develop. The developer's guide uses example schema names like "org.openoffice.example" and such. You can use any name that fits into the hierarchical name structure.
Off topic. In the above, you'll notice I have a location node in my configuration data. In that, I store the value "%origin%". Pkgchk will replace "%origin%" with a string that is the URL of the folder where the component was installed to. You first have to macro expand that string. But effectively, the GetMyLocation() function returns something that when macro expanded (beyond the scope of this thread) returns the pathname of other files, such as bitmaps and other files that were installed with my component. Therefore, when I create a dialog box, the dialog can have image controls whose properties are edited at runtime so that the dialog box displays pictures which are part of my component.
Hope this helps.
Danny _________________ Want to make OOo Drawings like the colored flower design to the left? |
|
| Back to top |
|
 |
beiwen Guest
|
Posted: Mon Apr 05, 2004 1:56 pm Post subject: |
|
|
Thank you so much for the extensive answer and the sample code. I have now a clear picture how to implement the addin!
Kind regards
Benno |
|
| Back to top |
|
 |
DannyB Moderator


Joined: 02 Apr 2003 Posts: 4021 Location: Lawrence, Kansas, USA
|
|
| Back to top |
|
 |
cbosdonnat Power User


Joined: 14 Nov 2004 Posts: 61 Location: France - Lyon
|
Posted: Tue Oct 31, 2006 7:07 am Post subject: |
|
|
Thank you Danny for your method: it's really useful.
I needed to create a new node from scratch in the configuration from a macro, and here is the way I did. It might help others.
| Code: | Function AddConfigNode( xAccess as Variant, sName as String, optional bForce as Boolean)
If IsMissing( bEnableSync ) Then
bEnableSync = False
EndIf
if xAccess.supportsService("com.sun.star.configuration.ConfigurationUpdateAccess") AND NOT isEmpty(sName) then
if NOT (xAccess.hasByName(sName) AND bForce) then
oNewNode = xAccess.createInstance()
xAccess.insertByName(sName, oNewNode)
AddConfigNode() = oNewNode
end if
end if
End Function |
Here is a sample of use of this method:
| Code: | oConfigAccess = GetConfigAccess( "/nom.DannyBrewer.Example.DannyExample/DannysConfig/Settings" )
oInsertedNode = AddConfigNode(oConfigAccess, "my.newSetting")
oInsertedNode.Setting = "New Setting" |
Now we have a new node named my.NewSetting, with the Setting value set to "New Setting".
Cedric _________________ Perso: http://cedric.bosdonnat.free.fr |
|
| Back to top |
|
 |
SergeM Super User

Joined: 09 Sep 2003 Posts: 3208 Location: Troyes France
|
|
| Back to top |
|
 |
9point9 Moderator

Joined: 31 Aug 2004 Posts: 3904 Location: UK
|
Posted: Thu Feb 01, 2007 11:59 am Post subject: |
|
|
Are their any addons/extensions which store settings in this way. I'd like to have a look at a working example as I can't get anything out of DannyB's code so far.  _________________ Arch Linux
OOo 3.2.0
OOoSVN, change control for OOo documents:
http://sourceforge.net/projects/ooosvn/ |
|
| Back to top |
|
 |
cbosdonnat Power User


Joined: 14 Nov 2004 Posts: 61 Location: France - Lyon
|
|
| Back to top |
|
 |
9point9 Moderator

Joined: 31 Aug 2004 Posts: 3904 Location: UK
|
Posted: Wed Aug 08, 2007 2:05 pm Post subject: |
|
|
I've had a few problems with the code to add a node:
| cbosdonnat wrote: |
Here is a sample of use of this method:
| Code: | oConfigAccess = GetConfigAccess( "/nom.DannyBrewer.Example.DannyExample/DannysConfig/Settings" )
oInsertedNode = AddConfigNode(oConfigAccess, "my.newSetting")
oInsertedNode.Setting = "New Setting" |
|
I have found that this will fail on the first line for me, however changing it to:
| Code: | | oConfigAccess = GetConfigAccess( "/nom.DannyBrewer.Example.DannyExample/DannysConfig/Settings", true) |
fixes that error for me.
The next error I get is on:
| Code: | | oNewNode = xAccess.createInstance() |
where I'm told that the Property or Method is not found. I've tried many alternatives and always fall down at this line. _________________ Arch Linux
OOo 3.2.0
OOoSVN, change control for OOo documents:
http://sourceforge.net/projects/ooosvn/ |
|
| Back to top |
|
 |
|
|
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
|