diff options
18 files changed, 1136 insertions, 696 deletions
diff --git a/extensions/image-properties/meson.build b/extensions/image-properties/meson.build index b292a1905..76a76213b 100644 --- a/extensions/image-properties/meson.build +++ b/extensions/image-properties/meson.build @@ -1,10 +1,10 @@ shared_module ( 'nautilus-image-properties', [ 'nautilus-image-properties-module.c', - 'nautilus-image-properties-page.c', - 'nautilus-image-properties-page.h', - 'nautilus-image-properties-page-provider.c', - 'nautilus-image-properties-page-provider.h' + 'nautilus-image-properties-page-model.c', + 'nautilus-image-properties-page-model.h', + 'nautilus-image-properties-page-model-provider.c', + 'nautilus-image-properties-page-model-provider.h' ], dependencies: [ gexiv, diff --git a/extensions/image-properties/nautilus-image-properties-module.c b/extensions/image-properties/nautilus-image-properties-module.c index 0ce02e973..3e4619b92 100644 --- a/extensions/image-properties/nautilus-image-properties-module.c +++ b/extensions/image-properties/nautilus-image-properties-module.c @@ -18,7 +18,7 @@ #include <config.h> -#include "nautilus-image-properties-page-provider.h" +#include "nautilus-image-properties-page-model-provider.h" #include <glib/gi18n-lib.h> @@ -30,7 +30,7 @@ nautilus_module_initialize (GTypeModule *module) bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - nautilus_image_properties_page_provider_load (module); + nautilus_image_properties_page_model_provider_load (module); } void @@ -47,7 +47,7 @@ nautilus_module_list_types (const GType **types, g_assert (types != NULL); g_assert (num_types != NULL); - type_list[0] = NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_PROVIDER; + type_list[0] = NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER; *types = type_list; *num_types = G_N_ELEMENTS (type_list); diff --git a/extensions/image-properties/nautilus-image-properties-page-model-provider.c b/extensions/image-properties/nautilus-image-properties-page-model-provider.c new file mode 100644 index 000000000..cf55f1094 --- /dev/null +++ b/extensions/image-properties/nautilus-image-properties-page-model-provider.c @@ -0,0 +1,250 @@ +/* Copyright (C) 2004 Red Hat, Inc + * Copyright (c) 2007 Novell, Inc. + * Copyright (c) 2017 Thomas Bechtold <thomasbechtold@jpberlin.de> + * Copyright (c) 2018 Ernestas Kulik <ernestask@gnome.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Alexander Larsson <alexl@redhat.com> + * XMP support by Hubert Figuiere <hfiguiere@novell.com> + */ + +#include "nautilus-image-properties-page-model-provider.h" +#include "nautilus-image-properties-page-model.h" +#include <glib/gi18n.h> +#include <nautilus-extension.h> + +#define NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL_NAME "NautilusImagePropertiesPageModel::property_page" + +struct _NautilusImagePropertiesPageModelProvider +{ + GObject parent_instance; + + NautilusPropertyPageModel *page_model; + GList *files; +}; + +enum +{ + PROP_0, + PROP_PAGE_MODEL, + PROP_FILES, + N_PROPERTIES +}; + +static void property_page_provider_iface_init (NautilusPropertyPageModelProviderInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED (NautilusImagePropertiesPageModelProvider, + nautilus_image_properties_page_model_provider, + G_TYPE_OBJECT, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC (NAUTILUS_TYPE_PROPERTY_PAGE_MODEL_PROVIDER, + property_page_provider_iface_init)) + +static gboolean +is_mime_type_supported (const char *mime_type) +{ + g_autoptr (GSList) formats = NULL; + + if (mime_type == NULL) + { + return FALSE; + } + + formats = gdk_pixbuf_get_formats (); + + for (GSList *l = formats; l != NULL; l = l->next) + { + g_auto (GStrv) mime_types = NULL; + + mime_types = gdk_pixbuf_format_get_mime_types (l->data); + if (mime_types == NULL) + { + continue; + } + + if (g_strv_contains ((const char *const *) mime_types, mime_type)) + { + return TRUE; + } + } + + return FALSE; +} + +static NautilusPropertyPageModel* +get_model (NautilusPropertyPageModelProvider *provider) +{ + NautilusImagePropertiesPageModelProvider *self; + + self = NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER (provider); + + return self->page_model; +} + +static void +set_files (NautilusPropertyPageModelProvider *provider, + GList *files) +{ + NautilusImagePropertiesPageModelProvider *self; + NautilusFileInfo *file_info; + g_autofree char *mime_type = NULL; + + self = NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER (provider); + + if (self->files != NULL) + { + g_list_free_full (self->files, g_object_unref); + self->files = NULL; + } + + self->files = g_list_copy_deep (files, + (GCopyFunc) g_object_ref, NULL); + + if (self->files == NULL || self->files->next != NULL) + { + return; + } + + file_info = NAUTILUS_FILE_INFO (self->files->data); + mime_type = nautilus_file_info_get_mime_type (file_info); + if (!is_mime_type_supported (mime_type)) + { + return; + } + + nautilus_image_properties_page_model_load_from_file_info (NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL (self->page_model), + file_info); +} + +static gboolean +supports_files (NautilusPropertyPageModelProvider *provider) +{ + g_autofree char *mime_type = NULL; + NautilusFileInfo *file_info; + NautilusImagePropertiesPageModelProvider *self; + + self = NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER (provider); + if (self->files == NULL || self->files->next != NULL) + { + return FALSE; + } + + file_info = NAUTILUS_FILE_INFO (self->files->data); + mime_type = nautilus_file_info_get_mime_type (file_info); + if (!is_mime_type_supported (mime_type)) + { + return FALSE; + } + + return TRUE; +} + +static void +nautilus_image_properties_page_model_provider_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NautilusImagePropertiesPageModelProvider *self = NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER (object); + switch (prop_id) + { + case PROP_PAGE_MODEL: + { + g_value_set_object (value, self->page_model); + } + break; + + case PROP_FILES: + { + g_value_set_pointer (value, self->files); + } + break; + + default: + { + g_assert_not_reached (); + } + } +} + +static void +nautilus_image_properties_page_model_provider_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + NautilusImagePropertiesPageModelProvider *self = NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER (object); + switch (prop_id) + { + case PROP_PAGE_MODEL: + { + g_clear_object (&self->page_model); + self->page_model = NAUTILUS_PROPERTY_PAGE_MODEL (g_value_get_object (value)); + } + break; + + case PROP_FILES: + { + set_files (NAUTILUS_PROPERTY_PAGE_MODEL_PROVIDER (self), + g_value_get_pointer (value)); + } + break; + + default: + { + g_assert_not_reached (); + } + } +} + +static void +property_page_provider_iface_init (NautilusPropertyPageModelProviderInterface *iface) +{ + iface->get_model = get_model; + iface->set_files = set_files; + iface->supports_files = supports_files; + +} + +static void +nautilus_image_properties_page_model_provider_init (NautilusImagePropertiesPageModelProvider *self) +{ + self->page_model = NAUTILUS_PROPERTY_PAGE_MODEL (nautilus_image_properties_page_model_new ()); +} + +static void +nautilus_image_properties_page_model_provider_class_init (NautilusImagePropertiesPageModelProviderClass *klass) +{ + GObjectClass *oclass; + + oclass = G_OBJECT_CLASS (klass); + oclass->get_property = nautilus_image_properties_page_model_provider_get_property; + oclass->set_property = nautilus_image_properties_page_model_provider_set_property; + + g_object_class_override_property (oclass, PROP_PAGE_MODEL, "page-model"); + g_object_class_override_property (oclass, PROP_FILES, "files"); +} + +static void +nautilus_image_properties_page_model_provider_class_finalize (NautilusImagePropertiesPageModelProviderClass *klass) +{ + (void) klass; +} + +void +nautilus_image_properties_page_model_provider_load (GTypeModule *module) +{ + nautilus_image_properties_page_model_provider_register_type (module); +} diff --git a/extensions/image-properties/nautilus-image-properties-page-provider.h b/extensions/image-properties/nautilus-image-properties-page-model-provider.h index 59fd6f905..f25449209 100644 --- a/extensions/image-properties/nautilus-image-properties-page-provider.h +++ b/extensions/image-properties/nautilus-image-properties-page-model-provider.h @@ -20,11 +20,11 @@ #include <glib-object.h> -#define NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_PROVIDER (nautilus_image_properties_page_provider_get_type ()) +#define NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER (nautilus_image_properties_page_model_provider_get_type ()) -G_DECLARE_FINAL_TYPE (NautilusImagesPropertiesPageProvider, - nautilus_image_properties_page_provider, - NAUTILUS, IMAGE_PROPERTIES_PAGE_PROVIDER, +G_DECLARE_FINAL_TYPE (NautilusImagePropertiesPageModelProvider, + nautilus_image_properties_page_model_provider, + NAUTILUS, IMAGE_PROPERTIES_PAGE_MODEL_PROVIDER, GObject) -void nautilus_image_properties_page_provider_load (GTypeModule *module);
\ No newline at end of file +void nautilus_image_properties_page_model_provider_load (GTypeModule *module); diff --git a/extensions/image-properties/nautilus-image-properties-page.c b/extensions/image-properties/nautilus-image-properties-page-model.c index bca0b56e8..437f8abda 100644 --- a/extensions/image-properties/nautilus-image-properties-page.c +++ b/extensions/image-properties/nautilus-image-properties-page-model.c @@ -19,16 +19,17 @@ * XMP support by Hubert Figuiere <hfiguiere@novell.com> */ -#include "nautilus-image-properties-page.h" +#include "nautilus-image-properties-page-model.h" #include <gexiv2/gexiv2.h> #include <glib/gi18n.h> #define LOAD_BUFFER_SIZE 8192 +#define SECTION_ID 0 -struct _NautilusImagesPropertiesPage +struct _NautilusImagePropertiesPageModel { - GtkGrid parent; + NautilusPropertyPageModel parent; GCancellable *cancellable; GtkWidget *grid; @@ -41,30 +42,56 @@ struct _NautilusImagesPropertiesPage GExiv2Metadata *md; gboolean md_ready; + + GList *sections; + GList *items; }; -G_DEFINE_TYPE (NautilusImagesPropertiesPage, - nautilus_image_properties_page, - GTK_TYPE_GRID); +G_DEFINE_TYPE (NautilusImagePropertiesPageModel, + nautilus_image_properties_page_model, + NAUTILUS_TYPE_PROPERTY_PAGE_MODEL); + + +static void +free_section (gpointer data) +{ + NautilusPropertyPageModelSection *section = (NautilusPropertyPageModelSection *) data; + + g_free(section->title); +} + +static void +free_item (gpointer data) +{ + NautilusPropertyPageModelItem *section = (NautilusPropertyPageModelItem *) data; + + g_free(section->field); + g_free(section->value); +} static void finalize (GObject *object) { - NautilusImagesPropertiesPage *page; + NautilusImagePropertiesPageModel *self; - page = NAUTILUS_IMAGE_PROPERTIES_PAGE (object); + self = NAUTILUS_IMAGE_PROPERTIES_PAGE_MODEL (object); - if (page->cancellable != NULL) + if (self->cancellable != NULL) { - g_cancellable_cancel (page->cancellable); - g_clear_object (&page->cancellable); + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); } - G_OBJECT_CLASS (nautilus_image_properties_page_parent_class)->finalize (object); + g_list_free_full (self->items, free_item); + g_list_free_full (self->sections, free_section); + self->items = NULL; + self->sections = NULL; + + G_OBJECT_CLASS (nautilus_image_properties_page_model_parent_class)->finalize (object); } static void -nautilus_image_properties_page_class_init (NautilusImagesPropertiesPageClass *klass) +nautilus_image_properties_page_model_class_init (NautilusImagePropertiesPageModelClass *klass) { GObjectClass *object_class; @@ -74,66 +101,35 @@ nautilus_image_properties_page_class_init (NautilusImagesPropertiesPageClass *kl } static void -append_item (NautilusImagesPropertiesPage *page, - const char *name, - const char *value) +append_item (NautilusImagePropertiesPageModel *self, + const char *name, + const char *value) { - GtkWidget *name_label; - PangoAttrList *attrs; - - name_label = gtk_label_new (name); - attrs = pango_attr_list_new (); - - pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD)); - gtk_label_set_attributes (GTK_LABEL (name_label), attrs); - pango_attr_list_unref (attrs); - gtk_container_add (GTK_CONTAINER (page->grid), name_label); - gtk_widget_set_halign (name_label, GTK_ALIGN_START); - gtk_widget_show (name_label); + NautilusPropertyPageModelItem *item; if (value != NULL) { - GtkWidget *value_label; - - value_label = gtk_label_new (value); - - gtk_label_set_line_wrap (GTK_LABEL (value_label), TRUE); - gtk_grid_attach_next_to (GTK_GRID (page->grid), value_label, - name_label, GTK_POS_RIGHT, - 1, 1); - gtk_widget_set_halign (value_label, GTK_ALIGN_START); - gtk_widget_set_hexpand (value_label, TRUE); - gtk_widget_show (value_label); + item = g_new (NautilusPropertyPageModelItem, 1); + item->section_id = SECTION_ID; + item->field = g_strdup (name); + item->value = g_strdup (value); + self->items = g_list_append (self->items, item); } } static void -nautilus_image_properties_page_init (NautilusImagesPropertiesPage *self) +nautilus_image_properties_page_model_init (NautilusImagePropertiesPageModel *self) { - GtkWidget *scrolled_window; - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - - gtk_widget_set_vexpand (GTK_WIDGET (scrolled_window), TRUE); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - - gtk_container_add (GTK_CONTAINER (self), scrolled_window); + NautilusPropertyPageModelSection *section; - self->grid = gtk_grid_new (); - - gtk_orientable_set_orientation (GTK_ORIENTABLE (self->grid), GTK_ORIENTATION_VERTICAL); - gtk_grid_set_row_spacing (GTK_GRID (self->grid), 6); - gtk_grid_set_column_spacing (GTK_GRID (self->grid), 18); - append_item (self, _("Loading…"), NULL); - gtk_container_add (GTK_CONTAINER (scrolled_window), self->grid); - - gtk_widget_show_all (GTK_WIDGET (self)); + section = g_new (NautilusPropertyPageModelSection, 1); + section->id = SECTION_ID; + section->title = g_strdup (_("Basic information")); + self->sections = g_list_append (NULL, section); } static void -append_basic_info (NautilusImagesPropertiesPage *page) +append_basic_info (NautilusImagePropertiesPageModel *page) { GdkPixbufFormat *format; g_autofree char *name = NULL; @@ -165,9 +161,9 @@ append_basic_info (NautilusImagesPropertiesPage *page) } static void -append_gexiv2_tag (NautilusImagesPropertiesPage *page, - const char **tag_names, - const char *description) +append_gexiv2_tag (NautilusImagePropertiesPageModel *page, + const char **tag_names, + const char *description) { g_assert (tag_names != NULL); @@ -195,7 +191,7 @@ append_gexiv2_tag (NautilusImagesPropertiesPage *page, } static void -append_gexiv2_info (NautilusImagesPropertiesPage *page) +append_gexiv2_info (NautilusImagePropertiesPageModel *page) { double longitude; double latitude; @@ -255,13 +251,8 @@ append_gexiv2_info (NautilusImagesPropertiesPage *page) } static void -load_finished (NautilusImagesPropertiesPage *page) +load_finished (NautilusImagePropertiesPageModel *page) { - GtkWidget *label; - - label = gtk_grid_get_child_at (GTK_GRID (page->grid), 0, 0); - gtk_container_remove (GTK_CONTAINER (page->grid), label); - if (page->loader != NULL) { gdk_pixbuf_loader_close (page->loader, NULL); @@ -284,6 +275,11 @@ load_finished (NautilusImagesPropertiesPage *page) } page->md_ready = FALSE; g_clear_object (&page->md); + + nautilus_property_page_model_set_sections (NAUTILUS_PROPERTY_PAGE_MODEL (page), + page->sections); + nautilus_property_page_model_set_items (NAUTILUS_PROPERTY_PAGE_MODEL (page), + page->items); } static void @@ -291,7 +287,7 @@ file_close_callback (GObject *object, GAsyncResult *res, gpointer data) { - NautilusImagesPropertiesPage *page; + NautilusImagePropertiesPageModel *page; GInputStream *stream; page = data; @@ -307,7 +303,7 @@ file_read_callback (GObject *object, GAsyncResult *res, gpointer data) { - NautilusImagesPropertiesPage *page; + NautilusImagePropertiesPageModel *page; GInputStream *stream; g_autoptr (GError) error = NULL; gssize count_read; @@ -380,7 +376,7 @@ size_prepared_callback (GdkPixbufLoader *loader, int height, gpointer callback_data) { - NautilusImagesPropertiesPage *page; + NautilusImagePropertiesPageModel *page; page = callback_data; @@ -392,7 +388,7 @@ size_prepared_callback (GdkPixbufLoader *loader, typedef struct { - NautilusImagesPropertiesPage *page; + NautilusImagePropertiesPageModel *page; NautilusFileInfo *file_info; } FileOpenData; @@ -402,7 +398,7 @@ file_open_callback (GObject *object, gpointer user_data) { g_autofree FileOpenData *data = NULL; - NautilusImagesPropertiesPage *page; + NautilusImagePropertiesPageModel *page; GFile *file; g_autofree char *uri = NULL; g_autoptr (GError) error = NULL; @@ -449,19 +445,26 @@ file_open_callback (GObject *object, } void -nautilus_image_properties_page_load_from_file_info (NautilusImagesPropertiesPage *self, - NautilusFileInfo *file_info) +nautilus_image_properties_page_model_load_from_file_info (NautilusImagePropertiesPageModel *self, + NautilusFileInfo *file_info) { g_autofree char *uri = NULL; g_autoptr (GFile) file = NULL; g_autofree char *path = NULL; FileOpenData *data; - g_return_if_fail (NAUTILUS_IS_IMAGE_PROPERTIES_PAGE (self)); + g_return_if_fail (NAUTILUS_IS_IMAGE_PROPERTIES_PAGE_MODEL (self)); g_return_if_fail (file_info != NULL); self->cancellable = g_cancellable_new (); + g_print ("### removing old info\n"); + /* Remove old information, if any */ + g_list_free_full (self->items, free_item); + self->items = NULL; + nautilus_property_page_model_set_items (NAUTILUS_PROPERTY_PAGE_MODEL (self), + NULL); + uri = nautilus_file_info_get_uri (file_info); file = g_file_new_for_uri (uri); path = g_file_get_path (file); @@ -503,13 +506,10 @@ nautilus_image_properties_page_load_from_file_info (NautilusImagesPropertiesPage data); } -NautilusImagesPropertiesPage * -nautilus_image_properties_page_new (void) +NautilusImagePropertiesPageModel * +nautilus_image_properties_page_model_new (void) { - return g_object_new (NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE, - "margin-bottom", 6, - "margin-end", 12, - "margin-start", 12, - "margin-top", 6, + return g_object_new (NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_MODEL, + "title", _("Image"), NULL); } diff --git a/extensions/image-properties/nautilus-image-properties-page.h b/extensions/image-properties/nautilus-image-properties-page-model.h index 5a2c3580a..469aaa6ba 100644 --- a/extensions/image-properties/nautilus-image-properties-page.h +++ b/extensions/image-properties/nautilus-image-properties-page-model.h @@ -22,14 +22,14 @@ #include <nautilus-extension.h> -#define NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE (nautilus_image_properties_page_get_type ()) +#define NAUTILUS_TYPE_IMAGE_PROPERTIES_PAGE_MODEL (nautilus_image_properties_page_model_get_type ()) -G_DECLARE_FINAL_TYPE (NautilusImagesPropertiesPage, - nautilus_image_properties_page, - NAUTILUS, IMAGE_PROPERTIES_PAGE, - GtkGrid) +G_DECLARE_FINAL_TYPE (NautilusImagePropertiesPageModel, + nautilus_image_properties_page_model, + NAUTILUS, IMAGE_PROPERTIES_PAGE_MODEL, + NautilusPropertyPageModel) -void nautilus_image_properties_page_load_from_file_info (NautilusImagesPropertiesPage *page, - NautilusFileInfo *file_info); +void nautilus_image_properties_page_model_load_from_file_info (NautilusImagePropertiesPageModel *page, + NautilusFileInfo *file_info); -NautilusImagesPropertiesPage *nautilus_image_properties_page_new (void);
\ No newline at end of file +NautilusImagePropertiesPageModel *nautilus_image_properties_page_model_new (void); diff --git a/extensions/image-properties/nautilus-image-properties-page-provider.c b/extensions/image-properties/nautilus-image-properties-page-provider.c deleted file mode 100644 index 99e495bb7..000000000 --- a/extensions/image-properties/nautilus-image-properties-page-provider.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (C) 2004 Red Hat, Inc - * Copyright (c) 2007 Novell, Inc. - * Copyright (c) 2017 Thomas Bechtold <thomasbechtold@jpberlin.de> - * Copyright (c) 2018 Ernestas Kulik <ernestask@gnome.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Alexander Larsson <alexl@redhat.com> - * XMP support by Hubert Figuiere <hfiguiere@novell.com> - */ - -#include "nautilus-image-properties-page-provider.h" - -#include "nautilus-image-properties-page.h" - -#include <glib/gi18n.h> - -#include <nautilus-extension.h> - -#define NAUTILUS_IMAGE_PROPERTIES_PAGE_NAME "NautilusImagePropertiesPage::property_page" - -struct _NautilusImagesPropertiesPageProvider -{ - GObject parent_instance; -}; - -static void property_page_provider_iface_init (NautilusPropertyPageProviderInterface *iface); - -G_DEFINE_DYNAMIC_TYPE_EXTENDED (NautilusImagesPropertiesPageProvider, - nautilus_image_properties_page_provider, - G_TYPE_OBJECT, - 0, - G_IMPLEMENT_INTERFACE_DYNAMIC (NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER, - property_page_provider_iface_init)) - -static gboolean -is_mime_type_supported (const char *mime_type) -{ - g_autoptr (GSList) formats = NULL; - - if (mime_type == NULL) - { - return FALSE; - } - - formats = gdk_pixbuf_get_formats (); - - for (GSList *l = formats; l != NULL; l = l->next) - { - g_auto (GStrv) mime_types = NULL; - - mime_types = gdk_pixbuf_format_get_mime_types (l->data); - if (mime_types == NULL) - { - continue; - } - - if (g_strv_contains ((const char *const *) mime_types, mime_type)) - { - return TRUE; - } - } - - return FALSE; -} - -static GList * -get_pages (NautilusPropertyPageProvider *provider, - GList *files) -{ - NautilusFileInfo *file_info; - g_autofree char *mime_type = NULL; - NautilusImagesPropertiesPage *image_properties_page; - NautilusPropertyPage *property_page; - - if (files == NULL || files->next != NULL) - { - return NULL; - } - - file_info = NAUTILUS_FILE_INFO (files->data); - mime_type = nautilus_file_info_get_mime_type (file_info); - if (!is_mime_type_supported (mime_type)) - { - return NULL; - } - image_properties_page = nautilus_image_properties_page_new (); - property_page = nautilus_property_page_new (NAUTILUS_IMAGE_PROPERTIES_PAGE_NAME, - gtk_label_new (_("Image")), - GTK_WIDGET (image_properties_page)); - - nautilus_image_properties_page_load_from_file_info (image_properties_page, file_info); - - return g_list_prepend (NULL, property_page); -} - -static void -property_page_provider_iface_init (NautilusPropertyPageProviderInterface *iface) -{ - iface->get_pages = get_pages; -} - -static void -nautilus_image_properties_page_provider_init (NautilusImagesPropertiesPageProvider *self) -{ - (void) self; -} - -static void -nautilus_image_properties_page_provider_class_init (NautilusImagesPropertiesPageProviderClass *klass) -{ - (void) klass; -} - -static void -nautilus_image_properties_page_provider_class_finalize (NautilusImagesPropertiesPageProviderClass *klass) -{ - (void) klass; -} - -void -nautilus_image_properties_page_provider_load (GTypeModule *module) -{ - nautilus_image_properties_page_provider_register_type (module); -} diff --git a/libnautilus-extension/meson.build b/libnautilus-extension/meson.build index d62b05c62..648054c29 100644 --- a/libnautilus-extension/meson.build +++ b/libnautilus-extension/meson.build @@ -1,4 +1,4 @@ -nautilus_extension_version = '1.5.0' +nautilus_extension_version = '2.0.0' libnautilus_extension_deprecated_headers = [ 'nautilus-extension-types.h', @@ -12,8 +12,8 @@ libnautilus_extension_headers = [ 'nautilus-info-provider.h', 'nautilus-location-widget-provider.h', 'nautilus-menu-provider.h', - 'nautilus-property-page-provider.h', - 'nautilus-property-page.h', + 'nautilus-property-page-model-provider.h', + 'nautilus-property-page-model.h', 'nautilus-menu.h' ] @@ -48,8 +48,8 @@ libnautilus_extension_sources = [ 'nautilus-location-widget-provider.c', 'nautilus-menu-item.c', 'nautilus-menu-provider.c', - 'nautilus-property-page-provider.c', - 'nautilus-property-page.c', + 'nautilus-property-page-model-provider.c', + 'nautilus-property-page-model.c', 'nautilus-menu.c' ] @@ -79,7 +79,7 @@ gnome.generate_gir( '-DNAUTILUS_COMPILATION' ], sources: libnautilus_extension_sources, - nsversion: '3.0', + nsversion: '4.0', namespace: 'Nautilus', includes: [ 'Gtk-3.0', @@ -114,7 +114,7 @@ pkgconfig.generate( ], variables: [ 'exec_prefix=${prefix}', - 'extensiondir=${libdir}/nautilus/extensions-3.0' + 'extensiondir=${libdir}/nautilus/extensions-4.0' ], version: meson.project_version() ) diff --git a/libnautilus-extension/nautilus-extension.h b/libnautilus-extension/nautilus-extension.h index 7723f453a..061959297 100644 --- a/libnautilus-extension/nautilus-extension.h +++ b/libnautilus-extension/nautilus-extension.h @@ -26,8 +26,8 @@ #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-property-page.h> -#include <libnautilus-extension/nautilus-property-page-provider.h> +#include <libnautilus-extension/nautilus-property-page-model.h> +#include <libnautilus-extension/nautilus-property-page-model-provider.h> /** * SECTION:nautilus-extension @@ -39,4 +39,4 @@ void nautilus_module_shutdown (void); void nautilus_module_list_types (const GType **types, int *num_types); -#endif
\ No newline at end of file +#endif diff --git a/libnautilus-extension/nautilus-property-page-model-provider.c b/libnautilus-extension/nautilus-property-page-model-provider.c new file mode 100644 index 000000000..12b0fe711 --- /dev/null +++ b/libnautilus-extension/nautilus-property-page-model-provider.c @@ -0,0 +1,118 @@ +/* + * nautilus-property-page-model-provider.c - Interface for Nautilus extensions + * * that provide property pages for + * * files. + * + * Copyright (C) 2003 Novell, Inc. + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Dave Camp <dave@ximian.com> + * Carlos Soriano <csoriano@redhat.com> + * + */ +#include "config.h" + +#include "nautilus-property-page-model-provider.h" +#include "nautilus-property-page-model.h" + +G_DEFINE_INTERFACE (NautilusPropertyPageModelProvider, nautilus_property_page_model_provider, + G_TYPE_OBJECT) + +/** + * SECTION:nautilus-property-page-model-provider-interface + * @title: NautilusPropertyPageModelProvider + * @short_description: Interface to provide a property page + * + * #NautilusPropertyPageModelProvider allows extension to provide an additional + * page for the file properties dialog. + */ + +static void +nautilus_property_page_model_provider_default_init (NautilusPropertyPageModelProviderInterface *klass) +{ + /** + * NautilusView::page-model: + * + * The page model associated with the provider. + */ + g_object_interface_install_property (klass, + g_param_spec_object ("page-model", + "Page model", + "The page model associated with the provider", + NAUTILUS_TYPE_PROPERTY_PAGE_MODEL, + G_PARAM_READWRITE)); + g_object_interface_install_property (klass, + g_param_spec_pointer ("files", + "Files", + "Files to get info from", + G_PARAM_READWRITE)); +} + +/** + * nautilus_property_page_model_provider_get_model: + * @provider: a #NautilusPropertyPageModelProvider + * @files: (element-type NautilusFileInfo): a #GList of #NautilusFileInfo + * + * This function is called by Nautilus when it wants property page + * items from the extension. + * + * This function is called in the main thread before a property page + * is shown, so it should return quickly. + * + * Returns: (element-type NautilusPropertyItem) (transfer full): A #GList of allocated #NautilusPropertyItem. + */ +NautilusPropertyPageModel * +nautilus_property_page_model_provider_get_model (NautilusPropertyPageModelProvider *self) +{ + NautilusPropertyPageModelProviderInterface *iface; + + g_return_val_if_fail (NAUTILUS_IS_PROPERTY_PAGE_MODEL_PROVIDER (self), NULL); + + iface = NAUTILUS_PROPERTY_PAGE_MODEL_PROVIDER_GET_IFACE (self); + + g_return_val_if_fail (iface->get_model != NULL, NULL); + + return iface->get_model (self); +} + +void +nautilus_property_page_model_provider_set_files (NautilusPropertyPageModelProvider *self, + GList *files) +{ + NautilusPropertyPageModelProviderInterface *iface; + + g_return_if_fail (NAUTILUS_IS_PROPERTY_PAGE_MODEL_PROVIDER (self)); + + iface = NAUTILUS_PROPERTY_PAGE_MODEL_PROVIDER_GET_IFACE (self); + + g_return_if_fail (iface->set_files != NULL); + + iface->set_files (self, files); +} + +gboolean +nautilus_property_page_model_provider_supports_files (NautilusPropertyPageModelProvider *self) +{ + NautilusPropertyPageModelProviderInterface *iface; + + g_return_val_if_fail (NAUTILUS_IS_PROPERTY_PAGE_MODEL_PROVIDER (self), FALSE); + + iface = NAUTILUS_PROPERTY_PAGE_MODEL_PROVIDER_GET_IFACE (self); + + g_return_val_if_fail (iface->supports_files != NULL, FALSE); + + return iface->supports_files (self); +} diff --git a/libnautilus-extension/nautilus-property-page-provider.h b/libnautilus-extension/nautilus-property-page-model-provider.h index e3c9416f8..750a4ca45 100644 --- a/libnautilus-extension/nautilus-property-page-provider.h +++ b/libnautilus-extension/nautilus-property-page-model-provider.h @@ -3,6 +3,7 @@ * that provide property pages. * * Copyright (C) 2003 Novell, Inc. + * Copyright (C) 2018 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -16,14 +17,15 @@ * * You should have received a copy of the GNU Library General Public * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * + * * Author: Dave Camp <dave@ximian.com> + * Carlos Soriano <csoriano@redhat.com> * */ -/* This interface is implemented by Nautilus extensions that want to - * add property page to property dialogs. Extensions are called when - * Nautilus needs property pages for a selection. They are passed a +/* This interface is implemented by Nautilus extensions that want to + * add property page to property dialogs. Extensions are called when + * Nautilus needs property pages for a selection. They are passed a * list of NautilusFileInfo objects for which information should * be displayed */ @@ -35,40 +37,43 @@ #include <glib-object.h> /* These should be removed at some point. */ +#include "nautilus-property-page-model.h" #include "nautilus-extension-types.h" #include "nautilus-file-info.h" -#include "nautilus-property-page.h" G_BEGIN_DECLS -#define NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER (nautilus_property_page_provider_get_type ()) +#define NAUTILUS_TYPE_PROPERTY_PAGE_MODEL_PROVIDER (nautilus_property_page_model_provider_get_type ()) -G_DECLARE_INTERFACE (NautilusPropertyPageProvider, nautilus_property_page_provider, - NAUTILUS, PROPERTY_PAGE_PROVIDER, +G_DECLARE_INTERFACE (NautilusPropertyPageModelProvider, nautilus_property_page_model_provider, + NAUTILUS, PROPERTY_PAGE_MODEL_PROVIDER, GObject) -/* For compatibility reasons, remove this once you start introducing breaking changes. */ -typedef NautilusPropertyPageProviderInterface NautilusPropertyPageProviderIface; - /** - * NautilusPropertyPageProviderInterface: + * NautilusPropertyPageModelProvider: * @g_iface: The parent interface. - * @get_pages: Returns a #GList of #NautilusPropertyPage. - * See nautilus_property_page_provider_get_pages() for details. + * @get_model: Returns #NautilusPropertyPageModel. + * See nautilus_property_page_provider_get_model() for details. * - * Interface for extensions to provide additional property pages. + * Interface for extensions to provide additional a property page. */ -struct _NautilusPropertyPageProviderInterface +struct _NautilusPropertyPageModelProviderInterface { - GTypeInterface g_iface; + GTypeInterface parent; - GList *(*get_pages) (NautilusPropertyPageProvider *provider, - GList *files); + NautilusPropertyPageModel *(*get_model) (NautilusPropertyPageModelProvider *provider); + + void (*set_files) (NautilusPropertyPageModelProvider *provider, + GList *files); + gboolean (*supports_files) (NautilusPropertyPageModelProvider *provider); }; /* Interface Functions */ -GList *nautilus_property_page_provider_get_pages (NautilusPropertyPageProvider *provider, - GList *files); +NautilusPropertyPageModel *nautilus_property_page_model_provider_get_model (NautilusPropertyPageModelProvider *provider); + +void nautilus_property_page_model_provider_set_files (NautilusPropertyPageModelProvider *provider, + GList *files); +gboolean nautilus_property_page_model_provider_supports_files (NautilusPropertyPageModelProvider *provider); -G_END_DECLS
\ No newline at end of file +G_END_DECLS diff --git a/libnautilus-extension/nautilus-property-page-model.c b/libnautilus-extension/nautilus-property-page-model.c new file mode 100644 index 000000000..62742ceb2 --- /dev/null +++ b/libnautilus-extension/nautilus-property-page-model.c @@ -0,0 +1,346 @@ +/* + * nautilus-property-page.h - Property pages exported by + * NautilusPropertyProvider objects. + * + * Copyright (C) 2003 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Dave Camp <dave@ximian.com> + * + */ + +#include <config.h> +#include "nautilus-property-page-model.h" + +#include <glib-object.h> + +enum +{ + PROP_0, + PROP_TITLE, + PROP_SECTIONS, + PROP_ITEMS, + LAST_PROP +}; + +typedef struct +{ + char *title; + GList *sections; + GList *items; +} NautilusPropertyPageModelPrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (NautilusPropertyPageModel, nautilus_property_page_model, G_TYPE_OBJECT) + +/** + * SECTION:nautilus-property-page + * @title: NautilusPropertyPageModel + * @short_description: Property page descriptor object + * + * #NautilusPropertyPageModel is an object that describes a page in the file + * properties dialog. Extensions can provide #NautilusPropertyPageModel objects + * by registering a #NautilusPropertyPageModelProvider and returning them from + * nautilus_property_page_model_provider_get_pages(), which will be called by the + * main application when creating file properties dialogs. + */ + +/** + * nautilus_property_page_model_new: + * @name: the identifier for the property page + * @label: the user-visible label of the property page + * @page: the property page to display + * + * Creates a new #NautilusPropertyPageModel from page_widget. + * + * Returns: a newly created #NautilusPropertyPageModel + */ +NautilusPropertyPageModel * +nautilus_property_page_model_new (const char *title, + GList *sections, + GList *items) +{ + NautilusPropertyPageModel *page; + + g_return_val_if_fail (title != NULL, NULL); + g_return_val_if_fail (sections != NULL, NULL); + g_return_val_if_fail (items != NULL, NULL); + + page = g_object_new (NAUTILUS_TYPE_PROPERTY_PAGE_MODEL, + "title", title, + "sections", sections, + "items", items, + NULL); + + return page; +} + +char * +nautilus_property_page_model_get_title (NautilusPropertyPageModel *self) +{ + NautilusPropertyPageModelPrivate *priv; + + g_return_val_if_fail (NAUTILUS_IS_PROPERTY_PAGE_MODEL (self), NULL); + + priv = nautilus_property_page_model_get_instance_private (self); + + return priv->title; +} + +static void +free_section (gpointer data) +{ + NautilusPropertyPageModelSection *section = (NautilusPropertyPageModelSection *) data; + + g_free(section->title); +} + +static NautilusPropertyPageModelSection* +copy_section (gconstpointer src, + gpointer data) +{ + NautilusPropertyPageModelSection *section = (NautilusPropertyPageModelSection *) src; + NautilusPropertyPageModelSection *copy = g_new (NautilusPropertyPageModelSection, 1); + + copy->title = g_strdup (section->title); + copy->id = section->id; + + return copy; +} + +static void +free_item (gpointer data) +{ + NautilusPropertyPageModelItem *section = (NautilusPropertyPageModelItem *) data; + + g_free(section->field); + g_free(section->value); +} + +static NautilusPropertyPageModelItem* +copy_item (gconstpointer src, + gpointer data) +{ + NautilusPropertyPageModelItem *item = (NautilusPropertyPageModelItem *) src; + NautilusPropertyPageModelItem *copy = g_new (NautilusPropertyPageModelItem, 1); + + copy->field = g_strdup (item->field); + copy->value = g_strdup (item->value); + copy->section_id = item->section_id; + + return copy; +} + + +static void +nautilus_property_page_model_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + NautilusPropertyPageModel *self; + NautilusPropertyPageModelPrivate *priv; + + g_return_if_fail (NAUTILUS_IS_PROPERTY_PAGE_MODEL (object)); + + self = NAUTILUS_PROPERTY_PAGE_MODEL (object); + priv = nautilus_property_page_model_get_instance_private (self); + + switch (param_id) + { + case PROP_TITLE: + { + g_value_set_string (value, priv->title); + } + break; + + case PROP_SECTIONS: + { + g_value_set_pointer (value, priv->sections); + } + break; + + case PROP_ITEMS: + { + g_value_set_pointer (value, priv->items); + } + break; + + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + } + break; + } +} + +static void +nautilus_property_page_model_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + NautilusPropertyPageModel *self; + NautilusPropertyPageModelPrivate *priv; + + g_return_if_fail (NAUTILUS_IS_PROPERTY_PAGE_MODEL (object)); + + self = NAUTILUS_PROPERTY_PAGE_MODEL (object); + priv = nautilus_property_page_model_get_instance_private (self); + + switch (param_id) + { + case PROP_TITLE: + { + g_free (priv->title); + priv->title = g_strdup (g_value_get_string (value)); + } + break; + + case PROP_SECTIONS: + { + if (priv->sections) + { + g_list_free_full (priv->sections, free_section); + } + + priv->sections = g_list_copy_deep (g_value_get_pointer (value), + (GCopyFunc) copy_section, NULL); + + g_object_notify (G_OBJECT (self), "sections"); + } + break; + + case PROP_ITEMS: + { + if (priv->items) + { + g_list_free_full (priv->items, free_item); + } + + priv->items = g_list_copy_deep (g_value_get_pointer (value), + (GCopyFunc) copy_item, NULL); + } + break; + + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + } + break; + } +} + +static void +nautilus_property_page_model_finalize (GObject *object) +{ + NautilusPropertyPageModel *self; + NautilusPropertyPageModelPrivate *priv; + + self = NAUTILUS_PROPERTY_PAGE_MODEL (object); + priv = nautilus_property_page_model_get_instance_private (self); + + if (priv->title != NULL) + { + g_free (priv->title); + priv->title = NULL; + } + if (priv->sections != NULL) + { + g_list_free_full (priv->sections, free_section); + priv->sections = NULL; + } + if (priv->items != NULL) + { + g_list_free_full (priv->items, free_item); + priv->items = NULL; + } + + G_OBJECT_CLASS (nautilus_property_page_model_parent_class)->finalize (object); +} + +static void +nautilus_property_page_model_init (NautilusPropertyPageModel *page) +{ +} + +static void +nautilus_property_page_model_class_init (NautilusPropertyPageModelClass *class) +{ + G_OBJECT_CLASS (class)->finalize = nautilus_property_page_model_finalize; + G_OBJECT_CLASS (class)->get_property = nautilus_property_page_model_get_property; + G_OBJECT_CLASS (class)->set_property = nautilus_property_page_model_set_property; + + g_object_class_install_property (G_OBJECT_CLASS (class), + PROP_TITLE, + g_param_spec_string ("title", + "Title", + "Title of the page", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_READABLE)); + g_object_class_install_property (G_OBJECT_CLASS (class), + PROP_SECTIONS, + g_param_spec_pointer ("sections", + "Sections", + "Sections of the page", + G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (class), + PROP_ITEMS, + g_param_spec_pointer ("items", + "Items", + "Items for the property page", + G_PARAM_READWRITE)); +} + +GList* +nautilus_property_page_model_get_sections (NautilusPropertyPageModel *self) +{ + NautilusPropertyPageModelPrivate *priv; + + priv = nautilus_property_page_model_get_instance_private (self); + + return priv->sections; +} + +GList* +nautilus_property_page_model_get_items (NautilusPropertyPageModel *self) +{ + NautilusPropertyPageModelPrivate *priv; + + priv = nautilus_property_page_model_get_instance_private (self); + + return priv->items; +} + +void +nautilus_property_page_model_set_sections (NautilusPropertyPageModel *self, + GList *sections) +{ + g_object_set (self, "sections", sections, NULL); +} + +void +nautilus_property_page_model_set_items (NautilusPropertyPageModel *self, + GList *items) +{ + g_object_set (self, "items", items, NULL); +} + +void +nautilus_property_page_model_set_title (NautilusPropertyPageModel *self, + const char *title) + +{ + g_object_set (self, "title", title, NULL); +} diff --git a/libnautilus-extension/nautilus-property-page-model.h b/libnautilus-extension/nautilus-property-page-model.h new file mode 100644 index 000000000..37f38f080 --- /dev/null +++ b/libnautilus-extension/nautilus-property-page-model.h @@ -0,0 +1,80 @@ +/* + * nautilus-property-page-model.h - Property pages exported by + * NautilusPropertyProvider objects. + * + * Copyright (C) 2003 Novell, Inc. + * Copyright (C) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Dave Camp <dave@ximian.com> + * + */ + +#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_PROPERTY_PAGE_MODEL (nautilus_property_page_model_get_type ()) + +G_DECLARE_DERIVABLE_TYPE (NautilusPropertyPageModel, nautilus_property_page_model, + NAUTILUS, PROPERTY_PAGE_MODEL, + GObject) + +struct _NautilusPropertyPageModelClass +{ + GObjectClass parent_class; +}; + +typedef struct +{ + int id; + char* title; +} NautilusPropertyPageModelSection; + +typedef struct +{ + int section_id; + char* field; + char* value; +} NautilusPropertyPageModelItem; + +NautilusPropertyPageModel *nautilus_property_page_model_new (const char *title, + GList *sections, + GList *items); +char * nautilus_property_page_model_get_title (NautilusPropertyPageModel *self); +void nautilus_property_page_model_set_title (NautilusPropertyPageModel *self, + const char *title); +GList *nautilus_property_page_model_get_sections (NautilusPropertyPageModel *self); +void +nautilus_property_page_model_set_sections (NautilusPropertyPageModel *self, + GList *sections); +GList *nautilus_property_page_model_get_items (NautilusPropertyPageModel *self); +void +nautilus_property_page_model_set_items (NautilusPropertyPageModel *self, + GList *items); + +/* NautilusPropertyPageModel has the following properties: + * label (string) - the user-visible label of the property page + * sections (GList of NautilusPropertyPageModelSection) - the sections + * items (GList of NautilusPropertyPageModelItem) - the items + */ + +G_END_DECLS diff --git a/libnautilus-extension/nautilus-property-page-provider.c b/libnautilus-extension/nautilus-property-page-provider.c deleted file mode 100644 index 26ec03cf5..000000000 --- a/libnautilus-extension/nautilus-property-page-provider.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * nautilus-property-page-provider.c - Interface for Nautilus extensions - * that provide property pages for - * files. - * - * Copyright (C) 2003 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Dave Camp <dave@ximian.com> - * - */ - -#include "nautilus-property-page-provider.h" - -G_DEFINE_INTERFACE (NautilusPropertyPageProvider, nautilus_property_page_provider, - G_TYPE_OBJECT) - -/** - * SECTION:nautilus-property-page-provider - * @title: NautilusPropertyPageProvider - * @short_description: Interface to provide additional property pages - * - * #NautilusPropertyPageProvider allows extension to provide additional pages - * for the file properties dialog. - */ - -static void -nautilus_property_page_provider_default_init (NautilusPropertyPageProviderInterface *klass) -{ -} - -/** - * nautilus_property_page_provider_get_pages: - * @provider: a #NautilusPropertyPageProvider - * @files: (element-type NautilusFileInfo): a #GList of #NautilusFileInfo - * - * This function is called by Nautilus when it wants property page - * items from the extension. - * - * This function is called in the main thread before a property page - * is shown, so it should return quickly. - * - * Returns: (element-type NautilusPropertyPage) (transfer full): A #GList of allocated #NautilusPropertyPage items. - */ -GList * -nautilus_property_page_provider_get_pages (NautilusPropertyPageProvider *self, - GList *files) -{ - NautilusPropertyPageProviderInterface *iface; - - g_return_val_if_fail (NAUTILUS_IS_PROPERTY_PAGE_PROVIDER (self), NULL); - - iface = NAUTILUS_PROPERTY_PAGE_PROVIDER_GET_IFACE (self); - - g_return_val_if_fail (iface->get_pages != NULL, NULL); - - return iface->get_pages (self, files); -} diff --git a/libnautilus-extension/nautilus-property-page.c b/libnautilus-extension/nautilus-property-page.c deleted file mode 100644 index ca81fc121..000000000 --- a/libnautilus-extension/nautilus-property-page.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * nautilus-property-page.h - Property pages exported by - * NautilusPropertyProvider objects. - * - * Copyright (C) 2003 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Dave Camp <dave@ximian.com> - * - */ - -#include <config.h> -#include "nautilus-property-page.h" - -#include <glib/gi18n-lib.h> - -enum -{ - PROP_0, - PROP_NAME, - PROP_LABEL, - PROP_PAGE, - LAST_PROP -}; - -struct _NautilusPropertyPage -{ - GObject parent_instance; - - char *name; - GtkWidget *label; - GtkWidget *page; -}; - -G_DEFINE_TYPE (NautilusPropertyPage, nautilus_property_page, G_TYPE_OBJECT) - -/** - * SECTION:nautilus-property-page - * @title: NautilusPropertyPage - * @short_description: Property page descriptor object - * - * #NautilusPropertyPage is an object that describes a page in the file - * properties dialog. Extensions can provide #NautilusPropertyPage objects - * by registering a #NautilusPropertyPageProvider and returning them from - * nautilus_property_page_provider_get_pages(), which will be called by the - * main application when creating file properties dialogs. - */ - -/** - * nautilus_property_page_new: - * @name: the identifier for the property page - * @label: the user-visible label of the property page - * @page: the property page to display - * - * Creates a new #NautilusPropertyPage from page_widget. - * - * Returns: a newly created #NautilusPropertyPage - */ -NautilusPropertyPage * -nautilus_property_page_new (const char *name, - GtkWidget *label, - GtkWidget *page_widget) -{ - NautilusPropertyPage *page; - - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (GTK_IS_WIDGET (label), NULL); - g_return_val_if_fail (GTK_IS_WIDGET (page_widget), NULL); - - page = g_object_new (NAUTILUS_TYPE_PROPERTY_PAGE, - "name", name, - "label", label, - "page", page_widget, - NULL); - - return page; -} - -static void -nautilus_property_page_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - NautilusPropertyPage *page; - - page = NAUTILUS_PROPERTY_PAGE (object); - - switch (param_id) - { - case PROP_NAME: - { - g_value_set_string (value, page->name); - } - break; - - case PROP_LABEL: - { - g_value_set_object (value, page->label); - } - break; - - case PROP_PAGE: - { - g_value_set_object (value, page->page); - } - break; - - default: - { - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } - break; - } -} - -static void -nautilus_property_page_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - NautilusPropertyPage *page; - - page = NAUTILUS_PROPERTY_PAGE (object); - - switch (param_id) - { - case PROP_NAME: - { - g_free (page->name); - page->name = g_strdup (g_value_get_string (value)); - g_object_notify (object, "name"); - } - break; - - case PROP_LABEL: - { - if (page->label) - { - g_object_unref (page->label); - } - - page->label = g_object_ref (g_value_get_object (value)); - g_object_notify (object, "label"); - } - break; - - case PROP_PAGE: - { - if (page->page) - { - g_object_unref (page->page); - } - - page->page = g_object_ref (g_value_get_object (value)); - g_object_notify (object, "page"); - } - break; - - default: - { - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } - break; - } -} - -static void -nautilus_property_page_dispose (GObject *object) -{ - NautilusPropertyPage *page; - - page = NAUTILUS_PROPERTY_PAGE (object); - - if (page->label) - { - g_object_unref (page->label); - page->label = NULL; - } - if (page->page) - { - g_object_unref (page->page); - page->page = NULL; - } -} - -static void -nautilus_property_page_finalize (GObject *object) -{ - NautilusPropertyPage *page; - - page = NAUTILUS_PROPERTY_PAGE (object); - - g_free (page->name); - - G_OBJECT_CLASS (nautilus_property_page_parent_class)->finalize (object); -} - -static void -nautilus_property_page_init (NautilusPropertyPage *page) -{ -} - -static void -nautilus_property_page_class_init (NautilusPropertyPageClass *class) -{ - G_OBJECT_CLASS (class)->finalize = nautilus_property_page_finalize; - G_OBJECT_CLASS (class)->dispose = nautilus_property_page_dispose; - G_OBJECT_CLASS (class)->get_property = nautilus_property_page_get_property; - G_OBJECT_CLASS (class)->set_property = nautilus_property_page_set_property; - - g_object_class_install_property (G_OBJECT_CLASS (class), - PROP_NAME, - g_param_spec_string ("name", - "Name", - "Name of the page", - NULL, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_READABLE)); - g_object_class_install_property (G_OBJECT_CLASS (class), - PROP_LABEL, - g_param_spec_object ("label", - "Label", - "Label widget to display in the notebook tab", - GTK_TYPE_WIDGET, - G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (class), - PROP_PAGE, - g_param_spec_object ("page", - "Page", - "Widget for the property page", - GTK_TYPE_WIDGET, - G_PARAM_READWRITE)); -} diff --git a/libnautilus-extension/nautilus-property-page.h b/libnautilus-extension/nautilus-property-page.h deleted file mode 100644 index 70e31925a..000000000 --- a/libnautilus-extension/nautilus-property-page.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * nautilus-property-page.h - Property pages exported by - * NautilusPropertyProvider objects. - * - * Copyright (C) 2003 Novell, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Dave Camp <dave@ximian.com> - * - */ - -#pragma once - -#if !defined (NAUTILUS_EXTENSION_H) && !defined (NAUTILUS_COMPILATION) -#warning "Only <nautilus-extension.h> should be included directly." -#endif - -#include <glib-object.h> -#include <gtk/gtk.h> -/* This should be removed at some point. */ -#include "nautilus-extension-types.h" - -G_BEGIN_DECLS - -#define NAUTILUS_TYPE_PROPERTY_PAGE (nautilus_property_page_get_type ()) - -G_DECLARE_FINAL_TYPE (NautilusPropertyPage, nautilus_property_page, - NAUTILUS, PROPERTY_PAGE, - GObject) - -NautilusPropertyPage *nautilus_property_page_new (const char *name, - GtkWidget *label, - GtkWidget *page); - -/* NautilusPropertyPage has the following properties: - * name (string) - the identifier for the property page - * label (widget) - the user-visible label of the property page - * page (widget) - the property page to display - */ - -G_END_DECLS
\ No newline at end of file diff --git a/meson.build b/meson.build index 4e9be097b..9659b0fba 100644 --- a/meson.build +++ b/meson.build @@ -10,7 +10,7 @@ datadir = get_option('datadir') desktopdir = join_paths(datadir, 'applications') includedir = get_option('includedir') libdir = get_option('libdir') -extensiondir = join_paths(libdir, 'nautilus', 'extensions-3.0') +extensiondir = join_paths(libdir, 'nautilus', 'extensions-4.0') prefix = get_option('prefix') servicedir = join_paths(datadir, 'dbus-1', 'services') # diff --git a/src/nautilus-properties-window.c b/src/nautilus-properties-window.c index 9543d4105..f25a1a63e 100644 --- a/src/nautilus-properties-window.c +++ b/src/nautilus-properties-window.c @@ -203,7 +203,8 @@ static void remove_pending (StartupData *data, gboolean cancel_call_when_ready, gboolean cancel_timed_wait, gboolean cancel_destroy_handler); -static void append_extension_pages (NautilusPropertiesWindow *window); +static void create_extension_pages_ui (NautilusPropertiesWindow *window); +static void setup_extension_pages (NautilusPropertiesWindow *window); static void name_field_focus_changed (GObject *object, GParamSpec *pspec, @@ -913,24 +914,21 @@ update_properties_window_title (NautilusPropertiesWindow *window) } static void -clear_extension_pages (NautilusPropertiesWindow *window) +clear_extension_pages_ui (NautilusPropertiesWindow *window) { int i; int num_pages; - GtkWidget *page; + GtkWidget *page_widget; - num_pages = gtk_notebook_get_n_pages - (GTK_NOTEBOOK (window->notebook)); + num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); for (i = 0; i < num_pages; i++) { - page = gtk_notebook_get_nth_page - (GTK_NOTEBOOK (window->notebook), i); + page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), i); - if (g_object_get_data (G_OBJECT (page), "is-extension-page")) + if (g_object_get_data (G_OBJECT (page_widget), "is-extension-page")) { - gtk_notebook_remove_page - (GTK_NOTEBOOK (window->notebook), i); + gtk_notebook_remove_page (GTK_NOTEBOOK (window->notebook), i); num_pages--; i--; } @@ -938,10 +936,66 @@ clear_extension_pages (NautilusPropertiesWindow *window) } static void -refresh_extension_pages (NautilusPropertiesWindow *window) +clear_extension_pages (NautilusPropertiesWindow *window) +{ + GList *model_providers; + GList *p; + + model_providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_PROPERTY_PAGE_MODEL_PROVIDER); + + for (p = model_providers; p != NULL; p = p->next) + { + NautilusPropertyPageModelProvider *model_provider; + NautilusPropertyPageModel *page_model = NULL; + + model_provider = NAUTILUS_PROPERTY_PAGE_MODEL_PROVIDER (p->data); + + page_model = nautilus_property_page_model_provider_get_model (model_provider); + g_signal_handlers_disconnect_by_data (page_model, window); + } +} + +static void +recreate_extension_pages (NautilusPropertiesWindow *window) { clear_extension_pages (window); - append_extension_pages (window); + clear_extension_pages_ui (window); + setup_extension_pages (window); + create_extension_pages_ui (window); +} + +static void +refresh_extension_pages (NautilusPropertiesWindow *window) +{ + clear_extension_pages_ui (window); + create_extension_pages_ui (window); +} + +static void +setup_extension_pages (NautilusPropertiesWindow *window) +{ + GList *model_providers = NULL; + GList *p; + + model_providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_PROPERTY_PAGE_MODEL_PROVIDER); + + for (p = model_providers; p != NULL; p = p->next) + { + NautilusPropertyPageModelProvider *model_provider; + NautilusPropertyPageModel *page; + + model_provider = NAUTILUS_PROPERTY_PAGE_MODEL_PROVIDER (p->data); + + page = nautilus_property_page_model_provider_get_model (model_provider); + + g_signal_connect_swapped (page, "notify::sections", + G_CALLBACK (refresh_extension_pages), window); + g_signal_connect_swapped (page, "notify::items", + G_CALLBACK (refresh_extension_pages), window); + + nautilus_property_page_model_provider_set_files (model_provider, + window->original_files); + } } static void @@ -1183,7 +1237,7 @@ properties_window_update (NautilusPropertiesWindow *window, { if (!mime_list_equal (window->mime_list, mime_list)) { - refresh_extension_pages (window); + recreate_extension_pages (window); } g_list_free_full (window->mime_list, g_free); @@ -4769,58 +4823,137 @@ create_permissions_page (NautilusPropertiesWindow *window) } } -static void -append_extension_pages (NautilusPropertiesWindow *window) -{ - GList *providers; - GList *p; - - providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_PROPERTY_PAGE_PROVIDER); - - for (p = providers; p != NULL; p = p->next) - { - NautilusPropertyPageProvider *provider; - GList *pages; - GList *l; +static GtkWidget* +create_extension_page_ui (NautilusPropertiesWindow *window, + NautilusPropertyPageModelProvider *model_provider) +{ + NautilusPropertyPageModel *page; + GtkWidget *page_container; + GList *sections; + GList *items; + GList *section_iter; + + page = nautilus_property_page_model_provider_get_model (model_provider); + page_container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_margin_bottom (page_container, 6); + gtk_widget_set_margin_top (page_container, 6); + gtk_widget_set_margin_end (page_container, 6); + gtk_widget_set_margin_start (page_container, 6); + + sections = nautilus_property_page_model_get_sections (page); + items = nautilus_property_page_model_get_items (page); + for (section_iter = sections; section_iter != NULL; section_iter = section_iter->next) + { + NautilusPropertyPageModelSection *section; + int section_id; + char *section_title; + char *section_title_markup; + GList *item_iter = NULL; + GtkBox *section_container; + GtkGrid *items_container; + GtkLabel *section_title_label; + int grid_row; + + section = (NautilusPropertyPageModelSection *) section_iter->data; + section_id = section->id; + section_title = section->title; + + section_container = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6)); + + section_title_markup = g_markup_printf_escaped ("<b>%s</b>", section_title); + section_title_label = GTK_LABEL (gtk_label_new (NULL)); + gtk_label_set_markup (section_title_label, section_title_markup); + gtk_label_set_xalign (section_title_label, 0); + gtk_container_add (GTK_CONTAINER (section_container), + GTK_WIDGET (section_title_label)); + + items_container = GTK_GRID (gtk_grid_new ()); + gtk_grid_set_column_spacing (items_container, 20); + gtk_container_add (GTK_CONTAINER (section_container), + GTK_WIDGET (items_container)); + + gtk_container_add (GTK_CONTAINER (page_container), + GTK_WIDGET (section_container)); + + grid_row = 0; + for (item_iter = items; item_iter != NULL; item_iter = item_iter->next) + { + NautilusPropertyPageModelItem *item; + int item_section_id; + char *field; + char *value; + char *markup; + g_autofree gchar *field_text = NULL; + GtkLabel *value_label; + GtkLabel *field_label; + + item = (NautilusPropertyPageModelItem *) item_iter->data; + item_section_id = item->section_id; + field = item->field; + value = item->value; + + if (item_section_id != section_id) + { + continue; + } - provider = NAUTILUS_PROPERTY_PAGE_PROVIDER (p->data); + field_text = g_strconcat (field, ":", NULL); + field_label = GTK_LABEL (gtk_label_new (field_text)); + gtk_label_set_xalign (field_label, 0); + markup = g_markup_printf_escaped ("<i>%s</i>", value); + value_label = GTK_LABEL (gtk_label_new (NULL)); + gtk_label_set_markup (value_label, markup); - pages = nautilus_property_page_provider_get_pages - (provider, window->original_files); + gtk_grid_attach (items_container, GTK_WIDGET (field_label), + 0, grid_row, 1, 1); + gtk_grid_attach (items_container, GTK_WIDGET (value_label), + 1, grid_row, 1, 1); - for (l = pages; l != NULL; l = l->next) - { - NautilusPropertyPage *page; - GtkWidget *page_widget; - GtkWidget *label; + grid_row++; + } + } - page = NAUTILUS_PROPERTY_PAGE (l->data); + return page_container; +} - g_object_get (G_OBJECT (page), - "page", &page_widget, "label", &label, - NULL); +static void +create_extension_pages_ui (NautilusPropertiesWindow *window) +{ + GList *model_providers = NULL; + GList *p; - gtk_notebook_append_page (window->notebook, - page_widget, label); - gtk_container_child_set (GTK_CONTAINER (window->notebook), - page_widget, - "tab-expand", TRUE, - NULL); + model_providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_PROPERTY_PAGE_MODEL_PROVIDER); - g_object_set_data (G_OBJECT (page_widget), - "is-extension-page", - page); + for (p = model_providers; p != NULL; p = p->next) + { + NautilusPropertyPageModelProvider *model_provider; + NautilusPropertyPageModel *page; + GtkWidget *page_container; + GtkWidget *title; - g_object_unref (page_widget); - g_object_unref (label); + model_provider = NAUTILUS_PROPERTY_PAGE_MODEL_PROVIDER (p->data); - g_object_unref (page); + if (!nautilus_property_page_model_provider_supports_files (model_provider)) + { + continue; } - g_list_free (pages); + page = nautilus_property_page_model_provider_get_model (model_provider); + title = gtk_label_new (nautilus_property_page_model_get_title (page)); + page_container = create_extension_page_ui (window, model_provider); + gtk_notebook_append_page (window->notebook, page_container, title); + gtk_widget_show_all (page_container); + gtk_container_child_set (GTK_CONTAINER (window->notebook), + page_container, + "tab-expand", TRUE, + NULL); + + g_object_set_data (G_OBJECT (page_container), + "is-extension-page", + page); } - nautilus_module_extension_list_free (providers); + nautilus_module_extension_list_free (model_providers); } static gboolean @@ -5141,7 +5274,7 @@ create_properties_window (StartupData *startup_data) } /* append pages from available views */ - append_extension_pages (window); + recreate_extension_pages (window); /* Update from initial state */ properties_window_update (window, NULL); @@ -5505,6 +5638,18 @@ real_finalize (GObject *object) G_OBJECT_CLASS (nautilus_properties_window_parent_class)->finalize (object); } +static void +real_dispose (GObject *object) +{ + NautilusPropertiesWindow *window; + + window = NAUTILUS_PROPERTIES_WINDOW (object); + + clear_extension_pages (window); + + G_OBJECT_CLASS (nautilus_properties_window_parent_class)->dispose (object); +} + /* icon selection callback to set the image of the file object to the selected file */ static void set_icon (const char *icon_uri, @@ -5736,6 +5881,7 @@ nautilus_properties_window_class_init (NautilusPropertiesWindowClass *class) GtkBindingSet *binding_set; G_OBJECT_CLASS (class)->finalize = real_finalize; + G_OBJECT_CLASS (class)->dispose = real_dispose; GTK_WIDGET_CLASS (class)->destroy = real_destroy; GTK_DIALOG_CLASS (class)->response = real_response; |