[gthumb/ext: 25/79] Added the ability to activate/deactivate extensions
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext: 25/79] Added the ability to activate/deactivate extensions
- Date: Sun, 2 Aug 2009 20:25:59 +0000 (UTC)
commit 539153c3bbc92f2aee96081b318ad87debd8f07d
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Jun 27 23:45:35 2009 +0200
Added the ability to activate/deactivate extensions
data/gthumb.schemas.in | 14 +
data/ui/Makefile.am | 1 +
data/ui/extensions.ui | 127 ++++++
data/ui/preferences.ui | 4 +-
extensions/catalogs/catalogs.extension.in.in | 7 +-
extensions/comments/comments.extension.in.in | 6 +-
extensions/exiv2/exiv2.extension.in.in | 6 +-
.../file_manager/file_manager.extension.in.in | 8 +-
extensions/file_tools/file_tools.extension.in.in | 8 +-
extensions/file_viewer/file_viewer.extension.in.in | 6 +-
.../image_viewer/image_viewer.extension.in.in | 9 +-
extensions/search/search.extension.in.in | 6 +-
gthumb/Makefile.am | 3 +
gthumb/dlg-extensions.c | 441 ++++++++++++++++++++
gthumb/dlg-extensions.h | 30 ++
gthumb/dlg-personalize-filters.c | 26 +-
gthumb/gth-browser-actions-callbacks.c | 9 +
gthumb/gth-browser-actions-callbacks.h | 1 +
gthumb/gth-browser-actions-entries.h | 5 +
gthumb/gth-browser-ui.h | 1 +
gthumb/gth-extensions.c | 175 +++++++--
gthumb/gth-extensions.h | 75 ++--
gthumb/gth-main.c | 81 ++++-
gthumb/gth-preferences.h | 1 +
gthumb/gthumb-error.h | 5 +
gthumb/main.c | 26 +-
gthumb/main.h | 32 ++
po/POTFILES.in | 1 +
28 files changed, 994 insertions(+), 120 deletions(-)
---
diff --git a/data/gthumb.schemas.in b/data/gthumb.schemas.in
index 0acd2bc..e846034 100644
--- a/data/gthumb.schemas.in
+++ b/data/gthumb.schemas.in
@@ -95,6 +95,20 @@
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/gthumb/general/active_extensions</key>
+ <applyto>/apps/gthumb/general/active_extensions</applyto>
+ <owner>gthumb</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <default>[]</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
<!-- Browser -->
<schema>
diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am
index 08a6c66..f57c614 100644
--- a/data/ui/Makefile.am
+++ b/data/ui/Makefile.am
@@ -1,6 +1,7 @@
uidir = $(datadir)/gthumb/ui
ui_DATA = \
bookmarks.ui \
+ extensions.ui \
filter-editor.ui \
personalize-filters.ui \
preferences.ui \
diff --git a/data/ui/extensions.ui b/data/ui/extensions.ui
new file mode 100644
index 0000000..fba62e7
--- /dev/null
+++ b/data/ui/extensions.ui
@@ -0,0 +1,127 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkDialog" id="extensions_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">gthumb Extensions</property>
+ <property name="type_hint">normal</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="extensions_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Available extensions:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="extensions_scrolledwindow">
+ <property name="width_request">300</property>
+ <property name="height_request">350</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="about_button">
+ <property name="label" translatable="yes">gtk-about</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="preferences_button">
+ <property name="label" translatable="yes">gtk-preferences</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">-1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close_button">
+ <property name="label" translatable="yes">gtk-close</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">about_button</action-widget>
+ <action-widget response="0">preferences_button</action-widget>
+ <action-widget response="0">close_button</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui
index e48e8d7..df7e7be 100644
--- a/data/ui/preferences.ui
+++ b/data/ui/preferences.ui
@@ -4,7 +4,7 @@
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkDialog" id="preferences_dialog">
<property name="border_width">6</property>
- <property name="title" translatable="yes">gThumb Preferences</property>
+ <property name="title" translatable="yes">gthumb Preferences</property>
<property name="resizable">False</property>
<property name="type_hint">dialog</property>
<property name="has_separator">False</property>
@@ -181,8 +181,8 @@
<child>
<object class="GtkFileChooserButton" id="startup_dir_filechooserbutton">
<property name="visible">True</property>
- <property name="action">select-folder</property>
<property name="local_only">False</property>
+ <property name="action">select-folder</property>
<property name="title" translatable="yes">Choose startup folder</property>
</object>
<packing>
diff --git a/extensions/catalogs/catalogs.extension.in.in b/extensions/catalogs/catalogs.extension.in.in
index 2874d45..0c60d69 100644
--- a/extensions/catalogs/catalogs.extension.in.in
+++ b/extensions/catalogs/catalogs.extension.in.in
@@ -1,9 +1,10 @@
[Extension]
_Name=Catalogs
_Description=Allow to create file collections.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2008-2009 Paolo Bacchilega
-Version=1
+_Authors=Paolo Bacchilega <paobac src gnome org>
+Copyright=Copyright © 2008-2009 The Free Software Foundation, Inc.
+Version=1.0
+URL=http://live.gnome.org/gthumb
[Loader]
Type=module
diff --git a/extensions/comments/comments.extension.in.in b/extensions/comments/comments.extension.in.in
index 297016c..9b9c248 100644
--- a/extensions/comments/comments.extension.in.in
+++ b/extensions/comments/comments.extension.in.in
@@ -1,9 +1,9 @@
[Extension]
_Name=Comments and tags
_Description=Allow to add comments and tags to files.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2009 Paolo Bacchilega
-Version=1
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
[Loader]
Type=module
diff --git a/extensions/exiv2/exiv2.extension.in.in b/extensions/exiv2/exiv2.extension.in.in
index 9454099..37c2bd0 100644
--- a/extensions/exiv2/exiv2.extension.in.in
+++ b/extensions/exiv2/exiv2.extension.in.in
@@ -1,9 +1,9 @@
[Extension]
_Name=Image metadata
_Description=Read and write exif/iptc and xmp metadata.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2009 Paolo Bacchilega
-Version=1
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
[Loader]
Type=module
diff --git a/extensions/file_manager/file_manager.extension.in.in b/extensions/file_manager/file_manager.extension.in.in
index d0f62bb..7f6c746 100644
--- a/extensions/file_manager/file_manager.extension.in.in
+++ b/extensions/file_manager/file_manager.extension.in.in
@@ -1,9 +1,9 @@
[Extension]
-_Name=File Manager
+_Name=File manager
_Description=File manager operations.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2009 Paolo Bacchilega
-Version=1
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
[Loader]
Type=module
diff --git a/extensions/file_tools/file_tools.extension.in.in b/extensions/file_tools/file_tools.extension.in.in
index a93016f..62848a1 100644
--- a/extensions/file_tools/file_tools.extension.in.in
+++ b/extensions/file_tools/file_tools.extension.in.in
@@ -1,9 +1,9 @@
[Extension]
-_Name=Image Tools
+_Name=Image tools
_Description=Basic tools to modify images.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2009 Paolo Bacchilega
-Version=1
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
[Loader]
Type=module
diff --git a/extensions/file_viewer/file_viewer.extension.in.in b/extensions/file_viewer/file_viewer.extension.in.in
index 00123f5..9a557a4 100644
--- a/extensions/file_viewer/file_viewer.extension.in.in
+++ b/extensions/file_viewer/file_viewer.extension.in.in
@@ -1,9 +1,5 @@
[Extension]
-_Name=Image Viewer
-_Description=Allows to view images.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2009 Paolo Bacchilega
-Version=1
+Mandatory=true
[Loader]
Type=module
diff --git a/extensions/image_viewer/image_viewer.extension.in.in b/extensions/image_viewer/image_viewer.extension.in.in
index 00123f5..0a3d3ac 100644
--- a/extensions/image_viewer/image_viewer.extension.in.in
+++ b/extensions/image_viewer/image_viewer.extension.in.in
@@ -1,10 +1,11 @@
[Extension]
-_Name=Image Viewer
+_Name=Image viewer
_Description=Allows to view images.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2009 Paolo Bacchilega
-Version=1
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
[Loader]
+Requires=file_viewer
Type=module
File=%LIBRARY%
diff --git a/extensions/search/search.extension.in.in b/extensions/search/search.extension.in.in
index 37fb172..b4dbb70 100644
--- a/extensions/search/search.extension.in.in
+++ b/extensions/search/search.extension.in.in
@@ -1,9 +1,9 @@
[Extension]
_Name=Search
_Description=Allows to search for files.
-Authors=Paolo Bacchilega <paobac src gnome org>
-Copyright=Copyright © 2008-2009 Paolo Bacchilega
-Version=1
+_Authors=gthumb development team
+Copyright=Copyright © 2008-2009 The Free Software Foundation, Inc.
+Version=1.0
[Loader]
Type=module
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 8308dc8..adbe63a 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -92,6 +92,7 @@ PUBLIC_HEADER_FILES = \
gth-window.h \
gthumb-error.h \
gtk-utils.h \
+ main.h \
pixbuf-io.h \
pixbuf-utils.h \
typedefs.h \
@@ -101,6 +102,7 @@ PUBLIC_HEADER_FILES = \
PRIVATE_HEADER_FILES = \
dlg-bookmarks.h \
dlg-edit-metadata.h \
+ dlg-extensions.h \
gth-browser-actions-callbacks.h \
gth-browser-actions-entries.h \
gth-browser-ui.h \
@@ -120,6 +122,7 @@ gthumb_SOURCES = \
$(PRIVATE_HEADER_FILES) \
dlg-bookmarks.c \
dlg-edit-metadata.c \
+ dlg-extensions.c \
dlg-personalize-filters.c \
dlg-preferences.c \
dlg-sort-order.c \
diff --git a/gthumb/dlg-extensions.c b/gthumb/dlg-extensions.c
new file mode 100644
index 0000000..d3eaca2
--- /dev/null
+++ b/gthumb/dlg-extensions.c
@@ -0,0 +1,441 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include "gconf-utils.h"
+#include "glib-utils.h"
+#include "gth-browser.h"
+#include "gth-main.h"
+#include "gth-preferences.h"
+#include "gtk-utils.h"
+#include "main.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
+#define DEFAULT_ICON "application-x-executable"
+
+
+typedef struct {
+ GthBrowser *browser;
+ GtkBuilder *builder;
+ GtkWidget *dialog;
+ GtkWidget *list_view;
+ GtkListStore *list_store;
+ GSList *active_extensions;
+} DialogData;
+
+
+static gboolean
+list_equal (GSList *list1,
+ GSList *list2)
+{
+ GSList *sscan1;
+
+ if (g_slist_length (list1) != g_slist_length (list2))
+ return FALSE;
+
+ for (sscan1 = list1; sscan1; sscan1 = sscan1->next) {
+ char *name1 = sscan1->data;
+ GSList *sscan2;
+
+ for (sscan2 = list2; sscan2; sscan2 = sscan2->next) {
+ char *name2 = sscan2->data;
+
+ if (strcmp (name1, name2) == 0)
+ break;
+ }
+
+ if (sscan2 == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* called when the main dialog is closed. */
+static void
+destroy_cb (GtkWidget *widget,
+ DialogData *data)
+{
+ GSList *active_extensions;
+ GthExtensionManager *manager;
+ GList *names;
+ GList *scan;
+
+ active_extensions = NULL;
+ manager = gth_main_get_default_extension_manager ();
+ names = gth_extension_manager_get_extensions (manager);
+ for (scan = names; scan; scan = scan->next) {
+ char *name = scan->data;
+ GthExtensionDescription *description;
+
+ description = gth_extension_manager_get_description (manager, name);
+ if (gth_extension_description_is_active (description))
+ active_extensions = g_slist_prepend (active_extensions, g_strdup (name));
+ }
+ active_extensions = g_slist_reverse (active_extensions);
+ eel_gconf_set_string_list (PREF_ACTIVE_EXTENSIONS, active_extensions);
+
+ if (! list_equal (active_extensions, data->active_extensions)) {
+ GtkWidget *dialog;
+ int response;
+
+ dialog = _gtk_message_dialog_new (GTK_WINDOW (data->browser),
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_DIALOG_WARNING,
+ _("Restart required"),
+ _("You need to restart gthumb for these changes to take effect"),
+ _("_Continue"), GTK_RESPONSE_CANCEL,
+ _("_Restart"), GTK_RESPONSE_OK,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ if (response == GTK_RESPONSE_OK)
+ gth_restart ();
+ }
+
+ gth_browser_set_dialog (data->browser, "extensions", NULL);
+
+ g_slist_foreach (active_extensions, (GFunc) g_free, NULL);
+ g_slist_free (active_extensions);
+
+ g_slist_foreach (data->active_extensions, (GFunc) g_free, NULL);
+ g_slist_free (data->active_extensions);
+ g_object_unref (data->builder);
+ g_free (data);
+}
+
+
+static void
+extension_description_data_func_cb (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GthExtensionDescription *description;
+ char *text;
+
+ gtk_tree_model_get (tree_model, iter, 0, &description, -1);
+
+ text = g_markup_printf_escaped ("<b>%s</b>\n%s", description->name, description->description);
+ g_object_set (G_OBJECT (cell), "markup", text, NULL);
+ g_object_set (G_OBJECT (cell), "sensitive", gth_extension_description_is_active (description), NULL);
+
+ g_free (text);
+ g_object_unref (description);
+}
+
+
+static void
+extension_icon_data_func_cb (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GthExtensionDescription *description;
+
+ gtk_tree_model_get (tree_model, iter, 0, &description, -1);
+ if (description->icon_name != NULL)
+ g_object_set (G_OBJECT (cell), "icon-name", description->icon_name, NULL);
+ else
+ g_object_set (G_OBJECT (cell), "icon-name", DEFAULT_ICON, NULL);
+ g_object_set (G_OBJECT (cell), "sensitive", gth_extension_description_is_active (description), NULL);
+
+ g_object_unref (description);
+}
+
+
+static void
+extension_active_data_func_cb (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GthExtensionDescription *description;
+
+ gtk_tree_model_get (tree_model, iter, 0, &description, -1);
+ g_object_set (G_OBJECT (cell), "active", gth_extension_description_is_active (description), NULL);
+
+ g_object_unref (description);
+}
+
+
+static void
+cell_renderer_toggle_toggled_cb (GtkCellRendererToggle *cell_renderer,
+ char *path,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ GtkTreePath *tree_path;
+ GtkTreeIter iter;
+
+ tree_path = gtk_tree_path_new_from_string (path);
+ if (tree_path == NULL)
+ return;
+
+ if (gtk_tree_model_get_iter (GTK_TREE_MODEL (data->list_store), &iter, tree_path)) {
+ GthExtensionDescription *description;
+ GError *error = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (data->list_store), &iter, 0, &description, -1);
+ if (! gth_extension_description_is_active (description)) {
+ if (! gth_extension_manager_activate (gth_main_get_default_extension_manager (), description->id, &error))
+ _gtk_error_dialog_from_gerror_run (GTK_WINDOW (data->dialog), _("Could not activate the extension"), &error);
+ else
+ gtk_list_store_set (data->list_store, &iter, 0, description,-1);
+ }
+ else {
+ if (! gth_extension_manager_deactivate (gth_main_get_default_extension_manager (), description->id, &error))
+ _gtk_error_dialog_from_gerror_run (GTK_WINDOW (data->dialog), _("Could not deactivate the extension"), &error);
+ else
+ gtk_list_store_set (data->list_store, &iter, 0, description,-1);
+ }
+
+ g_object_unref (description);
+ }
+
+ gtk_tree_path_free (tree_path);
+}
+
+
+static void
+add_columns (GtkTreeView *treeview,
+ DialogData *data)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ /* the name column. */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Extension"));
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
+ gtk_tree_view_column_set_cell_data_func (column, renderer, extension_icon_data_func_cb, data, NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_column_set_cell_data_func (column, renderer, extension_description_data_func_cb, data, NULL);
+
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+ /* the checkbox column */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Use"));
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ g_signal_connect (renderer,
+ "toggled",
+ G_CALLBACK (cell_renderer_toggle_toggled_cb),
+ data);
+
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer, extension_active_data_func_cb, data, NULL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+}
+
+
+static int
+extension_compare_func (GtkTreeModel *tree_model,
+ GtkTreeIter *iter_a,
+ GtkTreeIter *iter_b,
+ gpointer user_data)
+{
+ GthExtensionDescription *description_a;
+ GthExtensionDescription *description_b;
+ int result;
+
+ gtk_tree_model_get (tree_model, iter_a, 0, &description_a, -1);
+ gtk_tree_model_get (tree_model, iter_b, 0, &description_b, -1);
+
+ result = strcmp (description_a->name, description_b->name);
+
+ g_object_unref (description_a);
+ g_object_unref (description_b);
+
+ return result;
+}
+
+
+static void
+list_view_selection_changed_cb (GtkTreeSelection *treeselection,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GthExtensionDescription *description;
+ GthExtension *extension;
+
+ model = GTK_TREE_MODEL (data->list_store);
+ if (! gtk_tree_selection_get_selected (treeselection, &model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter, 0, &description, -1);
+
+ extension = gth_extension_description_get_extension (description);
+ gtk_widget_set_sensitive (GET_WIDGET ("preferences_button"), (extension != NULL) && gth_extension_is_configurable (extension));
+
+ g_object_unref (description);
+}
+
+
+static void
+about_button_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GthExtensionDescription *description;
+ GtkWidget *dialog;
+
+ model = GTK_TREE_MODEL (data->list_store);
+ if (! gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (data->list_view)), &model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter, 0, &description, -1);
+
+ dialog = gtk_about_dialog_new ();
+ if (description->name != NULL)
+ g_object_set (dialog, "program-name", description->name, NULL);
+ if (description->description != NULL)
+ g_object_set (dialog, "comments", description->description, NULL);
+ if (description->version != NULL)
+ g_object_set (dialog, "version", description->version, NULL);
+ if (description->authors != NULL)
+ g_object_set (dialog, "authors", description->authors, NULL);
+ if (description->copyright != NULL)
+ g_object_set (dialog, "copyright", description->copyright, NULL);
+ if (description->icon_name != NULL)
+ g_object_set (dialog, "logo-icon-name", description->icon_name, NULL);
+ else
+ g_object_set (dialog, "logo-icon-name", DEFAULT_ICON, NULL);
+ if (description->url != NULL)
+ g_object_set (dialog, "website", description->url, NULL);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ g_object_unref (description);
+}
+
+
+void
+dlg_extensions (GthBrowser *browser)
+{
+ DialogData *data;
+ GthExtensionManager *manager;
+ GList *extensions;
+ GList *scan;
+ GtkTreePath *first;
+
+ if (gth_browser_get_dialog (browser, "extensions") != NULL) {
+ gtk_window_present (GTK_WINDOW (gth_browser_get_dialog (browser, "extensions")));
+ return;
+ }
+
+ data = g_new0 (DialogData, 1);
+ data->browser = browser;
+ data->builder = _gtk_builder_new_from_file ("extensions.ui", NULL);
+ data->active_extensions = eel_gconf_get_string_list (PREF_ACTIVE_EXTENSIONS);
+
+ /* Get the widgets. */
+
+ data->dialog = _gtk_builder_get_widget (data->builder, "extensions_dialog");
+ gth_browser_set_dialog (browser, "extensions", data->dialog);
+ g_object_set_data (G_OBJECT (data->dialog), "dialog_data", data);
+
+ /* Set widgets data. */
+
+ data->list_store = gtk_list_store_new (1, G_TYPE_OBJECT);
+ data->list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (data->list_store));
+ g_object_unref (data->list_store);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (data->list_view), TRUE);
+
+ add_columns (GTK_TREE_VIEW (data->list_view), data);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->list_store), 0, extension_compare_func, NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->list_store), 0, GTK_SORT_ASCENDING);
+
+ gtk_widget_show (data->list_view);
+ gtk_container_add (GTK_CONTAINER (GET_WIDGET ("extensions_scrolledwindow")), data->list_view);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("extensions_label")), data->list_view);
+ gtk_label_set_use_underline (GTK_LABEL (GET_WIDGET ("extensions_label")), TRUE);
+
+ manager = gth_main_get_default_extension_manager ();
+ extensions = gth_extension_manager_get_extensions (manager);
+ for (scan = extensions; scan; scan = scan->next) {
+ const char *name = scan->data;
+ GthExtensionDescription *description;
+ GtkTreeIter iter;
+
+ description = gth_extension_manager_get_description (manager, name);
+ if ((description == NULL) || description->mandatory)
+ continue;
+
+ gtk_list_store_append (data->list_store, &iter);
+ gtk_list_store_set (data->list_store, &iter, 0, description, -1);
+ }
+ g_list_free (extensions);
+
+ /* Set the signals handlers. */
+
+ g_signal_connect (G_OBJECT (data->dialog),
+ "destroy",
+ G_CALLBACK (destroy_cb),
+ data);
+ g_signal_connect_swapped (GET_WIDGET ("close_button"),
+ "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (data->dialog));
+ g_signal_connect (GET_WIDGET ("about_button"),
+ "clicked",
+ G_CALLBACK (about_button_clicked_cb),
+ data);
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (data->list_view)),
+ "changed",
+ G_CALLBACK (list_view_selection_changed_cb),
+ data);
+ first = gtk_tree_path_new_first ();
+ gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (data->list_view)), first);
+ gtk_tree_path_free (first);
+
+ /* run dialog. */
+
+ gtk_window_set_transient_for (GTK_WINDOW (data->dialog),
+ GTK_WINDOW (browser));
+ gtk_window_set_modal (GTK_WINDOW (data->dialog), TRUE);
+ gtk_widget_show (data->dialog);
+}
diff --git a/gthumb/dlg-extensions.h b/gthumb/dlg-extensions.h
new file mode 100644
index 0000000..cc533e1
--- /dev/null
+++ b/gthumb/dlg-extensions.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DLG_EXTENSIONS_H
+#define DLG_EXTENSIONS_H
+
+#include "gth-browser.h"
+
+void dlg_extensions (GthBrowser *browser);
+
+#endif /* DLG_EXTENSIONS_H */
diff --git a/gthumb/dlg-personalize-filters.c b/gthumb/dlg-personalize-filters.c
index 08db11d..1c549dd 100644
--- a/gthumb/dlg-personalize-filters.c
+++ b/gthumb/dlg-personalize-filters.c
@@ -457,7 +457,7 @@ update_sensitivity (DialogData *data)
g_object_unref (test);
}
}
-
+
gtk_widget_set_sensitive (GET_WIDGET ("edit_button"), is_filter);
gtk_widget_set_sensitive (GET_WIDGET ("delete_button"), is_filter);
}
@@ -477,7 +477,7 @@ general_filter_changed_cb (GtkComboBox *widget,
{
DialogData *data = user_data;
int idx;
-
+
idx = gtk_combo_box_get_active (widget);
eel_gconf_set_string (PREF_GENERAL_FILTER, g_list_nth (data->general_tests, idx)->data);
}
@@ -491,7 +491,7 @@ dlg_personalize_filters (GthBrowser *browser)
char *general_filter;
int i, active_filter;
int i_general;
-
+
if (gth_browser_get_dialog (browser, "personalize_filters") != NULL) {
gtk_window_present (GTK_WINDOW (gth_browser_get_dialog (browser, "personalize_filters")));
return;
@@ -517,22 +517,22 @@ dlg_personalize_filters (GthBrowser *browser)
for (i = 0, i_general = -1, scan = tests; scan; scan = scan->next, i++) {
const char *registered_test_id = scan->data;
GthTest *test;
-
- if (strncmp (registered_test_id, "file::type::", 12) != 0)
+
+ if (strncmp (registered_test_id, "file::type::", 12) != 0)
continue;
-
+
i_general += 1;
-
+
if (strcmp (registered_test_id, general_filter) == 0)
active_filter = i_general;
test = gth_main_get_test (registered_test_id);
- data->general_tests = g_list_prepend (data->general_tests, g_strdup (gth_test_get_id (test)));
+ data->general_tests = g_list_prepend (data->general_tests, g_strdup (gth_test_get_id (test)));
gtk_combo_box_append_text (GTK_COMBO_BOX (data->general_filter_combobox), gth_test_get_display_name (test));
g_object_unref (test);
}
data->general_tests = g_list_reverse (data->general_tests);
-
+
gtk_combo_box_set_active (GTK_COMBO_BOX (data->general_filter_combobox), active_filter);
gtk_widget_show (data->general_filter_combobox);
gtk_container_add (GTK_CONTAINER (GET_WIDGET ("general_filter_box")), data->general_filter_combobox);
@@ -542,9 +542,9 @@ dlg_personalize_filters (GthBrowser *browser)
g_free (general_filter);
_g_string_list_free (tests);
-
+
/**/
-
+
data->list_store = gtk_list_store_new (NUM_COLUMNS,
G_TYPE_OBJECT,
G_TYPE_STRING,
@@ -565,7 +565,7 @@ dlg_personalize_filters (GthBrowser *browser)
update_filter_list (data);
update_sensitivity (data);
-
+
/* Set the signals handlers. */
g_signal_connect (G_OBJECT (data->dialog),
@@ -604,7 +604,7 @@ dlg_personalize_filters (GthBrowser *browser)
"changed",
G_CALLBACK (general_filter_changed_cb),
data);
-
+
data->filters_changed_id = g_signal_connect (gth_main_get_default_monitor (),
"filters-changed",
G_CALLBACK (filters_changed_cb),
diff --git a/gthumb/gth-browser-actions-callbacks.c b/gthumb/gth-browser-actions-callbacks.c
index b7edd02..8778750 100644
--- a/gthumb/gth-browser-actions-callbacks.c
+++ b/gthumb/gth-browser-actions-callbacks.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <glib/gi18n.h>
#include "dlg-bookmarks.h"
+#include "dlg-extensions.h"
#include "dlg-edit-metadata.h"
#include "dlg-personalize-filters.h"
#include "dlg-preferences.h"
@@ -132,6 +133,14 @@ gth_browser_activate_action_edit_preferences (GtkAction *action,
void
+gth_browser_activate_action_edit_extensions (GtkAction *action,
+ GthBrowser *browser)
+{
+ dlg_extensions (browser);
+}
+
+
+void
gth_browser_activate_action_go_back (GtkAction *action,
GthBrowser *browser)
{
diff --git a/gthumb/gth-browser-actions-callbacks.h b/gthumb/gth-browser-actions-callbacks.h
index 7626888..f0aef4c 100644
--- a/gthumb/gth-browser-actions-callbacks.h
+++ b/gthumb/gth-browser-actions-callbacks.h
@@ -32,6 +32,7 @@ DEFINE_ACTION(gth_browser_activate_action_bookmarks_edit)
DEFINE_ACTION(gth_browser_activate_action_browser_mode)
DEFINE_ACTION(gth_browser_activate_action_edit_metadata)
DEFINE_ACTION(gth_browser_activate_action_edit_preferences)
+DEFINE_ACTION(gth_browser_activate_action_edit_extensions)
DEFINE_ACTION(gth_browser_activate_action_edit_select_all)
DEFINE_ACTION(gth_browser_activate_action_file_open_with)
DEFINE_ACTION(gth_browser_activate_action_file_new_window)
diff --git a/gthumb/gth-browser-actions-entries.h b/gthumb/gth-browser-actions-entries.h
index d48e261..bf4e1cb 100644
--- a/gthumb/gth-browser-actions-entries.h
+++ b/gthumb/gth-browser-actions-entries.h
@@ -75,6 +75,11 @@ static GtkActionEntry gth_browser_action_entries[] = {
N_("Edit various preferences"),
G_CALLBACK (gth_browser_activate_action_edit_preferences) },
+ { "Edit_Extensions", NULL,
+ N_("Extensions"), NULL,
+ N_("Activate and configure the application extensions"),
+ G_CALLBACK (gth_browser_activate_action_edit_extensions) },
+
{ "Edit_SelectAll", GTK_STOCK_SELECT_ALL,
NULL, NULL,
NULL,
diff --git a/gthumb/gth-browser-ui.h b/gthumb/gth-browser-ui.h
index 9d88c0f..e8fb5a3 100644
--- a/gthumb/gth-browser-ui.h
+++ b/gthumb/gth-browser-ui.h
@@ -54,6 +54,7 @@ static const char *fixed_ui_info =
" <separator/>"
" <placeholder name='Edit_Actions'/>"
" <separator/>"
+" <menuitem action='Edit_Extensions'/>"
" <menuitem action='Edit_Preferences'/>"
" </menu>"
" <menu name='View' action='ViewMenu'>"
diff --git a/gthumb/gth-extensions.c b/gthumb/gth-extensions.c
index ace257a..69a664e 100644
--- a/gthumb/gth-extensions.c
+++ b/gthumb/gth-extensions.c
@@ -21,8 +21,11 @@
*/
#include <config.h>
+#include <glib/gi18n.h>
#include "glib-utils.h"
#include "gth-extensions.h"
+#include "gthumb-error.h"
+
#define EXTENSION_SUFFIX ".extension"
@@ -48,19 +51,21 @@ gth_extension_base_close (GthExtension *self)
}
-static void
-gth_extension_base_activate (GthExtension *self)
+static gboolean
+gth_extension_base_activate (GthExtension *self,
+ GError **error)
{
- g_return_if_fail (GTH_IS_EXTENSION (self));
self->active = TRUE;
+ return TRUE;
}
-static void
-gth_extension_base_deactivate (GthExtension *self)
+static gboolean
+gth_extension_base_deactivate (GthExtension *self,
+ GError **error)
{
- g_return_if_fail (GTH_IS_EXTENSION (self));
self->active = FALSE;
+ return TRUE;
}
@@ -148,17 +153,19 @@ gth_extension_is_active (GthExtension *self)
}
-void
-gth_extension_activate (GthExtension *self)
+gboolean
+gth_extension_activate (GthExtension *self,
+ GError **error)
{
- GTH_EXTENSION_GET_CLASS (self)->activate (self);
+ return GTH_EXTENSION_GET_CLASS (self)->activate (self, error);
}
-void
-gth_extension_deactivate (GthExtension *self)
+gboolean
+gth_extension_deactivate (GthExtension *self,
+ GError **error)
{
- GTH_EXTENSION_GET_CLASS (self)->deactivate (self);
+ return GTH_EXTENSION_GET_CLASS (self)->deactivate (self, error);
}
@@ -193,7 +200,7 @@ static gboolean
gth_extension_module_real_open (GthExtension *base)
{
GthExtensionModule *self;
- char *file_name;
+ char *file_name;
self = GTH_EXTENSION_MODULE (base);
@@ -244,49 +251,63 @@ get_module_function_name (GthExtensionModule *self,
}
-static void
-gth_extension_module_exec_generic_func (GthExtensionModule *self,
- const char *name)
+static gboolean
+gth_extension_module_exec_generic_func (GthExtensionModule *self,
+ const char *name,
+ GError **error)
{
char *function_name;
void (*func) (void);
- g_return_if_fail (GTH_IS_EXTENSION_MODULE (self));
- g_return_if_fail (name != NULL);
-
function_name = get_module_function_name (self, name);
if (g_module_symbol (self->priv->module, function_name, (gpointer *)&func))
func();
else
- g_warning ("could not exec module function: %s\n", g_module_error ());
+ *error = g_error_new_literal (GTHUMB_ERROR, GTH_ERROR_GENERIC, g_module_error ());
g_free (function_name);
+
+ return (*error == NULL);
}
-static void
-gth_extension_module_real_activate (GthExtension *base)
+static gboolean
+gth_extension_module_real_activate (GthExtension *base,
+ GError **error)
{
GthExtensionModule *self;
+ gboolean success;
self = GTH_EXTENSION_MODULE (base);
if (base->active)
- return;
+ return TRUE;
+
+ success = gth_extension_module_exec_generic_func (self, "activate", error);
+ if (success)
+ base->active = TRUE;
- gth_extension_module_exec_generic_func (self, "activate");
- base->active = TRUE;
+ return success;
}
-static void
-gth_extension_module_real_deactivate (GthExtension *base)
+static gboolean
+gth_extension_module_real_deactivate (GthExtension *base,
+ GError **error)
{
GthExtensionModule *self;
+ gboolean success;
self = GTH_EXTENSION_MODULE (base);
- gth_extension_module_exec_generic_func (self, "deactivate");
+ if (! base->active)
+ return TRUE;
+
+ success = gth_extension_module_exec_generic_func (self, "deactivate", error);
+ if (success)
+ base->active = FALSE;
+
+ return success;
}
@@ -413,7 +434,6 @@ gth_extension_module_new (const char *module_name)
struct _GthExtensionDescriptionPrivate {
gboolean opened;
- gboolean activated;
GthExtension *extension;
};
@@ -428,11 +448,13 @@ gth_extension_description_finalize (GObject *obj)
self = GTH_EXTENSION_DESCRIPTION (obj);
+ g_free (self->id);
g_free (self->name);
g_free (self->description);
g_strfreev (self->authors);
g_free (self->copyright);
g_free (self->version);
+ g_free (self->icon_name);
g_free (self->url);
g_free (self->loader_type);
g_free (self->loader_file);
@@ -458,7 +480,6 @@ gth_extension_description_instance_init (GthExtensionDescription *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_EXTENSION_DESCRIPTION, GthExtensionDescriptionPrivate);
self->priv->opened = FALSE;
- self->priv->activated = FALSE;
self->priv->extension = NULL;
}
@@ -492,22 +513,28 @@ gth_extension_description_load_from_file (GthExtensionDescription *desc,
{
GKeyFile *key_file;
char *file_path;
+ char *basename;
key_file = g_key_file_new ();
file_path = g_file_get_path (file);
if (! g_key_file_load_from_file (key_file, file_path, G_KEY_FILE_NONE, NULL))
return FALSE;
+ basename = g_file_get_basename (file);
+ desc->id = _g_uri_remove_extension (basename);
desc->name = g_key_file_get_string (key_file, "Extension", "Name", NULL);
desc->description = g_key_file_get_string (key_file, "Extension", "Description", NULL);
desc->version = g_key_file_get_string (key_file, "Extension", "Version", NULL);
desc->authors = g_key_file_get_string_list (key_file, "Extension", "Authors", NULL, NULL);
desc->copyright = g_key_file_get_string (key_file, "Extension", "Copyright", NULL);
+ desc->icon_name = g_key_file_get_string (key_file, "Extension", "Icon", NULL);
desc->url = g_key_file_get_string (key_file, "Extension", "URL", NULL);
+ desc->mandatory = g_key_file_get_boolean (key_file, "Extension", "Mandatory", NULL);
desc->loader_type = g_key_file_get_string (key_file, "Loader", "Type", NULL);
desc->loader_file = g_key_file_get_string (key_file, "Loader", "File", NULL);
desc->loader_requires = g_key_file_get_string_list (key_file, "Loader", "Requires", NULL, NULL);
+ g_free (basename);
g_free (file_path);
g_key_file_free (key_file);
@@ -530,6 +557,20 @@ gth_extension_description_new (GFile *file)
}
+gboolean
+gth_extension_description_is_active (GthExtensionDescription *desc)
+{
+ return (desc->priv->extension != NULL) && desc->priv->extension->active;
+}
+
+
+GthExtension *
+gth_extension_description_get_extension (GthExtensionDescription *desc)
+{
+ return desc->priv->extension;
+}
+
+
/* -- gth_extension_manager -- */
@@ -679,8 +720,9 @@ gth_extension_manager_open (GthExtensionManager *manager,
gboolean
-gth_extension_manager_activate (GthExtensionManager *manager,
- const char *extension_name)
+gth_extension_manager_activate (GthExtensionManager *manager,
+ const char *extension_name,
+ GError **error)
{
GthExtensionDescription *description;
@@ -692,12 +734,75 @@ gth_extension_manager_activate (GthExtensionManager *manager,
int i;
for (i = 0; description->loader_requires[i] != NULL; i++)
- if (! gth_extension_manager_activate (manager, description->loader_requires[i]))
+ if (! gth_extension_manager_activate (manager, description->loader_requires[i], error))
return FALSE;
}
- gth_extension_activate (description->priv->extension);
- return TRUE;
+ return gth_extension_activate (description->priv->extension, error);
+}
+
+
+static GList *
+get_extension_dependencies (GthExtensionManager *manager,
+ GthExtensionDescription *description)
+{
+ GList *dependencies = NULL;
+ GList *names;
+ GList *scan;
+
+ names = g_hash_table_get_keys (manager->priv->extensions);
+ for (scan = names; scan; scan = scan->next) {
+ const char *extension_name = scan->data;
+ GthExtensionDescription *other_description;
+
+ other_description = g_hash_table_lookup (manager->priv->extensions, extension_name);
+ if (other_description->loader_requires != NULL) {
+ int i;
+
+ for (i = 0; other_description->loader_requires[i] != NULL; i++)
+ if (strcmp (description->id, other_description->loader_requires[i]) == 0)
+ dependencies = g_list_prepend (dependencies, other_description);
+ }
+ }
+
+ g_list_free (names);
+
+ return g_list_reverse (dependencies);
+}
+
+
+gboolean
+gth_extension_manager_deactivate (GthExtensionManager *manager,
+ const char *extension_name,
+ GError **error)
+{
+ GthExtensionDescription *description;
+ GList *required_by;
+ GList *scan;
+
+ if (! gth_extension_manager_open (manager, extension_name))
+ return TRUE;
+
+ description = g_hash_table_lookup (manager->priv->extensions, extension_name);
+ if (! gth_extension_description_is_active (description))
+ return TRUE;
+
+ required_by = get_extension_dependencies (manager, description);
+ for (scan = required_by; scan; scan = scan->next) {
+ GthExtensionDescription *child_description = scan->data;
+
+ if (gth_extension_description_is_active (child_description)) {
+ *error = g_error_new (GTHUMB_ERROR, GTH_ERROR_EXTENSION_DEPENDENCY, _("The extension '%s' is required by the extension '%s'"), description->name, child_description->name);
+ break;
+ }
+ }
+
+ g_list_free (required_by);
+
+ if (*error == NULL)
+ return gth_extension_deactivate (description->priv->extension, error);
+ else
+ return FALSE;
}
diff --git a/gthumb/gth-extensions.h b/gthumb/gth-extensions.h
index 16f178e..6839014 100644
--- a/gthumb/gth-extensions.h
+++ b/gthumb/gth-extensions.h
@@ -84,13 +84,15 @@ struct _GthExtension {
struct _GthExtensionClass {
GObjectClass parent_class;
- gboolean (*open) (GthExtension *self);
- void (*close) (GthExtension *self);
- void (*activate) (GthExtension *self);
- void (*deactivate) (GthExtension *self);
- gboolean (*is_configurable) (GthExtension *self);
- void (*configure) (GthExtension *self,
- GtkWindow *parent);
+ gboolean (*open) (GthExtension *self);
+ void (*close) (GthExtension *self);
+ gboolean (*activate) (GthExtension *self,
+ GError **error);
+ gboolean (*deactivate) (GthExtension *self,
+ GError **error);
+ gboolean (*is_configurable) (GthExtension *self);
+ void (*configure) (GthExtension *self,
+ GtkWindow *parent);
};
struct _GthExtensionModule {
@@ -104,15 +106,18 @@ struct _GthExtensionModuleClass {
struct _GthExtensionDescription {
GObject parent_instance;
- char *name;
- char *description;
- char **authors;
- char *copyright;
- char *version;
- char *url;
- char *loader_type;
- char *loader_file;
- char **loader_requires;
+ char *id;
+ char *name;
+ char *description;
+ char **authors;
+ char *copyright;
+ char *version;
+ char *icon_name;
+ char *url;
+ char *loader_type;
+ char *loader_file;
+ char **loader_requires;
+ gboolean mandatory;
GthExtensionDescriptionPrivate *priv;
};
@@ -130,30 +135,38 @@ struct _GthExtensionManagerClass {
};
GType gth_extension_get_type (void);
-gboolean gth_extension_open (GthExtension *self);
-void gth_extension_close (GthExtension *self);
-gboolean gth_extension_is_active (GthExtension *self);
-void gth_extension_activate (GthExtension *self);
-void gth_extension_deactivate (GthExtension *self);
-gboolean gth_extension_is_configurable (GthExtension *self);
-void gth_extension_configure (GthExtension *self,
- GtkWindow *parent);
+gboolean gth_extension_open (GthExtension *self);
+void gth_extension_close (GthExtension *self);
+gboolean gth_extension_is_active (GthExtension *self);
+gboolean gth_extension_activate (GthExtension *self,
+ GError **error);
+gboolean gth_extension_deactivate (GthExtension *self,
+ GError **error);
+gboolean gth_extension_is_configurable (GthExtension *self);
+void gth_extension_configure (GthExtension *self,
+ GtkWindow *parent);
GType gth_extension_module_get_type (void);
GthExtension * gth_extension_module_new (const char *module_name);
GType gth_extension_description_get_type (void);
GthExtensionDescription * gth_extension_description_new (GFile *file);
+gboolean gth_extension_description_is_active (GthExtensionDescription *desc);
+GthExtension * gth_extension_description_get_extension (GthExtensionDescription *desc);
GType gth_extension_manager_get_type (void);
GthExtensionManager * gth_extension_manager_new (void);
-gboolean gth_extension_manager_open (GthExtensionManager *manager,
- const char *extension_name);
-gboolean gth_extension_manager_activate (GthExtensionManager *manager,
- const char *extension_name);
-GList * gth_extension_manager_get_extensions (GthExtensionManager *manager);
-GthExtensionDescription * gth_extension_manager_get_description (GthExtensionManager *manager,
- const char *extension_name);
+gboolean gth_extension_manager_open (GthExtensionManager *manager,
+ const char *extension_name);
+gboolean gth_extension_manager_activate (GthExtensionManager *manager,
+ const char *extension_name,
+ GError **error);
+gboolean gth_extension_manager_deactivate (GthExtensionManager *manager,
+ const char *extension_name,
+ GError **error);
+GList * gth_extension_manager_get_extensions (GthExtensionManager *manager);
+GthExtensionDescription * gth_extension_manager_get_description (GthExtensionManager *manager,
+ const char *extension_name);
G_END_DECLS
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index ee780a6..4993022 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -34,6 +34,7 @@
#include "gth-metadata-provider.h"
#include "gth-user-dir.h"
#include "gth-preferences.h"
+#include "gtk-utils.h"
#include "pixbuf-io.h"
#include "typedefs.h"
@@ -200,12 +201,58 @@ gth_main_get_type (void)
}
+static void
+about_dialog_activate_link_cb (GtkAboutDialog *about,
+ const char *link_,
+ gpointer data)
+{
+ GError *error = NULL;
+
+ if (! gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (about)), link_, GDK_CURRENT_TIME, &error)) {
+ char *title;
+
+ title = g_strdup_printf (_("Unable to show '%s'"), link_);
+ _gtk_error_dialog_from_gerror_run (GTK_WINDOW (about), title, &error);
+
+ g_free (title);
+ }
+}
+
+
+static void
+about_dialog_activate_email_cb (GtkAboutDialog *about,
+ const char *link_,
+ gpointer data)
+{
+ GError *error = NULL;
+ char *url;
+
+ url = g_strconcat ("mailto:", link_, NULL);
+ if (! gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (about)), url, GDK_CURRENT_TIME, &error)) {
+ char *title;
+
+ title = g_strdup_printf (_("Unable to open '%s'"), link_);
+ _gtk_error_dialog_from_gerror_run (GTK_WINDOW (about), title, &error);
+
+ g_free (title);
+ }
+
+ g_free (url);
+}
+
+
void
gth_main_initialize (void)
{
if (Main != NULL)
return;
Main = (GthMain*) g_object_new (GTH_TYPE_MAIN, NULL);
+
+ g_set_application_name (_("gthumb"));
+ gtk_window_set_default_icon_name ("gthumb");
+ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), GTHUMB_PKGDATADIR G_DIR_SEPARATOR_S "icons");
+ gtk_about_dialog_set_url_hook (about_dialog_activate_link_cb, NULL, NULL);
+ gtk_about_dialog_set_email_hook (about_dialog_activate_email_cb, NULL, NULL);
}
@@ -992,14 +1039,40 @@ gth_main_get_default_extension_manager (void)
void
gth_main_activate_extensions (void)
{
- const char *default_extensions[] = { "catalogs", "comments", "exiv2", "file_manager", "file_tools", "file_viewer", "image_viewer", "search", NULL };
+ const char *mandatory_extensions[] = { "file_viewer", NULL };
+ const char *default_extensions[] = { "catalogs", "comments", "exiv2", "file_manager", "file_tools", "image_viewer", "search", NULL };
int i;
+ GSList *active_extensions;
+ GSList *scan;
if (Main->priv->extension_manager == NULL)
Main->priv->extension_manager = gth_extension_manager_new ();
- /* FIXME: read the extensions list from a gconf key */
+ for (i = 0; mandatory_extensions[i] != NULL; i++) {
+ GError *error = NULL;
+
+ if (! gth_extension_manager_activate (Main->priv->extension_manager, mandatory_extensions[i], &error)) {
+ g_warning ("Could not load the '%s' extension: %s", mandatory_extensions[i], error->message);
+ g_clear_error (&error);
+ }
+ }
+
+ active_extensions = eel_gconf_get_string_list (PREF_ACTIVE_EXTENSIONS);
+ if (active_extensions == NULL)
+ for (i = 0; default_extensions[i] != NULL; i++)
+ active_extensions = g_slist_prepend (active_extensions, g_strdup (default_extensions[i]));
+ active_extensions = g_slist_reverse (active_extensions);
+
+ for (scan = active_extensions; scan; scan = scan->next) {
+ char *name = scan->data;
+ GError *error = NULL;
+
+ if (! gth_extension_manager_activate (Main->priv->extension_manager, name, &error)) {
+ g_warning ("Could not load the '%s' extension: %s", name, error->message);
+ g_clear_error (&error);
+ }
+ }
- for (i = 0; default_extensions[i] != NULL; i++)
- gth_extension_manager_activate (Main->priv->extension_manager, default_extensions[i]);
+ g_slist_foreach (active_extensions, (GFunc) g_free, NULL);
+ g_slist_free (active_extensions);
}
diff --git a/gthumb/gth-preferences.h b/gthumb/gth-preferences.h
index 74dc1d3..ebee44b 100644
--- a/gthumb/gth-preferences.h
+++ b/gthumb/gth-preferences.h
@@ -38,6 +38,7 @@ G_BEGIN_DECLS
#define PREF_EDITORS "/apps/gthumb/general/editors"
#define PREF_MIGRATE_DIRECTORIES "/apps/gthumb/general/migrate_directories"
#define PREF_MIGRATE_COMMENT_SYSTEM "/apps/gthumb/general/migrate_comment_system"
+#define PREF_ACTIVE_EXTENSIONS "/apps/gthumb/general/active_extensions"
#define PREF_GENERAL_FILTER "/apps/gthumb/browser/general_filter"
#define PREF_SHOW_HIDDEN_FILES "/apps/gthumb/browser/show_hidden_files"
diff --git a/gthumb/gthumb-error.h b/gthumb/gthumb-error.h
index ce404cd..67c84c2 100644
--- a/gthumb/gthumb-error.h
+++ b/gthumb/gthumb-error.h
@@ -27,6 +27,11 @@
G_BEGIN_DECLS
+typedef enum {
+ GTH_ERROR_GENERIC,
+ GTH_ERROR_EXTENSION_DEPENDENCY
+} GthErrorCode;
+
#define GTHUMB_ERROR gthumb_error_quark ()
GQuark gthumb_error_quark (void);
diff --git a/gthumb/main.c b/gthumb/main.c
index ee45576..f9aea63 100644
--- a/gthumb/main.c
+++ b/gthumb/main.c
@@ -25,6 +25,7 @@
#include <gtk/gtk.h>
#include <unique/unique.h>
#include "eggsmclient.h"
+#include "glib-utils.h"
#include "gth-browser.h"
#include "gth-file-data.h"
#include "gth-file-source-vfs.h"
@@ -47,6 +48,7 @@ gboolean ImportPhotos = FALSE;
static UniqueApp *gthumb_app;
static char **remaining_args;
static const char *program_argv0; /* argv[0] from main(); used as the command to restart the program */
+static gboolean restart = FALSE;
static const GOptionEntry options[] = {
@@ -310,12 +312,6 @@ main (int argc, char *argv[])
}
g_option_context_free (context);
- /* application properties */
-
- g_set_application_name (_("gthumb"));
- gtk_window_set_default_icon_name ("gthumb");
- gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), GTHUMB_PKGDATADIR G_DIR_SEPARATOR_S "icons");
-
/* other initializations */
gth_session_manager_init ();
@@ -341,5 +337,23 @@ main (int argc, char *argv[])
gth_main_release ();
gth_pref_release ();
+ if (restart)
+ g_spawn_command_line_async (program_argv0, NULL);
+
return 0;
}
+
+
+void
+gth_restart (void)
+{
+ GList *windows;
+ GList *scan;
+
+ windows = g_list_copy (gth_window_get_window_list ());
+ for (scan = windows; scan; scan = scan->next)
+ gth_window_close (GTH_WINDOW (scan->data));
+ g_list_free (windows);
+
+ restart = TRUE;
+}
diff --git a/gthumb/main.h b/gthumb/main.h
new file mode 100644
index 0000000..a4b2489
--- /dev/null
+++ b/gthumb/main.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef MAIN_H
+#define MAIN_H
+
+G_BEGIN_DECLS
+
+void gth_restart (void);
+
+G_END_DECLS
+
+#endif /* MAIN_H */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 8776e4f..8e6705d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -5,6 +5,7 @@ copy-n-paste/eggsmclient.c
data/gthumb.desktop.in.in
data/gthumb.schemas.in
[type: gettext/glade]data/ui/bookmarks.ui
+[type: gettext/glade]data/ui/extensions.ui
[type: gettext/glade]data/ui/filter-editor.ui
[type: gettext/glade]data/ui/personalize-filters.ui
[type: gettext/glade]data/ui/preferences.ui
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]