/* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2021 Sergios - Anestis Kefalidis * * 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 * Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "thunar/thunar-abstract-dialog.h" #include "thunar/thunar-application.h" #include "thunar/thunar-dialogs.h" #include "thunar/thunar-gtk-extensions.h" #include "thunar/thunar-pango-extensions.h" #include "thunar/thunar-preferences.h" #include "thunar/thunar-private.h" #include "thunar/thunar-toolbar-editor.h" #include #include enum { COL_ID, COL_VISIBILITY, COL_CHECKBOX_VISIBLE, COL_ICON, COL_LABEL, COL_TOOLTIP, N_COLS }; static void thunar_toolbar_editor_finalize (GObject *object); static void thunar_toolbar_editor_help_clicked (ThunarToolbarEditor *toolbar_editor, GtkWidget *button); static void thunar_toolbar_editor_swap_toolbar_items_for_all_windows (ThunarToolbarEditor *editor, GtkTreeIter *item1, GtkTreeIter *item2); static void thunar_toolbar_editor_move_down (ThunarToolbarEditor *toolbar_editor, GtkWidget *button); static void thunar_toolbar_editor_move_up (ThunarToolbarEditor *toolbar_editor, GtkWidget *button); static void thunar_toolbar_editor_toggle_visibility (ThunarToolbarEditor *toolbar_editor, const gchar *path_string, GtkCellRendererToggle *cell_renderer); static void thunar_toolbar_editor_update_buttons (ThunarToolbarEditor *toolbar_editor); static void thunar_toolbar_editor_use_defaults (ThunarToolbarEditor *toolbar_editor, GtkWidget *button); static void thunar_toolbar_editor_toggle_symbolic_icons (ThunarToolbarEditor *toolbar_editor); static void thunar_toolbar_editor_save_model (ThunarToolbarEditor *toolbar_editor); static void thunar_toolbar_editor_populate_model (ThunarToolbarEditor *toolbar_editor); struct _ThunarToolbarEditorClass { ThunarAbstractDialogClass __parent__; }; struct _ThunarToolbarEditor { ThunarAbstractDialog __parent__; ThunarPreferences *preferences; GtkListStore *model; /* Used to get information about the toolbar items, it is used as a reference. All the toolbars are changed, not just this one. */ GtkWidget *toolbar; GtkWidget *tree_view; GtkWidget *up_button; GtkWidget *down_button; }; G_DEFINE_TYPE (ThunarToolbarEditor, thunar_toolbar_editor, THUNAR_TYPE_ABSTRACT_DIALOG) static void thunar_toolbar_editor_class_init (ThunarToolbarEditorClass *klass) { GObjectClass *gobject_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = thunar_toolbar_editor_finalize; } static void thunar_toolbar_editor_init (ThunarToolbarEditor *toolbar_editor) { GtkCellRenderer *renderer; GtkWidget *button; GtkWidget *image; GtkWidget *label; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *vbox_buttons; GtkWidget *separator; GtkWidget *swin; /* grab a reference on the preferences */ toolbar_editor->preferences = thunar_preferences_get (); /* grab a reference on the shared toolbar model */ toolbar_editor->model = gtk_list_store_new (N_COLS, G_TYPE_STRING, /* action id */ G_TYPE_BOOLEAN, /* visibility */ G_TYPE_BOOLEAN, /* checkbox visible */ G_TYPE_STRING, /* icon */ G_TYPE_STRING, /* label */ G_TYPE_STRING); /* tooltip */ /* setup the dialog */ gtk_dialog_add_button (GTK_DIALOG (toolbar_editor), _("_Close"), GTK_RESPONSE_CLOSE); gtk_dialog_set_default_response (GTK_DIALOG (toolbar_editor), GTK_RESPONSE_CLOSE); gtk_window_set_default_size (GTK_WINDOW (toolbar_editor), 450, 500); gtk_window_set_resizable (GTK_WINDOW (toolbar_editor), TRUE); gtk_window_set_title (GTK_WINDOW (toolbar_editor), _("Configure the Toolbar")); /* add the "Help" button */ button = gtk_button_new_with_mnemonic (_("_Help")); g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (thunar_toolbar_editor_help_clicked), toolbar_editor); gtk_box_pack_start (GTK_BOX (exo_gtk_dialog_get_action_area (GTK_DIALOG (toolbar_editor))), button, FALSE, FALSE, 0); gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (exo_gtk_dialog_get_action_area (GTK_DIALOG (toolbar_editor))), button, TRUE); gtk_widget_show (button); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (toolbar_editor))), vbox, TRUE, TRUE, 0); gtk_widget_show (vbox); /* create the top label for the toolbar editor dialog */ label = gtk_label_new (_("Configure the order and visibility of toolbar items.\n" "Note that toolbar items are always executed for the current directory.")); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_xalign (GTK_LABEL (label), 0.0f); gtk_widget_set_hexpand (label, TRUE); gtk_widget_set_vexpand (label, FALSE); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 6); gtk_widget_show (hbox); /* create the scrolled window for the tree view */ swin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_IN); gtk_widget_set_hexpand (swin, TRUE); gtk_widget_set_vexpand (swin, TRUE); gtk_box_pack_start (GTK_BOX (hbox), swin, TRUE, TRUE, 0); gtk_widget_show (swin); /* create the tree view */ toolbar_editor->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (toolbar_editor->model)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (toolbar_editor->tree_view), FALSE); gtk_tree_view_set_search_column (GTK_TREE_VIEW (toolbar_editor->tree_view), COL_LABEL); gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (toolbar_editor->tree_view), COL_TOOLTIP); gtk_container_add (GTK_CONTAINER (swin), toolbar_editor->tree_view); gtk_widget_show (toolbar_editor->tree_view); /* append the toggle visibility column */ renderer = gtk_cell_renderer_toggle_new (); g_signal_connect_swapped (G_OBJECT (renderer), "toggled", G_CALLBACK (thunar_toolbar_editor_toggle_visibility), toolbar_editor); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (toolbar_editor->tree_view), -1, "Active", renderer, "active", COL_VISIBILITY, "visible", COL_CHECKBOX_VISIBLE, NULL); /* append the icon column */ renderer = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (toolbar_editor->tree_view), -1, "Icon", renderer, "icon-name", COL_ICON, NULL); /* append the label column */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (toolbar_editor->tree_view), -1, "Label", renderer, "text", COL_LABEL, NULL); /* Create the buttons vbox container */ vbox_buttons = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_box_pack_start (GTK_BOX (hbox), vbox_buttons, FALSE, FALSE, 0); gtk_widget_set_vexpand (vbox_buttons, FALSE); gtk_widget_show (vbox_buttons); /* create the "Move Up" button */ toolbar_editor->up_button = gtk_button_new_with_mnemonic (_("Move _Up")); g_signal_connect_swapped (G_OBJECT (toolbar_editor->up_button), "clicked", G_CALLBACK (thunar_toolbar_editor_move_up), toolbar_editor); gtk_box_pack_start (GTK_BOX (vbox_buttons), toolbar_editor->up_button, FALSE, FALSE, 0); gtk_widget_show (toolbar_editor->up_button); image = gtk_image_new_from_icon_name ("go-up-symbolic", GTK_ICON_SIZE_BUTTON); gtk_button_set_always_show_image (GTK_BUTTON (toolbar_editor->up_button), TRUE); gtk_button_set_image (GTK_BUTTON (toolbar_editor->up_button), image); gtk_widget_show (image); /* create the "Move Down" button */ toolbar_editor->down_button = gtk_button_new_with_mnemonic (_("Move Dow_n")); g_signal_connect_swapped (G_OBJECT (toolbar_editor->down_button), "clicked", G_CALLBACK (thunar_toolbar_editor_move_down), toolbar_editor); gtk_box_pack_start (GTK_BOX (vbox_buttons), toolbar_editor->down_button, FALSE, FALSE, 0); gtk_widget_show (toolbar_editor->down_button); image = gtk_image_new_from_icon_name ("go-down-symbolic", GTK_ICON_SIZE_BUTTON); gtk_button_set_always_show_image (GTK_BUTTON (toolbar_editor->down_button), TRUE); gtk_button_set_image (GTK_BUTTON (toolbar_editor->down_button), image); gtk_widget_show (image); /* add separator */ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_start (GTK_BOX (vbox_buttons), separator, FALSE, FALSE, 0); gtk_widget_show (separator); /* create the "Use Default" button */ button = gtk_button_new_with_mnemonic (_("De_fault Order")); g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (thunar_toolbar_editor_use_defaults), toolbar_editor); gtk_box_pack_start (GTK_BOX (vbox_buttons), button, FALSE, FALSE, 0); gtk_widget_show (button); /* create the "Symbolic Icons" checkbox */ button = gtk_check_button_new_with_mnemonic (_("_Symbolic Icons")); g_object_bind_property (G_OBJECT (toolbar_editor->preferences), "misc-symbolic-icons-in-toolbar", G_OBJECT (button), "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); gtk_widget_set_tooltip_text (button, _("Use symbolic icons instead of regular ones (if available).")); gtk_box_pack_end (GTK_BOX (vbox_buttons), button, FALSE, FALSE, 0); gtk_widget_show (button); g_signal_connect_swapped (G_OBJECT (toolbar_editor->preferences), "notify::misc-symbolic-icons-in-toolbar", G_CALLBACK (thunar_toolbar_editor_toggle_symbolic_icons), toolbar_editor); /* grab focus to the tree view */ gtk_widget_grab_focus (toolbar_editor->tree_view); } static void thunar_toolbar_editor_finalize (GObject *object) { ThunarToolbarEditor *toolbar_editor = THUNAR_TOOLBAR_EDITOR (object); thunar_toolbar_editor_save_model (toolbar_editor); /* release our reference on the shared toolbar model */ g_signal_handlers_disconnect_by_data (G_OBJECT (toolbar_editor->model), toolbar_editor); g_object_unref (G_OBJECT (toolbar_editor->model)); /* release our reference on the preferences */ g_signal_handlers_disconnect_by_data (G_OBJECT (toolbar_editor->preferences), toolbar_editor); g_object_unref (G_OBJECT (toolbar_editor->preferences)); (*G_OBJECT_CLASS (thunar_toolbar_editor_parent_class)->finalize) (object); } static void thunar_toolbar_editor_help_clicked (ThunarToolbarEditor *toolbar_editor, GtkWidget *button) { _thunar_return_if_fail (THUNAR_IS_TOOLBAR_EDITOR (toolbar_editor)); _thunar_return_if_fail (GTK_IS_BUTTON (button)); /* open the user manual */ xfce_dialog_show_help (GTK_WINDOW (gtk_widget_get_toplevel (button)), "thunar", "the-file-manager-window", "toolbar_customization"); } static void thunar_toolbar_editor_swap_toolbar_items_for_all_windows (ThunarToolbarEditor *editor, GtkTreeIter *item1, GtkTreeIter *item2) { ThunarApplication *application; GList *windows; GtkTreePath *path1; GtkTreePath *path2; path1 = gtk_tree_model_get_path (GTK_TREE_MODEL (editor->model), item1); path2 = gtk_tree_model_get_path (GTK_TREE_MODEL (editor->model), item2); application = thunar_application_get (); windows = thunar_application_get_windows (application); for (GList *lp = windows; lp != NULL; lp = lp->next) { ThunarWindow *window = lp->data; thunar_window_toolbar_swap_items (window, gtk_tree_path_get_indices (path1)[0], gtk_tree_path_get_indices (path2)[0]); } g_object_unref (application); g_list_free (windows); gtk_tree_path_free (path1); gtk_tree_path_free (path2); } static void thunar_toolbar_editor_move_down (ThunarToolbarEditor *toolbar_editor, GtkWidget *button) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter1; GtkTreeIter iter2; _thunar_return_if_fail (THUNAR_IS_TOOLBAR_EDITOR (toolbar_editor)); _thunar_return_if_fail (GTK_IS_BUTTON (button)); /* determine the selected tree iterator */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (toolbar_editor->tree_view)); gtk_tree_selection_get_selected (selection, &model, &iter1); iter2 = iter1; if (gtk_tree_model_iter_next (model, &iter2) == FALSE) return; gtk_list_store_swap (GTK_LIST_STORE (model), &iter1, &iter2); thunar_toolbar_editor_swap_toolbar_items_for_all_windows (toolbar_editor, &iter1, &iter2); } static void thunar_toolbar_editor_move_up (ThunarToolbarEditor *toolbar_editor, GtkWidget *button) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter1; GtkTreeIter iter2; _thunar_return_if_fail (THUNAR_IS_TOOLBAR_EDITOR (toolbar_editor)); _thunar_return_if_fail (GTK_IS_BUTTON (button)); /* determine the selected tree iterator */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (toolbar_editor->tree_view)); gtk_tree_selection_get_selected (selection, &model, &iter1); iter2 = iter1; if (gtk_tree_model_iter_previous (model, &iter2) == FALSE) return; gtk_list_store_swap (GTK_LIST_STORE (model), &iter1, &iter2); thunar_toolbar_editor_swap_toolbar_items_for_all_windows (toolbar_editor, &iter1, &iter2); } static void thunar_toolbar_editor_toggle_visibility (ThunarToolbarEditor *toolbar_editor, const gchar *path_string, GtkCellRendererToggle *cell_renderer) { ThunarApplication *application; GList *windows; GtkTreePath *path; GtkTreeIter iter; gboolean visible; _thunar_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (cell_renderer)); _thunar_return_if_fail (THUNAR_IS_TOOLBAR_EDITOR (toolbar_editor)); _thunar_return_if_fail (path_string != NULL); /* determine the tree path for the string */ path = gtk_tree_path_new_from_string (path_string); if (gtk_tree_model_get_iter (GTK_TREE_MODEL (toolbar_editor->model), &iter, path)) { gtk_tree_model_get (GTK_TREE_MODEL (toolbar_editor->model), &iter, 1, &visible, -1); gtk_list_store_set (toolbar_editor->model, &iter, 1, !visible, -1); } application = thunar_application_get (); windows = thunar_application_get_windows (application); for (GList *lp = windows; lp != NULL; lp = lp->next) { ThunarWindow *window = lp->data; thunar_window_toolbar_toggle_item_visibility (window, gtk_tree_path_get_indices (path)[0]); } g_object_unref (application); g_list_free (windows); gtk_tree_path_free (path); } static void thunar_toolbar_editor_update_buttons (ThunarToolbarEditor *toolbar_editor) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; gint idx; /* determine the selected row */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (toolbar_editor->tree_view)); if (gtk_tree_selection_get_selected (selection, &model, &iter)) { /* determine the tree path for the iter */ path = gtk_tree_model_get_path (model, &iter); if (G_UNLIKELY (path == NULL)) return; /* update the "Move Up"/"Move Down" buttons */ idx = gtk_tree_path_get_indices (path)[0]; gtk_widget_set_sensitive (toolbar_editor->up_button, (idx > 0)); gtk_widget_set_sensitive (toolbar_editor->down_button, (idx + 1 < gtk_tree_model_iter_n_children (model, NULL))); /* release the path */ gtk_tree_path_free (path); } else { /* just disable all buttons */ gtk_widget_set_sensitive (toolbar_editor->down_button, FALSE); gtk_widget_set_sensitive (toolbar_editor->up_button, FALSE); } } static void thunar_toolbar_editor_use_defaults (ThunarToolbarEditor *toolbar_editor, GtkWidget *button) { GList *toolbar_items; guint item_count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (toolbar_editor->model), NULL); guint target_order[item_count]; guint current_order[item_count]; guint index; toolbar_items = gtk_container_get_children (GTK_CONTAINER (toolbar_editor->toolbar)); index = 0; for (GList *lp = toolbar_items; lp != NULL; lp = lp->next) { GtkWidget *item = lp->data; gint *order = NULL; order = g_object_get_data (G_OBJECT (item), "default-order"); current_order[index] = *order; target_order[index] = index; index++; } /* now rearrange the toolbar items, the goal is to make the current_order like the target_order */ for (guint i = 0; i < item_count; i++) { guint x = target_order[i]; for (guint j = 0; j < item_count; j++) { guint y = current_order[j]; if (x == y && i != j) { GtkTreeIter iter_i, iter_j; gchar *path_i, *path_j; path_i = g_strdup_printf ("%i", i); path_j = g_strdup_printf ("%i", j); /* swap the positions of the toolbar items */ gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (toolbar_editor->model), &iter_i, path_i); gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (toolbar_editor->model), &iter_j, path_j); gtk_list_store_swap (GTK_LIST_STORE (toolbar_editor->model), &iter_i, &iter_j); thunar_toolbar_editor_swap_toolbar_items_for_all_windows (toolbar_editor, &iter_i, &iter_j); y = current_order[i]; current_order[i] = target_order[i]; current_order[j] = y; g_free (path_i); g_free (path_j); break; } } } g_list_free (toolbar_items); } static void thunar_toolbar_editor_toggle_symbolic_icons (ThunarToolbarEditor *toolbar_editor) { /* clear the tree view */ gtk_list_store_clear (toolbar_editor->model); g_signal_handlers_disconnect_by_data (G_OBJECT (toolbar_editor->model), toolbar_editor); /* populate the tree view */ thunar_toolbar_editor_populate_model (toolbar_editor); } static void thunar_toolbar_editor_save_model (ThunarToolbarEditor *toolbar_editor) { GString *items; guint item_count; items = g_string_sized_new (512); item_count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (toolbar_editor->model), NULL); /* read the internal id and visibility column values and store them */ for (guint i = 0; i < item_count; i++) { GtkTreeIter iter; gchar *path; gchar *id; gboolean visible; /* get iterator for the ith item */ path = g_strdup_printf ("%i", i); gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (toolbar_editor->model), &iter, path); g_free (path); /* get the id value of the entry */ gtk_tree_model_get (GTK_TREE_MODEL (toolbar_editor->model), &iter, COL_ID, &id, -1); if (id == NULL) continue; /* append a comma if not empty */ if (*items->str != '\0') g_string_append_c (items, ','); /* store the id value */ g_string_append (items, id); g_free (id); /* append the separator character */ g_string_append_c (items, ':'); /* get the visibility value of the entry and store it */ gtk_tree_model_get (GTK_TREE_MODEL (toolbar_editor->model), &iter, COL_VISIBILITY, &visible, -1); g_string_append_printf (items, "%i", visible); } /* save the toolbar configuration */ g_object_set (G_OBJECT (toolbar_editor->preferences), "last-toolbar-items", items->str, NULL); /* release the string */ g_string_free (items, TRUE); } static void thunar_toolbar_editor_populate_model (ThunarToolbarEditor *toolbar_editor) { GtkTreeSelection *selection; GtkTreeIter iter; GList *toolbar_items; toolbar_items = gtk_container_get_children (GTK_CONTAINER (toolbar_editor->toolbar)); for (GList *lp = toolbar_items; lp != NULL; lp = lp->next) { GtkWidget *item = lp->data; GtkWidget *widget = NULL; /* used to remove mnemonics */ gchar *id = NULL; gchar *icon = NULL; gchar *label_with_mnemonic = NULL; gchar *tooltip = NULL; gboolean checkbox_visible = TRUE; id = g_object_get_data (G_OBJECT (item), "id"); icon = g_object_get_data (G_OBJECT (item), "icon"); label_with_mnemonic = g_object_get_data (G_OBJECT (item), "label"); widget = gtk_label_new_with_mnemonic (label_with_mnemonic); g_object_ref_sink (widget); if (g_strcmp0 (id, "menu") == 0) { checkbox_visible = FALSE; tooltip = _("Only visible when the menubar is hidden"); } gtk_list_store_append (toolbar_editor->model, &iter); gtk_list_store_set (toolbar_editor->model, &iter, COL_ID, id, COL_VISIBILITY, gtk_widget_is_visible (item), COL_CHECKBOX_VISIBLE, checkbox_visible, COL_ICON, icon, COL_LABEL, gtk_label_get_text (GTK_LABEL (widget)), COL_TOOLTIP, tooltip, -1); g_object_unref (widget); } /* connect after model has been fully initialized */ g_signal_connect_data (G_OBJECT (toolbar_editor->model), "row-changed", G_CALLBACK (thunar_toolbar_editor_update_buttons), toolbar_editor, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED); g_signal_connect_data (G_OBJECT (toolbar_editor->model), "rows-reordered", G_CALLBACK (thunar_toolbar_editor_update_buttons), toolbar_editor, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED); /* set up the tree selection */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (toolbar_editor->tree_view)); g_signal_connect_swapped (G_OBJECT (selection), "changed", G_CALLBACK (thunar_toolbar_editor_update_buttons), toolbar_editor); /* select the first item */ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (toolbar_editor->model), &iter)) gtk_tree_selection_select_iter (selection, &iter); g_list_free (toolbar_items); } /** * thunar_show_toolbar_editor: * @parent : the #GtkWidget the #GdkScreen on which to open the * toolbar editor dialog. May also be %NULL in which case * the default #GdkScreen will be used. * * Convenience function to display a #ThunarToolbarEditor. **/ void thunar_show_toolbar_editor (GtkWidget *window, GtkWidget *window_toolbar) { GtkWidget *dialog; GdkScreen *screen = NULL; _thunar_return_if_fail (GTK_IS_WIDGET (window)); screen = gtk_widget_get_screen (window); window = gtk_widget_get_toplevel (window); /* display the toolbar editor */ dialog = g_object_new (THUNAR_TYPE_TOOLBAR_EDITOR, NULL); /* set the toolbar used for gathering information */ g_object_ref (window_toolbar); THUNAR_TOOLBAR_EDITOR (dialog)->toolbar = window_toolbar; /* now that the toolbar is set, populate the tree view */ thunar_toolbar_editor_populate_model (THUNAR_TOOLBAR_EDITOR (dialog)); /* check if we have a toplevel window */ if (G_LIKELY (window != NULL && gtk_widget_get_toplevel (window))) { /* dialog is transient for toplevel window and modal */ gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window)); } /* set the screen for the window */ if (screen != NULL && GDK_IS_SCREEN (screen)) gtk_window_set_screen (GTK_WINDOW (dialog), screen); /* run the dialog */ gtk_dialog_run (GTK_DIALOG (dialog)); /* destroy the dialog */ g_object_unref (window_toolbar); gtk_widget_destroy (dialog); } /** * thunar_save_toolbar_configuration: * @toolbar: a #GtkWidget instance. * * Trigger a configuration save without displaying the #ThunarToolbarEditor. **/ void thunar_save_toolbar_configuration (GtkWidget *toolbar) { GtkWidget *dialog; /* create the toolbar editor */ dialog = g_object_new (THUNAR_TYPE_TOOLBAR_EDITOR, NULL); /* set the toolbar used for gathering information */ THUNAR_TOOLBAR_EDITOR (dialog)->toolbar = toolbar; /* now that the toolbar is set, populate the tree view */ thunar_toolbar_editor_populate_model (THUNAR_TOOLBAR_EDITOR (dialog)); /* destroy the dialog */ gtk_widget_destroy (dialog); }