19f22d7c2SAndrew Rist# *************************************************************
29f22d7c2SAndrew Rist#
39f22d7c2SAndrew Rist#  Licensed to the Apache Software Foundation (ASF) under one
49f22d7c2SAndrew Rist#  or more contributor license agreements.  See the NOTICE file
59f22d7c2SAndrew Rist#  distributed with this work for additional information
69f22d7c2SAndrew Rist#  regarding copyright ownership.  The ASF licenses this file
79f22d7c2SAndrew Rist#  to you under the Apache License, Version 2.0 (the
89f22d7c2SAndrew Rist#  "License"); you may not use this file except in compliance
99f22d7c2SAndrew Rist#  with the License.  You may obtain a copy of the License at
109f22d7c2SAndrew Rist#
119f22d7c2SAndrew Rist#    http://www.apache.org/licenses/LICENSE-2.0
129f22d7c2SAndrew Rist#
139f22d7c2SAndrew Rist#  Unless required by applicable law or agreed to in writing,
149f22d7c2SAndrew Rist#  software distributed under the License is distributed on an
159f22d7c2SAndrew Rist#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f22d7c2SAndrew Rist#  KIND, either express or implied.  See the License for the
179f22d7c2SAndrew Rist#  specific language governing permissions and limitations
189f22d7c2SAndrew Rist#  under the License.
199f22d7c2SAndrew Rist#
209f22d7c2SAndrew Rist# *************************************************************
219f22d7c2SAndrew Rist
22cdf0e10cSrcweir# XScript implementation for python
23cdf0e10cSrcweirimport uno
24cdf0e10cSrcweirimport unohelper
25cdf0e10cSrcweirimport sys
26cdf0e10cSrcweirimport os
27cdf0e10cSrcweirimport imp
28cdf0e10cSrcweirimport time
29*13cfd8dfSPedro Giffuniimport ast
30cdf0e10cSrcweir
31cdf0e10cSrcweirclass LogLevel:
32cdf0e10cSrcweir    NONE = 0
33cdf0e10cSrcweir    ERROR = 1
34cdf0e10cSrcweir    DEBUG = 2
35cdf0e10cSrcweir
36cdf0e10cSrcweir# Configuration ----------------------------------------------------
37cdf0e10cSrcweirLogLevel.use = LogLevel.NONE                # production level
38cdf0e10cSrcweir#LogLevel.use = LogLevel.ERROR               # for script developers
39cdf0e10cSrcweir#LogLevel.use = LogLevel.DEBUG               # for script framework developers
40cdf0e10cSrcweirLOG_STDOUT = True                           # True, writes to stdout (difficult on windows)
41cdf0e10cSrcweir                                            # False, writes to user/Scripts/python/log.txt
42cdf0e10cSrcweirENABLE_EDIT_DIALOG=False                    # offers a minimal editor for editing.
43cdf0e10cSrcweir#-------------------------------------------------------------------
44cdf0e10cSrcweir
45cdf0e10cSrcweirdef encfile(uni):
46cdf0e10cSrcweir    return uni.encode( sys.getfilesystemencoding())
47cdf0e10cSrcweir
48cdf0e10cSrcweirdef lastException2String():
49cdf0e10cSrcweir    (excType,excInstance,excTraceback) = sys.exc_info()
50cdf0e10cSrcweir    ret = str(excType) + ": "+str(excInstance) + "\n" + \
51cdf0e10cSrcweir          uno._uno_extract_printable_stacktrace( excTraceback )
52cdf0e10cSrcweir    return ret
53cdf0e10cSrcweir
54cdf0e10cSrcweirdef logLevel2String( level ):
55cdf0e10cSrcweir    ret = " NONE"
56cdf0e10cSrcweir    if level == LogLevel.ERROR:
57cdf0e10cSrcweir        ret = "ERROR"
58cdf0e10cSrcweir    elif level >= LogLevel.DEBUG:
59cdf0e10cSrcweir        ret = "DEBUG"
60cdf0e10cSrcweir    return ret
61cdf0e10cSrcweir
62cdf0e10cSrcweirdef getLogTarget():
63cdf0e10cSrcweir    ret = sys.stdout
64cdf0e10cSrcweir    if not LOG_STDOUT:
65cdf0e10cSrcweir        try:
66cdf0e10cSrcweir            pathSubst = uno.getComponentContext().ServiceManager.createInstance(
67cdf0e10cSrcweir                "com.sun.star.util.PathSubstitution" )
68cdf0e10cSrcweir            userInstallation =  pathSubst.getSubstituteVariableValue( "user" )
69cdf0e10cSrcweir            if len( userInstallation ) > 0:
70cdf0e10cSrcweir                systemPath = uno.fileUrlToSystemPath( userInstallation + "/Scripts/python/log.txt" )
71cdf0e10cSrcweir                ret = file( systemPath , "a" )
72cdf0e10cSrcweir        except Exception,e:
73cdf0e10cSrcweir            print "Exception during creation of pythonscript logfile: "+ lastException2String() + "\n, delagating log to stdout\n"
74cdf0e10cSrcweir    return ret
75*13cfd8dfSPedro Giffuni
76cdf0e10cSrcweirclass Logger(LogLevel):
77cdf0e10cSrcweir    def __init__(self , target ):
78cdf0e10cSrcweir        self.target = target
79cdf0e10cSrcweir
80cdf0e10cSrcweir    def isDebugLevel( self ):
81cdf0e10cSrcweir        return self.use >= self.DEBUG
82*13cfd8dfSPedro Giffuni
83cdf0e10cSrcweir    def debug( self, msg ):
84cdf0e10cSrcweir        if self.isDebugLevel():
85cdf0e10cSrcweir            self.log( self.DEBUG, msg )
86*13cfd8dfSPedro Giffuni
87cdf0e10cSrcweir    def isErrorLevel( self ):
88cdf0e10cSrcweir        return self.use >= self.ERROR
89cdf0e10cSrcweir
90cdf0e10cSrcweir    def error( self, msg ):
91cdf0e10cSrcweir        if self.isErrorLevel():
92cdf0e10cSrcweir            self.log( self.ERROR, msg )
93cdf0e10cSrcweir
94cdf0e10cSrcweir    def log( self, level, msg ):
95cdf0e10cSrcweir        if self.use >= level:
96cdf0e10cSrcweir            try:
97cdf0e10cSrcweir                self.target.write(
98cdf0e10cSrcweir                    time.asctime() +
99cdf0e10cSrcweir                    " [" +
100cdf0e10cSrcweir                    logLevel2String( level ) +
101cdf0e10cSrcweir                    "] " +
102cdf0e10cSrcweir                    encfile(msg) +
103cdf0e10cSrcweir                    "\n" )
104cdf0e10cSrcweir                self.target.flush()
105cdf0e10cSrcweir            except Exception,e:
106cdf0e10cSrcweir                print "Error during writing to stdout: " +lastException2String() + "\n"
107cdf0e10cSrcweir
108cdf0e10cSrcweirlog = Logger( getLogTarget() )
109cdf0e10cSrcweir
110cdf0e10cSrcweirlog.debug( "pythonscript loading" )
111cdf0e10cSrcweir
112cdf0e10cSrcweir#from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider
113cdf0e10cSrcweirfrom com.sun.star.uno import RuntimeException
114cdf0e10cSrcweirfrom com.sun.star.lang import XServiceInfo
115cdf0e10cSrcweirfrom com.sun.star.io import IOException
11661c9e2f8SAriel Constenla-Hailefrom com.sun.star.ucb import CommandAbortedException, XCommandEnvironment, XProgressHandler, Command
117cdf0e10cSrcweirfrom com.sun.star.task import XInteractionHandler
11861c9e2f8SAriel Constenla-Hailefrom com.sun.star.beans import XPropertySet, Property
119cdf0e10cSrcweirfrom com.sun.star.container import XNameContainer
120cdf0e10cSrcweirfrom com.sun.star.xml.sax import XDocumentHandler, InputSource
121cdf0e10cSrcweirfrom com.sun.star.uno import Exception as UnoException
122cdf0e10cSrcweirfrom com.sun.star.script import XInvocation
123cdf0e10cSrcweirfrom com.sun.star.awt import XActionListener
124cdf0e10cSrcweir
125cdf0e10cSrcweirfrom com.sun.star.script.provider import XScriptProvider, XScript, XScriptContext, ScriptFrameworkErrorException
126cdf0e10cSrcweirfrom com.sun.star.script.browse import XBrowseNode
127cdf0e10cSrcweirfrom com.sun.star.script.browse.BrowseNodeTypes import SCRIPT, CONTAINER, ROOT
128cdf0e10cSrcweirfrom com.sun.star.util import XModifyListener
129cdf0e10cSrcweir
130cdf0e10cSrcweirLANGUAGENAME = "Python"
131cdf0e10cSrcweirGLOBAL_SCRIPTCONTEXT_NAME = "XSCRIPTCONTEXT"
132cdf0e10cSrcweirCALLABLE_CONTAINER_NAME =  "g_exportedScripts"
133cdf0e10cSrcweir
134cdf0e10cSrcweir# pythonloader looks for a static g_ImplementationHelper variable
135cdf0e10cSrcweirg_ImplementationHelper = unohelper.ImplementationHelper()
136cdf0e10cSrcweirg_implName = "org.openoffice.pyuno.LanguageScriptProviderFor"+LANGUAGENAME
137cdf0e10cSrcweir
138cdf0e10cSrcweir
139cdf0e10cSrcweir
140cdf0e10cSrcweirBLOCK_SIZE = 65536
141cdf0e10cSrcweirdef readTextFromStream( inputStream ):
142cdf0e10cSrcweir    # read the file
143cdf0e10cSrcweir    code = uno.ByteSequence( "" )
144cdf0e10cSrcweir    while True:
145cdf0e10cSrcweir        read,out = inputStream.readBytes( None , BLOCK_SIZE )
146cdf0e10cSrcweir        code = code + out
147cdf0e10cSrcweir        if read < BLOCK_SIZE:
148*13cfd8dfSPedro Giffuni            break
149cdf0e10cSrcweir    return code.value
150*13cfd8dfSPedro Giffuni
151cdf0e10cSrcweirdef toIniName( str ):
152cdf0e10cSrcweir    # TODO: what is the official way to get to know whether i am on the windows platform ?
153cdf0e10cSrcweir    if( hasattr(sys , "dllhandle") ):
154cdf0e10cSrcweir        return str + ".ini"
155cdf0e10cSrcweir    return str + "rc"
156cdf0e10cSrcweir
157cdf0e10cSrcweir
158cdf0e10cSrcweir""" definition: storageURI is the system dependent, absolute file url, where the script is stored on disk
159cdf0e10cSrcweir                scriptURI is the system independent uri
160cdf0e10cSrcweir"""
161cdf0e10cSrcweirclass MyUriHelper:
162cdf0e10cSrcweir
163cdf0e10cSrcweir    def __init__( self, ctx, location ):
164cdf0e10cSrcweir        self.s_UriMap = \
165cdf0e10cSrcweir        { "share" : "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" +  toIniName( "bootstrap") + "::BaseInstallation}/share/Scripts/python" , \
166cdf0e10cSrcweir          "share:uno_packages" : "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages", \
167cdf0e10cSrcweir          "user" : "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" + toIniName( "bootstrap") + "::UserInstallation}/user/Scripts/python" , \
168*13cfd8dfSPedro Giffuni          "user:uno_packages" : "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages" }
169cdf0e10cSrcweir        self.m_uriRefFac = ctx.ServiceManager.createInstanceWithContext("com.sun.star.uri.UriReferenceFactory",ctx)
170cdf0e10cSrcweir        if location.startswith( "vnd.sun.star.tdoc" ):
171cdf0e10cSrcweir            self.m_baseUri = location + "/Scripts/python"
172cdf0e10cSrcweir            self.m_scriptUriLocation = "document"
173cdf0e10cSrcweir        else:
174cdf0e10cSrcweir            self.m_baseUri = expandUri( self.s_UriMap[location] )
175cdf0e10cSrcweir            self.m_scriptUriLocation = location
176cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "initialized urihelper with baseUri="+self.m_baseUri + ",m_scriptUriLocation="+self.m_scriptUriLocation )
177*13cfd8dfSPedro Giffuni
178cdf0e10cSrcweir    def getRootStorageURI( self ):
179cdf0e10cSrcweir        return self.m_baseUri
180*13cfd8dfSPedro Giffuni
181cdf0e10cSrcweir    def getStorageURI( self, scriptURI ):
182cdf0e10cSrcweir        return self.scriptURI2StorageUri(scriptURI)
183cdf0e10cSrcweir
184cdf0e10cSrcweir    def getScriptURI( self, storageURI ):
185cdf0e10cSrcweir        return self.storageURI2ScriptUri(storageURI)
186cdf0e10cSrcweir
187cdf0e10cSrcweir    def storageURI2ScriptUri( self, storageURI ):
188cdf0e10cSrcweir        if not storageURI.startswith( self.m_baseUri ):
189cdf0e10cSrcweir            message = "pythonscript: storage uri '" + storageURI + "' not in base uri '" + self.m_baseUri + "'"
190cdf0e10cSrcweir            log.isDebugLevel() and log.debug( message )
191cdf0e10cSrcweir            raise RuntimeException( message )
192cdf0e10cSrcweir
193cdf0e10cSrcweir        ret = "vnd.sun.star.script:" + \
194cdf0e10cSrcweir              storageURI[len(self.m_baseUri)+1:].replace("/","|") + \
195cdf0e10cSrcweir              "?language=" + LANGUAGENAME + "&location=" + self.m_scriptUriLocation
196cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "converting storageURI="+storageURI + " to scriptURI=" + ret )
197cdf0e10cSrcweir        return ret
198*13cfd8dfSPedro Giffuni
199cdf0e10cSrcweir    def scriptURI2StorageUri( self, scriptURI ):
200cdf0e10cSrcweir        try:
201cdf0e10cSrcweir            myUri = self.m_uriRefFac.parse(scriptURI)
202cdf0e10cSrcweir            ret = self.m_baseUri + "/" + myUri.getName().replace( "|", "/" )
203cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "converting scriptURI="+scriptURI + " to storageURI=" + ret )
204cdf0e10cSrcweir            return ret
205cdf0e10cSrcweir        except UnoException, e:
206cdf0e10cSrcweir            log.error( "error during converting scriptURI="+scriptURI + ": " + e.Message)
207cdf0e10cSrcweir            raise RuntimeException( "pythonscript:scriptURI2StorageUri: " +e.getMessage(), None )
208cdf0e10cSrcweir        except Exception, e:
209cdf0e10cSrcweir            log.error( "error during converting scriptURI="+scriptURI + ": " + str(e))
210cdf0e10cSrcweir            raise RuntimeException( "pythonscript:scriptURI2StorageUri: " + str(e), None )
211*13cfd8dfSPedro Giffuni
212cdf0e10cSrcweir
213cdf0e10cSrcweirclass ModuleEntry:
214cdf0e10cSrcweir    def __init__( self, lastRead, module ):
215cdf0e10cSrcweir        self.lastRead = lastRead
216cdf0e10cSrcweir        self.module = module
217cdf0e10cSrcweir
218cdf0e10cSrcweirdef hasChanged( oldDate, newDate ):
219cdf0e10cSrcweir    return newDate.Year > oldDate.Year or \
220cdf0e10cSrcweir           newDate.Month > oldDate.Month or \
221cdf0e10cSrcweir           newDate.Day > oldDate.Day or \
222cdf0e10cSrcweir           newDate.Hours > oldDate.Hours or \
223cdf0e10cSrcweir           newDate.Minutes > oldDate.Minutes or \
224cdf0e10cSrcweir           newDate.Seconds > oldDate.Seconds or \
225cdf0e10cSrcweir           newDate.HundredthSeconds > oldDate.HundredthSeconds
226cdf0e10cSrcweir
227cdf0e10cSrcweirdef ensureSourceState( code ):
228cdf0e10cSrcweir    if not code.endswith( "\n" ):
229cdf0e10cSrcweir        code = code + "\n"
230cdf0e10cSrcweir    code = code.replace( "\r", "" )
231cdf0e10cSrcweir    return code
232cdf0e10cSrcweir
233cdf0e10cSrcweir
234cdf0e10cSrcweirdef checkForPythonPathBesideScript( url ):
235cdf0e10cSrcweir    if url.startswith( "file:" ):
236cdf0e10cSrcweir        path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" );
237cdf0e10cSrcweir        log.log( LogLevel.DEBUG,  "checking for existence of " + path )
238cdf0e10cSrcweir        if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path:
239cdf0e10cSrcweir            log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" )
240cdf0e10cSrcweir            sys.path.append( path )
241cdf0e10cSrcweir
242cdf0e10cSrcweir        path = unohelper.fileUrlToSystemPath( url+"/pythonpath" );
243cdf0e10cSrcweir        log.log( LogLevel.DEBUG,  "checking for existence of " + path )
244cdf0e10cSrcweir        if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path:
245cdf0e10cSrcweir            log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" )
246cdf0e10cSrcweir            sys.path.append( path )
247*13cfd8dfSPedro Giffuni
248*13cfd8dfSPedro Giffuni
249cdf0e10cSrcweirclass ScriptContext(unohelper.Base):
25061c9e2f8SAriel Constenla-Haile    def __init__( self, ctx, doc, inv ):
251cdf0e10cSrcweir        self.ctx = ctx
252cdf0e10cSrcweir        self.doc = doc
25361c9e2f8SAriel Constenla-Haile        self.inv = inv
254*13cfd8dfSPedro Giffuni
255cdf0e10cSrcweir   # XScriptContext
256cdf0e10cSrcweir    def getDocument(self):
25761c9e2f8SAriel Constenla-Haile        if self.doc:
25861c9e2f8SAriel Constenla-Haile            return self.doc
259cdf0e10cSrcweir        return self.getDesktop().getCurrentComponent()
260cdf0e10cSrcweir
261cdf0e10cSrcweir    def getDesktop(self):
262cdf0e10cSrcweir        return self.ctx.ServiceManager.createInstanceWithContext(
263cdf0e10cSrcweir            "com.sun.star.frame.Desktop", self.ctx )
264cdf0e10cSrcweir
265cdf0e10cSrcweir    def getComponentContext(self):
266cdf0e10cSrcweir        return self.ctx
267cdf0e10cSrcweir
26861c9e2f8SAriel Constenla-Haile    def getInvocationContext(self):
26961c9e2f8SAriel Constenla-Haile        return self.inv
27061c9e2f8SAriel Constenla-Haile
271cdf0e10cSrcweir#----------------------------------
272cdf0e10cSrcweir# Global Module Administration
273cdf0e10cSrcweir# does not fit together with script
274cdf0e10cSrcweir# engine lifetime management
275cdf0e10cSrcweir#----------------------------------
276cdf0e10cSrcweir#g_scriptContext = ScriptContext( uno.getComponentContext(), None )
277cdf0e10cSrcweir#g_modules = {}
278cdf0e10cSrcweir#def getModuleByUrl( url, sfa ):
279cdf0e10cSrcweir#    entry =  g_modules.get(url)
280cdf0e10cSrcweir#    load = True
281cdf0e10cSrcweir#    lastRead = sfa.getDateTimeModified( url )
282cdf0e10cSrcweir#    if entry:
283cdf0e10cSrcweir#        if hasChanged( entry.lastRead, lastRead ):
284cdf0e10cSrcweir#            log.isDebugLevel() and log.debug("file " + url + " has changed, reloading")
285cdf0e10cSrcweir#        else:
286cdf0e10cSrcweir#            load = False
287*13cfd8dfSPedro Giffuni#
288cdf0e10cSrcweir#    if load:
289cdf0e10cSrcweir#        log.isDebugLevel() and log.debug( "opening >" + url + "<" )
290cdf0e10cSrcweir#
291cdf0e10cSrcweir#        code = readTextFromStream( sfa.openFileRead( url ) )
292*13cfd8dfSPedro Giffuni
293cdf0e10cSrcweir        # execute the module
294cdf0e10cSrcweir#        entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") )
295cdf0e10cSrcweir#        entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext
296cdf0e10cSrcweir#        entry.module.__file__ = url
297cdf0e10cSrcweir#        exec code in entry.module.__dict__
298cdf0e10cSrcweir#        g_modules[ url ] = entry
299cdf0e10cSrcweir#        log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) )
300cdf0e10cSrcweir#    return entry.module
301cdf0e10cSrcweir
302cdf0e10cSrcweirclass ProviderContext:
303cdf0e10cSrcweir    def __init__( self, storageType, sfa, uriHelper, scriptContext ):
304cdf0e10cSrcweir        self.storageType = storageType
305cdf0e10cSrcweir        self.sfa = sfa
306cdf0e10cSrcweir        self.uriHelper = uriHelper
307cdf0e10cSrcweir        self.scriptContext = scriptContext
308cdf0e10cSrcweir        self.modules = {}
309cdf0e10cSrcweir        self.rootUrl = None
310cdf0e10cSrcweir        self.mapPackageName2Path = None
311cdf0e10cSrcweir
312cdf0e10cSrcweir    def getTransientPartFromUrl( self, url ):
313cdf0e10cSrcweir        rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
314cdf0e10cSrcweir        return rest[0:rest.find("/")]
315*13cfd8dfSPedro Giffuni
316cdf0e10cSrcweir    def getPackageNameFromUrl( self, url ):
317cdf0e10cSrcweir        rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
318cdf0e10cSrcweir        start = rest.find("/") +1
319cdf0e10cSrcweir        return rest[start:rest.find("/",start)]
320*13cfd8dfSPedro Giffuni
321*13cfd8dfSPedro Giffuni
322cdf0e10cSrcweir    def removePackageByUrl( self, url ):
323cdf0e10cSrcweir        items = self.mapPackageName2Path.items()
324cdf0e10cSrcweir        for i in items:
325cdf0e10cSrcweir            if url in i[1].pathes:
326cdf0e10cSrcweir                self.mapPackageName2Path.pop(i[0])
327cdf0e10cSrcweir                break
328cdf0e10cSrcweir
329cdf0e10cSrcweir    def addPackageByUrl( self, url ):
330cdf0e10cSrcweir        packageName = self.getPackageNameFromUrl( url )
331cdf0e10cSrcweir        transientPart = self.getTransientPartFromUrl( url )
332cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "addPackageByUrl : " + packageName + ", " + transientPart + "("+url+")" + ", rootUrl="+self.rootUrl )
333cdf0e10cSrcweir        if self.mapPackageName2Path.has_key( packageName ):
334cdf0e10cSrcweir            package = self.mapPackageName2Path[ packageName ]
335cdf0e10cSrcweir            package.pathes = package.pathes + (url, )
336cdf0e10cSrcweir        else:
337cdf0e10cSrcweir            package = Package( (url,), transientPart)
338cdf0e10cSrcweir            self.mapPackageName2Path[ packageName ] = package
339*13cfd8dfSPedro Giffuni
340cdf0e10cSrcweir    def isUrlInPackage( self, url ):
341cdf0e10cSrcweir        values = self.mapPackageName2Path.values()
342cdf0e10cSrcweir        for i in values:
343*13cfd8dfSPedro Giffuni#           print "checking " + url + " in " + str(i.pathes)
344cdf0e10cSrcweir            if url in i.pathes:
345*13cfd8dfSPedro Giffuni                return True
346cdf0e10cSrcweir#        print "false"
347cdf0e10cSrcweir        return False
348*13cfd8dfSPedro Giffuni
349cdf0e10cSrcweir    def setPackageAttributes( self, mapPackageName2Path, rootUrl ):
350cdf0e10cSrcweir        self.mapPackageName2Path = mapPackageName2Path
351cdf0e10cSrcweir        self.rootUrl = rootUrl
352*13cfd8dfSPedro Giffuni
353cdf0e10cSrcweir    def getPersistentUrlFromStorageUrl( self, url ):
354cdf0e10cSrcweir        # package name is the second directory
355cdf0e10cSrcweir        ret = url
356cdf0e10cSrcweir        if self.rootUrl:
357cdf0e10cSrcweir            pos = len( self.rootUrl) +1
358cdf0e10cSrcweir            ret = url[0:pos]+url[url.find("/",pos)+1:len(url)]
359cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "getPersistentUrlFromStorageUrl " + url +  " -> "+ ret)
360cdf0e10cSrcweir        return ret
361cdf0e10cSrcweir
362cdf0e10cSrcweir    def getStorageUrlFromPersistentUrl( self, url):
363cdf0e10cSrcweir        ret = url
364cdf0e10cSrcweir        if self.rootUrl:
365cdf0e10cSrcweir            pos = len(self.rootUrl)+1
366cdf0e10cSrcweir            packageName = url[pos:url.find("/",pos+1)]
367cdf0e10cSrcweir            package = self.mapPackageName2Path[ packageName ]
368cdf0e10cSrcweir            ret = url[0:pos]+ package.transientPathElement + "/" + url[pos:len(url)]
369cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "getStorageUrlFromPersistentUrl " + url + " -> "+ ret)
370cdf0e10cSrcweir        return ret
371cdf0e10cSrcweir
372cdf0e10cSrcweir    def getFuncsByUrl( self, url ):
373cdf0e10cSrcweir        src = readTextFromStream( self.sfa.openFileRead( url ) )
374cdf0e10cSrcweir        checkForPythonPathBesideScript( url[0:url.rfind('/')] )
375cdf0e10cSrcweir        src = ensureSourceState( src )
376cdf0e10cSrcweir
377cdf0e10cSrcweir        allFuncs = []
378cdf0e10cSrcweir        g_exportedScripts = []
379cdf0e10cSrcweir
380*13cfd8dfSPedro Giffuni        a = ast.parse(src, url)
381*13cfd8dfSPedro Giffuni
382*13cfd8dfSPedro Giffuni        if isinstance(a, ast.Module):
383*13cfd8dfSPedro Giffuni            for node in a.body:
384*13cfd8dfSPedro Giffuni                if isinstance(node, ast.FunctionDef):
385*13cfd8dfSPedro Giffuni                    allFuncs.append(node.name)
386*13cfd8dfSPedro Giffuni                elif isinstance(node, ast.Assign):
387*13cfd8dfSPedro Giffuni                    is_exported = False
388*13cfd8dfSPedro Giffuni                    for subnode in node.targets:
389*13cfd8dfSPedro Giffuni                        if isinstance(subnode, ast.Name) and \
390*13cfd8dfSPedro Giffuni                            subnode.id == "g_exportedScripts":
391*13cfd8dfSPedro Giffuni                            is_exported = True
392*13cfd8dfSPedro Giffuni                            break
393*13cfd8dfSPedro Giffuni                    if is_exported:
394*13cfd8dfSPedro Giffuni                        value_node = node.value
395*13cfd8dfSPedro Giffuni                        if isinstance(value_node, ast.List) or \
396*13cfd8dfSPedro Giffuni                            isinstance(value_node, ast.Tuple):
397*13cfd8dfSPedro Giffuni                            for elt in value_node.elts:
398*13cfd8dfSPedro Giffuni                                if isinstance(elt, ast.Str):
399*13cfd8dfSPedro Giffuni                                    g_exportedScripts.append(elt.s)
400*13cfd8dfSPedro Giffuni                                elif isinstance(elt, ast.Name):
401*13cfd8dfSPedro Giffuni                                    g_exportedScripts.append(elt.id)
402*13cfd8dfSPedro Giffuni                        elif isinstance(value_node, ast.Str):
403*13cfd8dfSPedro Giffuni                            g_exportedScripts.append(value_node.s)
404*13cfd8dfSPedro Giffuni                        elif isinstance(value_node, ast.Name):
405*13cfd8dfSPedro Giffuni                            g_exportedScripts.append(value_node.id)
406*13cfd8dfSPedro Giffuni                        return g_exportedScripts
407cdf0e10cSrcweir        return allFuncs
408*13cfd8dfSPedro Giffuni
409cdf0e10cSrcweir    def getModuleByUrl( self, url ):
410cdf0e10cSrcweir        entry =  self.modules.get(url)
411cdf0e10cSrcweir        load = True
412cdf0e10cSrcweir        lastRead = self.sfa.getDateTimeModified( url )
413cdf0e10cSrcweir        if entry:
414cdf0e10cSrcweir            if hasChanged( entry.lastRead, lastRead ):
415cdf0e10cSrcweir                log.isDebugLevel() and log.debug( "file " + url + " has changed, reloading" )
416cdf0e10cSrcweir            else:
417cdf0e10cSrcweir                load = False
418*13cfd8dfSPedro Giffuni
419cdf0e10cSrcweir        if load:
420cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "opening >" + url + "<" )
421*13cfd8dfSPedro Giffuni
422cdf0e10cSrcweir            src = readTextFromStream( self.sfa.openFileRead( url ) )
423cdf0e10cSrcweir            checkForPythonPathBesideScript( url[0:url.rfind('/')] )
424*13cfd8dfSPedro Giffuni            src = ensureSourceState( src )
425*13cfd8dfSPedro Giffuni
426cdf0e10cSrcweir            # execute the module
427cdf0e10cSrcweir            entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") )
428cdf0e10cSrcweir            entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.scriptContext
429cdf0e10cSrcweir
430cdf0e10cSrcweir            code = None
431cdf0e10cSrcweir            if url.startswith( "file:" ):
432cdf0e10cSrcweir                code = compile( src, encfile(uno.fileUrlToSystemPath( url ) ), "exec" )
433cdf0e10cSrcweir            else:
434cdf0e10cSrcweir                code = compile( src, url, "exec" )
435cdf0e10cSrcweir            exec code in entry.module.__dict__
436cdf0e10cSrcweir            entry.module.__file__ = url
437cdf0e10cSrcweir            self.modules[ url ] = entry
438cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) )
439cdf0e10cSrcweir        return  entry.module
440*13cfd8dfSPedro Giffuni
441cdf0e10cSrcweir#--------------------------------------------------
442cdf0e10cSrcweirdef isScript( candidate ):
443cdf0e10cSrcweir    ret = False
444cdf0e10cSrcweir    if isinstance( candidate, type(isScript) ):
445cdf0e10cSrcweir        ret = True
446cdf0e10cSrcweir    return ret
447*13cfd8dfSPedro Giffuni
448cdf0e10cSrcweir#-------------------------------------------------------
449cdf0e10cSrcweirclass ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, XActionListener ):
450cdf0e10cSrcweir    def __init__( self, provCtx, uri, fileName, funcName ):
451cdf0e10cSrcweir        self.fileName = fileName
452cdf0e10cSrcweir        self.funcName = funcName
453cdf0e10cSrcweir        self.provCtx = provCtx
454cdf0e10cSrcweir        self.uri = uri
455*13cfd8dfSPedro Giffuni
456cdf0e10cSrcweir    def getName( self ):
457cdf0e10cSrcweir        return self.funcName
458cdf0e10cSrcweir
459cdf0e10cSrcweir    def getChildNodes(self):
460cdf0e10cSrcweir        return ()
461cdf0e10cSrcweir
462cdf0e10cSrcweir    def hasChildNodes(self):
463cdf0e10cSrcweir        return False
464*13cfd8dfSPedro Giffuni
465cdf0e10cSrcweir    def getType( self):
466cdf0e10cSrcweir        return SCRIPT
467cdf0e10cSrcweir
468cdf0e10cSrcweir    def getPropertyValue( self, name ):
469cdf0e10cSrcweir        ret = None
470cdf0e10cSrcweir        try:
471cdf0e10cSrcweir            if name == "URI":
472cdf0e10cSrcweir                ret = self.provCtx.uriHelper.getScriptURI(
473cdf0e10cSrcweir                    self.provCtx.getPersistentUrlFromStorageUrl( self.uri + "$" + self.funcName ) )
474cdf0e10cSrcweir            elif name == "Editable" and ENABLE_EDIT_DIALOG:
475cdf0e10cSrcweir                ret = not self.provCtx.sfa.isReadOnly( self.uri )
476*13cfd8dfSPedro Giffuni
477cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) )
478cdf0e10cSrcweir        except Exception,e:
479cdf0e10cSrcweir            log.error( "ScriptBrowseNode.getPropertyValue error " + lastException2String())
480cdf0e10cSrcweir            raise
481*13cfd8dfSPedro Giffuni
482cdf0e10cSrcweir        return ret
483cdf0e10cSrcweir    def setPropertyValue( self, name, value ):
484cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "ScriptBrowseNode.setPropertyValue called " + name + "=" +str(value ) )
485cdf0e10cSrcweir    def getPropertySetInfo( self ):
486cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertySetInfo called "  )
487cdf0e10cSrcweir        return None
488*13cfd8dfSPedro Giffuni
489cdf0e10cSrcweir    def getIntrospection( self ):
490cdf0e10cSrcweir        return None
491cdf0e10cSrcweir
492cdf0e10cSrcweir    def invoke( self, name, params, outparamindex, outparams ):
493cdf0e10cSrcweir        if name == "Editable":
494cdf0e10cSrcweir            servicename = "com.sun.star.awt.DialogProvider"
495cdf0e10cSrcweir            ctx = self.provCtx.scriptContext.getComponentContext()
496cdf0e10cSrcweir            dlgprov = ctx.ServiceManager.createInstanceWithContext(
497cdf0e10cSrcweir                servicename, ctx )
498cdf0e10cSrcweir
499cdf0e10cSrcweir            self.editor = dlgprov.createDialog(
500cdf0e10cSrcweir                "vnd.sun.star.script:" +
501cdf0e10cSrcweir                "ScriptBindingLibrary.MacroEditor?location=application")
502cdf0e10cSrcweir
503cdf0e10cSrcweir            code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri))
504cdf0e10cSrcweir            code = ensureSourceState( code )
505cdf0e10cSrcweir            self.editor.getControl("EditorTextField").setText(code)
506cdf0e10cSrcweir
507cdf0e10cSrcweir            self.editor.getControl("RunButton").setActionCommand("Run")
508cdf0e10cSrcweir            self.editor.getControl("RunButton").addActionListener(self)
509cdf0e10cSrcweir            self.editor.getControl("SaveButton").setActionCommand("Save")
510cdf0e10cSrcweir            self.editor.getControl("SaveButton").addActionListener(self)
511cdf0e10cSrcweir
512cdf0e10cSrcweir            self.editor.execute()
513cdf0e10cSrcweir
514cdf0e10cSrcweir        return None
515cdf0e10cSrcweir
516cdf0e10cSrcweir    def actionPerformed( self, event ):
517cdf0e10cSrcweir        try:
518cdf0e10cSrcweir            if event.ActionCommand == "Run":
519cdf0e10cSrcweir                code = self.editor.getControl("EditorTextField").getText()
520cdf0e10cSrcweir                code = ensureSourceState( code )
521cdf0e10cSrcweir                mod = imp.new_module("ooo_script_framework")
522cdf0e10cSrcweir                mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext
523cdf0e10cSrcweir                exec code in mod.__dict__
524cdf0e10cSrcweir                values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
525cdf0e10cSrcweir                if not values:
526cdf0e10cSrcweir                    values = mod.__dict__.values()
527*13cfd8dfSPedro Giffuni
528cdf0e10cSrcweir                for i in values:
529cdf0e10cSrcweir                    if isScript( i ):
530cdf0e10cSrcweir                        i()
531cdf0e10cSrcweir                        break
532*13cfd8dfSPedro Giffuni
533cdf0e10cSrcweir            elif event.ActionCommand == "Save":
534cdf0e10cSrcweir                toWrite = uno.ByteSequence(
535cdf0e10cSrcweir                    str(
536cdf0e10cSrcweir                    self.editor.getControl("EditorTextField").getText().encode(
537cdf0e10cSrcweir                    sys.getdefaultencoding())) )
538cdf0e10cSrcweir                copyUrl = self.uri + ".orig"
539cdf0e10cSrcweir                self.provCtx.sfa.move( self.uri, copyUrl )
540cdf0e10cSrcweir                out = self.provCtx.sfa.openFileWrite( self.uri )
541cdf0e10cSrcweir                out.writeBytes( toWrite )
542cdf0e10cSrcweir                out.close()
543cdf0e10cSrcweir                self.provCtx.sfa.kill( copyUrl )
544cdf0e10cSrcweir#                log.isDebugLevel() and log.debug("Save is not implemented yet")
545cdf0e10cSrcweir#                text = self.editor.getControl("EditorTextField").getText()
546cdf0e10cSrcweir#                log.isDebugLevel() and log.debug("Would save: " + text)
547cdf0e10cSrcweir        except Exception,e:
548cdf0e10cSrcweir            # TODO: add an error box here !
549cdf0e10cSrcweir            log.error( lastException2String() )
550*13cfd8dfSPedro Giffuni
551cdf0e10cSrcweir
552cdf0e10cSrcweir    def setValue( self, name, value ):
553cdf0e10cSrcweir        return None
554cdf0e10cSrcweir
555cdf0e10cSrcweir    def getValue( self, name ):
556cdf0e10cSrcweir        return None
557cdf0e10cSrcweir
558cdf0e10cSrcweir    def hasMethod( self, name ):
559cdf0e10cSrcweir        return False
560cdf0e10cSrcweir
561cdf0e10cSrcweir    def hasProperty( self, name ):
562cdf0e10cSrcweir        return False
563cdf0e10cSrcweir
564*13cfd8dfSPedro Giffuni
565cdf0e10cSrcweir#-------------------------------------------------------
566cdf0e10cSrcweirclass FileBrowseNode( unohelper.Base, XBrowseNode ):
567cdf0e10cSrcweir    def __init__( self, provCtx, uri , name ):
568cdf0e10cSrcweir        self.provCtx = provCtx
569cdf0e10cSrcweir        self.uri = uri
570cdf0e10cSrcweir        self.name = name
571cdf0e10cSrcweir        self.funcnames = None
572*13cfd8dfSPedro Giffuni
573cdf0e10cSrcweir    def getName( self ):
574cdf0e10cSrcweir        return self.name
575*13cfd8dfSPedro Giffuni
576cdf0e10cSrcweir    def getChildNodes(self):
577cdf0e10cSrcweir        ret = ()
578cdf0e10cSrcweir        try:
579cdf0e10cSrcweir            self.funcnames = self.provCtx.getFuncsByUrl( self.uri )
580*13cfd8dfSPedro Giffuni
581cdf0e10cSrcweir            scriptNodeList = []
582cdf0e10cSrcweir            for i in self.funcnames:
583cdf0e10cSrcweir                scriptNodeList.append(
584cdf0e10cSrcweir                    ScriptBrowseNode(
585cdf0e10cSrcweir                    self.provCtx, self.uri, self.name, i ))
586cdf0e10cSrcweir            ret = tuple( scriptNodeList )
587cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "returning " +str(len(ret)) + " ScriptChildNodes on " + self.uri )
588cdf0e10cSrcweir        except Exception, e:
589cdf0e10cSrcweir            text = lastException2String()
590cdf0e10cSrcweir            log.error( "Error while evaluating " + self.uri + ":" + text )
591cdf0e10cSrcweir            raise
592cdf0e10cSrcweir        return ret
593cdf0e10cSrcweir
594cdf0e10cSrcweir    def hasChildNodes(self):
595cdf0e10cSrcweir        try:
596cdf0e10cSrcweir            return len(self.getChildNodes()) > 0
597cdf0e10cSrcweir        except Exception, e:
598cdf0e10cSrcweir            return False
599*13cfd8dfSPedro Giffuni
600cdf0e10cSrcweir    def getType( self):
601cdf0e10cSrcweir        return CONTAINER
602cdf0e10cSrcweir
603*13cfd8dfSPedro Giffuni
604cdf0e10cSrcweir
605cdf0e10cSrcweirclass DirBrowseNode( unohelper.Base, XBrowseNode ):
606cdf0e10cSrcweir    def __init__( self, provCtx, name, rootUrl ):
607cdf0e10cSrcweir        self.provCtx = provCtx
608cdf0e10cSrcweir        self.name = name
609cdf0e10cSrcweir        self.rootUrl = rootUrl
610cdf0e10cSrcweir
611cdf0e10cSrcweir    def getName( self ):
612cdf0e10cSrcweir        return self.name
613cdf0e10cSrcweir
614cdf0e10cSrcweir    def getChildNodes( self ):
615cdf0e10cSrcweir        try:
616cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "DirBrowseNode.getChildNodes called for " + self.rootUrl )
617cdf0e10cSrcweir            contents = self.provCtx.sfa.getFolderContents( self.rootUrl, True )
618cdf0e10cSrcweir            browseNodeList = []
619cdf0e10cSrcweir            for i in contents:
620cdf0e10cSrcweir                if i.endswith( ".py" ):
621cdf0e10cSrcweir                    log.isDebugLevel() and log.debug( "adding filenode " + i )
622cdf0e10cSrcweir                    browseNodeList.append(
623cdf0e10cSrcweir                        FileBrowseNode( self.provCtx, i, i[i.rfind("/")+1:len(i)-3] ) )
624cdf0e10cSrcweir                elif self.provCtx.sfa.isFolder( i ) and not i.endswith("/pythonpath"):
625cdf0e10cSrcweir                    log.isDebugLevel() and log.debug( "adding DirBrowseNode " + i )
626cdf0e10cSrcweir                    browseNodeList.append( DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)],i))
627cdf0e10cSrcweir            return tuple( browseNodeList )
628cdf0e10cSrcweir        except Exception, e:
629cdf0e10cSrcweir            text = lastException2String()
630cdf0e10cSrcweir            log.error( "DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl)
631cdf0e10cSrcweir            log.error( text)
632cdf0e10cSrcweir            return ()
633cdf0e10cSrcweir
634cdf0e10cSrcweir    def hasChildNodes( self ):
635cdf0e10cSrcweir        return True
636cdf0e10cSrcweir
637cdf0e10cSrcweir    def getType( self ):
638cdf0e10cSrcweir        return CONTAINER
639cdf0e10cSrcweir
640cdf0e10cSrcweir    def getScript( self, uri ):
641cdf0e10cSrcweir        log.debug( "DirBrowseNode getScript " + uri + " invoked" )
642cdf0e10cSrcweir        raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 )
643cdf0e10cSrcweir
644cdf0e10cSrcweir
645cdf0e10cSrcweirclass ManifestHandler( XDocumentHandler, unohelper.Base ):
646cdf0e10cSrcweir    def __init__( self, rootUrl ):
647cdf0e10cSrcweir        self.rootUrl = rootUrl
648*13cfd8dfSPedro Giffuni
649cdf0e10cSrcweir    def startDocument( self ):
650cdf0e10cSrcweir        self.urlList = []
651*13cfd8dfSPedro Giffuni
652cdf0e10cSrcweir    def endDocument( self ):
653cdf0e10cSrcweir        pass
654*13cfd8dfSPedro Giffuni
655cdf0e10cSrcweir    def startElement( self , name, attlist):
656cdf0e10cSrcweir        if name == "manifest:file-entry":
657cdf0e10cSrcweir            if attlist.getValueByName( "manifest:media-type" ) == "application/vnd.sun.star.framework-script":
658cdf0e10cSrcweir                self.urlList.append(
659cdf0e10cSrcweir                    self.rootUrl + "/" + attlist.getValueByName( "manifest:full-path" ) )
660cdf0e10cSrcweir
661cdf0e10cSrcweir    def endElement( self, name ):
662cdf0e10cSrcweir        pass
663cdf0e10cSrcweir
664cdf0e10cSrcweir    def characters ( self, chars ):
665cdf0e10cSrcweir        pass
666cdf0e10cSrcweir
667cdf0e10cSrcweir    def ignoreableWhitespace( self, chars ):
668cdf0e10cSrcweir        pass
669cdf0e10cSrcweir
670cdf0e10cSrcweir    def setDocumentLocator( self, locator ):
671cdf0e10cSrcweir        pass
672cdf0e10cSrcweir
673cdf0e10cSrcweirdef isPyFileInPath( sfa, path ):
674cdf0e10cSrcweir    ret = False
675cdf0e10cSrcweir    contents = sfa.getFolderContents( path, True )
676cdf0e10cSrcweir    for i in contents:
677cdf0e10cSrcweir        if sfa.isFolder(i):
678cdf0e10cSrcweir            ret = isPyFileInPath(sfa,i)
679cdf0e10cSrcweir        else:
680cdf0e10cSrcweir            if i.endswith(".py"):
681cdf0e10cSrcweir                ret = True
682cdf0e10cSrcweir        if ret:
683cdf0e10cSrcweir            break
684cdf0e10cSrcweir    return ret
685cdf0e10cSrcweir
686*13cfd8dfSPedro Giffuni# extracts META-INF directory from
687cdf0e10cSrcweirdef getPathesFromPackage( rootUrl, sfa ):
688cdf0e10cSrcweir    ret = ()
689cdf0e10cSrcweir    try:
690*13cfd8dfSPedro Giffuni        fileUrl = rootUrl + "/META-INF/manifest.xml"
691cdf0e10cSrcweir        inputStream = sfa.openFileRead( fileUrl )
692cdf0e10cSrcweir        parser = uno.getComponentContext().ServiceManager.createInstance( "com.sun.star.xml.sax.Parser" )
693cdf0e10cSrcweir        handler = ManifestHandler( rootUrl )
694cdf0e10cSrcweir        parser.setDocumentHandler( handler )
695cdf0e10cSrcweir        parser.parseStream( InputSource( inputStream , "", fileUrl, fileUrl ) )
696cdf0e10cSrcweir        for i in tuple(handler.urlList):
697cdf0e10cSrcweir            if not isPyFileInPath( sfa, i ):
698cdf0e10cSrcweir                handler.urlList.remove(i)
699cdf0e10cSrcweir        ret = tuple( handler.urlList )
700cdf0e10cSrcweir    except UnoException, e:
701cdf0e10cSrcweir        text = lastException2String()
702cdf0e10cSrcweir        log.debug( "getPathesFromPackage " + fileUrl + " Exception: " +text )
703cdf0e10cSrcweir        pass
704cdf0e10cSrcweir    return ret
705*13cfd8dfSPedro Giffuni
706cdf0e10cSrcweir
707cdf0e10cSrcweirclass Package:
708cdf0e10cSrcweir    def __init__( self, pathes, transientPathElement ):
709cdf0e10cSrcweir        self.pathes = pathes
710cdf0e10cSrcweir        self.transientPathElement = transientPathElement
711cdf0e10cSrcweir
712cdf0e10cSrcweirclass DummyInteractionHandler( unohelper.Base, XInteractionHandler ):
713cdf0e10cSrcweir    def __init__( self ):
714cdf0e10cSrcweir        pass
715cdf0e10cSrcweir    def handle( self, event):
716cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "pythonscript: DummyInteractionHandler.handle " + str( event ) )
717cdf0e10cSrcweir
718cdf0e10cSrcweirclass DummyProgressHandler( unohelper.Base, XProgressHandler ):
719cdf0e10cSrcweir    def __init__( self ):
720cdf0e10cSrcweir        pass
721*13cfd8dfSPedro Giffuni
722*13cfd8dfSPedro Giffuni    def push( self,status ):
723cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.push " + str( status ) )
724*13cfd8dfSPedro Giffuni    def update( self,status ):
725cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.update " + str( status ) )
726*13cfd8dfSPedro Giffuni    def pop( self ):
727cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.push " + str( event ) )
728cdf0e10cSrcweir
729cdf0e10cSrcweirclass CommandEnvironment(unohelper.Base, XCommandEnvironment):
730cdf0e10cSrcweir    def __init__( self ):
731cdf0e10cSrcweir        self.progressHandler = DummyProgressHandler()
732cdf0e10cSrcweir        self.interactionHandler = DummyInteractionHandler()
733cdf0e10cSrcweir    def getInteractionHandler( self ):
734cdf0e10cSrcweir        return self.interactionHandler
735cdf0e10cSrcweir    def getProgressHandler( self ):
736cdf0e10cSrcweir        return self.progressHandler
737cdf0e10cSrcweir
738cdf0e10cSrcweir#maybe useful for debugging purposes
739cdf0e10cSrcweir#class ModifyListener( unohelper.Base, XModifyListener ):
740cdf0e10cSrcweir#    def __init__( self ):
741cdf0e10cSrcweir#        pass
742cdf0e10cSrcweir#    def modified( self, event ):
743cdf0e10cSrcweir#        log.isDebugLevel() and log.debug( "pythonscript: ModifyListener.modified " + str( event ) )
744cdf0e10cSrcweir#    def disposing( self, event ):
745cdf0e10cSrcweir#        log.isDebugLevel() and log.debug( "pythonscript: ModifyListener.disposing " + str( event ) )
74661c9e2f8SAriel Constenla-Haile
74761c9e2f8SAriel Constenla-Hailedef getModelFromDocUrl(ctx, url):
74861c9e2f8SAriel Constenla-Haile    """Get document model from document url."""
74961c9e2f8SAriel Constenla-Haile    doc = None
75061c9e2f8SAriel Constenla-Haile    args = ("Local", "Office")
75161c9e2f8SAriel Constenla-Haile    ucb = ctx.getServiceManager().createInstanceWithArgumentsAndContext(
75261c9e2f8SAriel Constenla-Haile        "com.sun.star.ucb.UniversalContentBroker", args, ctx)
75361c9e2f8SAriel Constenla-Haile    identifier = ucb.createContentIdentifier(url)
75461c9e2f8SAriel Constenla-Haile    content = ucb.queryContent(identifier)
75561c9e2f8SAriel Constenla-Haile    p = Property()
75661c9e2f8SAriel Constenla-Haile    p.Name = "DocumentModel"
75761c9e2f8SAriel Constenla-Haile    p.Handle = -1
758*13cfd8dfSPedro Giffuni
75961c9e2f8SAriel Constenla-Haile    c = Command()
76061c9e2f8SAriel Constenla-Haile    c.Handle = -1
76161c9e2f8SAriel Constenla-Haile    c.Name = "getPropertyValues"
76261c9e2f8SAriel Constenla-Haile    c.Argument = uno.Any("[]com.sun.star.beans.Property", (p,))
763*13cfd8dfSPedro Giffuni
76461c9e2f8SAriel Constenla-Haile    env = CommandEnvironment()
76561c9e2f8SAriel Constenla-Haile    try:
76661c9e2f8SAriel Constenla-Haile        ret = content.execute(c, 0, env)
76761c9e2f8SAriel Constenla-Haile        doc = ret.getObject(1, None)
76861c9e2f8SAriel Constenla-Haile    except Exception, e:
76961c9e2f8SAriel Constenla-Haile        log.isErrorLevel() and log.error("getModelFromDocUrl: %s" % url)
77061c9e2f8SAriel Constenla-Haile    return doc
77161c9e2f8SAriel Constenla-Haile
772cdf0e10cSrcweirdef mapStorageType2PackageContext( storageType ):
773cdf0e10cSrcweir    ret = storageType
774cdf0e10cSrcweir    if( storageType == "share:uno_packages" ):
775cdf0e10cSrcweir        ret = "shared"
776cdf0e10cSrcweir    if( storageType == "user:uno_packages" ):
777cdf0e10cSrcweir        ret = "user"
778cdf0e10cSrcweir    return ret
779cdf0e10cSrcweir
780cdf0e10cSrcweirdef getPackageName2PathMap( sfa, storageType ):
781cdf0e10cSrcweir    ret = {}
782cdf0e10cSrcweir    packageManagerFactory = uno.getComponentContext().getValueByName(
783cdf0e10cSrcweir        "/singletons/com.sun.star.deployment.thePackageManagerFactory" )
784cdf0e10cSrcweir    packageManager = packageManagerFactory.getPackageManager(
785cdf0e10cSrcweir        mapStorageType2PackageContext(storageType))
786cdf0e10cSrcweir#    packageManager.addModifyListener( ModifyListener() )
787cdf0e10cSrcweir    log.isDebugLevel() and log.debug( "pythonscript: getPackageName2PathMap start getDeployedPackages" )
788cdf0e10cSrcweir    packages = packageManager.getDeployedPackages(
789cdf0e10cSrcweir        packageManager.createAbortChannel(), CommandEnvironment( ) )
790cdf0e10cSrcweir    log.isDebugLevel() and log.debug( "pythonscript: getPackageName2PathMap end getDeployedPackages (" + str(len(packages))+")" )
791cdf0e10cSrcweir
792cdf0e10cSrcweir    for i in packages:
793cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "inspecting package " + i.Name + "("+i.Identifier.Value+")" )
794cdf0e10cSrcweir        transientPathElement = penultimateElement( i.URL )
795cdf0e10cSrcweir        j = expandUri( i.URL )
796cdf0e10cSrcweir        pathes = getPathesFromPackage( j, sfa )
797cdf0e10cSrcweir        if len( pathes ) > 0:
798cdf0e10cSrcweir            # map package name to url, we need this later
799cdf0e10cSrcweir            log.isErrorLevel() and log.error( "adding Package " + transientPathElement + " " + str( pathes ) )
800cdf0e10cSrcweir            ret[ lastElement( j ) ] = Package( pathes, transientPathElement )
801cdf0e10cSrcweir    return ret
802cdf0e10cSrcweir
803cdf0e10cSrcweirdef penultimateElement( aStr ):
804cdf0e10cSrcweir    lastSlash = aStr.rindex("/")
805cdf0e10cSrcweir    penultimateSlash = aStr.rindex("/",0,lastSlash-1)
806cdf0e10cSrcweir    return  aStr[ penultimateSlash+1:lastSlash ]
807cdf0e10cSrcweir
808cdf0e10cSrcweirdef lastElement( aStr):
809cdf0e10cSrcweir    return aStr[ aStr.rfind( "/" )+1:len(aStr)]
810cdf0e10cSrcweir
811cdf0e10cSrcweirclass PackageBrowseNode( unohelper.Base, XBrowseNode ):
812cdf0e10cSrcweir    def __init__( self, provCtx, name, rootUrl ):
813cdf0e10cSrcweir        self.provCtx = provCtx
814cdf0e10cSrcweir        self.name = name
815cdf0e10cSrcweir        self.rootUrl = rootUrl
816cdf0e10cSrcweir
817cdf0e10cSrcweir    def getName( self ):
818cdf0e10cSrcweir        return self.name
819cdf0e10cSrcweir
820cdf0e10cSrcweir    def getChildNodes( self ):
821cdf0e10cSrcweir        items = self.provCtx.mapPackageName2Path.items()
822cdf0e10cSrcweir        browseNodeList = []
823cdf0e10cSrcweir        for i in items:
824cdf0e10cSrcweir            if len( i[1].pathes ) == 1:
825cdf0e10cSrcweir                browseNodeList.append(
826cdf0e10cSrcweir                    DirBrowseNode( self.provCtx, i[0], i[1].pathes[0] ))
827cdf0e10cSrcweir            else:
828cdf0e10cSrcweir                for j in i[1].pathes:
829cdf0e10cSrcweir                    browseNodeList.append(
830cdf0e10cSrcweir                        DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j), j ) )
831cdf0e10cSrcweir        return tuple( browseNodeList )
832cdf0e10cSrcweir
833cdf0e10cSrcweir    def hasChildNodes( self ):
834cdf0e10cSrcweir        return len( self.mapPackageName2Path ) > 0
835cdf0e10cSrcweir
836cdf0e10cSrcweir    def getType( self ):
837cdf0e10cSrcweir        return CONTAINER
838cdf0e10cSrcweir
839cdf0e10cSrcweir    def getScript( self, uri ):
840cdf0e10cSrcweir        log.debug( "DirBrowseNode getScript " + uri + " invoked" )
841cdf0e10cSrcweir        raise IllegalArgumentException( "PackageBrowseNode couldn't instantiate script " + uri , self , 0 )
842cdf0e10cSrcweir
843cdf0e10cSrcweir
844cdf0e10cSrcweir
845cdf0e10cSrcweir
846cdf0e10cSrcweirclass PythonScript( unohelper.Base, XScript ):
847cdf0e10cSrcweir    def __init__( self, func, mod ):
848cdf0e10cSrcweir        self.func = func
849cdf0e10cSrcweir        self.mod = mod
850cdf0e10cSrcweir    def invoke(self, args, out, outindex ):
851cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "PythonScript.invoke " + str( args ) )
852cdf0e10cSrcweir        try:
853cdf0e10cSrcweir            ret = self.func( *args )
854cdf0e10cSrcweir        except UnoException,e:
855cdf0e10cSrcweir            # UNO Exception continue to fly ...
856cdf0e10cSrcweir            text = lastException2String()
857cdf0e10cSrcweir            complete = "Error during invoking function " + \
858cdf0e10cSrcweir                str(self.func.__name__) + " in module " + \
859cdf0e10cSrcweir                self.mod.__file__ + " (" + text + ")"
860cdf0e10cSrcweir            log.isDebugLevel() and log.debug( complete )
861cdf0e10cSrcweir            # some people may beat me up for modifying the exception text,
862cdf0e10cSrcweir            # but otherwise office just shows
863cdf0e10cSrcweir            # the type name and message text with no more information,
864*13cfd8dfSPedro Giffuni            # this is really bad for most users.
865cdf0e10cSrcweir            e.Message = e.Message + " (" + complete + ")"
866cdf0e10cSrcweir            raise
867cdf0e10cSrcweir        except Exception,e:
868cdf0e10cSrcweir            # General python exception are converted to uno RuntimeException
869cdf0e10cSrcweir            text = lastException2String()
870cdf0e10cSrcweir            complete = "Error during invoking function " + \
871cdf0e10cSrcweir                str(self.func.__name__) + " in module " + \
872cdf0e10cSrcweir                self.mod.__file__ + " (" + text + ")"
873cdf0e10cSrcweir            log.isDebugLevel() and log.debug( complete )
874cdf0e10cSrcweir            raise RuntimeException( complete , self )
875cdf0e10cSrcweir        log.isDebugLevel() and log.debug( "PythonScript.invoke ret = " + str( ret ) )
876cdf0e10cSrcweir        return ret, (), ()
877cdf0e10cSrcweir
878cdf0e10cSrcweirdef expandUri(  uri ):
879cdf0e10cSrcweir    if uri.startswith( "vnd.sun.star.expand:" ):
880cdf0e10cSrcweir        uri = uri.replace( "vnd.sun.star.expand:", "",1)
881cdf0e10cSrcweir        uri = uno.getComponentContext().getByName(
882cdf0e10cSrcweir                    "/singletons/com.sun.star.util.theMacroExpander" ).expandMacros( uri )
883cdf0e10cSrcweir    if uri.startswith( "file:" ):
884cdf0e10cSrcweir        uri = uno.absolutize("",uri)   # necessary to get rid of .. in uri
885cdf0e10cSrcweir    return uri
886*13cfd8dfSPedro Giffuni
887cdf0e10cSrcweir#--------------------------------------------------------------
888cdf0e10cSrcweirclass PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer):
889cdf0e10cSrcweir    def __init__( self, ctx, *args ):
890cdf0e10cSrcweir        if log.isDebugLevel():
891cdf0e10cSrcweir            mystr = ""
892cdf0e10cSrcweir            for i in args:
893cdf0e10cSrcweir                if len(mystr) > 0:
894cdf0e10cSrcweir                    mystr = mystr +","
895cdf0e10cSrcweir                mystr = mystr + str(i)
896cdf0e10cSrcweir            log.debug( "Entering PythonScriptProvider.ctor" + mystr )
897cdf0e10cSrcweir
89861c9e2f8SAriel Constenla-Haile        doc = None
89961c9e2f8SAriel Constenla-Haile        inv = None
900cdf0e10cSrcweir        storageType = ""
90161c9e2f8SAriel Constenla-Haile
902cdf0e10cSrcweir        if isinstance(args[0],unicode ):
903cdf0e10cSrcweir            storageType = args[0]
90461c9e2f8SAriel Constenla-Haile            if storageType.startswith( "vnd.sun.star.tdoc" ):
90561c9e2f8SAriel Constenla-Haile                doc = getModelFromDocUrl(ctx, storageType)
906cdf0e10cSrcweir        else:
90761c9e2f8SAriel Constenla-Haile            inv = args[0]
90861c9e2f8SAriel Constenla-Haile            try:
90961c9e2f8SAriel Constenla-Haile                doc = inv.ScriptContainer
91061c9e2f8SAriel Constenla-Haile                content = ctx.getServiceManager().createInstanceWithContext(
911*13cfd8dfSPedro Giffuni                    "com.sun.star.frame.TransientDocumentsDocumentContentFactory",
91261c9e2f8SAriel Constenla-Haile                    ctx).createDocumentContent(doc)
91361c9e2f8SAriel Constenla-Haile                storageType = content.getIdentifier().getContentIdentifier()
91461c9e2f8SAriel Constenla-Haile            except Exception, e:
91561c9e2f8SAriel Constenla-Haile                text = lastException2String()
91661c9e2f8SAriel Constenla-Haile                log.error( text )
91761c9e2f8SAriel Constenla-Haile
918cdf0e10cSrcweir        isPackage = storageType.endswith( ":uno_packages" )
919cdf0e10cSrcweir
920cdf0e10cSrcweir        try:
921cdf0e10cSrcweir#            urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext(
922cdf0e10cSrcweir#                "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx)
923cdf0e10cSrcweir            urlHelper = MyUriHelper( ctx, storageType )
924cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "got urlHelper " + str( urlHelper ) )
925*13cfd8dfSPedro Giffuni
926cdf0e10cSrcweir            rootUrl = expandUri( urlHelper.getRootStorageURI() )
927cdf0e10cSrcweir            log.isDebugLevel() and log.debug( storageType + " transformed to " + rootUrl )
928cdf0e10cSrcweir
929cdf0e10cSrcweir            ucbService = "com.sun.star.ucb.SimpleFileAccess"
930cdf0e10cSrcweir            sfa = ctx.ServiceManager.createInstanceWithContext( ucbService, ctx )
931cdf0e10cSrcweir            if not sfa:
932cdf0e10cSrcweir                log.debug("PythonScriptProvider couldn't instantiate " +ucbService)
933cdf0e10cSrcweir                raise RuntimeException(
934cdf0e10cSrcweir                    "PythonScriptProvider couldn't instantiate " +ucbService, self)
935cdf0e10cSrcweir            self.provCtx = ProviderContext(
93661c9e2f8SAriel Constenla-Haile                storageType, sfa, urlHelper, ScriptContext( uno.getComponentContext(), doc, inv ) )
937cdf0e10cSrcweir            if isPackage:
938cdf0e10cSrcweir                mapPackageName2Path = getPackageName2PathMap( sfa, storageType )
939cdf0e10cSrcweir                self.provCtx.setPackageAttributes( mapPackageName2Path , rootUrl )
940cdf0e10cSrcweir                self.dirBrowseNode = PackageBrowseNode( self.provCtx, LANGUAGENAME, rootUrl )
941cdf0e10cSrcweir            else:
942cdf0e10cSrcweir                self.dirBrowseNode = DirBrowseNode( self.provCtx, LANGUAGENAME, rootUrl )
943*13cfd8dfSPedro Giffuni
944cdf0e10cSrcweir        except Exception, e:
945cdf0e10cSrcweir            text = lastException2String()
946cdf0e10cSrcweir            log.debug( "PythonScriptProvider could not be instantiated because of : " + text )
947cdf0e10cSrcweir            raise e
948cdf0e10cSrcweir
949cdf0e10cSrcweir    def getName( self ):
950cdf0e10cSrcweir        return self.dirBrowseNode.getName()
951cdf0e10cSrcweir
952cdf0e10cSrcweir    def getChildNodes( self ):
953*13cfd8dfSPedro Giffuni        return self.dirBrowseNode.getChildNodes()
954cdf0e10cSrcweir
955cdf0e10cSrcweir    def hasChildNodes( self ):
956cdf0e10cSrcweir        return self.dirBrowseNode.hasChildNodes()
957cdf0e10cSrcweir
958cdf0e10cSrcweir    def getType( self ):
959cdf0e10cSrcweir        return self.dirBrowseNode.getType()
960cdf0e10cSrcweir
961cdf0e10cSrcweir    def getScript( self, uri ):
962cdf0e10cSrcweir        log.debug( "DirBrowseNode getScript " + uri + " invoked" )
963*13cfd8dfSPedro Giffuni
964cdf0e10cSrcweir        raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 )
965cdf0e10cSrcweir
966cdf0e10cSrcweir    def getScript( self, scriptUri ):
967cdf0e10cSrcweir        try:
968cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "getScript " + scriptUri + " invoked")
969*13cfd8dfSPedro Giffuni
970cdf0e10cSrcweir            storageUri = self.provCtx.getStorageUrlFromPersistentUrl(
971cdf0e10cSrcweir                self.provCtx.uriHelper.getStorageURI(scriptUri) );
972cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "getScript: storageUri = " + storageUri)
973cdf0e10cSrcweir            fileUri = storageUri[0:storageUri.find( "$" )]
974*13cfd8dfSPedro Giffuni            funcName = storageUri[storageUri.find( "$" )+1:len(storageUri)]
975*13cfd8dfSPedro Giffuni
976cdf0e10cSrcweir            mod = self.provCtx.getModuleByUrl( fileUri )
977cdf0e10cSrcweir            log.isDebugLevel() and log.debug( " got mod " + str(mod) )
978*13cfd8dfSPedro Giffuni
979cdf0e10cSrcweir            func = mod.__dict__[ funcName ]
980cdf0e10cSrcweir
981cdf0e10cSrcweir            log.isDebugLevel() and log.debug( "got func " + str( func ) )
982cdf0e10cSrcweir            return PythonScript( func, mod )
983cdf0e10cSrcweir        except Exception, e:
984cdf0e10cSrcweir            text = lastException2String()
985cdf0e10cSrcweir            log.error( text )
986cdf0e10cSrcweir            raise ScriptFrameworkErrorException( text, self, scriptUri, LANGUAGENAME, 0 )
987*13cfd8dfSPedro Giffuni
988cdf0e10cSrcweir
989cdf0e10cSrcweir    # XServiceInfo
990cdf0e10cSrcweir    def getSupportedServices( self ):
991cdf0e10cSrcweir        return g_ImplementationHelper.getSupportedServices(g_implName)
992cdf0e10cSrcweir
993cdf0e10cSrcweir    def supportsService( self, ServiceName ):
994cdf0e10cSrcweir        return g_ImplementationHelper.supportsService( g_implName, ServiceName )
995cdf0e10cSrcweir
996cdf0e10cSrcweir    def getImplementationName(self):
997cdf0e10cSrcweir        return g_implName
998cdf0e10cSrcweir
999cdf0e10cSrcweir    def getByName( self, name ):
1000cdf0e10cSrcweir        log.debug( "getByName called" + str( name ))
1001cdf0e10cSrcweir        return None
1002cdf0e10cSrcweir
1003*13cfd8dfSPedro Giffuni
1004cdf0e10cSrcweir    def getElementNames( self ):
1005cdf0e10cSrcweir        log.debug( "getElementNames called")
1006cdf0e10cSrcweir        return ()
1007*13cfd8dfSPedro Giffuni
1008cdf0e10cSrcweir    def hasByName( self, name ):
1009cdf0e10cSrcweir        try:
1010cdf0e10cSrcweir            log.debug( "hasByName called " + str( name ))
1011cdf0e10cSrcweir            uri = expandUri(name)
1012cdf0e10cSrcweir            ret = self.provCtx.isUrlInPackage( uri )
1013cdf0e10cSrcweir            log.debug( "hasByName " + uri + " " +str( ret ) )
1014cdf0e10cSrcweir            return ret
1015cdf0e10cSrcweir        except Exception, e:
1016cdf0e10cSrcweir            text = lastException2String()
1017cdf0e10cSrcweir            log.debug( "Error in hasByName:" +  text )
1018cdf0e10cSrcweir            return False
1019cdf0e10cSrcweir
1020cdf0e10cSrcweir    def removeByName( self, name ):
1021cdf0e10cSrcweir        log.debug( "removeByName called" + str( name ))
1022cdf0e10cSrcweir        uri = expandUri( name )
1023cdf0e10cSrcweir        if self.provCtx.isUrlInPackage( uri ):
1024cdf0e10cSrcweir            self.provCtx.removePackageByUrl( uri )
1025cdf0e10cSrcweir        else:
1026cdf0e10cSrcweir            log.debug( "removeByName unknown uri " + str( name ) + ", ignoring" )
1027cdf0e10cSrcweir            raise NoSuchElementException( uri + "is not in package" , self )
1028cdf0e10cSrcweir        log.debug( "removeByName called" + str( uri ) + " successful" )
1029*13cfd8dfSPedro Giffuni
1030cdf0e10cSrcweir    def insertByName( self, name, value ):
1031cdf0e10cSrcweir        log.debug( "insertByName called " + str( name ) + " " + str( value ))
1032cdf0e10cSrcweir        uri = expandUri( name )
1033cdf0e10cSrcweir        if isPyFileInPath( self.provCtx.sfa, uri ):
1034cdf0e10cSrcweir            self.provCtx.addPackageByUrl( uri )
1035cdf0e10cSrcweir        else:
1036cdf0e10cSrcweir            # package is no python package ...
1037cdf0e10cSrcweir            log.debug( "insertByName: no python files in " + str( uri ) + ", ignoring" )
1038cdf0e10cSrcweir            raise IllegalArgumentException( uri + " does not contain .py files", self, 1 )
1039cdf0e10cSrcweir        log.debug( "insertByName called " + str( uri ) + " successful" )
1040cdf0e10cSrcweir
1041cdf0e10cSrcweir    def replaceByName( self, name, value ):
1042cdf0e10cSrcweir        log.debug( "replaceByName called " + str( name ) + " " + str( value ))
1043cdf0e10cSrcweir        removeByName( name )
1044cdf0e10cSrcweir        insertByName( name )
1045cdf0e10cSrcweir        log.debug( "replaceByName called" + str( uri ) + " successful" )
1046cdf0e10cSrcweir
1047cdf0e10cSrcweir    def getElementType( self ):
1048cdf0e10cSrcweir        log.debug( "getElementType called" )
1049cdf0e10cSrcweir        return uno.getTypeByName( "void" )
1050*13cfd8dfSPedro Giffuni
1051cdf0e10cSrcweir    def hasElements( self ):
1052cdf0e10cSrcweir        log.debug( "hasElements got called")
1053cdf0e10cSrcweir        return False
1054*13cfd8dfSPedro Giffuni
1055cdf0e10cSrcweirg_ImplementationHelper.addImplementation( \
1056*13cfd8dfSPedro Giffuni        PythonScriptProvider,g_implName, \
1057cdf0e10cSrcweir    ("com.sun.star.script.provider.LanguageScriptProvider",
1058cdf0e10cSrcweir     "com.sun.star.script.provider.ScriptProviderFor"+ LANGUAGENAME,),)
1059cdf0e10cSrcweir
1060cdf0e10cSrcweir
1061cdf0e10cSrcweirlog.debug( "pythonscript finished intializing" )
1062