[nautilus/wip/antoniof/extension-properties: 1/3] libnautilus-extension: Introduce model-based properties extensions




commit 6c3b87a41a471bec8d260a79e116e4c12cadd692
Author: António Fernandes <antoniof gnome org>
Date:   Fri Aug 5 19:40:17 2022 +0100

    libnautilus-extension: Introduce model-based properties extensions
    
    This is meant to replace the existing GtkWidget-based solution.

 libnautilus-extension/meson.build                  |   6 +
 libnautilus-extension/nautilus-extension.h         |   3 +
 libnautilus-extension/nautilus-properties-item.c   | 150 +++++++++++++++++++
 libnautilus-extension/nautilus-properties-item.h   |  62 ++++++++
 .../nautilus-properties-model-provider.c           |  31 ++++
 .../nautilus-properties-model-provider.h           |  64 ++++++++
 libnautilus-extension/nautilus-properties-model.c  | 161 +++++++++++++++++++++
 libnautilus-extension/nautilus-properties-model.h  |  62 ++++++++
 8 files changed, 539 insertions(+)
---
diff --git a/libnautilus-extension/meson.build b/libnautilus-extension/meson.build
index 8450873de..27f21a5b5 100644
--- a/libnautilus-extension/meson.build
+++ b/libnautilus-extension/meson.build
@@ -7,6 +7,9 @@ libnautilus_extension_headers = [
   'nautilus-info-provider.h',
   'nautilus-location-widget-provider.h',
   'nautilus-menu-provider.h',
+  'nautilus-properties-model-provider.h',
+  'nautilus-properties-model.h',
+  'nautilus-properties-item.h',
   'nautilus-property-page-provider.h',
   'nautilus-property-page.h',
   'nautilus-menu.h'
@@ -42,6 +45,9 @@ libnautilus_extension_sources = [
   'nautilus-location-widget-provider.c',
   'nautilus-menu-item.c',
   'nautilus-menu-provider.c',
+  'nautilus-properties-model-provider.c',
+  'nautilus-properties-model.c',
+  'nautilus-properties-item.c',
   'nautilus-property-page-provider.c',
   'nautilus-property-page.c',
   'nautilus-menu.c'
diff --git a/libnautilus-extension/nautilus-extension.h b/libnautilus-extension/nautilus-extension.h
index 894322eb9..af3f67837 100644
--- a/libnautilus-extension/nautilus-extension.h
+++ b/libnautilus-extension/nautilus-extension.h
@@ -26,6 +26,9 @@
 #include <libnautilus-extension/nautilus-location-widget-provider.h>
 #include <libnautilus-extension/nautilus-menu.h>
 #include <libnautilus-extension/nautilus-menu-provider.h>
+#include <libnautilus-extension/nautilus-properties-model.h>
+#include <libnautilus-extension/nautilus-properties-model-provider.h>
+#include <libnautilus-extension/nautilus-properties-item.h>
 #include <libnautilus-extension/nautilus-property-page.h>
 #include <libnautilus-extension/nautilus-property-page-provider.h>
 
diff --git a/libnautilus-extension/nautilus-properties-item.c 
b/libnautilus-extension/nautilus-properties-item.c
new file mode 100644
index 000000000..d91a7e472
--- /dev/null
+++ b/libnautilus-extension/nautilus-properties-item.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2022 António Fernandes <antoniof gnome org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <config.h>
+#include "nautilus-properties-item.h"
+
+enum
+{
+    PROP_0,
+    PROP_NAME,
+    PROP_VALUE,
+    LAST_PROP
+};
+
+struct _NautilusPropertiesItem
+{
+    GObject parent_instance;
+
+    char *name;
+    char *value;
+};
+
+G_DEFINE_TYPE (NautilusPropertiesItem, nautilus_properties_item, G_TYPE_OBJECT)
+
+NautilusPropertiesItem *
+nautilus_properties_item_new (const char *name,
+                              const char *value)
+{
+    g_return_val_if_fail (name != NULL, NULL);
+    g_return_val_if_fail (name != NULL, NULL);
+
+    return g_object_new (NAUTILUS_TYPE_PROPERTIES_ITEM,
+                         "name", name,
+                         "value", value,
+                         NULL);
+}
+
+static void
+nautilus_properties_item_get_property (GObject    *object,
+                                       guint       param_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
+{
+    NautilusPropertiesItem *self = NAUTILUS_PROPERTIES_ITEM (object);
+
+    switch (param_id)
+    {
+        case PROP_NAME:
+        {
+            g_value_set_string (value, self->name);
+        }
+        break;
+
+        case PROP_VALUE:
+        {
+            g_value_set_string (value, self->value);
+        }
+        break;
+
+        default:
+        {
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        }
+        break;
+    }
+}
+
+static void
+nautilus_properties_item_set_property (GObject      *object,
+                                       guint         param_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
+{
+    NautilusPropertiesItem *self = NAUTILUS_PROPERTIES_ITEM (object);
+
+    switch (param_id)
+    {
+        case PROP_NAME:
+        {
+            g_free (self->name);
+            self->name = g_strdup (g_value_get_string (value));
+            g_object_notify (object, "name");
+        }
+        break;
+
+        case PROP_VALUE:
+        {
+            g_free (self->value);
+            self->value = g_strdup (g_value_get_string (value));
+            g_object_notify (object, "value");
+        }
+        break;
+
+        default:
+        {
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        }
+        break;
+    }
+}
+
+static void
+nautilus_properties_item_finalize (GObject *object)
+{
+    NautilusPropertiesItem *self = NAUTILUS_PROPERTIES_ITEM (object);
+
+    g_free (self->name);
+    g_free (self->value);
+
+    G_OBJECT_CLASS (nautilus_properties_item_parent_class)->finalize (object);
+}
+
+static void
+nautilus_properties_item_init (NautilusPropertiesItem *self)
+{
+}
+
+static void
+nautilus_properties_item_class_init (NautilusPropertiesItemClass *class)
+{
+    G_OBJECT_CLASS (class)->finalize = nautilus_properties_item_finalize;
+    G_OBJECT_CLASS (class)->get_property = nautilus_properties_item_get_property;
+    G_OBJECT_CLASS (class)->set_property = nautilus_properties_item_set_property;
+
+    g_object_class_install_property (G_OBJECT_CLASS (class),
+                                     PROP_NAME,
+                                     g_param_spec_string ("name", "", "",
+                                                          NULL,
+                                                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | 
G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (G_OBJECT_CLASS (class),
+                                     PROP_VALUE,
+                                     g_param_spec_string ("value", "", "",
+                                                          NULL,
+                                                          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | 
G_PARAM_STATIC_STRINGS));
+}
+
+const char *
+nautilus_properties_item_get_name (NautilusPropertiesItem *self)
+{
+    return self->name;
+}
+
+const char *
+nautilus_properties_item_get_value (NautilusPropertiesItem *self)
+{
+    return self->value;
+}
diff --git a/libnautilus-extension/nautilus-properties-item.h 
b/libnautilus-extension/nautilus-properties-item.h
new file mode 100644
index 000000000..8e71b0664
--- /dev/null
+++ b/libnautilus-extension/nautilus-properties-item.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 António Fernandes <antoniof gnome org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#if !defined (NAUTILUS_EXTENSION_H) && !defined (NAUTILUS_COMPILATION)
+#warning "Only <nautilus-extension.h> should be included directly."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_PROPERTIES_ITEM (nautilus_properties_item_get_type ())
+
+G_DECLARE_FINAL_TYPE (NautilusPropertiesItem, nautilus_properties_item,
+                      NAUTILUS, PROPERTIES_ITEM,
+                      GObject)
+
+/**
+ * SECTION:nautilus-properties-item
+ * @name: NautilusPropertiesItem
+ * @value: Properties item descriptor object
+ *
+ * #NautilusPropertiesItem is an object that describes a item in the file
+ * properties. Extensions can provide #NautilusPropertiesItem objects by
+ * registering a #NautilusPropertiesItemProvider and returning them from
+ * nautilus_properties_item_provider_get_items(), which will be called by the
+ * main application when creating file properties.
+ */
+
+/**
+ * nautilus_properties_item_new:
+ * @name: the user-visible name for the properties item
+ * @model: the properties item model, containing NautilusPropertiesItem objects.
+ *
+ * Returns: (transfer full): a new #NautilusPropertiesItem
+ */
+NautilusPropertiesItem *nautilus_properties_item_new (const char *name,
+                                                      const char *value);
+
+/**
+ * nautilus_properties_item_get_name:
+ * @item: the properties item
+ *
+ * Returns: (transfer none): the name of this #NautilusPropertiesItem
+ */
+const char *nautilus_properties_item_get_name (NautilusPropertiesItem *self);
+
+/**
+ * nautilus_properties_item_get_value:
+ * @item: the properties item
+ *
+ * Returns: (transfer none): the value of this #NautilusPropertiesItem
+ */
+const char * nautilus_properties_item_get_value (NautilusPropertiesItem *self);
+
+
+G_END_DECLS
diff --git a/libnautilus-extension/nautilus-properties-model-provider.c 
b/libnautilus-extension/nautilus-properties-model-provider.c
new file mode 100644
index 000000000..c14c5cd88
--- /dev/null
+++ b/libnautilus-extension/nautilus-properties-model-provider.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The GNOME project contributors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+#include "nautilus-properties-model-provider.h"
+
+G_DEFINE_INTERFACE (NautilusPropertiesModelProvider, nautilus_properties_model_provider,
+                    G_TYPE_OBJECT)
+
+static void
+nautilus_properties_model_provider_default_init (NautilusPropertiesModelProviderInterface *klass)
+{
+}
+
+GList *
+nautilus_properties_model_provider_get_groups (NautilusPropertiesModelProvider *self,
+                                               GList                           *files)
+{
+    NautilusPropertiesModelProviderInterface *iface;
+
+    g_return_val_if_fail (NAUTILUS_IS_PROPERTIES_MODEL_PROVIDER (self), NULL);
+
+    iface = NAUTILUS_PROPERTIES_MODEL_PROVIDER_GET_IFACE (self);
+
+    g_return_val_if_fail (iface->get_groups != NULL, NULL);
+
+    return iface->get_groups (self, files);
+}
diff --git a/libnautilus-extension/nautilus-properties-model-provider.h 
b/libnautilus-extension/nautilus-properties-model-provider.h
new file mode 100644
index 000000000..2c0497743
--- /dev/null
+++ b/libnautilus-extension/nautilus-properties-model-provider.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The GNOME project contributors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#if !defined (NAUTILUS_EXTENSION_H) && !defined (NAUTILUS_COMPILATION)
+#warning "Only <nautilus-extension.h> should be included directly."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_PROPERTIES_MODEL_PROVIDER (nautilus_properties_model_provider_get_type ())
+
+G_DECLARE_INTERFACE (NautilusPropertiesModelProvider, nautilus_properties_model_provider,
+                     NAUTILUS, PROPERTIES_MODEL_PROVIDER,
+                     GObject)
+
+/**
+ * SECTION:nautilus-properties-model-provider
+ * @title: NautilusPropertiesModelProvider
+ * @short_description: Interface to provide additional groups of properties
+ *
+ * #NautilusPropertiesModelProvider allows extension to provide additional
+ * groups of properties for the file properties dialog.
+ */
+
+/**
+ * NautilusPropertiesModelProviderInterface:
+ * @g_iface: The parent interface.
+ * @get_pages: Returns a #GList of #NautilusPropertyPage.
+ *   See nautilus_properties_model_provider_get_pages() for details.
+ *
+ * Interface for extensions to provide additional property pages.
+ */
+struct _NautilusPropertiesModelProviderInterface
+{
+    GTypeInterface g_iface;
+
+    GList *(*get_groups) (NautilusPropertiesModelProvider *provider,
+                          GList                           *files);
+};
+
+/**
+ * nautilus_properties_model_provider_get_pages:
+ * @provider: a #NautilusPropertiesModelProvider
+ * @files: (element-type NautilusFileInfo): a #GList of #NautilusFileInfo
+ *
+ * This function is called by Nautilus when it wants properties groups
+ * items from the extension.
+ *
+ * This function is called in the main thread before the Properties are shown,
+ * so it should return quickly.
+ *
+ * Returns: (nullable) (element-type NautilusPropertyPage) (transfer full): A #GList of allocated 
#NautilusPropertiesModel models.
+ */
+GList *nautilus_properties_model_provider_get_groups (NautilusPropertiesModelProvider *provider,
+                                                      GList                           *files);
+
+G_END_DECLS
diff --git a/libnautilus-extension/nautilus-properties-model.c 
b/libnautilus-extension/nautilus-properties-model.c
new file mode 100644
index 000000000..1d2be6af7
--- /dev/null
+++ b/libnautilus-extension/nautilus-properties-model.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2022 The GNOME project contributors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <config.h>
+#include "nautilus-properties-model.h"
+#include "nautilus-properties-item.h"
+
+enum
+{
+    PROP_0,
+    PROP_NAME,
+    PROP_MODEL,
+    LAST_PROP
+};
+
+struct _NautilusPropertiesModel
+{
+    GObject parent_instance;
+
+    char *name;
+    GListModel *model;
+};
+
+G_DEFINE_TYPE (NautilusPropertiesModel, nautilus_properties_model, G_TYPE_OBJECT)
+
+NautilusPropertiesModel *
+nautilus_properties_model_new (const char *name,
+                               GListModel *model)
+{
+    g_return_val_if_fail (name != NULL, NULL);
+    g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL);
+    g_return_val_if_fail (g_list_model_get_item_type (model) == NAUTILUS_TYPE_PROPERTIES_ITEM, NULL);
+
+    return g_object_new (NAUTILUS_TYPE_PROPERTIES_MODEL,
+                         "name", name,
+                         "model", model,
+                         NULL);
+}
+
+static void
+nautilus_properties_model_get_property (GObject    *object,
+                                        guint       param_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+    NautilusPropertiesModel *self = NAUTILUS_PROPERTIES_MODEL (object);
+
+    switch (param_id)
+    {
+        case PROP_NAME:
+        {
+            g_value_set_string (value, self->name);
+        }
+        break;
+
+        case PROP_MODEL:
+        {
+            g_value_set_object (value, self->model);
+        }
+        break;
+
+        default:
+        {
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        }
+        break;
+    }
+}
+
+static void
+nautilus_properties_model_set_property (GObject      *object,
+                                        guint         param_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+    NautilusPropertiesModel *self = NAUTILUS_PROPERTIES_MODEL (object);
+
+    switch (param_id)
+    {
+        case PROP_NAME:
+        {
+            g_free (self->name);
+            self->name = g_strdup (g_value_get_string (value));
+            g_object_notify (object, "name");
+        }
+        break;
+
+        case PROP_MODEL:
+        {
+            g_set_object (&self->model, g_value_get_object (value));
+            g_object_notify (object, "model");
+        }
+        break;
+
+        default:
+        {
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+        }
+        break;
+    }
+}
+
+static void
+nautilus_properties_model_dispose (GObject *object)
+{
+    NautilusPropertiesModel *self = NAUTILUS_PROPERTIES_MODEL (object);
+
+    g_clear_object (&self->model);
+
+    G_OBJECT_CLASS (nautilus_properties_model_parent_class)->dispose (object);
+}
+
+static void
+nautilus_properties_model_finalize (GObject *object)
+{
+    NautilusPropertiesModel *self = NAUTILUS_PROPERTIES_MODEL (object);
+
+    g_free (self->name);
+
+    G_OBJECT_CLASS (nautilus_properties_model_parent_class)->finalize (object);
+}
+
+static void
+nautilus_properties_model_init (NautilusPropertiesModel *self)
+{
+}
+
+static void
+nautilus_properties_model_class_init (NautilusPropertiesModelClass *class)
+{
+    G_OBJECT_CLASS (class)->finalize = nautilus_properties_model_finalize;
+    G_OBJECT_CLASS (class)->dispose = nautilus_properties_model_dispose;
+    G_OBJECT_CLASS (class)->get_property = nautilus_properties_model_get_property;
+    G_OBJECT_CLASS (class)->set_property = nautilus_properties_model_set_property;
+
+    g_object_class_install_property (G_OBJECT_CLASS (class),
+                                     PROP_NAME,
+                                     g_param_spec_string ("name", "", "",
+                                                          NULL,
+                                                          G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | 
G_PARAM_STATIC_STRINGS));
+    g_object_class_install_property (G_OBJECT_CLASS (class),
+                                     PROP_MODEL,
+                                     g_param_spec_object ("model", "", "",
+                                                          G_TYPE_LIST_MODEL,
+                                                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+const char *
+nautilus_properties_model_get_name (NautilusPropertiesModel *self)
+{
+    return self->name;
+}
+
+GListModel *
+nautilus_properties_model_get_model (NautilusPropertiesModel *self)
+{
+    return self->model;
+}
diff --git a/libnautilus-extension/nautilus-properties-model.h 
b/libnautilus-extension/nautilus-properties-model.h
new file mode 100644
index 000000000..3e45e2b77
--- /dev/null
+++ b/libnautilus-extension/nautilus-properties-model.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The GNOME project contributors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#if !defined (NAUTILUS_EXTENSION_H) && !defined (NAUTILUS_COMPILATION)
+#warning "Only <nautilus-extension.h> should be included directly."
+#endif
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_PROPERTIES_MODEL (nautilus_properties_model_get_type ())
+
+G_DECLARE_FINAL_TYPE (NautilusPropertiesModel, nautilus_properties_model,
+                      NAUTILUS, PROPERTIES_MODEL,
+                      GObject)
+
+/**
+ * SECTION:nautilus-properties-model
+ * @title: NautilusPropertiesModel
+ * @short_description: Properties group descriptor object
+ *
+ * #NautilusPropertiesModel is an object that describes a group in the file
+ * properties. Extensions can provide #NautilusPropertiesModel objects by
+ * registering a #NautilusPropertiesModelProvider and returning them from
+ * nautilus_properties_model_provider_get_groups(), which will be called by the
+ * main application when creating file properties.
+ */
+
+/**
+ * nautilus_properties_model_new:
+ * @name: the user-visible name for the properties group
+ * @model: the properties group model, containing #NautilusPropertyItem objects.
+ *
+ * Returns: (transfer full): a new #NautilusPropertiesModel
+ */
+NautilusPropertiesModel *nautilus_properties_model_new (const char *name,
+                                                        GListModel *model);
+
+/**
+ * nautilus_properties_model_get_name:
+ * @group: the properties group
+ *
+ * Returns: (transfer none): the name of this #NautilusPropertiesModel
+ */
+const char *nautilus_properties_model_get_name (NautilusPropertiesModel *self);
+
+/**
+ * nautilus_properties_model_get_model:
+ * @group: the properties group
+ *
+ * Returns: (transfer none): the model associated wtih this #NautilusPropertiesModel
+ */
+GListModel * nautilus_properties_model_get_model (NautilusPropertiesModel *self);
+
+
+G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]