1# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- 2# 3# This file is part of the LibreOffice project. 4# 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/. 8# 9# This file incorporates work covered by the following license notice: 10# 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 . 18# 19import pyuno 20import sys 21import traceback 22import warnings 23 24# since on Windows sal3.dll no longer calls WSAStartup 25import socket 26 27# Some Python 2/3 compatibility code copied from the six library 28PY2 = sys.version_info[0] == 2 29 30if PY2: 31 six_string_types = basestring, 32else: 33 six_string_types = str, 34 35# All functions and variables starting with a underscore (_) must be 36# considered private and can be changed at any time. Don't use them. 37_component_context = pyuno.getComponentContext() 38 39 40def getComponentContext(): 41 """Returns the UNO component context used to initialize the Python runtime.""" 42 43 return _component_context 44 45 46def getCurrentContext(): 47 """Returns the current context. 48 49 See http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context 50 for an explanation on the current context concept. 51 """ 52 53 return pyuno.getCurrentContext() 54 55 56def setCurrentContext(newContext): 57 """Sets newContext as new UNO context. 58 59 The newContext must implement the XCurrentContext interface. The 60 implementation should handle the desired properties and delegate 61 unknown properties to the old context. Ensure that the old one 62 is reset when you leave your stack, see 63 http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context 64 """ 65 66 return pyuno.setCurrentContext(newContext) 67 68 69def getConstantByName(constant): 70 """Looks up the value of an IDL constant by giving its explicit name.""" 71 72 return pyuno.getConstantByName(constant) 73 74 75def getTypeByName(typeName): 76 """Returns a `uno.Type` instance of the type given by typeName. 77 78 If the type does not exist, a `com.sun.star.uno.RuntimeException` is raised. 79 """ 80 81 return pyuno.getTypeByName(typeName) 82 83 84def createUnoStruct(typeName, *args, **kwargs): 85 """Creates a UNO struct or exception given by typeName. 86 87 Can be called with: 88 89 1) No additional argument. 90 In this case, you get a default constructed UNO structure. 91 (e.g. `createUnoStruct("com.sun.star.uno.Exception")`) 92 2) Exactly one additional argument that is an instance of typeName. 93 In this case, a copy constructed instance of typeName is returned 94 (e.g. `createUnoStruct("com.sun.star.uno.Exception" , e)`) 95 3) As many additional arguments as the number of elements within typeName 96 (e.g. `createUnoStruct("com.sun.star.uno.Exception", "foo error" , self)`). 97 4) Keyword arguments to give values for each element of the struct by name. 98 5) A mix of 3) and 4), such that each struct element is given a value exactly once, 99 either by a positional argument or by a keyword argument. 100 101 The additional and/or keyword arguments must match the type of each struct element, 102 otherwise an exception is thrown. 103 """ 104 105 return getClass(typeName)(*args, **kwargs) 106 107 108def getClass(typeName): 109 """Returns the class of a concrete UNO exception, struct, or interface.""" 110 111 return pyuno.getClass(typeName) 112 113 114def isInterface(obj): 115 """Returns True, when obj is a class of a UNO interface.""" 116 117 return pyuno.isInterface(obj) 118 119 120def generateUuid(): 121 """Returns a 16 byte sequence containing a newly generated uuid or guid. 122 123 For more information, see rtl/uuid.h. 124 """ 125 126 return pyuno.generateUuid() 127 128 129def systemPathToFileUrl(systemPath): 130 """Returns a file URL for the given system path.""" 131 132 return pyuno.systemPathToFileUrl(systemPath) 133 134 135def fileUrlToSystemPath(url): 136 """Returns a system path. 137 138 This path is determined by the system that the Python interpreter is running on. 139 """ 140 141 return pyuno.fileUrlToSystemPath(url) 142 143 144def absolutize(path, relativeUrl): 145 """Returns an absolute file url from the given urls.""" 146 147 return pyuno.absolutize(path, relativeUrl) 148 149 150class Enum: 151 """Represents a UNO enum. 152 153 Use an instance of this class to explicitly pass an enum to UNO. 154 155 :param typeName: The name of the enum as a string. 156 :param value: The actual value of this enum as a string. 157 """ 158 159 def __init__(self, typeName, value): 160 self.typeName = typeName 161 self.value = value 162 pyuno.checkEnum(self) 163 164 def __repr__(self): 165 return "<Enum instance %s (%r)>" % (self.typeName, self.value) 166 167 def __eq__(self, that): 168 if not isinstance(that, Enum): 169 return False 170 171 return (self.typeName == that.typeName) and (self.value == that.value) 172 173 def __ne__(self,other): 174 return not self.__eq__(other) 175 176 177class Type: 178 """Represents a UNO type. 179 180 Use an instance of this class to explicitly pass a type to UNO. 181 182 :param typeName: Name of the UNO type 183 :param typeClass: Python Enum of TypeClass, see com/sun/star/uno/TypeClass.idl 184 """ 185 186 def __init__(self, typeName, typeClass): 187 self.typeName = typeName 188 self.typeClass = typeClass 189 pyuno.checkType(self) 190 191 def __repr__(self): 192 return "<Type instance %s (%r)>" % (self.typeName, self.typeClass) 193 194 def __eq__(self, that): 195 if not isinstance(that, Type): 196 return False 197 198 return self.typeClass == that.typeClass and self.typeName == that.typeName 199 200 def __ne__(self,other): 201 return not self.__eq__(other) 202 203 def __hash__(self): 204 return self.typeName.__hash__() 205 206 207class Bool(object): 208 """Represents a UNO boolean. 209 210 Use an instance of this class to explicitly pass a boolean to UNO. 211 212 Note: This class is deprecated. Use Python's True and False directly instead. 213 """ 214 215 def __new__(cls, value): 216 message = "The Bool class is deprecated. Use Python's True and False directly instead." 217 warnings.warn(message, DeprecationWarning) 218 219 if isinstance(value, six_string_types) and value == "true": 220 return True 221 222 if isinstance(value, six_string_types) and value == "false": 223 return False 224 225 if value: 226 return True 227 228 return False 229 230 231class Char: 232 """Represents a UNO char. 233 234 Use an instance of this class to explicitly pass a char to UNO. 235 236 For Python 2, this class only works with unicode objects. Creating 237 a Char instance with a normal str object or comparing a Char instance 238 to a normal str object will raise an AssertionError. 239 240 :param value: A Unicode string with length 1 241 """ 242 243 def __init__(self, value): 244 if PY2: 245 assert isinstance(value, unicode), "Expected unicode object, got %s instead." % type(value) 246 else: 247 assert isinstance(value, str), "Expected str object, got %s instead." % type(value) 248 249 assert len(value) == 1, "Char value must have length of 1." 250 251 self.value = value 252 253 def __repr__(self): 254 return "<Char instance %s>" % (self.value,) 255 256 def __eq__(self, that): 257 if isinstance(that, six_string_types): 258 if len(that) > 1: 259 return False 260 261 return self.value == that[0] 262 263 if isinstance(that, Char): 264 return self.value == that.value 265 266 return False 267 268 def __ne__(self,other): 269 return not self.__eq__(other) 270 271 272class ByteSequence: 273 """Represents a UNO ByteSequence value. 274 275 Use an instance of this class to explicitly pass a byte sequence to UNO. 276 277 :param value: A string or bytesequence 278 """ 279 280 def __init__(self, value): 281 if isinstance(value, bytes): 282 self.value = value 283 284 elif isinstance(value, ByteSequence): 285 self.value = value.value 286 287 else: 288 raise TypeError("Expected bytes object or ByteSequence, got %s instead." % type(value)) 289 290 def __repr__(self): 291 return "<ByteSequence instance '%s'>" % (self.value,) 292 293 def __eq__(self, that): 294 if isinstance(that, bytes): 295 return self.value == that 296 297 if isinstance(that, ByteSequence): 298 return self.value == that.value 299 300 return False 301 302 def __len__(self): 303 return len(self.value) 304 305 def __getitem__(self, index): 306 return self.value[index] 307 308 def __iter__(self): 309 return self.value.__iter__() 310 311 def __add__(self, b): 312 if isinstance(b, bytes): 313 return ByteSequence(self.value + b) 314 315 elif isinstance(b, ByteSequence): 316 return ByteSequence(self.value + b.value) 317 318 else: 319 raise TypeError("Can't add ByteString and %s." % type(b)) 320 321 def __hash__(self): 322 return self.value.hash() 323 324 325class Any: 326 """Represents a UNO Any value. 327 328 Use only in connection with uno.invoke() to pass an explicit typed Any. 329 """ 330 331 def __init__(self, type, value): 332 if isinstance(type, Type): 333 self.type = type 334 else: 335 self.type = getTypeByName(type) 336 337 self.value = value 338 339 340def invoke(object, methodname, argTuple): 341 """Use this function to pass exactly typed Anys to the callee (using uno.Any).""" 342 343 return pyuno.invoke(object, methodname, argTuple) 344 345 346# ----------------------------------------------------------------------------- 347# Don't use any functions beyond this point; private section, likely to change. 348# ----------------------------------------------------------------------------- 349_builtin_import = __import__ 350 351 352def _uno_import(name, *optargs, **kwargs): 353 """Overrides built-in import to allow directly importing LibreOffice classes.""" 354 355 try: 356 return _builtin_import(name, *optargs, **kwargs) 357 except ImportError as e: 358 # process optargs 359 globals, locals, fromlist = list(optargs)[:3] + [kwargs.get('globals', {}), kwargs.get('locals', {}), 360 kwargs.get('fromlist', [])][len(optargs):] 361 362 # from import form only, but skip if a uno lookup has already failed 363 if not fromlist or hasattr(e, '_uno_import_failed'): 364 raise 365 366 # hang onto exception for possible use on subsequent uno lookup failure 367 py_import_exc = e 368 369 mod = None 370 d = sys.modules 371 372 for module in name.split("."): 373 if module in d: 374 mod = d[module] 375 else: 376 # How to create a module ?? 377 mod = pyuno.__class__(module) 378 379 d = mod.__dict__ 380 381 RuntimeException = pyuno.getClass("com.sun.star.uno.RuntimeException") 382 383 for class_name in fromlist: 384 if class_name not in d: 385 failed = False 386 387 try: 388 # check for structs, exceptions or interfaces 389 d[class_name] = pyuno.getClass(name + "." + class_name) 390 except RuntimeException: 391 # check for enums 392 try: 393 d[class_name] = Enum(name, class_name) 394 except RuntimeException: 395 # check for constants 396 try: 397 d[class_name] = getConstantByName(name + "." + class_name) 398 except RuntimeException: 399 # check for constant group 400 try: 401 d[class_name] = _impl_getConstantGroupByName(name, class_name) 402 except ValueError: 403 failed = True 404 405 if failed: 406 # We have an import failure, but cannot distinguish between 407 # uno and non-uno errors as uno lookups are attempted for all 408 # "from xxx import yyy" imports following a python failure. 409 # 410 # In Python 3, the original python exception traceback is reused 411 # to help pinpoint the actual failing location. Its original 412 # message, unlike Python 2, is unlikely to be helpful for uno 413 # failures, as it most commonly is just a top level module like 414 # 'com'. So our exception appends the uno lookup failure. 415 # This is more ambiguous, but it plus the traceback should be 416 # sufficient to identify a root cause for python or uno issues. 417 # 418 # Our exception is raised outside of the nested exception 419 # handlers above, to avoid Python 3 nested exception 420 # information for the RuntimeExceptions during lookups. 421 # 422 # Finally, a private attribute is used to prevent further 423 # processing if this failure was in a nested import. That 424 # keeps the exception relevant to the primary failure point, 425 # preventing us from re-processing our own import errors. 426 427 uno_import_exc = ImportError("%s (or '%s.%s' is unknown)" % 428 (py_import_exc, name, class_name)) 429 430 if sys.version_info[0] >= 3: 431 uno_import_exc = uno_import_exc.with_traceback(py_import_exc.__traceback__) 432 433 uno_import_exc._uno_import_failed = True 434 raise uno_import_exc 435 436 return mod 437 438 439try: 440 import __builtin__ 441except ImportError: 442 import builtins as __builtin__ 443 444# hook into the __import__ chain 445__builtin__.__dict__['__import__'] = _uno_import 446 447 448class _ConstantGroup(object): 449 """Represents a group of UNOIDL constants.""" 450 451 __slots__ = ['_constants'] 452 453 def __init__(self, constants): 454 self._constants = constants 455 456 def __dir__(self): 457 return self._constants.keys() 458 459 def __getattr__(self, name): 460 if name in self._constants: 461 return self._constants[name] 462 463 raise AttributeError("The constant '%s' could not be found." % name) 464 465 466def _impl_getConstantGroupByName(module, group): 467 """Gets UNOIDL constant group by name.""" 468 469 constants = Enum('com.sun.star.uno.TypeClass', 'CONSTANTS') 470 one = Enum('com.sun.star.reflection.TypeDescriptionSearchDepth', 'ONE') 471 type_desc_mgr = _component_context.getValueByName('/singletons/com.sun.star.reflection.theTypeDescriptionManager') 472 type_descs = type_desc_mgr.createTypeDescriptionEnumeration(module, (constants,), one) 473 qualified_name = module + '.' + group 474 475 for type_desc in type_descs: 476 if type_desc.Name == qualified_name: 477 return _ConstantGroup(dict( 478 (c.Name.split('.')[-1], c.ConstantValue) 479 for c in type_desc.Constants)) 480 481 raise ValueError("The constant group '%s' could not be found." % qualified_name) 482 483 484def _uno_struct__init__(self, *args, **kwargs): 485 """Initializes a UNO struct. 486 487 Referenced from the pyuno shared library. 488 489 This function can be called with either an already constructed UNO struct, which it 490 will then just reference without copying, or with arguments to create a new UNO struct. 491 """ 492 493 # Check to see if this function was passed an existing UNO struct 494 if len(kwargs) == 0 and len(args) == 1 and getattr(args[0], "__class__", None) == self.__class__: 495 self.__dict__['value'] = args[0] 496 else: 497 struct, used = pyuno._createUnoStructHelper(self.__class__.__pyunostruct__, args, **kwargs) 498 499 for kwarg in kwargs.keys(): 500 if not used.get(kwarg): 501 RuntimeException = pyuno.getClass("com.sun.star.uno.RuntimeException") 502 raise RuntimeException("_uno_struct__init__: unused keyword argument '%s'." % kwarg, None) 503 504 self.__dict__["value"] = struct 505 506 507def _uno_struct__getattr__(self, name): 508 """Gets attribute from UNO struct. 509 510 Referenced from the pyuno shared library. 511 """ 512 513 return getattr(self.__dict__["value"], name) 514 515 516def _uno_struct__setattr__(self, name, value): 517 """Sets attribute on UNO struct. 518 519 Referenced from the pyuno shared library. 520 """ 521 522 return setattr(self.__dict__["value"], name, value) 523 524 525def _uno_struct__repr__(self): 526 """Converts a UNO struct to a printable string. 527 528 Referenced from the pyuno shared library. 529 """ 530 531 return repr(self.__dict__["value"]) 532 533 534def _uno_struct__str__(self): 535 """Converts a UNO struct to a string.""" 536 537 return str(self.__dict__["value"]) 538 539def _uno_struct__ne__(self, other): 540 return not self.__eq__(other) 541 542def _uno_struct__eq__(self, that): 543 """Compares two UNO structs. 544 545 Referenced from the pyuno shared library. 546 """ 547 548 if hasattr(that, "value"): 549 return self.__dict__["value"] == that.__dict__["value"] 550 551 return False 552 553 554def _uno_extract_printable_stacktrace(trace): 555 """Extracts a printable stacktrace. 556 557 Referenced from pyuno shared lib and pythonscript.py. 558 """ 559 560 return ''.join(traceback.format_tb(trace)) 561 562# vim: set shiftwidth=4 softtabstop=4 expandtab: 563