Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / pyuno / source / module / uno.py
blob6f8744bc034822f9746dfe328ae4b45bab59d4dd
1 # -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 # This file incorporates work covered by the following license notice:
11 # Licensed to the Apache Software Foundation (ASF) under one or more
12 # contributor license agreements. See the NOTICE file distributed
13 # with this work for additional information regarding copyright
14 # ownership. The ASF licenses this file to you under the Apache
15 # License, Version 2.0 (the "License"); you may not use this file
16 # except in compliance with the License. You may obtain a copy of
17 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 import sys
21 import pyuno
23 try:
24 import __builtin__
25 except ImportError:
26 import builtins as __builtin__
28 try:
29 unicode
30 except NameError:
31 # Python 3 compatibility
32 unicode = str
34 import socket # since on Windows sal3.dll no longer calls WSAStartup
36 # all functions and variables starting with a underscore (_) must be considered private
37 # and can be changed at any time. Don't use them
38 _g_ctx = pyuno.getComponentContext( )
39 _g_delegatee = __builtin__.__dict__["__import__"]
41 def getComponentContext():
42 """ returns the UNO component context, that was used to initialize the python runtime.
43 """
44 return _g_ctx
46 def getConstantByName( constant ):
47 "Looks up the value of a idl constant by giving its explicit name"
48 return pyuno.getConstantByName( constant )
50 def getTypeByName( typeName):
51 """ returns a uno.Type instance of the type given by typeName. In case the
52 type does not exist, a com.sun.star.uno.RuntimeException is raised.
53 """
54 return pyuno.getTypeByName( typeName )
56 def createUnoStruct( typeName, *args, **kwargs ):
57 """creates a uno struct or exception given by typeName. Can be called with:
58 1) No additional argument.
59 In this case, you get a default constructed uno structure.
60 ( e.g. createUnoStruct( "com.sun.star.uno.Exception" ) )
61 2) Exactly one additional argument that is an instance of typeName.
62 In this case, a copy constructed instance of typeName is returned
63 ( e.g. createUnoStruct( "com.sun.star.uno.Exception" , e ) )
64 3) As many additional arguments as the number of elements within typeName
65 (e.g. createUnoStruct( "com.sun.star.uno.Exception", "foo error" , self) ).
66 4) Keyword arguments to give values for each element of the struct by name.
67 5) A mix of 3) and 4), such that each struct element is given a value exactly once,
68 either by a positional argument or by a keyword argument.
69 The additional and/or keyword arguments must match the type of each struct element,
70 otherwise an exception is thrown.
71 """
72 return getClass(typeName)( *args, **kwargs )
74 def getClass( typeName ):
75 """returns the class of a concrete uno exception, struct or interface
76 """
77 return pyuno.getClass(typeName)
79 def isInterface( obj ):
80 """returns true, when obj is a class of a uno interface"""
81 return pyuno.isInterface( obj )
83 def generateUuid():
84 "returns a 16 byte sequence containing a newly generated uuid or guid, see rtl/uuid.h "
85 return pyuno.generateUuid()
87 def systemPathToFileUrl( systemPath ):
88 "returns a file-url for the given system path"
89 return pyuno.systemPathToFileUrl( systemPath )
91 def fileUrlToSystemPath( url ):
92 "returns a system path (determined by the system, the python interpreter is running on)"
93 return pyuno.fileUrlToSystemPath( url )
95 def absolutize( path, relativeUrl ):
96 "returns an absolute file url from the given urls"
97 return pyuno.absolutize( path, relativeUrl )
99 def getCurrentContext():
100 """Returns the currently valid current context.
101 see http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context
102 for an explanation on the current context concept
104 return pyuno.getCurrentContext()
106 def setCurrentContext( newContext ):
107 """Sets newContext as new uno current context. The newContext must
108 implement the XCurrentContext interface. The implemenation should
109 handle the desired properties and delegate unknown properties to the
110 old context. Ensure to reset the old one when you leave your stack ...
111 see http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context
113 return pyuno.setCurrentContext( newContext )
116 class Enum:
117 "Represents a UNO idl enum, use an instance of this class to explicitly pass a boolean to UNO"
118 #typeName the name of the enum as a string
119 #value the actual value of this enum as a string
120 def __init__(self,typeName, value):
121 self.typeName = typeName
122 self.value = value
123 pyuno.checkEnum( self )
125 def __repr__(self):
126 return "<uno.Enum %s (%r)>" % (self.typeName, self.value)
128 def __eq__(self, that):
129 if not isinstance(that, Enum):
130 return False
131 return (self.typeName == that.typeName) and (self.value == that.value)
133 class Type:
134 "Represents a UNO type, use an instance of this class to explicitly pass a boolean to UNO"
135 # typeName # Name of the UNO type
136 # typeClass # python Enum of TypeClass, see com/sun/star/uno/TypeClass.idl
137 def __init__(self, typeName, typeClass):
138 self.typeName = typeName
139 self.typeClass = typeClass
140 pyuno.checkType(self)
141 def __repr__(self):
142 return "<Type instance %s (%r)>" % (self.typeName, self.typeClass)
144 def __eq__(self, that):
145 if not isinstance(that, Type):
146 return False
147 return self.typeClass == that.typeClass and self.typeName == that.typeName
149 def __hash__(self):
150 return self.typeName.__hash__()
152 class Bool(object):
153 """Represents a UNO boolean, use an instance of this class to explicitly
154 pass a boolean to UNO.
155 Note: This class is deprecated. Use python's True and False directly instead
157 def __new__(cls, value):
158 if isinstance(value, (str, unicode)) and value == "true":
159 return True
160 if isinstance(value, (str, unicode)) and value == "false":
161 return False
162 if value:
163 return True
164 return False
166 class Char:
167 "Represents a UNO char, use an instance of this class to explicitly pass a char to UNO"
168 # @param value pass a Unicode string with length 1
169 def __init__(self,value):
170 assert isinstance(value, unicode)
171 assert len(value) == 1
172 self.value=value
174 def __repr__(self):
175 return "<Char instance %s>" % (self.value, )
177 def __eq__(self, that):
178 if isinstance(that, (str, unicode)):
179 if len(that) > 1:
180 return False
181 return self.value == that[0]
182 if isinstance(that, Char):
183 return self.value == that.value
184 return False
186 # Suggested by Christian, but still some open problems which need to be solved first
188 #class ByteSequence(str):
190 # def __repr__(self):
191 # return "<ByteSequence instance %s>" % str.__repr__(self)
193 # for a little bit compatitbility; setting value is not possible as
194 # strings are immutable
195 # def _get_value(self):
196 # return self
198 # value = property(_get_value)
200 class ByteSequence:
201 def __init__(self, value):
202 if isinstance(value, bytes):
203 self.value = value
204 elif isinstance(value, str):
205 self.value = value.encode("utf-8") # Python 2 compatibility
206 elif isinstance(value, ByteSequence):
207 self.value = value.value
208 else:
209 raise TypeError("expected string or bytesequence")
211 def __repr__(self):
212 return "<ByteSequence instance '%s'>" % (self.value, )
214 def __eq__(self, that):
215 if isinstance( that, ByteSequence):
216 return self.value == that.value
217 if isinstance(that, bytes):
218 return self.value == that
219 if isinstance(that, str):
220 return self.value == that.encode("utf-8")
221 return False
223 def __len__(self):
224 return len(self.value)
226 def __getitem__(self, index):
227 return self.value[index]
229 def __iter__( self ):
230 return self.value.__iter__()
232 def __add__( self , b ):
233 if isinstance( b, bytes):
234 return ByteSequence(self.value + b)
235 elif isinstance( b, str ):
236 return ByteSequence( self.value + b.encode("utf-8") )
237 elif isinstance( b, ByteSequence ):
238 return ByteSequence( self.value + b.value )
239 raise TypeError( "expected string or ByteSequence as operand" )
241 def __hash__( self ):
242 return self.value.hash()
245 class Any:
246 "use only in connection with uno.invoke() to pass an explicit typed any"
247 def __init__(self, type, value ):
248 if isinstance( type, Type ):
249 self.type = type
250 else:
251 self.type = getTypeByName( type )
252 self.value = value
254 def invoke( object, methodname, argTuple ):
255 "use this function to pass exactly typed anys to the callee (using uno.Any)"
256 return pyuno.invoke( object, methodname, argTuple )
258 #---------------------------------------------------------------------------------------
259 # don't use any functions beyond this point, private section, likely to change
260 #---------------------------------------------------------------------------------------
261 #def _uno_import( name, globals={}, locals={}, fromlist=[], level=-1 ):
262 def _uno_import( name, *optargs, **kwargs ):
263 try:
264 # print "optargs = " + repr(optargs)
265 return _g_delegatee( name, *optargs, **kwargs )
266 except ImportError as e:
267 # process optargs
268 globals, locals, fromlist = list(optargs)[:3] + [kwargs.get('globals',{}), kwargs.get('locals',{}), kwargs.get('fromlist',[])][len(optargs):]
269 # from import form only, but skip if an uno lookup has already failed
270 if not fromlist or hasattr(e, '_uno_import_failed'):
271 raise
272 # hang onto exception for possible use on subsequent uno lookup failure
273 py_import_exc = e
274 modnames = name.split( "." )
275 mod = None
276 d = sys.modules
277 for x in modnames:
278 if x in d:
279 mod = d[x]
280 else:
281 mod = pyuno.__class__(x) # How to create a module ??
282 d = mod.__dict__
284 RuntimeException = pyuno.getClass( "com.sun.star.uno.RuntimeException" )
285 for x in fromlist:
286 if x not in d:
287 failed = False
288 if x.startswith( "typeOf" ):
289 try:
290 d[x] = pyuno.getTypeByName( name + "." + x[6:len(x)] )
291 except RuntimeException:
292 failed = True
293 else:
294 try:
295 # check for structs, exceptions or interfaces
296 d[x] = pyuno.getClass( name + "." + x )
297 except RuntimeException:
298 # check for enums
299 try:
300 d[x] = Enum( name , x )
301 except RuntimeException:
302 # check for constants
303 try:
304 d[x] = getConstantByName( name + "." + x )
305 except RuntimeException:
306 failed = True
308 if failed:
309 # We have an import failure, but cannot distinguish between
310 # uno and non-uno errors as uno lookups are attempted for all
311 # "from xxx import yyy" imports following a python failure.
313 # In Python 3, the original python exception traceback is reused
314 # to help pinpoint the actual failing location. Its original
315 # message, unlike Python 2, is unlikely to be helpful for uno
316 # failures, as it most commonly is just a top level module like
317 # 'com'. So our exception appends the uno lookup failure.
318 # This is more ambiguous, but it plus the traceback should be
319 # sufficient to identify a root cause for python or uno issues.
321 # Our exception is raised outside of the nested exception
322 # handlers above, to avoid Python 3 nested exception
323 # information for the RuntimeExceptions during lookups.
325 # Finally, a private attribute is used to prevent further
326 # processing if this failure was in a nested import. That
327 # keeps the exception relevant to the primary failure point,
328 # preventing us from re-processing our own import errors.
330 uno_import_exc = ImportError("%s (or '%s.%s' is unknown)" %
331 (py_import_exc, name, x))
332 if sys.version_info[0] >= 3:
333 uno_import_exc = uno_import_exc.with_traceback(py_import_exc.__traceback__)
334 uno_import_exc._uno_import_failed = True
335 raise uno_import_exc
337 return mod
339 # private function, don't use
340 def _impl_extractName(name):
341 r = list(range(len(name)-1,0,-1))
342 for i in r:
343 if name[i] == ".":
344 name = name[i+1:len(name)]
345 break
346 return name
348 # private, referenced from the pyuno shared library
349 def _uno_struct__init__(self,*args, **kwargs):
350 if len(kwargs) == 0 and len(args) == 1 and hasattr(args[0], "__class__") and args[0].__class__ == self.__class__ :
351 self.__dict__["value"] = args[0]
352 else:
353 struct, used = pyuno._createUnoStructHelper(self.__class__.__pyunostruct__,args,**kwargs)
354 for kw in kwargs.keys():
355 if not (kw in used and used[kw]):
356 RuntimeException = pyuno.getClass( "com.sun.star.uno.RuntimeException" )
357 raise RuntimeException("_uno_struct__init__: unused keyword argument '" + kw + "'", None)
358 self.__dict__["value"] = struct
360 # private, referenced from the pyuno shared library
361 def _uno_struct__getattr__(self,name):
362 return __builtin__.getattr(self.__dict__["value"],name)
364 # private, referenced from the pyuno shared library
365 def _uno_struct__setattr__(self,name,value):
366 return __builtin__.setattr(self.__dict__["value"],name,value)
368 # private, referenced from the pyuno shared library
369 def _uno_struct__repr__(self):
370 return repr(self.__dict__["value"])
372 def _uno_struct__str__(self):
373 return str(self.__dict__["value"])
375 # private, referenced from the pyuno shared library
376 def _uno_struct__eq__(self,cmp):
377 if hasattr(cmp,"value"):
378 return self.__dict__["value"] == cmp.__dict__["value"]
379 return False
381 # referenced from pyuno shared lib and pythonscript.py
382 def _uno_extract_printable_stacktrace( trace ):
383 mod = None
384 try:
385 mod = __import__("traceback")
386 except ImportError as e:
387 pass
388 ret = ""
389 if mod:
390 lst = mod.extract_tb( trace )
391 max = len(lst)
392 for j in range(max):
393 i = lst[max-j-1]
394 ret = ret + " " + str(i[0]) + ":" + \
395 str(i[1]) + " in function " + \
396 str(i[2]) + "() [" + str(i[3]) + "]\n"
397 else:
398 ret = "Couldn't import traceback module"
399 return ret
401 # hook into the __import__ chain
402 __builtin__.__dict__["__import__"] = _uno_import
404 # vim:set shiftwidth=4 softtabstop=4 expandtab: