tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / pyuno / source / module / pyuno_struct.cxx
blob937345ac87b7eaf409f44690ae3f1f3573198510
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <sal/config.h>
22 #include <com/sun/star/beans/UnknownPropertyException.hpp>
23 #include <com/sun/star/beans/XMaterialHolder.hpp>
24 #include <com/sun/star/script/CannotConvertException.hpp>
25 #include <com/sun/star/script/XInvocation2.hpp>
26 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
28 #include "pyuno_impl.hxx"
30 using com::sun::star::uno::Sequence;
31 using com::sun::star::uno::Reference;
32 using com::sun::star::uno::Any;
33 using com::sun::star::uno::UNO_QUERY;
34 using com::sun::star::uno::TypeClass;
35 using com::sun::star::uno::RuntimeException;
36 using com::sun::star::uno::Exception;
37 using com::sun::star::lang::XSingleServiceFactory;
38 using com::sun::star::script::XInvocation2;
39 using com::sun::star::beans::XMaterialHolder;
41 namespace pyuno
44 static void PyUNOStruct_del( PyObject* self )
46 PyUNO *me = reinterpret_cast<PyUNO*>( self );
48 PyThreadDetach antiguard;
49 delete me->members;
51 PyObject_Del( self );
54 static PyObject *PyUNOStruct_str( PyObject *self )
56 PyUNO *me = reinterpret_cast<PyUNO*>( self );
57 OString buf;
59 Reference<XMaterialHolder> rHolder( me->members->xInvocation,UNO_QUERY );
60 if( rHolder.is() )
62 PyThreadDetach antiguard;
63 Any a = rHolder->getMaterial();
64 OUString s = val2str( a.getValue(), a.getValueType().getTypeLibType() );
65 buf = OUStringToOString( s, RTL_TEXTENCODING_ASCII_US );
68 return PyUnicode_FromString( buf.getStr());
71 static PyObject *PyUNOStruct_repr( PyObject *self )
73 PyUNO *me = reinterpret_cast<PyUNO*>( self );
74 PyObject *ret = nullptr;
76 if( me->members->wrappedObject.getValueTypeClass()
77 == css::uno::TypeClass_EXCEPTION )
79 Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
80 if( rHolder.is() )
82 Any a = rHolder->getMaterial();
83 Exception e;
84 a >>= e;
85 ret = ustring2PyUnicode(e.Message ).getAcquired();
88 else
90 ret = PyUNOStruct_str( self );
93 return ret;
96 static PyObject* PyUNOStruct_dir( PyObject *self )
98 PyUNO *me = reinterpret_cast<PyUNO*>( self );
100 PyObject* member_list = nullptr;
104 member_list = PyList_New( 0 );
105 const css::uno::Sequence<OUString> aMemberNames = me->members->xInvocation->getMemberNames();
106 for( const auto& aMember : aMemberNames )
108 // setitem steals a reference
109 PyList_Append( member_list, ustring2PyString( aMember ).getAcquired() );
112 catch( const RuntimeException &e )
114 raisePyExceptionWithAny( Any(e) );
117 return member_list;
120 static PyObject* PyUNOStruct_getattr( PyObject* self, char* name )
122 PyUNO *me = reinterpret_cast<PyUNO*>( self );
126 Runtime runtime;
128 if (strcmp (name, "__dict__") == 0)
130 Py_INCREF (Py_TYPE(me)->tp_dict);
131 return Py_TYPE(me)->tp_dict;
133 if( strcmp( name, "__class__" ) == 0 )
135 return getClass(
136 me->members->wrappedObject.getValueTypeName(), runtime ).getAcquired();
139 PyObject *pRet = PyObject_GenericGetAttr( self, PyUnicode_FromString( name ) );
140 if( pRet )
141 return pRet;
142 PyErr_Clear();
144 OUString attrName( OUString::createFromAscii( name ) );
145 if( me->members->xInvocation->hasProperty( attrName ) )
147 //Return the value of the property
148 Any anyRet;
150 PyThreadDetach antiguard;
151 anyRet = me->members->xInvocation->getValue( attrName );
153 PyRef ret = runtime.any2PyObject( anyRet );
154 Py_XINCREF( ret.get() );
155 return ret.get();
158 //or else...
159 PyErr_SetString (PyExc_AttributeError, name);
161 catch( const css::reflection::InvocationTargetException & e )
163 raisePyExceptionWithAny( e.TargetException );
165 catch( const css::beans::UnknownPropertyException & e )
167 raisePyExceptionWithAny( Any(e) );
169 catch( const css::lang::IllegalArgumentException &e )
171 raisePyExceptionWithAny( Any(e) );
173 catch( const css::script::CannotConvertException &e )
175 raisePyExceptionWithAny( Any(e) );
177 catch( const RuntimeException &e )
179 raisePyExceptionWithAny( Any(e) );
182 return nullptr;
185 static int PyUNOStruct_setattr (PyObject* self, char* name, PyObject* value)
187 PyUNO* me = reinterpret_cast<PyUNO*>(self);
190 Runtime runtime;
191 Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
193 OUString attrName( OUString::createFromAscii( name ) );
195 PyThreadDetach antiguard;
196 if (me->members->xInvocation->hasProperty (attrName))
198 me->members->xInvocation->setValue (attrName, val);
199 return 0; //Keep with Python's boolean system
203 catch( const css::reflection::InvocationTargetException & e )
205 raisePyExceptionWithAny( e.TargetException );
206 return 1;
208 catch( const css::beans::UnknownPropertyException & e )
210 raisePyExceptionWithAny( Any(e) );
211 return 1;
213 catch( const css::script::CannotConvertException &e )
215 raisePyExceptionWithAny( Any(e) );
216 return 1;
218 catch( const RuntimeException & e )
220 raisePyExceptionWithAny( Any( e ) );
221 return 1;
223 PyErr_SetString (PyExc_AttributeError, name);
224 return 1; //as above.
228 static PyObject* PyUNOStruct_cmp( PyObject *self, PyObject *that, int op )
230 PyObject *result;
232 if(op != Py_EQ && op != Py_NE)
234 PyErr_SetString( PyExc_TypeError, "only '==' and '!=' comparisons are defined" );
235 return nullptr;
237 if( self == that )
239 result = (op == Py_EQ ? Py_True : Py_False);
240 Py_INCREF( result );
241 return result;
245 Runtime runtime;
246 if( PyObject_IsInstance( that, getPyUnoStructClass().get() ) )
249 PyUNO *me = reinterpret_cast< PyUNO * > ( self );
250 PyUNO *other = reinterpret_cast< PyUNO * > ( that );
251 css::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
252 css::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
254 if( tcMe == tcOther )
256 if( tcMe == css::uno::TypeClass_STRUCT ||
257 tcMe == css::uno::TypeClass_EXCEPTION )
259 Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY );
260 Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
261 if( xMe->getMaterial() == xOther->getMaterial() )
263 result = (op == Py_EQ ? Py_True : Py_False);
264 Py_INCREF( result );
265 return result;
271 catch( const css::uno::RuntimeException & e)
273 raisePyExceptionWithAny( Any( e ) );
276 result = (op == Py_EQ ? Py_False : Py_True);
277 Py_INCREF(result);
278 return result;
281 #if defined __GNUC__ && !defined __clang__
282 #pragma GCC diagnostic push
283 #pragma GCC diagnostic ignored "-Wcast-function-type"
284 #endif
285 static PyMethodDef PyUNOStructMethods[] =
287 #if defined __clang__
288 #if __has_warning("-Wcast-function-type-mismatch")
289 #pragma clang diagnostic push
290 #pragma clang diagnostic ignored "-Wcast-function-type-mismatch"
291 #endif
292 #endif
293 {"__dir__", reinterpret_cast<PyCFunction>(PyUNOStruct_dir), METH_NOARGS, nullptr},
294 #if defined __clang__
295 #if __has_warning("-Wcast-function-type-mismatch")
296 #pragma clang diagnostic pop
297 #endif
298 #endif
299 {nullptr, nullptr, 0, nullptr}
301 #if defined __GNUC__ && !defined __clang__
302 #pragma GCC diagnostic pop
303 #endif
305 static PyTypeObject PyUNOStructType =
307 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
308 "pyuno.struct",
309 sizeof (PyUNO),
311 PyUNOStruct_del,
312 #if PY_VERSION_HEX >= 0x03080000
313 0, // Py_ssize_t tp_vectorcall_offset
314 #else
315 nullptr, // printfunc tp_print
316 #endif
317 PyUNOStruct_getattr,
318 PyUNOStruct_setattr,
319 /* this type does not exist in Python 3: (cmpfunc) */ nullptr,
320 PyUNOStruct_repr,
321 nullptr,
322 nullptr,
323 nullptr,
324 nullptr,
325 nullptr,
326 PyUNOStruct_str,
327 nullptr,
328 nullptr,
329 nullptr,
330 Py_TPFLAGS_HAVE_RICHCOMPARE,
331 nullptr,
332 nullptr,
333 nullptr,
334 PyUNOStruct_cmp,
336 nullptr,
337 nullptr,
338 PyUNOStructMethods,
339 nullptr,
340 nullptr,
341 nullptr,
342 nullptr,
343 nullptr,
344 nullptr,
346 nullptr,
347 nullptr,
348 nullptr,
349 nullptr,
350 nullptr,
351 nullptr,
352 nullptr,
353 nullptr,
354 nullptr,
355 nullptr,
356 nullptr
358 #if PY_VERSION_HEX >= 0x03040000
359 , nullptr
360 #if PY_VERSION_HEX >= 0x03080000
361 , nullptr // vectorcallfunc tp_vectorcall
362 #if PY_VERSION_HEX < 0x03090000
363 #if defined __clang__
364 #pragma clang diagnostic push
365 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
366 #endif
367 , nullptr // tp_print
368 #if defined __clang__
369 #pragma clang diagnostic pop
370 #endif
371 #endif
372 #if PY_VERSION_HEX >= 0x030C00A1
373 , 0 // tp_watched
374 #endif
375 #endif
376 #endif
379 int PyUNOStruct_initType()
381 return PyType_Ready( &PyUNOStructType );
384 PyRef getPyUnoStructClass()
386 return PyRef( reinterpret_cast< PyObject * > ( &PyUNOStructType ) );
389 PyRef PyUNOStruct_new (
390 const Any &targetInterface,
391 const Reference<XSingleServiceFactory> &ssf )
393 Reference<XInvocation2> xInvocation;
396 PyThreadDetach antiguard;
397 xInvocation.set(
398 ssf->createInstanceWithArguments( Sequence<Any>( &targetInterface, 1 ) ), css::uno::UNO_QUERY_THROW );
400 if( !Py_IsInitialized() )
401 throw RuntimeException();
403 PyUNO* self = PyObject_New (PyUNO, &PyUNOStructType);
404 if (self == nullptr)
405 return PyRef(); // == error
406 self->members = new PyUNOInternals;
407 self->members->xInvocation = std::move(xInvocation);
408 self->members->wrappedObject = targetInterface;
409 return PyRef( reinterpret_cast<PyObject*>(self), SAL_NO_ACQUIRE );
415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */