From 6120fa1e494f29b3f286fb85268232f97ae86262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20St=C3=B6sel?= Date: Tue, 7 Jun 2011 21:02:09 +0200 Subject: [PATCH] Add new signal for extension preferences If the "preferences" property is TRUE and the signal is implemented, a button is shown next to the extension and the callback is invoked on click. --- midori/midori-extension.c | 64 +++++++++++++++++++- midori/midori-extension.h | 3 + midori/midori-extensions-column.vala | 4 ++ midori/midori.vapi | 3 + midori/wscript_build | 1 + panels/midori-extensions.c | 88 ++++++++++++++++++++++++++++ 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 midori/midori-extensions-column.vala diff --git a/midori/midori-extension.c b/midori/midori-extension.c index cd96ec1c..7bf40f95 100644 --- a/midori/midori-extension.c +++ b/midori/midori-extension.c @@ -29,6 +29,7 @@ struct _MidoriExtensionPrivate gchar* version; gchar* authors; gchar* website; + gboolean preferences; MidoriApp* app; gint active; @@ -131,12 +132,14 @@ enum PROP_DESCRIPTION, PROP_VERSION, PROP_AUTHORS, - PROP_WEBSITE + PROP_WEBSITE, + PROP_PREFERENCES }; enum { ACTIVATE, DEACTIVATE, + OPEN_PREFERENCES, LAST_SIGNAL }; @@ -186,6 +189,24 @@ midori_extension_class_init (MidoriExtensionClass* class) G_TYPE_NONE, 0, G_TYPE_NONE); + /** + * MidoriExtension::open-preferences: + * + * The preferences of the extension should be opened. + * + * Since: 0.4.0 + */ + signals[OPEN_PREFERENCES] = g_signal_new ( + "open-preferences", + G_TYPE_FROM_CLASS (class), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + 0, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, + G_TYPE_NONE); + gobject_class = G_OBJECT_CLASS (class); gobject_class->finalize = midori_extension_finalize; gobject_class->set_property = midori_extension_set_property; @@ -245,6 +266,22 @@ midori_extension_class_init (MidoriExtensionClass* class) NULL, flags)); + /** + * MidoriExtension:preferences: + * + * True if the extension can handle the preferences signal. + * + * Since: 0.4.0 + */ + g_object_class_install_property (gobject_class, + PROP_PREFERENCES, + g_param_spec_boolean ( + "preferences", + "Preferences", + "True if the extension can handle the preferences signal.", + FALSE, + flags)); + g_type_class_add_private (class, sizeof (MidoriExtensionPrivate)); } @@ -409,6 +446,9 @@ midori_extension_set_property (GObject* object, case PROP_WEBSITE: katze_assign (extension->priv->website, g_value_dup_string (value)); break; + case PROP_PREFERENCES: + extension->priv->preferences = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -440,6 +480,9 @@ midori_extension_get_property (GObject* object, case PROP_WEBSITE: g_value_set_string (value, extension->priv->website); break; + case PROP_PREFERENCES: + g_value_set_boolean (value, extension->priv->preferences); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -468,6 +511,25 @@ midori_extension_is_prepared (MidoriExtension* extension) return FALSE; } +/** + * midori_extension_has_preferences: + * @extension: a #MidoriExtension + * + * Determines if @extension has preferences. + * + * Return value: %TRUE if @extension has preferences + **/ +gboolean +midori_extension_has_preferences (MidoriExtension* extension) +{ + g_return_val_if_fail (MIDORI_IS_EXTENSION (extension), FALSE); + + if (extension->priv->preferences + && g_signal_has_handler_pending (extension, signals[OPEN_PREFERENCES], 0, FALSE)) + return TRUE; + return FALSE; +} + /** * midori_extension_is_active: * @extension: a #MidoriExtension diff --git a/midori/midori-extension.h b/midori/midori-extension.h index 9fceb982..fe74d00f 100644 --- a/midori/midori-extension.h +++ b/midori/midori-extension.h @@ -51,6 +51,9 @@ midori_extension_get_type (void) G_GNUC_CONST; gboolean midori_extension_is_prepared (MidoriExtension* extension); +gboolean +midori_extension_has_preferences (MidoriExtension* extension); + gboolean midori_extension_is_active (MidoriExtension* extension); diff --git a/midori/midori-extensions-column.vala b/midori/midori-extensions-column.vala new file mode 100644 index 00000000..76b4ff9a --- /dev/null +++ b/midori/midori-extensions-column.vala @@ -0,0 +1,4 @@ + +public class Midori.ExtensionsCoumn : Gtk.TreeViewColumn { + public signal void row_clicked (Gtk.TreeView view, Gtk.TreePath path); +} diff --git a/midori/midori.vapi b/midori/midori.vapi index 4e2098d1..cbf145a6 100644 --- a/midori/midori.vapi +++ b/midori/midori.vapi @@ -101,9 +101,12 @@ namespace Midori { public string version { get; set; } [NoAccessorMethod] public string authors { get; set; } + [NoAccessorMethod] + public bool preferences { get; set; } public signal void activate (Midori.App app); public signal void deactivate (); + public signal void open_preferences (); } public class View : Gtk.VBox { diff --git a/midori/wscript_build b/midori/wscript_build index 371e8bc6..a69e08de 100644 --- a/midori/wscript_build +++ b/midori/wscript_build @@ -17,6 +17,7 @@ if progressive or Options.commands['check']: obj.uselib = libs obj.add_marshal_file ('marshal.list', 'midori_cclosure_marshal') obj.install_path = None + obj.packages = 'glib-2.0 gio-2.0 gtk+-2.0 libsoup-2.4 webkit-1.0' bld.add_group () if progressive: diff --git a/panels/midori-extensions.c b/panels/midori-extensions.c index fdae315b..5cd5202b 100644 --- a/panels/midori-extensions.c +++ b/panels/midori-extensions.c @@ -16,6 +16,8 @@ #include "midori-stock.h" #include "midori-viewable.h" +#include "midori-extensions-column.c" + #include "sokoke.h" #include @@ -244,6 +246,23 @@ midori_extensions_treeview_render_icon_cb (GtkTreeViewColumn* column, g_object_unref (extension); } +static void +midori_extensions_treeview_render_preferences_cb (GtkTreeViewColumn* column, + GtkCellRenderer* renderer, + GtkTreeModel* model, + GtkTreeIter* iter, + GtkWidget* treeview) +{ + MidoriExtension* extension; + gtk_tree_model_get (model, iter, 0, &extension, -1); + + g_object_set (renderer, "stock-id", GTK_STOCK_PREFERENCES, + "stock-size", GTK_ICON_SIZE_BUTTON, + "visible", midori_extension_has_preferences (extension), + "xpad", 4, NULL); + g_object_unref (extension); +} + static void midori_extensions_treeview_render_text_cb (GtkTreeViewColumn* column, GtkCellRenderer* renderer, @@ -351,6 +370,56 @@ midori_extensions_tree_sort_func (GtkTreeModel* model, return result; } +static void +midori_extensions_treeview_column_preference_clicked_cb (GtkWidget* widget, + GtkTreeView* treeview, + GtkTreePath* path) +{ + GtkTreeModel* model; + GtkTreeIter iter; + + model = gtk_tree_view_get_model (treeview); + if (gtk_tree_model_get_iter (model, &iter, path)) + { + MidoriExtension* extension; + + gtk_tree_model_get (model, &iter, 0, &extension, -1); + g_signal_emit_by_name (extension, "open-preferences"); + g_object_unref (extension); + } + +} + +static gboolean +midori_extensions_treeview_button_pressed_cb (GtkWidget* view, + GdkEventButton* bevent, + gpointer data) +{ + gboolean ret = FALSE; + GtkTreePath* path; + GtkTreeViewColumn* column; + guint signal_id; + + if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), + bevent->x, bevent->y, &path, &column, NULL, NULL)) + { + if (path != NULL) + { + if (MIDORI_IS_EXTENSIONS_COUMN (column)) + { + signal_id = g_signal_lookup ("row-clicked", G_OBJECT_TYPE (column)); + + if (signal_id && g_signal_has_handler_pending (column, signal_id, 0, FALSE)) { + g_signal_emit (column, signal_id, 0, GTK_TREE_VIEW (view), path); + ret = TRUE; + } + } + gtk_tree_path_free (path); + } + } + return ret; +} + static void midori_extensions_init (MidoriExtensions* extensions) { @@ -359,8 +428,13 @@ midori_extensions_init (MidoriExtensions* extensions) GtkCellRenderer* renderer_icon; GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_toggle; + GtkCellRenderer* renderer_preferences; GtkListStore* liststore = gtk_list_store_new (1, G_TYPE_OBJECT); extensions->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore)); + g_object_connect (extensions->treeview, + "signal::button-press-event", + midori_extensions_treeview_button_pressed_cb, NULL, + NULL); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore), 0, GTK_SORT_ASCENDING); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (liststore), @@ -386,10 +460,24 @@ midori_extensions_init (MidoriExtensions* extensions) gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); renderer_text = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer_text, FALSE); + gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_column_set_cell_data_func (column, renderer_text, (GtkTreeCellDataFunc)midori_extensions_treeview_render_text_cb, extensions->treeview, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (extensions->treeview), column); + column = GTK_TREE_VIEW_COLUMN (midori_extensions_coumn_new ()); + g_signal_connect (column, + "row-clicked", + G_CALLBACK (midori_extensions_treeview_column_preference_clicked_cb), + NULL); + renderer_preferences = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, renderer_preferences, FALSE); + gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (column, 30); + gtk_tree_view_column_set_cell_data_func (column, renderer_preferences, + (GtkTreeCellDataFunc)midori_extensions_treeview_render_preferences_cb, + extensions->treeview, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (extensions->treeview), column); g_object_unref (liststore); g_object_connect (extensions->treeview, "signal::row-activated",