diff options
author | Patrick Monnerat <[email protected]> | 2019-02-17 17:36:11 +0100 |
---|---|---|
committer | raveit65 <[email protected]> | 2019-03-31 12:30:00 +0200 |
commit | 1d5a8b7aa497c6d3d3257887f95832eda397347c (patch) | |
tree | 65471eef27198f9eeb9cf5c3c7f79fb05c13a729 | |
parent | 75906bebc8b7ce8adef7040d5bebde8ff7f59090 (diff) | |
download | python-caja-1d5a8b7aa497c6d3d3257887f95832eda397347c.tar.bz2 python-caja-1d5a8b7aa497c6d3d3257887f95832eda397347c.tar.xz |
Make Caja.OperationHandle usable.
The Caja.OperationHandle.handle property is added: this gives access to the
effective handle taking the form of a non-zero signed integer that can be
stored in a void pointer. Trying to set this property with an invalid value
raises an exception.
Upon update_file_info_full call, the new Caja.OperationHandle is preset with
a "unique" non-null value generated from an atomic counter. When the python
method returns, the handle value is transmitted to Caja whatever it is:
this fixes the problem of Caja expecting a non-null handle when
CAJA_OPERATION_IN_PROGRESS is returned.
Ref: https://github.com/mate-desktop/python-caja/issues/36
-rw-r--r-- | docs/Makefile.am | 4 | ||||
-rw-r--r-- | docs/reference/caja-python-class-reference.xml | 1 | ||||
-rw-r--r-- | docs/reference/caja-python-info-provider.xml | 6 | ||||
-rw-r--r-- | docs/reference/caja-python-operation-handle.xml | 68 | ||||
-rw-r--r-- | src/caja-python-object.c | 19 | ||||
-rw-r--r-- | src/caja-python.c | 53 |
6 files changed, 145 insertions, 6 deletions
diff --git a/docs/Makefile.am b/docs/Makefile.am index 70021bc..b05ab92 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -24,7 +24,8 @@ XML_FILES = \ reference/caja-python-file-info.xml \ reference/caja-python-info-provider.xml \ reference/caja-python-enum-reference.xml \ - reference/caja-python-operation-result.xml + reference/caja-python-operation-result.xml \ + reference/caja-python-operation-handle.xml HTMLdir = $(datadir)/gtk-doc/html/caja-python HTML_FILES = \ @@ -45,6 +46,7 @@ HTML_FILES = \ html/class-caja-python-location-widget-provider.html \ html/class-caja-python-file-info.html \ html/class-caja-python-info-provider.html \ + html/class-caja-python-operation-handle.html \ html/caja-python-enum-reference.html \ html/enum-caja-python-operation-result.html \ html/caja-python.devhelp diff --git a/docs/reference/caja-python-class-reference.xml b/docs/reference/caja-python-class-reference.xml index 5386ee9..ca47353 100644 --- a/docs/reference/caja-python-class-reference.xml +++ b/docs/reference/caja-python-class-reference.xml @@ -10,5 +10,6 @@ <xi:include href="caja-python-menu.xml"/> <xi:include href="caja-python-menu-item.xml"/> <xi:include href="caja-python-property-page.xml"/> + <xi:include href="caja-python-operation-handle.xml"/> </chapter> diff --git a/docs/reference/caja-python-info-provider.xml b/docs/reference/caja-python-info-provider.xml index 424fdb0..b8ca549 100644 --- a/docs/reference/caja-python-info-provider.xml +++ b/docs/reference/caja-python-info-provider.xml @@ -127,7 +127,7 @@ class ColumnExtension(GObject.GObject, Caja.InfoProvider): </varlistentry> <varlistentry> <term><parameter role="keyword">handle</parameter> :</term> - <listitem><simpara>a <classname>gobject.gpointer</classname> generated solely to track this call</simpara></listitem> + <listitem><simpara>a <link linkend="class-caja-python-operation-handle"><classname>Caja.OperationHandle</classname></link> generated solely to track this call</simpara></listitem> </varlistentry> <varlistentry> <term><parameter role="keyword">closure</parameter> :</term> @@ -184,7 +184,7 @@ class ColumnExtension(GObject.GObject, Caja.InfoProvider): </varlistentry> <varlistentry> <term><parameter role="keyword">handle</parameter> :</term> - <listitem><simpara>a <classname>gobject.gpointer</classname> generated by a specific update_file_info_full call</simpara></listitem> + <listitem><simpara>a <link linkend="class-caja-python-operation-handle"><classname>Caja.OperationHandle</classname></link> generated for a specific update_file_info_full call</simpara></listitem> </varlistentry> </variablelist> @@ -221,7 +221,7 @@ class ColumnExtension(GObject.GObject, Caja.InfoProvider): </varlistentry> <varlistentry> <term><parameter role="keyword">handle</parameter> :</term> - <listitem><simpara>a <classname>gobject.gpointer</classname> generated by a specific update_file_info_full call</simpara></listitem> + <listitem><simpara>a <link linkend="class-caja-python-operation-handle"><classname>Caja.OperationHandle</classname></link> generated for a specific update_file_info_full call</simpara></listitem> </varlistentry> <varlistentry> <term><parameter role="keyword">closure</parameter> :</term> diff --git a/docs/reference/caja-python-operation-handle.xml b/docs/reference/caja-python-operation-handle.xml new file mode 100644 index 0000000..379b51c --- /dev/null +++ b/docs/reference/caja-python-operation-handle.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> + +<refentry id="class-caja-python-operation-handle"> + <refnamediv> + <refname>Caja.OperationHandle</refname> + <refpurpose><link linkend="class-caja-python-file-info"><classname>Caja.FileInfo</classname></link> update in progress handle</refpurpose> + </refnamediv> + +<!-- ******************************* --> +<!-- BEGIN OF CAJA-PYTHON SYNOPSIS --> +<!-- ******************************* --> + + <refsect1> + <title>Synopsis</title> + + <classsynopsis language="python"> + <ooclass><classname>Caja.OperationHandle</classname></ooclass> + </classsynopsis> + </refsect1> + + +<!-- ********************************** --> +<!-- BEGIN OF DESCRIPTION --> +<!-- ********************************** --> + + <refsect1 id="description-operation-handle"> + <title>Description</title> + + <para> + A handle for a <link linkend="class-caja-python-file-info"><classname>Caja.FileInfo</classname></link> update operation in progress. The handle value is a non-zero signed integer that can be stored in a <classname>gobject.gpointer</classname>. It cannot be explicitly constructed and is always generated by Caja itself. + </para> + <para> + As every instance is created and initialized by Caja, handle values may be used as keys within the extension. It is however possible to update these values with more convenient ones. + </para> + + </refsect1> + + +<!-- *********************************** --> +<!-- BEGIN OF PROPERTIES --> +<!-- *********************************** --> + +<refsect1> + <title>Properties</title> + + <blockquote role="properties"> + <informaltable pgwide="1" frame="none"> + <tgroup cols="3"> + <colspec column="1" colwidth="1in"/> + <colspec column="2" colwidth="1in"/> + <colspec column="3" colwidth="4in"/> + <tbody> + + <row valign="top"> + <entry>"handle"</entry> + <entry>The unique handle value. Default value: preset by Caja.</entry> + <entry>Read-Write</entry> + </row> + + </tbody> + </tgroup> + </informaltable> + </blockquote> +</refsect1> + +</refentry> diff --git a/src/caja-python-object.c b/src/caja-python-object.c index e2bdf85..fbc5f79 100644 --- a/src/caja-python-object.c +++ b/src/caja-python-object.c @@ -411,20 +411,34 @@ caja_python_object_update_file_info (CajaInfoProvider *provider, CajaOperationResult ret = CAJA_OPERATION_COMPLETE; PyObject *py_ret = NULL; PyGILState_STATE state = pyg_gil_state_ensure(); - PyObject *py_handle = caja_python_boxed_new (_PyCajaOperationHandle_Type, *handle, FALSE); + static volatile gssize handle_generator = 1; debug_enter(); CHECK_OBJECT(object); + *handle = NULL; + if (PyObject_HasAttrString(object->instance, "update_file_info_full")) { + PyObject *py_handle; + void *h; + + /* Generate a new handle with a default value. */ + do { + h = (CajaOperationHandle *) g_atomic_pointer_add (&handle_generator, 1); + } while (!h); + py_handle = caja_python_boxed_new (_PyCajaOperationHandle_Type, + h, FALSE); + + py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX "update_file_info_full", "(NNNN)", pygobject_new((GObject*)provider), py_handle, pyg_boxed_new(G_TYPE_CLOSURE, update_complete, TRUE, TRUE), pygobject_new((GObject*)file)); + *handle = (void *) ((PyGBoxed *) py_handle)->boxed; } else if (PyObject_HasAttrString(object->instance, "update_file_info")) { @@ -447,6 +461,9 @@ caja_python_object_update_file_info (CajaInfoProvider *provider, } ret = INT_ASLONG(py_ret); + + if (!*handle && ret == CAJA_OPERATION_IN_PROGRESS) + ret = CAJA_OPERATION_FAILED; beach: free_pygobject_data(file, NULL); diff --git a/src/caja-python.c b/src/caja-python.c index e9940ab..f609b1e 100644 --- a/src/caja-python.c +++ b/src/caja-python.c @@ -22,6 +22,7 @@ #endif #include <Python.h> +#include <structmember.h> #include <pygobject.h> #include <gmodule.h> #include <gtk/gtk.h> @@ -33,8 +34,12 @@ #if PY_MAJOR_VERSION >= 3 #define STRING_FROMSTRING(str) PyUnicode_FromString(str) +#define INT_FROMSSIZE_T(val) PyLong_FromSsize_t(val) +#define INT_ASSSIZE_T(obj) PyLong_AsSsize_t(obj) #else #define STRING_FROMSTRING(str) PyString_FromString(str) +#define INT_FROMSSIZE_T(val) PyInt_FromSsize_t(val) +#define INT_ASSSIZE_T(obj) PyInt_AsSsize_t(obj) #endif static const GDebugKey caja_python_debug_keys[] = { @@ -49,6 +54,37 @@ static GArray *all_types = NULL; static GList *all_pyfiles = NULL; +/* Caja.OperationHandle value access. */ +static PyObject * +caja_operationhandle_get_handle(PyGBoxed *self, void *closure) +{ + return INT_FROMSSIZE_T((Py_ssize_t) (size_t) self->boxed); +} + +static int +caja_operationhandle_set_handle(PyGBoxed *self, PyObject *value, void *closure) +{ + Py_ssize_t val = INT_ASSSIZE_T(value); + + if (!PyErr_Occurred()) { + if (val) { + self->boxed = (void *) val; + return 0; + } + PyErr_SetString(PyExc_ValueError, "invalid operation handle value"); + } + return -1; +} + +static PyGetSetDef caja_operationhandle_handle = { + "handle", + (getter) caja_operationhandle_get_handle, + (setter) caja_operationhandle_set_handle, + "Operation handle value", + NULL +}; + + static inline gboolean np_init_pygobject(void) { @@ -163,7 +199,7 @@ caja_python_load_dir (GTypeModule *module, static gboolean caja_python_init_python (void) { - PyObject *gi, *require_version, *args, *caja; + PyObject *gi, *require_version, *args, *caja, *descr; GModule *libpython; #if PY_MAJOR_VERSION >= 3 wchar_t *argv[] = { L"caja", NULL }; @@ -256,6 +292,21 @@ caja_python_init_python (void) IMPORT(OperationHandle, "OperationHandle"); #undef IMPORT + + /* Add the "handle" member to the OperationHandle type. */ + descr = PyDescr_NewGetSet(_PyCajaOperationHandle_Type, + &caja_operationhandle_handle); + if (!descr) { + PyErr_Print(); + return FALSE; + } + if (PyDict_SetItemString(_PyCajaOperationHandle_Type->tp_dict, + caja_operationhandle_handle.name, descr)) { + Py_DECREF(descr); + PyErr_Print(); + return FALSE; + } + Py_DECREF(descr); return TRUE; } |