From 139930daf186db03d49efb1d78f4cd665d586030 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer <benny@xfce.org> Date: Mon, 11 Jul 2005 21:55:32 +0000 Subject: [PATCH] 2005-07-11 Benedikt Meurer <benny@xfce.org> * thunar/thunar-navigator.c(thunar_navigator_class_init): Use EXO_PARAM_READWRITE instead of G_PARAM_READWRITE. * thunar/thunar-list-model.c: Fix several bugs related to incorrect signal registration/removal in the hidden files handling. * thunar/thunar-view.{c,h}: Add a new "ui-manager" property, which is set by the surrounding window for the view in question. The view in turn can hook its own actions - and thereby menu and toolbar items - into the ui manager, using GtkUIManager's merging capabilities. * thunar/thunar-window.c(thunar_window_init): Tell the main view about our UI manager. * thunar/thunar-window-ui.xml, thunar/thunar-standard-view-ui.xml, thunar/thunar-standard-view.{c,h}, thunar/Makefile.am: Add initial support for menu merging to the standard view class - and thereby to the icon and details view. You can now control the "show-hidden" property of the main view's model from the menu bar. (Old svn revision: 16381) --- ChangeLog | 18 ++++ thunar/Makefile.am | 10 +- thunar/thunar-list-model.c | 13 ++- thunar/thunar-navigator.c | 2 +- thunar/thunar-standard-view-ui.xml | 23 +++++ thunar/thunar-standard-view.c | 159 +++++++++++++++++++++++------ thunar/thunar-standard-view.h | 4 + thunar/thunar-view.c | 57 +++++++++++ thunar/thunar-view.h | 20 ++-- thunar/thunar-window-ui.xml | 4 +- thunar/thunar-window.c | 4 +- 11 files changed, 269 insertions(+), 45 deletions(-) create mode 100644 thunar/thunar-standard-view-ui.xml diff --git a/ChangeLog b/ChangeLog index 4f396c7cd..3af51e769 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2005-07-11 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-navigator.c(thunar_navigator_class_init): Use + EXO_PARAM_READWRITE instead of G_PARAM_READWRITE. + * thunar/thunar-list-model.c: Fix several bugs related to incorrect + signal registration/removal in the hidden files handling. + * thunar/thunar-view.{c,h}: Add a new "ui-manager" property, which is + set by the surrounding window for the view in question. The view in + turn can hook its own actions - and thereby menu and toolbar items - + into the ui manager, using GtkUIManager's merging capabilities. + * thunar/thunar-window.c(thunar_window_init): Tell the main view about + our UI manager. + * thunar/thunar-window-ui.xml, thunar/thunar-standard-view-ui.xml, + thunar/thunar-standard-view.{c,h}, thunar/Makefile.am: Add initial + support for menu merging to the standard view class - and thereby to + the icon and details view. You can now control the "show-hidden" + property of the main view's model from the menu bar. + 2005-07-10 Benedikt Meurer <benny@xfce.org> * thunar/thunar-list-model.{c,h}: Readd the get_statusbar_text() method. diff --git a/thunar/Makefile.am b/thunar/Makefile.am index 7f452583f..ffaca0b32 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -55,6 +55,7 @@ Thunar_SOURCES = \ thunar-side-pane.h \ thunar-standard-view.c \ thunar-standard-view.h \ + thunar-standard-view-ui.h \ thunar-statusbar.c \ thunar-statusbar.h \ thunar-trash-file.c \ @@ -93,20 +94,27 @@ clean-local: if MAINTAINER_MODE DISTCLEANFILES = \ thunar-fallback-icon.c \ + thunar-standard-view-ui.h \ thunar-window-ui.h BUILT_SOURCES = \ thunar-fallback-icon.c \ + thunar-standard-view-ui.h \ thunar-window-ui.h thunar-fallback-icon.c: $(srcdir)/thunar-fallback-icon.png Makefile (echo "#include <thunar/thunar-fallback-icon.h>" && gdk-pixbuf-csource --extern --raw --stream --name=thunar_fallback_icon $(srcdir)/thunar-fallback-icon.png) > thunar-fallback-icon.c +thunar-standard-view-ui.h: Makefile $(srcdir)/thunar-standard-view-ui.xml + exo-csource --static --name=thunar_standard_view_ui $(srcdir)/thunar-standard-view-ui.xml > thunar-standard-view-ui.h + thunar-window-ui.h: Makefile $(srcdir)/thunar-window-ui.xml exo-csource --static --name=thunar_window_ui $(srcdir)/thunar-window-ui.xml > thunar-window-ui.h endif EXTRA_DIST = \ - thunar-fallback-icon.png + thunar-fallback-icon.png \ + thunar-standard-view-ui.xml \ + thunar-window-ui.xml # vi:set ts=8 sw=8 noet ai nocindent syntax=automake: diff --git a/thunar/thunar-list-model.c b/thunar/thunar-list-model.c index d0d9fafd8..47ffad180 100644 --- a/thunar/thunar-list-model.c +++ b/thunar/thunar-list-model.c @@ -1609,8 +1609,8 @@ thunar_list_model_set_folder (ThunarListModel *store, /* check if this file should be shown/hidden */ if (!store->show_hidden && thunar_file_is_hidden (file)) { - g_signal_handlers_disconnect_matched (G_OBJECT (file), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE, - store->file_destroy_id, 0, store->file_destroy_closure, NULL, NULL); + g_signal_connect_closure_by_id (G_OBJECT (file), store->file_destroy_id, + 0, store->file_destroy_closure, TRUE); store->hidden = g_slist_prepend (store->hidden, file); } else @@ -1790,8 +1790,6 @@ thunar_list_model_set_show_hidden (ThunarListModel *store, for (hidden_rows = files = NULL, row = store->rows; row != NULL; row = row->next) if (thunar_file_is_hidden (row->file)) { - g_signal_handlers_disconnect_matched (G_OBJECT (row->file), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_CLOSURE, - store->file_changed_id, 0, store->file_changed_closure, NULL, NULL); hidden_rows = g_slist_prepend (hidden_rows, row); files = g_slist_prepend (files, g_object_ref (row->file)); } @@ -1807,6 +1805,13 @@ thunar_list_model_set_show_hidden (ThunarListModel *store, g_slist_free (hidden_rows); store->hidden = files; + + /* re-connect the "destroy" handlers to all hidden files */ + for (lp = store->hidden; lp != NULL; lp = lp->next) + { + g_signal_connect_closure_by_id (G_OBJECT (lp->data), store->file_destroy_id, + 0, store->file_destroy_closure, TRUE); + } } } diff --git a/thunar/thunar-navigator.c b/thunar/thunar-navigator.c index 9e81a6484..047a0efd8 100644 --- a/thunar/thunar-navigator.c +++ b/thunar/thunar-navigator.c @@ -137,7 +137,7 @@ thunar_navigator_class_init (gpointer klass) _("Current directory"), _("The directory currently displayed by the navigator"), THUNAR_TYPE_FILE, - G_PARAM_READWRITE)); + EXO_PARAM_READWRITE)); } diff --git a/thunar/thunar-standard-view-ui.xml b/thunar/thunar-standard-view-ui.xml new file mode 100644 index 000000000..f8c6f843f --- /dev/null +++ b/thunar/thunar-standard-view-ui.xml @@ -0,0 +1,23 @@ +<ui> + + <!-- + $Id$ + + Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + + Thunar standard view user interface description file. Do NOT + simply edit this file if you don't know how the whole system + works, because it's too easy to break something. + --> + + <menubar name="main-menu"> + <menu action="view-menu"> + <placeholder name="placeholder-view-display-preferences"> + <menuitem action="show-hidden-files" /> + </placeholder> + </menu> + </menubar> + +</ui> + +<!-- vi: set ts=2 sw=2 et ai nocindent syntax=xml: --> diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c index fa4f9abba..d97bef0d2 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -22,6 +22,7 @@ #endif #include <thunar/thunar-standard-view.h> +#include <thunar/thunar-standard-view-ui.h> @@ -31,36 +32,47 @@ enum PROP_CURRENT_DIRECTORY, PROP_LOADING, PROP_STATUSBAR_TEXT, + PROP_UI_MANAGER, }; -static void thunar_standard_view_class_init (ThunarStandardViewClass *klass); -static void thunar_standard_view_navigator_init (ThunarNavigatorIface *iface); -static void thunar_standard_view_view_init (ThunarViewIface *iface); -static void thunar_standard_view_init (ThunarStandardView *standard_view); -static GObject *thunar_standard_view_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); -static void thunar_standard_view_dispose (GObject *object); -static void thunar_standard_view_finalize (GObject *object); -static void thunar_standard_view_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_standard_view_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static ThunarFile *thunar_standard_view_get_current_directory (ThunarNavigator *navigator); -static void thunar_standard_view_set_current_directory (ThunarNavigator *navigator, - ThunarFile *current_directory); -static gboolean thunar_standard_view_get_loading (ThunarView *view); -static const gchar *thunar_standard_view_get_statusbar_text (ThunarView *view); -static gboolean thunar_standard_view_loading_idle (gpointer user_data); -static void thunar_standard_view_loading_idle_destroy (gpointer user_data); - - +static void thunar_standard_view_class_init (ThunarStandardViewClass *klass); +static void thunar_standard_view_navigator_init (ThunarNavigatorIface *iface); +static void thunar_standard_view_view_init (ThunarViewIface *iface); +static void thunar_standard_view_init (ThunarStandardView *standard_view); +static GObject *thunar_standard_view_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); +static void thunar_standard_view_dispose (GObject *object); +static void thunar_standard_view_finalize (GObject *object); +static void thunar_standard_view_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_standard_view_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static ThunarFile *thunar_standard_view_get_current_directory (ThunarNavigator *navigator); +static void thunar_standard_view_set_current_directory (ThunarNavigator *navigator, + ThunarFile *current_directory); +static gboolean thunar_standard_view_get_loading (ThunarView *view); +static const gchar *thunar_standard_view_get_statusbar_text (ThunarView *view); +static GtkUIManager *thunar_standard_view_get_ui_manager (ThunarView *view); +static void thunar_standard_view_set_ui_manager (ThunarView *view, + GtkUIManager *ui_manager); +static void thunar_standard_view_action_show_hidden_files (GtkToggleAction *toggle_action, + ThunarStandardView *standard_view); +static gboolean thunar_standard_view_loading_idle (gpointer user_data); +static void thunar_standard_view_loading_idle_destroy (gpointer user_data); + + + +static const GtkToggleActionEntry const toggle_action_entries[] = +{ + { "show-hidden-files", NULL, N_("Show _hidden files"), NULL, N_("Toggles the display of hidden files in the current window"), G_CALLBACK (thunar_standard_view_action_show_hidden_files), FALSE }, +}; static GObjectClass *thunar_standard_view_parent_class; @@ -138,6 +150,9 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) g_object_class_override_property (gobject_class, PROP_STATUSBAR_TEXT, "statusbar-text"); + g_object_class_override_property (gobject_class, + PROP_UI_MANAGER, + "ui-manager"); } @@ -156,6 +171,8 @@ thunar_standard_view_view_init (ThunarViewIface *iface) { iface->get_loading = thunar_standard_view_get_loading; iface->get_statusbar_text = thunar_standard_view_get_statusbar_text; + iface->get_ui_manager = thunar_standard_view_get_ui_manager; + iface->set_ui_manager = thunar_standard_view_set_ui_manager; } @@ -169,6 +186,12 @@ thunar_standard_view_init (ThunarStandardView *standard_view) gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (standard_view), NULL); gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (standard_view), NULL); + /* setup the action group for this view */ + standard_view->action_group = gtk_action_group_new ("thunar-standard-view"); + gtk_action_group_add_toggle_actions (standard_view->action_group, toggle_action_entries, + G_N_ELEMENTS (toggle_action_entries), + GTK_WIDGET (standard_view)); + standard_view->model = thunar_list_model_new (); standard_view->loading_idle_id = -1; @@ -215,8 +238,8 @@ thunar_standard_view_dispose (GObject *object) if (G_UNLIKELY (standard_view->loading_idle_id >= 0)) g_source_remove (standard_view->loading_idle_id); - /* reset the model's folder */ - thunar_list_model_set_folder (standard_view->model, NULL); + /* reset the UI manager property */ + thunar_view_set_ui_manager (THUNAR_VIEW (standard_view), NULL); G_OBJECT_CLASS (thunar_standard_view_parent_class)->dispose (object); } @@ -228,6 +251,9 @@ thunar_standard_view_finalize (GObject *object) { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (object); + /* release the reference on the action group */ + g_object_unref (G_OBJECT (standard_view->action_group)); + /* release the reference on the list model */ g_object_unref (G_OBJECT (standard_view->model)); @@ -259,6 +285,10 @@ thunar_standard_view_get_property (GObject *object, g_value_set_static_string (value, thunar_view_get_statusbar_text (THUNAR_VIEW (object))); break; + case PROP_UI_MANAGER: + g_value_set_object (value, thunar_view_get_ui_manager (THUNAR_VIEW (object))); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -273,12 +303,14 @@ thunar_standard_view_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - ThunarNavigator *navigator = THUNAR_NAVIGATOR (object); - switch (prop_id) { case PROP_CURRENT_DIRECTORY: - thunar_navigator_set_current_directory (navigator, g_value_get_object (value)); + thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (object), g_value_get_object (value)); + break; + + case PROP_UI_MANAGER: + thunar_view_set_ui_manager (THUNAR_VIEW (object), g_value_get_object (value)); break; default: @@ -430,6 +462,71 @@ thunar_standard_view_get_statusbar_text (ThunarView *view) +static GtkUIManager* +thunar_standard_view_get_ui_manager (ThunarView *view) +{ + return THUNAR_STANDARD_VIEW (view)->ui_manager; +} + + + +static void +thunar_standard_view_set_ui_manager (ThunarView *view, + GtkUIManager *ui_manager) +{ + ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); + + /* disconnect from the previous UI manager */ + if (G_LIKELY (standard_view->ui_manager != NULL)) + { + /* drop our action group from the previous UI manager */ + gtk_ui_manager_remove_action_group (standard_view->ui_manager, standard_view->action_group); + + /* unmerge our ui controls from the previous UI manager */ + gtk_ui_manager_remove_ui (standard_view->ui_manager, standard_view->ui_merge_id); + + /* drop the reference on the previous UI manager */ + g_object_unref (G_OBJECT (standard_view->ui_manager)); + } + + /* apply the new setting */ + standard_view->ui_manager = ui_manager; + + /* connect to the new manager (if any) */ + if (G_LIKELY (ui_manager != NULL)) + { + /* we keep a reference on the new manager */ + g_object_ref (G_OBJECT (ui_manager)); + + /* add our action group to the new manager */ + gtk_ui_manager_insert_action_group (ui_manager, standard_view->action_group, -1); + + /* merge our UI control items with the new manager */ + standard_view->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_standard_view_ui, + thunar_standard_view_ui_length, NULL); + } + + /* let others know that we have a new manager */ + g_object_notify (G_OBJECT (view), "ui-manager"); +} + + + +static void +thunar_standard_view_action_show_hidden_files (GtkToggleAction *toggle_action, + ThunarStandardView *standard_view) +{ + gboolean active; + + g_return_if_fail (GTK_IS_TOGGLE_ACTION (toggle_action)); + g_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + active = gtk_toggle_action_get_active (toggle_action); + thunar_list_model_set_show_hidden (standard_view->model, active); +} + + + static gboolean thunar_standard_view_loading_idle (gpointer user_data) { diff --git a/thunar/thunar-standard-view.h b/thunar/thunar-standard-view.h index 4ac3f70b7..8951fcf54 100644 --- a/thunar/thunar-standard-view.h +++ b/thunar/thunar-standard-view.h @@ -51,6 +51,10 @@ struct _ThunarStandardView ThunarListModel *model; gchar *statusbar_text; + GtkActionGroup *action_group; + GtkUIManager *ui_manager; + guint ui_merge_id; + gint loading_idle_id; }; diff --git a/thunar/thunar-view.c b/thunar/thunar-view.c index 77e3d54f7..a24e459d2 100644 --- a/thunar/thunar-view.c +++ b/thunar/thunar-view.c @@ -99,6 +99,20 @@ thunar_view_class_init (gpointer klass) _("Text to be displayed in the statusbar associated with this view"), NULL, EXO_PARAM_READABLE)); + + /** + * ThunarView:ui-manager: + * + * The UI manager used by the surrounding #ThunarWindow. The + * #ThunarView implementations may connect additional actions + * to the UI manager. + **/ + g_object_interface_install_property (klass, + g_param_spec_object ("ui-manager", + _("UI manager"), + _("UI manager of the surrounding window"), + GTK_TYPE_UI_MANAGER, + EXO_PARAM_READWRITE)); } @@ -140,4 +154,47 @@ thunar_view_get_statusbar_text (ThunarView *view) +/** + * thunar_view_get_ui_manager: + * @view : a #ThunarView instance. + * + * Returns the #GtkUIManager associated with @view or + * %NULL if @view has no #GtkUIManager associated with + * it. + * + * Return value: the #GtkUIManager associated with @view + * or %NULL. + **/ +GtkUIManager* +thunar_view_get_ui_manager (ThunarView *view) +{ + g_return_val_if_fail (THUNAR_IS_VIEW (view), NULL); + return THUNAR_VIEW_GET_IFACE (view)->get_ui_manager (view); +} + + + +/** + * thunar_view_set_ui_manager: + * @view : a #ThunarView instance. + * @ui_manager : a #GtkUIManager or %NULL. + * + * Installs a new #GtkUIManager for @view or resets the ::ui-manager + * property. + * + * Implementations of the #ThunarView interface must first disconnect + * from any previously set #GtkUIManager and then connect to the + * @ui_manager if not %NULL. + **/ +void +thunar_view_set_ui_manager (ThunarView *view, + GtkUIManager *ui_manager) +{ + g_return_if_fail (THUNAR_IS_VIEW (view)); + g_return_if_fail (ui_manager == NULL || GTK_IS_UI_MANAGER (ui_manager)); + + THUNAR_VIEW_GET_IFACE (view)->set_ui_manager (view, ui_manager); +} + + diff --git a/thunar/thunar-view.h b/thunar/thunar-view.h index 627c18af0..bafd72528 100644 --- a/thunar/thunar-view.h +++ b/thunar/thunar-view.h @@ -36,15 +36,23 @@ struct _ThunarViewIface { GTypeInterface __parent__; - /* methods */ - gboolean (*get_loading) (ThunarView *view); - const gchar *(*get_statusbar_text) (ThunarView *view); + /* virtual methods */ + gboolean (*get_loading) (ThunarView *view); + const gchar *(*get_statusbar_text) (ThunarView *view); + + GtkUIManager *(*get_ui_manager) (ThunarView *view); + void (*set_ui_manager) (ThunarView *view, + GtkUIManager *ui_manager); }; -GType thunar_view_get_type (void) G_GNUC_CONST; +GType thunar_view_get_type (void) G_GNUC_CONST; + +gboolean thunar_view_get_loading (ThunarView *view); +const gchar *thunar_view_get_statusbar_text (ThunarView *view); -gboolean thunar_view_get_loading (ThunarView *view); -const gchar *thunar_view_get_statusbar_text (ThunarView *view); +GtkUIManager *thunar_view_get_ui_manager (ThunarView *view); +void thunar_view_set_ui_manager (ThunarView *view, + GtkUIManager *ui_manager); G_END_DECLS; diff --git a/thunar/thunar-window-ui.xml b/thunar/thunar-window-ui.xml index 25f12d0d6..5c08f8fa2 100644 --- a/thunar/thunar-window-ui.xml +++ b/thunar/thunar-window-ui.xml @@ -17,7 +17,9 @@ <menu action="edit-menu" /> - <menu action="view-menu" /> + <menu action="view-menu"> + <placeholder name="placeholder-view-display-preferences" /> + </menu> <menu action="go-menu"> <menuitem action="open-parent" /> diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 647c0eb03..fc862e3e2 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -189,7 +189,9 @@ thunar_window_init (ThunarWindow *window) gtk_box_pack_start (GTK_BOX (box), window->location_bar, FALSE, FALSE, 0); gtk_widget_show (window->location_bar); - window->view = thunar_details_view_new (); + window->view = g_object_new (THUNAR_TYPE_DETAILS_VIEW, + "ui-manager", window->ui_manager, + NULL); g_signal_connect (G_OBJECT (window->view), "notify::loading", G_CALLBACK (thunar_window_notify_loading), window); g_signal_connect_swapped (G_OBJECT (window->view), "change-directory", -- GitLab