[nautilus-python/wip/jtojnar/nautilus-4: 4/4] Implement NautilusPropertiesModelProvider support
- From: Jan Tojnar <jtojnar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-python/wip/jtojnar/nautilus-4: 4/4] Implement NautilusPropertiesModelProvider support
- Date: Wed, 10 Aug 2022 21:10:05 +0000 (UTC)
commit c0803439c16259601cc649c83502b8b68a0d2d75
Author: Jan Tojnar <jtojnar gmail com>
Date: Wed Aug 10 22:34:35 2022 +0200
Implement NautilusPropertiesModelProvider support
This replaces NautilusPropertyPageProvider from Nautilus-3.0.
docs/reference/nautilus-python-class-reference.xml | 1 +
docs/reference/nautilus-python-overview.xml | 2 +-
.../nautilus-python-properties-model-provider.xml | 125 +++++++++++++++++++
.../reference/nautilus-python-properties-model.xml | 135 +++++++++++++++++++++
.../nautilus-python-provider-reference.xml | 1 +
examples/md5sum-properties-model.py | 29 +++++
examples/meson.build | 1 +
src/nautilus-python-object.c | 46 +++++++
src/nautilus-python.c | 6 +-
src/nautilus-python.h | 9 ++
10 files changed, 353 insertions(+), 2 deletions(-)
---
diff --git a/docs/reference/nautilus-python-class-reference.xml
b/docs/reference/nautilus-python-class-reference.xml
index bc4a751..c234996 100644
--- a/docs/reference/nautilus-python-class-reference.xml
+++ b/docs/reference/nautilus-python-class-reference.xml
@@ -9,5 +9,6 @@
<xi:include href="nautilus-python-file-info.xml"/>
<xi:include href="nautilus-python-menu.xml"/>
<xi:include href="nautilus-python-menu-item.xml"/>
+ <xi:include href="nautilus-python-properties-model.xml"/>
</chapter>
diff --git a/docs/reference/nautilus-python-overview.xml b/docs/reference/nautilus-python-overview.xml
index ccdc291..cac3c12 100644
--- a/docs/reference/nautilus-python-overview.xml
+++ b/docs/reference/nautilus-python-overview.xml
@@ -10,7 +10,7 @@
One simply imports the Nautilus module from the gobject introspection repository and creates a class
which is derived from a gobject.GObject and
one of the Nautilus module's classes. When an extension derives a class, it becomes a "provider",
telling Nautilus to ask it for information. There are several types of providers
- available for extensions to use: there is MenuProvider,
+ available for extensions to use: there is MenuProvider, PropertiesModelProvider,
ColumnProvider, and InfoProvider, all of which will be explained
in more detail below. Your class can be derived from multiple providers.</para>
diff --git a/docs/reference/nautilus-python-properties-model-provider.xml
b/docs/reference/nautilus-python-properties-model-provider.xml
new file mode 100644
index 0000000..336f4a8
--- /dev/null
+++ b/docs/reference/nautilus-python-properties-model-provider.xml
@@ -0,0 +1,125 @@
+<?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-nautilus-python-properties-model-provider">
+ <refnamediv>
+ <refname>Nautilus.PropertiesModelProvider</refname>
+ <refpurpose>Nautilus.PropertiesModelProvider Reference</refpurpose>
+ </refnamediv>
+
+<!-- ******************************* -->
+<!-- BEGIN OF SYNOPSIS -->
+<!-- ******************************* -->
+
+ <refsect1>
+ <title>Synopsis</title>
+
+ <classsynopsis language="python">
+ <ooclass><classname>Nautilus.PropertiesModelProvider</classname></ooclass>
+
+ <methodsynopsis language="python">
+ <methodname><link
linkend="method-nautilus-properties-model-provider--get-models">get_models</link></methodname>
+ <methodparam><parameter role="keyword">files</parameter></methodparam>
+ </methodsynopsis>
+ </classsynopsis>
+ </refsect1>
+
+<!-- ********************************** -->
+<!-- BEGIN OF DESCRIPTION -->
+<!-- ********************************** -->
+
+ <refsect1 id="description-properties-model-provider">
+ <title>Description</title>
+
+ <para>
+ If subclassed, Nautilus will request a list of custom properties models that should
+ appear when a user opens the Properties dialog for a file or folder.
+ </para>
+
+<example>
+ <title>Nautilus.PropertiesModelProvider Example</title>
+ <programlisting>
+import hashlib
+
+from urllib.parse import unquote
+
+from gi.repository import Nautilus, GObject
+
+class MD5SumPropertiesModel(GObject.GObject, Nautilus.PropertiesModelProvider):
+ def __init__(self):
+ pass
+
+ def get_properties_models(self, files):
+ if len(files) != 1:
+ return
+
+ file = files[0]
+ if file.get_uri_scheme() != 'file':
+ return
+
+ if file.is_directory():
+ return
+
+ filename = unquote(file.get_uri()[7:])
+
+ self.property_label = Gtk.Label('MD5Sum')
+ self.property_label.show()
+
+ self.hbox = Gtk.HBox(homogeneous=False, spacing=0)
+ self.hbox.show()
+
+ label = Gtk.Label('MD5Sum:')
+ label.show()
+ self.hbox.pack_start(label, False, False, 0)
+
+ self.value_label = Gtk.Label()
+ self.hbox.pack_start(self.value_label, False, False, 0)
+
+ md5sum = hashlib.md5(filename.encode("utf-8")).hexdigest()
+ self.value_label.set_text(md5sum)
+ self.value_label.show()
+
+ return Nautilus.PropertiesModel(name="NautilusPython::md5_sum",
+ label=self.property_label,
+ page=self.hbox),
+ </programlisting>
+</example>
+
+ </refsect1>
+
+<!-- ****************************** -->
+<!-- BEGIN OF METHODS -->
+<!-- ****************************** -->
+
+ <refsect1>
+ <title>Passive Methods</title>
+
+ <refsect2 id="method-nautilus-properties-model-provider--get-models">
+ <title>Nautilus.PropertiesModelProvider.get_models</title>
+
+ <programlisting><methodsynopsis language="python">
+ <methodname>get_models</methodname>
+ <methodparam></methodparam>
+ </methodsynopsis></programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter role="keyword">files</parameter> :</term>
+ <listitem><simpara>a list of <link
linkend="class-nautilus-python-file-info"><classname>Nautilus.FileInfo</classname></link>
objects.</simpara></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>Returns</emphasis> :</term>
+ <listitem><simpara>a list of <link
linkend="class-nautilus-python-properties-model"><classname>Nautilus.PropertiesModel</classname></link>
objects</simpara></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This function is called by Nautilus when it wants properties model items from the extension.
+ It is called in the main thread before a properties model is shown, so it should return
quickly.
+ </para>
+ </refsect2>
+ </refsect1>
+
+</refentry>
+
diff --git a/docs/reference/nautilus-python-properties-model.xml
b/docs/reference/nautilus-python-properties-model.xml
new file mode 100644
index 0000000..2b3a4f5
--- /dev/null
+++ b/docs/reference/nautilus-python-properties-model.xml
@@ -0,0 +1,135 @@
+<?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-nautilus-python-properties-model">
+ <refnamediv>
+ <refname>Nautilus.PropertiesModel</refname>
+ <refpurpose>Nautilus.PropertiesModel Reference</refpurpose>
+ </refnamediv>
+
+<!-- ******************************* -->
+<!-- BEGIN OF NAUTILUS-PYTHON SYNOPSIS -->
+<!-- ******************************* -->
+
+ <refsect1>
+ <title>Synopsis</title>
+
+ <classsynopsis language="python">
+ <ooclass><classname>Nautilus.PropertiesModel</classname></ooclass>
+ <ooclass><classname><link linkend="class-gobject">gobject.GObject</link></classname></ooclass>
+
+ <constructorsynopsis language="python">
+ <methodname><link
linkend="constructor-nautilus-properties-model">Nautilus.PropertiesModel</link></methodname>
+ <methodparam><parameter role="keyword">name</parameter></methodparam>
+ <methodparam><parameter role="keyword">label</parameter></methodparam>
+ <methodparam><parameter role="keyword">page</parameter></methodparam>
+ </constructorsynopsis>
+ </classsynopsis>
+ </refsect1>
+
+<!-- ********************************* -->
+<!-- BEGIN OF ANCESTRY -->
+<!-- ********************************* -->
+
+<refsect1>
+ <title>Ancestry</title>
+
+<synopsis>+-- <link linkend="class-gobject">gobject.GObject</link>
+ +-- <link linkend="class-nautilus-python-properties-model">Nautilus.PropertiesModel</link>
+</synopsis>
+</refsect1>
+
+
+<!-- ********************************** -->
+<!-- BEGIN OF DESCRIPTION -->
+<!-- ********************************** -->
+
+ <refsect1 id="description-properties-model">
+ <title>Description</title>
+
+ <para>
+ A <link
linkend="class-nautilus-python-properties-model"><classname>Nautilus.PropertiesModel</classname></link>
object is returned by <link
linkend="class-nautilus-python-properties-model-provider"><classname>Nautilus.PropertyPageProvider</classname></link>
extensions.
+ </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>"label"</entry>
+ <entry>The label widget displayed in the notebook tab.</entry>
+ <entry>Read-Write</entry>
+ </row>
+
+ <row valign="top">
+ <entry>"name"</entry>
+ <entry>The name of the page. Default value: None</entry>
+ <entry>Read-Write-ConstructOnly</entry>
+ </row>
+
+ <row valign="top">
+ <entry>"page"</entry>
+ <entry>The properties model widget</entry>
+ <entry>Read-Write</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </blockquote>
+</refsect1>
+
+
+<!-- ************************************ -->
+<!-- BEGIN OF CONSTRUCTOR -->
+<!-- ************************************ -->
+
+<refsect1 id="constructor-nautilus-properties-model">
+ <title>Constructor</title>
+
+ <programlisting><constructorsynopsis language="python">
+ <methodname>Nautilus.PropertiesModel</methodname>
+ <methodparam><parameter role="keyword">name</parameter></methodparam>
+ <methodparam><parameter role="keyword">label</parameter></methodparam>
+ <methodparam><parameter role="keyword">page</parameter></methodparam>
+ </constructorsynopsis></programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter role="keyword">name</parameter> :</term>
+ <listitem><simpara>identifier of the properties model</simpara></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter role="keyword">label</parameter> :</term>
+ <listitem><simpara>the user-visible label for the properties model</simpara></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter role="keyword">page</parameter> :</term>
+ <listitem><simpara>the properties model widget</simpara></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Creates a new <link
linkend="class-nautilus-python-properties-model"><classname>Nautilus.PropertiesModel</classname></link>
object.
+ </para>
+</refsect1>
+
+
+
+</refentry>
+
diff --git a/docs/reference/nautilus-python-provider-reference.xml
b/docs/reference/nautilus-python-provider-reference.xml
index 3c0d335..4a87e3a 100644
--- a/docs/reference/nautilus-python-provider-reference.xml
+++ b/docs/reference/nautilus-python-provider-reference.xml
@@ -8,5 +8,6 @@
<xi:include href="nautilus-python-column-provider.xml"/>
<xi:include href="nautilus-python-info-provider.xml"/>
<xi:include href="nautilus-python-menu-provider.xml"/>
+ <xi:include href="nautilus-python-properties-model-provider.xml"/>
</chapter>
diff --git a/examples/md5sum-properties-model.py b/examples/md5sum-properties-model.py
new file mode 100644
index 0000000..9cffe43
--- /dev/null
+++ b/examples/md5sum-properties-model.py
@@ -0,0 +1,29 @@
+import hashlib
+
+from urllib.parse import unquote
+from gi.repository import Nautilus, GObject
+from typing import List
+
+class MD5SumPropertiesModel(GObject.GObject, Nautilus.PropertiesModelProvider):
+ def get_models(self, files: List[Nautilus.FileInfo]) -> List[Nautilus.PropertiesModel]:
+ if len(files) != 1:
+ return []
+
+ file = files[0]
+ if file.get_uri_scheme() != 'file':
+ return []
+
+ if file.is_directory():
+ return []
+
+ filename = unquote(file.get_uri()[7:])
+
+ section_model = Gio.ListStore.new(item_type=Nautilus.PropertiesItem)
+ section_model.append(Nautilus.PropertiesItem(name='MD5Sum:', value=md5sum))
+
+ return [
+ Nautilus.PropertiesModel(
+ title='MD5Sum',
+ model=section_model,
+ ),
+ ]
diff --git a/examples/meson.build b/examples/meson.build
index 266c0eb..914f5fd 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -10,6 +10,7 @@ install_data(
'background-image.py',
'block-size-column.py',
'open-terminal.py',
+ 'md5sum-properties-model.py',
'submenu.py',
'update-file-info-async.py',
],
diff --git a/src/nautilus-python-object.c b/src/nautilus-python-object.c
index 3ee2a0a..0301e5c 100644
--- a/src/nautilus-python-object.c
+++ b/src/nautilus-python-object.c
@@ -156,6 +156,40 @@ nautilus_python_boxed_new (PyTypeObject *type, gpointer boxed, gboolean free_on_
return (PyObject *) self;
}
+#define METHOD_NAME "get_models"
+static GList *
+nautilus_python_object_get_models (NautilusPropertiesModelProvider *provider,
+ GList *files) {
+ NautilusPythonObject *object = (NautilusPythonObject*)provider;
+ PyObject *py_files, *py_ret = NULL;
+ GList *ret = NULL;
+ PyGILState_STATE state = pyg_gil_state_ensure();
+
+ debug_enter();
+
+ CHECK_OBJECT(object);
+ CHECK_METHOD_NAME(object->instance);
+
+ CONVERT_LIST(py_files, files);
+
+ py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX METHOD_NAME,
+ "(N)", py_files);
+ HANDLE_RETVAL(py_ret);
+
+ HANDLE_LIST(py_ret, NautilusPropertiesModel, "Nautilus.PropertiesModel");
+
+beach:
+ Py_XDECREF(py_ret);
+ pyg_gil_state_release(state);
+ return ret;
+}
+#undef METHOD_NAME
+
+static void
+nautilus_python_object_properties_model_provider_interface_init (NautilusPropertiesModelProviderInterface
*interface) {
+ interface->get_models = nautilus_python_object_get_models;
+}
+
#define METHOD_NAME "get_file_items"
static GList *
nautilus_python_object_get_file_items (NautilusMenuProvider *provider,
@@ -401,6 +435,12 @@ nautilus_python_object_get_type (GTypeModule *module,
const char *type_name;
GType gtype;
+ static const GInterfaceInfo properties_model_provider_interface_info = {
+ (GInterfaceInitFunc) nautilus_python_object_properties_model_provider_interface_init,
+ NULL,
+ NULL
+ };
+
static const GInterfaceInfo menu_provider_interface_info = {
(GInterfaceInitFunc) nautilus_python_object_menu_provider_interface_init,
NULL,
@@ -438,6 +478,12 @@ nautilus_python_object_get_type (GTypeModule *module,
type_name,
info, 0);
+ if (PyObject_IsSubclass(type, (PyObject*)&PyNautilusPropertiesModelProvider_Type)) {
+ g_type_module_add_interface (module, gtype,
+ NAUTILUS_TYPE_PROPERTIES_MODEL_PROVIDER,
+ &properties_model_provider_interface_info);
+ }
+
if (PyObject_IsSubclass(type, (PyObject*)&PyNautilusMenuProvider_Type)) {
g_type_module_add_interface (module, gtype,
NAUTILUS_TYPE_MENU_PROVIDER,
diff --git a/src/nautilus-python.c b/src/nautilus-python.c
index 39b27a0..df2dc7c 100644
--- a/src/nautilus-python.c
+++ b/src/nautilus-python.c
@@ -84,7 +84,8 @@ nautilus_python_load_file(GTypeModule *type_module,
if (PyObject_IsSubclass(value, (PyObject*)&PyNautilusColumnProvider_Type) ||
PyObject_IsSubclass(value, (PyObject*)&PyNautilusInfoProvider_Type) ||
- PyObject_IsSubclass(value, (PyObject*)&PyNautilusMenuProvider_Type)) {
+ PyObject_IsSubclass(value, (PyObject*)&PyNautilusMenuProvider_Type) ||
+ PyObject_IsSubclass(value,
(PyObject*)&PyNautilusPropertiesModelProvider_Type)) {
gtype = nautilus_python_object_get_type(type_module, value);
g_array_append_val(all_types, gtype);
}
@@ -211,6 +212,9 @@ nautilus_python_init_python (void) {
IMPORT(Menu, "Menu");
IMPORT(MenuItem, "MenuItem");
IMPORT(MenuProvider, "MenuProvider");
+ IMPORT(PropertiesItem, "PropertiesItem");
+ IMPORT(PropertiesModel, "PropertiesModel");
+ IMPORT(PropertiesModelProvider, "PropertiesModelProvider");
IMPORT(OperationHandle, "OperationHandle");
#undef IMPORT
diff --git a/src/nautilus-python.h b/src/nautilus-python.h
index 652f470..80f23a1 100644
--- a/src/nautilus-python.h
+++ b/src/nautilus-python.h
@@ -61,6 +61,15 @@ PyTypeObject *_PyNautilusMenuItem_Type;
PyTypeObject *_PyNautilusMenuProvider_Type;
#define PyNautilusMenuProvider_Type (*_PyNautilusMenuProvider_Type)
+PyTypeObject *_PyNautilusPropertiesItem_Type;
+#define PyNautilusPropertiesItem_Type (*_PyNautilusPropertiesItem_Type)
+
+PyTypeObject *_PyNautilusPropertiesModel_Type;
+#define PyNautilusPropertiesModel_Type (*_PyNautilusPropertiesModel_Type)
+
+PyTypeObject *_PyNautilusPropertiesModelProvider_Type;
+#define PyNautilusPropertiesModelProvider_Type (*_PyNautilusPropertiesModelProvider_Type)
+
PyTypeObject *_PyNautilusOperationHandle_Type;
#define PyNautilusOperationHandle_Type (*_PyNautilusOperationHandle_Type)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]