CalcFunctions
Originally posted in oooForum here.
This code deals with:
- Develop a trivial Calc function add on in Python.
- To be followed by more sophisticated functions.
- To be followed by eventually running a Poll on OOoForum asking what kind of functions shoudl be developed. (PLEASE don't post any answers to this question AT THIS TIME. This post is a ROADMAP, NOT A REQUEST for ideas.)
- Build a canned example, posted to OOoForum that is specifically designed for easy cloning and creation of new Calc functions.
The code has several issues, please read the forum topic for more detail issues on this code, also remember this code was never really debugged and is pretty old. So you are on your own. If you have a more update version or discover workarounds, please update the wiki.
import sys
import unohelper
from com.sun.star.sheet import XAddIn
from com.sun.star.sheet import XCompatibilityNames
from com.sun.star.lang import XServiceName
from com.sun.star.lang import XLocalizable
g_ImplementationHelper = unohelper.ImplementationHelper()
class DannysCalcFunctions1( unohelper.Base, XAddIn, XLocalizable, XCompatibilityNames, XServiceName ):
# The component must have a ctor with the component context as argument.
def __init__( self, oContext ):
self.oContext = oContext
self.oCoreReflection = None
self.StarDesktop = None
self.getDesktop()
#----------------------------------------
# Danny's stuff to make programming less convenient.
#----------------------------------------
def getServiceManager( self ):
"""Get the ServiceManager from the running OpenOffice.org.
"""
return self.oContext.ServiceManager
def createUnoService( self, cClass ):
"""A handy way to create a global objects within the running OOo.
"""
oServiceManager = self.getServiceManager()
oObj = oServiceManager.createInstance( cClass )
return oObj
def getDesktop( self ):
"""An easy way to obtain the Desktop object from a running OOo.
"""
if self.StarDesktop == None:
self.StarDesktop = self.createUnoService( "com.sun.star.frame.Desktop" )
return self.StarDesktop
def getCoreReflection( self ):
if self.oCoreReflection == None:
self.oCoreReflection = self.createUnoService( "com.sun.star.reflection.CoreReflection" )
return oCoreReflection
def createUnoStruct( self, cTypeName ):
"""Create a UNO struct and return it.
"""
oCoreReflection = self.getCoreReflection()
# Get the IDL class for the type name
oXIdlClass = oCoreReflection.forName( cTypeName )
# Create the struct.
oReturnValue, oStruct = oXIdlClass.createObject( None )
return oStruct
def makePropertyValue( self, cName=None, uValue=None, nHandle=None, nState=None ):
"""Create a com.sun.star.beans.PropertyValue struct and return it.
"""
oPropertyValue = self.createUnoStruct( "com.sun.star.beans.PropertyValue" )
if cName != None:
oPropertyValue.Name = cName
if uValue != None:
oPropertyValue.Value = uValue
if nHandle != None:
oPropertyValue.Handle = nHandle
if nState != None:
oPropertyValue.State = nState
return oPropertyValue
#----------------------------------------
# Inconvenience routines for working with structs needed later
#
def makeLocale( self, cLanguage="", cCountry="", cVariant="" ):
oLocale = self.createUnoStruct( "com.sun.star.lang.Locale" )
oLocale.Language = cLanguage
oLocale.Country = cCountry
oLocale.Variant = oVariant
return oLocale
def makeLocalizedName( self, stLocale, cName ):
oLocalizedName = self.createUnoStruct( "com.sun.star.sheet.LocalizedName" )
oLocalizedName.Locale = stLocale
oLocalizedName.Name = cName
return oLocalizedName
#----------------------------------------
# Interface: XAddIn
# Inherits from... XLocalizable
#----------------------------------------
# string
# getProgrammaticFuntionName( [in] string aDisplayName );
# Note: the method name spelling error is in the API!
def getProgrammaticFuntionName( self, cDisplayFnName ):
if cDisplayFnName == "AddFive":
return "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive"
elif cDisplayFnName == "AddSix":
return "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix"
return ""
# string
# getDisplayFunctionName( [in] string aProgrammaticName );
def getDisplayFunctioName( self, cProgrammaticFnName ):
if cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive":
return "AddFive"
elif cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix":
return "AddSix"
return ""
# string
# getFunctionDescription( [in] string aProgrammaticName );
def getFunctionDescription( self, ccProgrammaticFnName ):
if cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive":
return "Adds five to the argument."
elif cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix":
return "Add six to the argument."
return ""
# string
# getDisplayArgumentName( [in] string aProgrammaticName
# [in] long nArgument );
def getDisplayArgumentName( self, ccProgrammaticFnName, nArgNum ):
if cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive":
if nArgNum == 0:
return "number"
elif cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix":
if nArgNum == 0:
return "number"
return ""
# string
# getArgumentDescription( [in] string aProgrammaticName
# [in] long nArgument );
def getArgumentDescription( self, ccProgrammaticFnName, nArgNum ):
if cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive":
if nArgNum == 0:
return "A number to which five will be added."
elif cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix":
if nArgNum == 0:
return "A number to which six will be added."
return ""
# string
# getProgrammaticCategoryName( [in] string aProgrammaticName );
def getProgrammaticCategoryName( self, ccProgrammaticFnName ):
if cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive":
return "Add-In"
elif cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix":
return "Add-In"
return ""
# string
# getDisplayCategoryName( [in] string aProgrammaticName );
def getDisplayCategoryName( self, ccProgrammaticFnName ):
if cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive":
return "Add-In"
elif cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix":
return "Add-In"
return ""
#----------------------------------------
# Interface: XCompatibilityNames
#----------------------------------------
# sequence< LocalizedName >
# getCompatibilityNames( [in] string aProgrammaticName );
def getCompatibilityNames( self, ccProgrammaticFnName ):
if cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddFive":
return (
self.makeLocalizedName( self.makeLocale( "en", "US", "" ),
"AddFive" )
,)
elif cProgrammaticFnName == "nom.DannyBrewer.test.DannysCalcFunctions1.AddSix":
return (
self.makeLocalizedName( self.makeLocale( "en", "US", "" ),
"AddSix" )
,)
return ()
#----------------------------------------
# Interface: XLocalizable
# This is here because XAddIn inherits it.
#----------------------------------------
# void
# setLocale( [in] Locale eLocale );
def setLocale( self, stLocale ):
return
# Locale
# getLocale();
def getLocale( self ):
return self.makeLocale( "en", "US", "" )
#----------------------------------------
# Interface: XServiceName
#----------------------------------------
# string
# getServiceName();
def getServiceName( self ):
return "nom.DannyBrewer.test.DannysCalcFunctions1"
# add the class to the implementation container,
# which the loader uses to register/instantiate the component.
g_ImplementationHelper.addImplementation( \
# The class
DannysCalcFunctions1,
# The implementation name.
# Change this name for your own service.
"nom.DannyBrewer.test.DannysCalcFunctions1",
# A list of services that that are implemented.
("com.sun.star.sheet.AddIn",), )
Final notes on the code by danny: It is also worth noting that I have not figured out where to actually implement the two functions AddFive() and AddSix(). All of the above is just the infrastructure for making the two functions and their descriptions and argument lists known to Calc.
I still have to finish reading the above linked section of the Developer's Guide again. Maybe I can figure out what I'm missing. Or maybe there is a fully working Calc function example somewhere else (even in a different language?) that I can examine?