diff options
author | Alexander Schwinn <alexxcons@xfce.org> | 2020-04-24 01:17:33 +0200 |
---|---|---|
committer | Alexander Schwinn <alexxcons@xfce.org> | 2020-05-15 23:46:48 +0200 |
commit | 4929c96e78623ec561fcf61d0e4de4b1e1fb76ee (patch) | |
tree | aedc03cf421403e27a1270eb598c3698a37d6e98 | |
parent | 077bea9f6a01c7a347f58ab15486204a55197b04 (diff) | |
download | thunar-ReplaceGtkAction47.tar.gz |
giant commitReplaceGtkAction47
54 files changed, 9200 insertions, 6991 deletions
diff --git a/.project b/.project new file mode 100644 index 00000000..654e796e --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>thunar</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + </buildSpec> + <natures> + </natures> +</projectDescription> diff --git a/0001-Crash-when-chaning-views-pressing-select-all.patch b/0001-Crash-when-chaning-views-pressing-select-all.patch new file mode 100644 index 00000000..0dd3ed0d --- /dev/null +++ b/0001-Crash-when-chaning-views-pressing-select-all.patch @@ -0,0 +1,276 @@ +From dbaf5a7c49d78cbb092355fa4923e167d8c3e491 Mon Sep 17 00:00:00 2001 +From: Alexander Schwinn <alexxcons@xfce.org> +Date: Mon, 4 May 2020 22:26:38 +0200 +Subject: [PATCH] Crash when chaning views + pressing "select all" + +--- + thunar/thunar-standard-view.c | 60 ++++------------------------------- + thunar/thunar-standard-view.h | 15 ++------- + thunar/thunar-window.c | 50 +++++++++++++++++++++++------ + thunar/thunar-window.h | 3 ++ + 4 files changed, 53 insertions(+), 75 deletions(-) + +diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c +index 4d9238cc..3fbc2fe6 100644 +--- a/thunar/thunar-standard-view.c ++++ b/thunar/thunar-standard-view.c +@@ -160,9 +160,6 @@ static void thunar_standard_view_current_directory_changed (Thu + static GList *thunar_standard_view_get_selected_files_view (ThunarView *view); + static void thunar_standard_view_set_selected_files_view (ThunarView *view, + GList *selected_files); +-static void thunar_standard_view_select_all_files (ThunarView *view); +-static void thunar_standard_view_select_by_pattern (ThunarView *view); +-static void thunar_standard_view_selection_invert (ThunarView *view); + static GClosure *thunar_standard_view_new_files_closure (ThunarStandardView *standard_view, + GtkWidget *source_view); + static void thunar_standard_view_new_files (ThunarStandardView *standard_view, +@@ -333,15 +330,6 @@ struct _ThunarStandardViewPrivate + GtkTreePath *selection_before_delete; + }; + +-static XfceGtkActionEntry thunar_standard_view_action_entries[] = +-{ +- { THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES, "<Actions>/ThunarStandardView/select-all-files", "<Primary>a", XFCE_GTK_MENU_ITEM, N_ ("Select _all Files"), N_ ("Select all files in this window"), NULL, G_CALLBACK (thunar_standard_view_select_all_files), }, +- { THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN, "<Actions>/ThunarStandardView/select-by-pattern", "<Primary>s", XFCE_GTK_MENU_ITEM, N_ ("Select _by Pattern..."), N_ ("Select all files that match a certain pattern"), NULL, G_CALLBACK (thunar_standard_view_select_by_pattern), }, +- { THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION, "<Actions>/ThunarStandardView/invert-selection", "", XFCE_GTK_MENU_ITEM, N_ ("_Invert Selection"), N_ ("Select all files but not those currently selected"), NULL, G_CALLBACK (thunar_standard_view_selection_invert), }, +-}; +- +-#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_standard_view_action_entries,G_N_ELEMENTS(thunar_standard_view_action_entries),id) +- + /* Target types for dragging from the view */ + static const GtkTargetEntry drag_targets[] = + { +@@ -391,8 +379,6 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) + gtkwidget_class->grab_focus = thunar_standard_view_grab_focus; + gtkwidget_class->draw = thunar_standard_view_draw; + +- xfce_gtk_translate_action_entries (thunar_standard_view_action_entries, G_N_ELEMENTS (thunar_standard_view_action_entries)); +- + /** + * ThunarStandardView:loading: + * +@@ -1903,11 +1889,9 @@ thunar_standard_view_current_directory_changed (ThunarFile *current_dire + + + +-static void +-thunar_standard_view_select_all_files (ThunarView *view) ++void ++thunar_standard_view_select_all_files (ThunarStandardView *standard_view) + { +- ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); +- + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + /* grab the focus to the view */ +@@ -1919,10 +1903,9 @@ thunar_standard_view_select_all_files (ThunarView *view) + + + +-static void +-thunar_standard_view_select_by_pattern (ThunarView *view) ++void ++thunar_standard_view_select_by_pattern (ThunarStandardView *standard_view) + { +- ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); + GtkWidget *window; + GtkWidget *dialog; + GtkWidget *vbox; +@@ -2016,11 +1999,9 @@ thunar_standard_view_select_by_pattern (ThunarView *view) + + + +-static void +-thunar_standard_view_selection_invert (ThunarView *view) ++void ++thunar_standard_view_selection_invert (ThunarStandardView *standard_view) + { +- ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); +- + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + /* grab the focus to the view */ +@@ -3431,7 +3412,6 @@ thunar_standard_view_context_menu (ThunarStandardView *standard_view) + thunar_menu_add_sections (context_menu, THUNAR_MENU_SECTION_ZOOM + | THUNAR_MENU_SECTION_PROPERTIES); + } +- thunar_menu_hide_accel_labels (context_menu); + gtk_widget_show_all (GTK_WIDGET (context_menu)); + thunar_window_redirect_menu_tooltips_to_statusbar (THUNAR_WINDOW (window), GTK_MENU (context_menu)); + +@@ -3644,28 +3624,6 @@ thunar_standard_view_append_menu_items (ThunarStandardView *standard_view, + + + +-/** +- * thunar_standard_view_append_menu_item: +- * @standard_view : Instance of a #ThunarStandardView +- * @menu : #GtkMenuShell to which the item should be added +- * @action : #ThunarStandardViewAction to select which item should be added +- * +- * Adds the selected, widget specific #GtkMenuItem to the passed #GtkMenuShell +- * +- * Return value: (transfer none): The added #GtkMenuItem +- **/ +-void +-thunar_standard_view_append_menu_item (ThunarStandardView *standard_view, +- GtkMenu *menu, +- ThunarStandardViewAction action) +-{ +- _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); +- +- xfce_gtk_menu_item_new_from_action_entry (get_action_entry (action), G_OBJECT (standard_view), GTK_MENU_SHELL (menu)); +-} +- +- +- + /** + * thunar_standard_view_append_accelerators: + * @standard_view : a #ThunarStandardView. +@@ -3680,12 +3638,6 @@ thunar_standard_view_append_accelerators (ThunarStandardView *standard_view, + { + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + +- xfce_gtk_accel_map_add_entries (thunar_standard_view_action_entries, G_N_ELEMENTS (thunar_standard_view_action_entries)); +- xfce_gtk_accel_group_connect_action_entries (accel_group, +- thunar_standard_view_action_entries, +- G_N_ELEMENTS (thunar_standard_view_action_entries), +- standard_view); +- + /* as well append accelerators of derived widgets */ + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->append_accelerators) (standard_view, accel_group); + } +diff --git a/thunar/thunar-standard-view.h b/thunar/thunar-standard-view.h +index 67d20894..c95778c1 100644 +--- a/thunar/thunar-standard-view.h ++++ b/thunar/thunar-standard-view.h +@@ -40,15 +40,6 @@ typedef struct _ThunarStandardView ThunarStandardView; + #define THUNAR_IS_STANDARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_STANDARD_VIEW)) + #define THUNAR_STANDARD_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_STANDARD_VIEW, ThunarStandardViewClass)) + +-/* #XfceGtkActionEntrys provided by this widget */ +-typedef enum +-{ +- THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES, +- THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN, +- THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION, +- +-} ThunarStandardViewAction; +- + struct _ThunarStandardViewClass + { + GtkScrolledWindowClass __parent__; +@@ -157,11 +148,11 @@ ThunarHistory *thunar_standard_view_copy_history (ThunarStandardView + void thunar_standard_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group); +-void thunar_standard_view_append_menu_item (ThunarStandardView *standard_view, +- GtkMenu *menu, +- ThunarStandardViewAction action); + void thunar_standard_view_append_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group); ++void thunar_standard_view_select_all_files (ThunarStandardView *standard_view); ++void thunar_standard_view_select_by_pattern (ThunarStandardView *standard_view); ++void thunar_standard_view_selection_invert (ThunarStandardView *standard_view); + + G_END_DECLS; + +diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c +index 1afa5362..935b6c34 100644 +--- a/thunar/thunar-window.c ++++ b/thunar/thunar-window.c +@@ -156,6 +156,9 @@ static void thunar_window_action_close_tab (ThunarWindow + GtkWidget *menu_item); + static void thunar_window_action_close_window (ThunarWindow *window, + GtkWidget *menu_item); ++static void thunar_window_action_select_all_files (ThunarWindow *window); ++static void thunar_window_action_select_by_pattern (ThunarWindow *window); ++static void thunar_window_action_selection_invert (ThunarWindow *window); + static void thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item); + static void thunar_window_action_reload (ThunarWindow *window, +@@ -339,6 +342,9 @@ static XfceGtkActionEntry thunar_window_action_entries[] = + { THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS, "<Actions>/ThunarWindow/close-all-windows", "<Primary><Shift>w", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Close _All Windows"), N_ ("Close all Thunar windows"), NULL, G_CALLBACK (thunar_window_action_close_all_windows), }, + + { THUNAR_WINDOW_ACTION_EDIT_MENU, "<Actions>/ThunarWindow/edit-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Edit"), NULL, NULL, NULL, }, ++ { THUNAR_WINDOW_ACTION_SELECT_ALL_FILES, "<Actions>/ThunarStandardView/select-all-files", "<Primary>a", XFCE_GTK_MENU_ITEM, N_ ("Select _all Files"), N_ ("Select all files in this window"), NULL, G_CALLBACK (thunar_window_action_select_all_files), }, ++ { THUNAR_WINDOW_ACTION_SELECT_BY_PATTERN, "<Actions>/ThunarStandardView/select-by-pattern", "<Primary>s", XFCE_GTK_MENU_ITEM, N_ ("Select _by Pattern..."), N_ ("Select all files that match a certain pattern"), NULL, G_CALLBACK (thunar_window_action_select_by_pattern), }, ++ { THUNAR_WINDOW_ACTION_INVERT_SELECTION, "<Actions>/ThunarStandardView/invert-selection", "", XFCE_GTK_MENU_ITEM, N_ ("_Invert Selection"), N_ ("Select all files but not those currently selected"), NULL, G_CALLBACK (thunar_window_action_selection_invert), }, + { THUNAR_WINDOW_ACTION_PREFERENCES, "<Actions>/ThunarWindow/preferences", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Pr_eferences..."), N_ ("Edit Thunars Preferences"), "preferences-system", G_CALLBACK (thunar_window_action_preferences), }, + + { THUNAR_WINDOW_ACTION_VIEW_MENU, "<Actions>/ThunarWindow/view-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_View"), NULL, NULL, NULL, }, +@@ -942,15 +948,9 @@ thunar_window_create_edit_menu (ThunarWindow *window, + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_CUT + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_TRASH_DELETE); +- if (window->view != NULL) +- { +- thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), +- GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES); +- thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), +- GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN); +- thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), +- GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION); +- } ++ xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SELECT_ALL_FILES), G_OBJECT (window), GTK_MENU_SHELL(submenu)); ++ xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SELECT_BY_PATTERN), G_OBJECT (window), GTK_MENU_SHELL(submenu)); ++ xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_INVERT_SELECTION), G_OBJECT (window), GTK_MENU_SHELL(submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_DUPLICATE + | THUNAR_MENU_SECTION_MAKELINK +@@ -2456,6 +2456,38 @@ thunar_window_action_close_window (ThunarWindow *window, + + + ++static void ++thunar_window_action_select_all_files (ThunarWindow *window) ++{ ++ _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); ++ ++ thunar_standard_view_select_all_files (THUNAR_STANDARD_VIEW (window->view)); ++ ++} ++ ++ ++ ++static void ++thunar_window_action_select_by_pattern (ThunarWindow *window) ++{ ++ _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); ++ ++ thunar_standard_view_select_by_pattern (THUNAR_STANDARD_VIEW (window->view)); ++} ++ ++ ++ ++static void ++thunar_window_action_selection_invert (ThunarWindow *window) ++{ ++ _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); ++ ++ thunar_standard_view_selection_invert (THUNAR_STANDARD_VIEW (window->view)); ++ ++} ++ ++ ++ + static void + thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item) +diff --git a/thunar/thunar-window.h b/thunar/thunar-window.h +index 5b595d6f..e2e98bac 100644 +--- a/thunar/thunar-window.h ++++ b/thunar/thunar-window.h +@@ -49,6 +49,9 @@ typedef enum + THUNAR_WINDOW_ACTION_CLOSE_WINDOW, + THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS, + THUNAR_WINDOW_ACTION_EDIT_MENU, ++ THUNAR_WINDOW_ACTION_SELECT_ALL_FILES, ++ THUNAR_WINDOW_ACTION_SELECT_BY_PATTERN, ++ THUNAR_WINDOW_ACTION_INVERT_SELECTION, + THUNAR_WINDOW_ACTION_PREFERENCES, + THUNAR_WINDOW_ACTION_VIEW_MENU, + THUNAR_WINDOW_ACTION_RELOAD, +-- +2.26.2 + diff --git a/0001-fix-crash-when-using-shortcut-for-select-all-after-s.patch b/0001-fix-crash-when-using-shortcut-for-select-all-after-s.patch new file mode 100644 index 00000000..ad527508 --- /dev/null +++ b/0001-fix-crash-when-using-shortcut-for-select-all-after-s.patch @@ -0,0 +1,260 @@ +From 4fdfd08211392d8551ab1dd5f12353cf22077217 Mon Sep 17 00:00:00 2001 +From: Alexander Schwinn <alexxcons@xfce.org> +Date: Mon, 27 Apr 2020 10:52:40 +0200 +Subject: [PATCH] fix crash when using shortcut for "select all" after + switching views + +--- + thunar/thunar-standard-view.c | 57 +++++------------------------------ + thunar/thunar-standard-view.h | 15 ++------- + thunar/thunar-window.c | 44 +++++++++++++++++++++++++-- + thunar/thunar-window.h | 3 ++ + 4 files changed, 54 insertions(+), 65 deletions(-) + +diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c +index fd2f2090..29061a39 100644 +--- a/thunar/thunar-standard-view.c ++++ b/thunar/thunar-standard-view.c +@@ -160,9 +160,6 @@ static void thunar_standard_view_current_directory_changed (Thu + static GList *thunar_standard_view_get_selected_files_view (ThunarView *view); + static void thunar_standard_view_set_selected_files_view (ThunarView *view, + GList *selected_files); +-static void thunar_standard_view_select_all_files (ThunarView *view); +-static void thunar_standard_view_select_by_pattern (ThunarView *view); +-static void thunar_standard_view_selection_invert (ThunarView *view); + static GClosure *thunar_standard_view_new_files_closure (ThunarStandardView *standard_view, + GtkWidget *source_view); + static void thunar_standard_view_new_files (ThunarStandardView *standard_view, +@@ -333,15 +330,6 @@ struct _ThunarStandardViewPrivate + GtkTreePath *selection_before_delete; + }; + +-static XfceGtkActionEntry thunar_standard_view_action_entries[] = +-{ +- { THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES, "<Actions>/ThunarStandardView/select-all-files", "<Primary>a", XFCE_GTK_MENU_ITEM, N_ ("Select _all Files"), N_ ("Select all files in this window"), NULL, G_CALLBACK (thunar_standard_view_select_all_files), }, +- { THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN, "<Actions>/ThunarStandardView/select-by-pattern", "<Primary>s", XFCE_GTK_MENU_ITEM, N_ ("Select _by Pattern..."), N_ ("Select all files that match a certain pattern"), NULL, G_CALLBACK (thunar_standard_view_select_by_pattern), }, +- { THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION, "<Actions>/ThunarStandardView/invert-selection", "", XFCE_GTK_MENU_ITEM, N_ ("_Invert Selection"), N_ ("Select all files but not those currently selected"), NULL, G_CALLBACK (thunar_standard_view_selection_invert), }, +-}; +- +-#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_standard_view_action_entries,G_N_ELEMENTS(thunar_standard_view_action_entries),id) +- + /* Target types for dragging from the view */ + static const GtkTargetEntry drag_targets[] = + { +@@ -391,8 +379,6 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) + gtkwidget_class->grab_focus = thunar_standard_view_grab_focus; + gtkwidget_class->draw = thunar_standard_view_draw; + +- xfce_gtk_translate_action_entries (thunar_standard_view_action_entries, G_N_ELEMENTS (thunar_standard_view_action_entries)); +- + /** + * ThunarStandardView:loading: + * +@@ -1903,11 +1889,9 @@ thunar_standard_view_current_directory_changed (ThunarFile *current_dire + + + +-static void +-thunar_standard_view_select_all_files (ThunarView *view) ++void ++thunar_standard_view_select_all_files (ThunarStandardView *standard_view) + { +- ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); +- + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + /* grab the focus to the view */ +@@ -1919,10 +1903,9 @@ thunar_standard_view_select_all_files (ThunarView *view) + + + +-static void +-thunar_standard_view_select_by_pattern (ThunarView *view) ++void ++thunar_standard_view_select_by_pattern (ThunarStandardView *standard_view) + { +- ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); + GtkWidget *window; + GtkWidget *dialog; + GtkWidget *vbox; +@@ -2016,11 +1999,9 @@ thunar_standard_view_select_by_pattern (ThunarView *view) + + + +-static void +-thunar_standard_view_selection_invert (ThunarView *view) ++void ++thunar_standard_view_selection_invert (ThunarStandardView *standard_view) + { +- ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); +- + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + /* grab the focus to the view */ +@@ -3643,28 +3624,6 @@ thunar_standard_view_append_menu_items (ThunarStandardView *standard_view, + + + +-/** +- * thunar_standard_view_append_menu_item: +- * @standard_view : Instance of a #ThunarStandardView +- * @menu : #GtkMenuShell to which the item should be added +- * @action : #ThunarStandardViewAction to select which item should be added +- * +- * Adds the selected, widget specific #GtkMenuItem to the passed #GtkMenuShell +- * +- * Return value: (transfer none): The added #GtkMenuItem +- **/ +-void +-thunar_standard_view_append_menu_item (ThunarStandardView *standard_view, +- GtkMenu *menu, +- ThunarStandardViewAction action) +-{ +- _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); +- +- xfce_gtk_menu_item_new_from_action_entry (get_action_entry (action), G_OBJECT (standard_view), GTK_MENU_SHELL (menu)); +-} +- +- +- + /** + * thunar_standard_view_append_accelerators: + * @standard_view : a #ThunarStandardView. +@@ -3679,8 +3638,6 @@ thunar_standard_view_append_accelerators (ThunarStandardView *standard_view, + { + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + +- xfce_gtk_accel_group_append (accel_group, thunar_standard_view_action_entries, G_N_ELEMENTS (thunar_standard_view_action_entries), standard_view); +- +- /* as well append accelerators of derived widgets */ ++ /* append accelerators of derived widgets */ + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->append_accelerators) (standard_view, accel_group); + } +diff --git a/thunar/thunar-standard-view.h b/thunar/thunar-standard-view.h +index 67d20894..c95778c1 100644 +--- a/thunar/thunar-standard-view.h ++++ b/thunar/thunar-standard-view.h +@@ -40,15 +40,6 @@ typedef struct _ThunarStandardView ThunarStandardView; + #define THUNAR_IS_STANDARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_STANDARD_VIEW)) + #define THUNAR_STANDARD_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_STANDARD_VIEW, ThunarStandardViewClass)) + +-/* #XfceGtkActionEntrys provided by this widget */ +-typedef enum +-{ +- THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES, +- THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN, +- THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION, +- +-} ThunarStandardViewAction; +- + struct _ThunarStandardViewClass + { + GtkScrolledWindowClass __parent__; +@@ -157,11 +148,11 @@ ThunarHistory *thunar_standard_view_copy_history (ThunarStandardView + void thunar_standard_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group); +-void thunar_standard_view_append_menu_item (ThunarStandardView *standard_view, +- GtkMenu *menu, +- ThunarStandardViewAction action); + void thunar_standard_view_append_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group); ++void thunar_standard_view_select_all_files (ThunarStandardView *standard_view); ++void thunar_standard_view_select_by_pattern (ThunarStandardView *standard_view); ++void thunar_standard_view_selection_invert (ThunarStandardView *standard_view); + + G_END_DECLS; + +diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c +index 20592b82..87ebcf66 100644 +--- a/thunar/thunar-window.c ++++ b/thunar/thunar-window.c +@@ -156,6 +156,9 @@ static void thunar_window_action_close_tab (ThunarWindow + GtkWidget *menu_item); + static void thunar_window_action_close_window (ThunarWindow *window, + GtkWidget *menu_item); ++static void thunar_window_action_select_all_files (ThunarWindow *window); ++static void thunar_window_action_select_by_pattern (ThunarWindow *window); ++static void thunar_window_action_selection_invert (ThunarWindow *window); + static void thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item); + static void thunar_window_action_reload (ThunarWindow *window, +@@ -339,6 +342,9 @@ static XfceGtkActionEntry thunar_window_action_entries[] = + { THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS, "<Actions>/ThunarWindow/close-all-windows", "<Primary><Shift>w", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Close _All Windows"), N_ ("Close all Thunar windows"), NULL, G_CALLBACK (thunar_window_action_close_all_windows), }, + + { THUNAR_WINDOW_ACTION_EDIT_MENU, "<Actions>/ThunarWindow/edit-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Edit"), NULL, NULL, NULL, }, ++ { THUNAR_WINDOW_ACTION_SELECT_ALL_FILES, "<Actions>/ThunarStandardView/select-all-files", "<Primary>a", XFCE_GTK_MENU_ITEM, N_ ("Select _all Files"), N_ ("Select all files in this window"), NULL, G_CALLBACK (thunar_window_action_select_all_files), }, ++ { THUNAR_WINDOW_ACTION_SELECT_BY_PATTERN, "<Actions>/ThunarStandardView/select-by-pattern", "<Primary>s", XFCE_GTK_MENU_ITEM, N_ ("Select _by Pattern..."), N_ ("Select all files that match a certain pattern"), NULL, G_CALLBACK (thunar_window_action_select_by_pattern), }, ++ { THUNAR_WINDOW_ACTION_INVERT_SELECTION, "<Actions>/ThunarStandardView/invert-selection", "", XFCE_GTK_MENU_ITEM, N_ ("_Invert Selection"), N_ ("Select all files but not those currently selected"), NULL, G_CALLBACK (thunar_window_action_selection_invert), }, + { THUNAR_WINDOW_ACTION_PREFERENCES, "<Actions>/ThunarWindow/preferences", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Pr_eferences..."), N_ ("Edit Thunars Preferences"), "preferences-system", G_CALLBACK (thunar_window_action_preferences), }, + + { THUNAR_WINDOW_ACTION_VIEW_MENU, "<Actions>/ThunarWindow/view-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_View"), NULL, NULL, NULL, }, +@@ -944,9 +950,9 @@ thunar_window_create_edit_menu (ThunarWindow *window, + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_CUT + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_TRASH_DELETE); +- thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES); +- thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN); +- thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION); ++ xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SELECT_ALL_FILES), G_OBJECT (window), GTK_MENU_SHELL(submenu)); ++ xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SELECT_BY_PATTERN), G_OBJECT (window), GTK_MENU_SHELL(submenu)); ++ xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_INVERT_SELECTION), G_OBJECT (window), GTK_MENU_SHELL(submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_DUPLICATE + | THUNAR_MENU_SECTION_MAKELINK +@@ -2447,6 +2453,38 @@ thunar_window_action_close_window (ThunarWindow *window, + + + ++static void ++thunar_window_action_select_all_files (ThunarWindow *window) ++{ ++ _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); ++ ++ thunar_standard_view_select_all_files (THUNAR_STANDARD_VIEW (window->view)); ++ ++} ++ ++ ++ ++static void ++thunar_window_action_select_by_pattern (ThunarWindow *window) ++{ ++ _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); ++ ++ thunar_standard_view_select_by_pattern (THUNAR_STANDARD_VIEW (window->view)); ++} ++ ++ ++ ++static void ++thunar_window_action_selection_invert (ThunarWindow *window) ++{ ++ _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); ++ ++ thunar_standard_view_selection_invert (THUNAR_STANDARD_VIEW (window->view)); ++ ++} ++ ++ ++ + static void + thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item) +diff --git a/thunar/thunar-window.h b/thunar/thunar-window.h +index 5b595d6f..e2e98bac 100644 +--- a/thunar/thunar-window.h ++++ b/thunar/thunar-window.h +@@ -49,6 +49,9 @@ typedef enum + THUNAR_WINDOW_ACTION_CLOSE_WINDOW, + THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS, + THUNAR_WINDOW_ACTION_EDIT_MENU, ++ THUNAR_WINDOW_ACTION_SELECT_ALL_FILES, ++ THUNAR_WINDOW_ACTION_SELECT_BY_PATTERN, ++ THUNAR_WINDOW_ACTION_INVERT_SELECTION, + THUNAR_WINDOW_ACTION_PREFERENCES, + THUNAR_WINDOW_ACTION_VIEW_MENU, + THUNAR_WINDOW_ACTION_RELOAD, +-- +2.26.2 + diff --git a/0001-fix-view-toggle.patch b/0001-fix-view-toggle.patch new file mode 100644 index 00000000..8aa3cafc --- /dev/null +++ b/0001-fix-view-toggle.patch @@ -0,0 +1,53 @@ +From 3adedde4b9a81c6c61073239ea5c6d3eee238a5e Mon Sep 17 00:00:00 2001 +From: Alexander Schwinn <alexxcons@xfce.org> +Date: Fri, 24 Apr 2020 00:02:01 +0200 +Subject: [PATCH] fix view toggle + +--- + thunar/thunar-window.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c +index 1a162145..20592b82 100644 +--- a/thunar/thunar-window.c ++++ b/thunar/thunar-window.c +@@ -993,7 +993,6 @@ thunar_window_create_view_menu (ThunarWindow *window, + GtkWidget *sub_items; + gchar *last_location_bar; + gchar *last_side_pane; +- gchar *last_view; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); +@@ -1037,14 +1036,12 @@ thunar_window_create_view_menu (ThunarWindow *window, + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_ZOOM_RESET), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + +- g_object_get (window->preferences, "last-view", &last_view, NULL); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_ICONS), +- G_OBJECT (window), exo_str_is_equal (last_view, g_type_name (THUNAR_TYPE_ICON_VIEW)), GTK_MENU_SHELL (submenu)); ++ G_OBJECT (window), window->view_type == THUNAR_TYPE_ICON_VIEW, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_DETAILED_LIST), +- G_OBJECT (window), exo_str_is_equal (last_view, g_type_name (THUNAR_TYPE_DETAILS_VIEW)), GTK_MENU_SHELL (submenu)); ++ G_OBJECT (window), window->view_type == THUNAR_TYPE_DETAILS_VIEW, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_COMPACT_LIST), +- G_OBJECT (window), exo_str_is_equal (last_view, g_type_name (THUNAR_TYPE_COMPACT_VIEW)), GTK_MENU_SHELL (submenu)); +- g_free (last_view); ++ G_OBJECT (window), window->view_type == THUNAR_TYPE_COMPACT_VIEW, GTK_MENU_SHELL (submenu)); + + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); +@@ -1653,6 +1650,10 @@ thunar_window_notebook_switch_page (GtkWidget *notebook, + + /* activate new view */ + window->view = page; ++ window->view_type = G_TYPE_FROM_INSTANCE (page); ++ ++ if (window->view_type != G_TYPE_NONE) ++ g_object_set (G_OBJECT (window->preferences), "last-view", g_type_name (window->view_type), NULL); + + /* connect to the new history */ + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); +-- +2.26.1 + diff --git a/configure.ac.in b/configure.ac.in index 5c82a191..e117e1e7 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -153,7 +153,7 @@ XDT_CHECK_PACKAGE([GMODULE], [gmodule-2.0], [2.42.0]) XDT_CHECK_PACKAGE([GTK], [gtk+-3.0], [3.22.0]) XDT_CHECK_PACKAGE([GDK_PIXBUF], [gdk-pixbuf-2.0], [2.14.0]) XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.12.0]) -XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-2], [4.15.0]) +XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-2], [4.15.2]) XDT_CHECK_PACKAGE([LIBXFCE4KBD_PRIVATE], [libxfce4kbd-private-3], [4.12.0]) XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.12.0]) XDT_CHECK_PACKAGE([PANGO], [pango], [1.38.0]) diff --git a/dbus.test.sh b/dbus.test.sh new file mode 100755 index 00000000..9fdabf4d --- /dev/null +++ b/dbus.test.sh @@ -0,0 +1,7 @@ + + dbus-send --dest=org.freedesktop.FileManager1 \ + --type=method_call \ + /org/freedesktop/FileManager1 \ + org.freedesktop.FileManager1.ShowItemProperties \ + array:string:"file:/home/schwinn/misc","file:/ec" \ + string:"0" diff --git a/po/POTFILES.in b/po/POTFILES.in index 63cc7e66..9d35f3f4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -29,7 +29,6 @@ thunar/thunar-gdk-extensions.c thunar/thunar-gio-extensions.c thunar/thunar-gobject-extensions.c thunar/thunar-gtk-extensions.c -thunar/thunar-history-action.c thunar/thunar-history.c thunar/thunar-ice.c thunar/thunar-icon-factory.c @@ -46,6 +45,7 @@ thunar/thunar-location-bar.c thunar/thunar-location-button.c thunar/thunar-location-buttons.c thunar/thunar-location-entry.c +thunar/thunar-menu.c thunar/thunar-notify.c thunar/thunar-navigator.c thunar/thunar-pango-extensions.c @@ -71,11 +71,9 @@ thunar/thunar-simple-job.c thunar/thunar-size-label.c thunar/thunar-standard-view.c thunar/thunar-statusbar.c -thunar/thunar-templates-action.c thunar/thunar-thumbnail-cache.c thunar/thunar-thumbnailer.c thunar/thunar-transfer-job.c -thunar/thunar-trash-action.c thunar/thunar-tree-model.c thunar/thunar-tree-pane.c thunar/thunar-tree-view.c diff --git a/thunar/Makefile.am b/thunar/Makefile.am index 3848ebe1..c2c75f91 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -24,12 +24,6 @@ bin_PROGRAMS = \ thunar_built_sources = \ thunar-marshal.c \ thunar-marshal.h \ - thunar-abstract-icon-view-ui.h \ - thunar-details-view-ui.h \ - thunar-launcher-ui.h \ - thunar-shortcuts-pane-ui.h \ - thunar-renamer-dialog-ui.h \ - thunar-standard-view-ui.h \ thunar-dbus-freedesktop-interfaces.h \ thunar-dbus-freedesktop-interfaces.c \ thunar-dbus-service-infos.h \ @@ -38,7 +32,6 @@ thunar_built_sources = \ thunar-thumbnailer-proxy.h \ thunar-thumbnail-cache-proxy.h \ thunar-thumbnail-cache-proxy.c \ - thunar-window-ui.h \ thunar-resources.h \ thunar-resources.c @@ -108,8 +101,6 @@ thunar_SOURCES = \ thunar-gobject-extensions.h \ thunar-gtk-extensions.c \ thunar-gtk-extensions.h \ - thunar-history-action.c \ - thunar-history-action.h \ thunar-history.c \ thunar-history.h \ thunar-ice.c \ @@ -142,8 +133,8 @@ thunar_SOURCES = \ thunar-location-buttons.h \ thunar-location-entry.c \ thunar-location-entry.h \ - thunar-menu-util.c \ - thunar-menu-util.h \ + thunar-menu.c \ + thunar-menu.h \ thunar-notify.c \ thunar-notify.h \ thunar-navigator.c \ @@ -195,16 +186,12 @@ thunar_SOURCES = \ thunar-standard-view.h \ thunar-statusbar.c \ thunar-statusbar.h \ - thunar-templates-action.c \ - thunar-templates-action.h \ thunar-thumbnail-cache.c \ thunar-thumbnail-cache.h \ thunar-thumbnailer.c \ thunar-thumbnailer.h \ thunar-transfer-job.c \ thunar-transfer-job.h \ - thunar-trash-action.c \ - thunar-trash-action.h \ thunar-tree-model.c \ thunar-tree-model.h \ thunar-tree-pane.c \ @@ -303,27 +290,6 @@ thunar-thumbnailer-proxy.h thunar-thumbnailer-proxy.c: $(srcdir)/thunar-thumbnai thunar-thumbnail-cache-proxy.h thunar-thumbnail-cache-proxy.c: $(srcdir)/thunar-thumbnail-cache-dbus.xml Makefile $(AM_V_GEN) gdbus-codegen --c-namespace Thunar --generate-c-code thunar-thumbnail-cache-proxy $(srcdir)/thunar-thumbnail-cache-dbus.xml -thunar-abstract-icon-view-ui.h: Makefile $(srcdir)/thunar-abstract-icon-view-ui.xml - $(AM_V_GEN) xdt-csource --strip-comments --strip-content --static --name=thunar_abstract_icon_view_ui $(srcdir)/thunar-abstract-icon-view-ui.xml > thunar-abstract-icon-view-ui.h - -thunar-details-view-ui.h: Makefile $(srcdir)/thunar-details-view-ui.xml - $(AM_V_GEN) xdt-csource --strip-comments --strip-content --static --name=thunar_details_view_ui $(srcdir)/thunar-details-view-ui.xml > thunar-details-view-ui.h - -thunar-launcher-ui.h: Makefile $(srcdir)/thunar-launcher-ui.xml - $(AM_V_GEN) xdt-csource --strip-comments --strip-content --static --name=thunar_launcher_ui $(srcdir)/thunar-launcher-ui.xml > thunar-launcher-ui.h - -thunar-shortcuts-pane-ui.h: Makefile $(srcdir)/thunar-shortcuts-pane-ui.xml - $(AM_V_GEN) xdt-csource --strip-comments --strip-content --static --name=thunar_shortcuts_pane_ui $(srcdir)/thunar-shortcuts-pane-ui.xml > thunar-shortcuts-pane-ui.h - -thunar-renamer-dialog-ui.h: Makefile $(srcdir)/thunar-renamer-dialog-ui.xml - $(AM_V_GEN) xdt-csource --strip-comments --strip-content --static --name=thunar_renamer_dialog_ui $(srcdir)/thunar-renamer-dialog-ui.xml > thunar-renamer-dialog-ui.h - -thunar-standard-view-ui.h: Makefile $(srcdir)/thunar-standard-view-ui.xml - $(AM_V_GEN) xdt-csource --strip-comments --strip-content --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 - $(AM_V_GEN) xdt-csource --strip-comments --strip-content --static --name=thunar_window_ui $(srcdir)/thunar-window-ui.xml > thunar-window-ui.h - thunar-marshal.h: stamp-thunar-marshal.h @true @@ -360,16 +326,10 @@ thunar-resources.h: thunar.gresource.xml endif EXTRA_DIST = \ - thunar-abstract-icon-view-ui.xml \ thunar-dbus-freedesktop-interfaces.xml \ thunar-dbus-service-infos.xml \ - thunar-details-view-ui.xml \ - thunar-launcher-ui.xml \ thunar-marshal.list \ - thunar-renamer-dialog-ui.xml \ - thunar-standard-view-ui.xml \ thunar-thumbnail-frame.png \ - thunar-window-ui.xml \ thunar-settings \ thunar.gresource.xml \ $(desktop_in_files) diff --git a/thunar/thunar-abstract-icon-view-ui.xml b/thunar/thunar-abstract-icon-view-ui.xml deleted file mode 100644 index c75a282a..00000000 --- a/thunar/thunar-abstract-icon-view-ui.xml +++ /dev/null @@ -1,43 +0,0 @@ -<ui> - - <!-- - Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - - Thunar icon 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-items-actions"> - <menu action="arrange-items-menu"> - <menuitem action="sort-by-name" /> - <menuitem action="sort-by-size" /> - <menuitem action="sort-by-type" /> - <menuitem action="sort-by-mtime" /> - <separator /> - <menuitem action="sort-ascending" /> - <menuitem action="sort-descending" /> - </menu> - </placeholder> - </menu> - </menubar> - - <popup action="folder-context-menu"> - <placeholder name="placeholder-view-items-actions"> - <menu action="arrange-items-menu"> - <menuitem action="sort-by-name" /> - <menuitem action="sort-by-size" /> - <menuitem action="sort-by-type" /> - <menuitem action="sort-by-mtime" /> - <separator /> - <menuitem action="sort-ascending" /> - <menuitem action="sort-descending" /> - </menu> - </placeholder> - </popup> - -</ui> - -<!-- vi: set ts=2 sw=2 et ai nocindent syntax=xml: --> diff --git a/thunar/thunar-abstract-icon-view.c b/thunar/thunar-abstract-icon-view.c index d5aea830..50be2728 100644 --- a/thunar/thunar-abstract-icon-view.c +++ b/thunar/thunar-abstract-icon-view.c @@ -24,20 +24,17 @@ #include <gdk/gdkkeysyms.h> #include <thunar/thunar-abstract-icon-view.h> -#include <thunar/thunar-abstract-icon-view-ui.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-launcher.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> +#include <thunar/thunar-window.h> static void thunar_abstract_icon_view_style_set (GtkWidget *widget, GtkStyle *previous_style); -static void thunar_abstract_icon_view_connect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager); -static void thunar_abstract_icon_view_disconnect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager); static GList *thunar_abstract_icon_view_get_selected_items (ThunarStandardView *standard_view); static void thunar_abstract_icon_view_select_all (ThunarStandardView *standard_view); static void thunar_abstract_icon_view_unselect_all (ThunarStandardView *standard_view); @@ -60,10 +57,13 @@ static gboolean thunar_abstract_icon_view_get_visible_range (ThunarStand GtkTreePath **end_path); static void thunar_abstract_icon_view_highlight_path (ThunarStandardView *standard_view, GtkTreePath *path); -static GtkAction *thunar_abstract_icon_view_gesture_action (ThunarAbstractIconView *abstract_icon_view); -static void thunar_abstract_icon_view_action_sort (GtkAction *action, - GtkAction *current, - ThunarStandardView *standard_view); +static void thunar_abstract_icon_view_connect_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group); +static void thunar_abstract_icon_view_disconnect_accelerators(ThunarStandardView *standard_view, + GtkAccelGroup *accel_group); +static void thunar_abstract_icon_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group); static void thunar_abstract_icon_view_notify_model (ExoIconView *view, GParamSpec *pspec, ThunarAbstractIconView *abstract_icon_view); @@ -88,13 +88,17 @@ static void thunar_abstract_icon_view_item_activated (ExoIconView static void thunar_abstract_icon_view_sort_column_changed (GtkTreeSortable *sortable, ThunarAbstractIconView *abstract_icon_view); static void thunar_abstract_icon_view_zoom_level_changed (ThunarAbstractIconView *abstract_icon_view); - - +static void thunar_abstract_icon_view_action_sort_by_name (ThunarStandardView *standard_view); +static void thunar_abstract_icon_view_action_sort_by_size (ThunarStandardView *standard_view); +static void thunar_abstract_icon_view_action_sort_by_type (ThunarStandardView *standard_view); +static void thunar_abstract_icon_view_action_sort_by_date (ThunarStandardView *standard_view); +static void thunar_abstract_icon_view_action_sort_ascending (ThunarStandardView *standard_view); +static void thunar_abstract_icon_view_action_sort_descending(ThunarStandardView *standard_view); struct _ThunarAbstractIconViewPrivate { - /* the UI manager merge id for the abstract icon view */ - gint ui_merge_id; + GtkSortType sort_order; + gint sort_column; /* mouse gesture support */ gint gesture_start_x; @@ -109,25 +113,18 @@ struct _ThunarAbstractIconViewPrivate }; - -static const GtkActionEntry action_entries[] = -{ - { "arrange-items-menu", NULL, N_ ("Arran_ge Items"), NULL, NULL, NULL, }, -}; - -static const GtkRadioActionEntry column_action_entries[] = +static XfceGtkActionEntry thunar_abstract_icon_view_action_entries[] = { - { "sort-by-name", NULL, N_ ("Sort By _Name"), NULL, N_ ("Keep items sorted by their name"), THUNAR_COLUMN_NAME, }, - { "sort-by-size", NULL, N_ ("Sort By _Size"), NULL, N_ ("Keep items sorted by their size"), THUNAR_COLUMN_SIZE, }, - { "sort-by-type", NULL, N_ ("Sort By _Type"), NULL, N_ ("Keep items sorted by their type"), THUNAR_COLUMN_TYPE, }, - { "sort-by-mtime", NULL, N_ ("Sort By Modification _Date"), NULL, N_ ("Keep items sorted by their modification date"), THUNAR_COLUMN_DATE_MODIFIED, }, + { THUNAR_ABSTRACT_ICON_VIEW_ACTION_ARRANGE_ITEMS_MENU, "<Actions>/ThunarStandardView/arrange-items-menu", "", XFCE_GTK_MENU_ITEM, N_ ("Arran_ge Items"), NULL, NULL, G_CALLBACK (NULL), }, + { THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_NAME, "<Actions>/ThunarStandardView/sort-by-name", "", XFCE_GTK_RADIO_MENU_ITEM, N_ ("Sort By _Name"), N_ ("Keep items sorted by their name"), NULL, G_CALLBACK (thunar_abstract_icon_view_action_sort_by_name), }, + { THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_SIZE, "<Actions>/ThunarStandardView/sort-by-size", "", XFCE_GTK_RADIO_MENU_ITEM, N_ ("Sort By _Size"), N_ ("Keep items sorted by their size"), NULL, G_CALLBACK (thunar_abstract_icon_view_action_sort_by_size), }, + { THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_TYPE, "<Actions>/ThunarStandardView/sort-by-type", "", XFCE_GTK_RADIO_MENU_ITEM, N_ ("Sort By _Type"), N_ ("Keep items sorted by their type"), NULL, G_CALLBACK (thunar_abstract_icon_view_action_sort_by_type), }, + { THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_MTIME, "<Actions>/ThunarStandardView/sort-by-mtime", "", XFCE_GTK_RADIO_MENU_ITEM, N_ ("Sort By Modification _Date"), N_ ("Keep items sorted by their modification date"), NULL, G_CALLBACK (thunar_abstract_icon_view_action_sort_by_date), }, + { THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_ASCENDING, "<Actions>/ThunarStandardView/sort-ascending", "", XFCE_GTK_RADIO_MENU_ITEM, N_ ("_Ascending"), N_ ("Sort items in ascending order"), NULL, G_CALLBACK (thunar_abstract_icon_view_action_sort_ascending), }, + { THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_DESCENDING, "<Actions>/ThunarStandardView/sort-descending", "", XFCE_GTK_RADIO_MENU_ITEM, N_ ("_Descending"), N_ ("Sort items in descending order"), NULL, G_CALLBACK (thunar_abstract_icon_view_action_sort_descending), }, }; -static const GtkRadioActionEntry order_action_entries[] = -{ - { "sort-ascending", NULL, N_ ("_Ascending"), NULL, N_ ("Sort items in ascending order"), GTK_SORT_ASCENDING, }, - { "sort-descending", NULL, N_ ("_Descending"), NULL, N_ ("Sort items in descending order"), GTK_SORT_DESCENDING, }, -}; +#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_abstract_icon_view_action_entries,G_N_ELEMENTS(thunar_abstract_icon_view_action_entries),id) @@ -145,8 +142,6 @@ thunar_abstract_icon_view_class_init (ThunarAbstractIconViewClass *klass) gtkwidget_class->style_set = thunar_abstract_icon_view_style_set; thunarstandard_view_class = THUNAR_STANDARD_VIEW_CLASS (klass); - thunarstandard_view_class->connect_ui_manager = thunar_abstract_icon_view_connect_ui_manager; - thunarstandard_view_class->disconnect_ui_manager = thunar_abstract_icon_view_disconnect_ui_manager; thunarstandard_view_class->get_selected_items = thunar_abstract_icon_view_get_selected_items; thunarstandard_view_class->select_all = thunar_abstract_icon_view_select_all; thunarstandard_view_class->unselect_all = thunar_abstract_icon_view_unselect_all; @@ -157,6 +152,11 @@ thunar_abstract_icon_view_class_init (ThunarAbstractIconViewClass *klass) thunarstandard_view_class->get_path_at_pos = thunar_abstract_icon_view_get_path_at_pos; thunarstandard_view_class->get_visible_range = thunar_abstract_icon_view_get_visible_range; thunarstandard_view_class->highlight_path = thunar_abstract_icon_view_highlight_path; + thunarstandard_view_class->append_menu_items = thunar_abstract_icon_view_append_menu_items; + thunarstandard_view_class->connect_accelerators = thunar_abstract_icon_view_connect_accelerators; + thunarstandard_view_class->disconnect_accelerators = thunar_abstract_icon_view_disconnect_accelerators; + + xfce_gtk_translate_action_entries (thunar_abstract_icon_view_action_entries, G_N_ELEMENTS (thunar_abstract_icon_view_action_entries)); /** * ThunarAbstractIconView:column-spacing: @@ -225,19 +225,6 @@ thunar_abstract_icon_view_init (ThunarAbstractIconView *abstract_icon_view) gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (view), THUNAR_STANDARD_VIEW (abstract_icon_view)->name_renderer, "text", THUNAR_COLUMN_NAME); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the abstract icon view actions */ - gtk_action_group_add_actions (THUNAR_STANDARD_VIEW (abstract_icon_view)->action_group, - action_entries, G_N_ELEMENTS (action_entries), - GTK_WIDGET (abstract_icon_view)); - gtk_action_group_add_radio_actions (THUNAR_STANDARD_VIEW (abstract_icon_view)->action_group, column_action_entries, - G_N_ELEMENTS (column_action_entries), THUNAR_COLUMN_NAME, - G_CALLBACK (thunar_abstract_icon_view_action_sort), abstract_icon_view); - gtk_action_group_add_radio_actions (THUNAR_STANDARD_VIEW (abstract_icon_view)->action_group, order_action_entries, - G_N_ELEMENTS (order_action_entries), GTK_SORT_ASCENDING, - G_CALLBACK (thunar_abstract_icon_view_action_sort), abstract_icon_view); -G_GNUC_END_IGNORE_DEPRECATIONS - /* we need to listen to sort column changes to sync the menu items */ g_signal_connect (G_OBJECT (THUNAR_STANDARD_VIEW (abstract_icon_view)->model), "sort-column-changed", G_CALLBACK (thunar_abstract_icon_view_sort_column_changed), abstract_icon_view); @@ -272,37 +259,6 @@ thunar_abstract_icon_view_style_set (GtkWidget *widget, -static void -thunar_abstract_icon_view_connect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager) -{ - ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); - GError *error = NULL; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - abstract_icon_view->priv->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_abstract_icon_view_ui, - thunar_abstract_icon_view_ui_length, &error); -G_GNUC_END_IGNORE_DEPRECATIONS - if (G_UNLIKELY (abstract_icon_view->priv->ui_merge_id == 0)) - { - g_error ("Failed to merge ThunarAbstractIconView menus: %s", error->message); - g_error_free (error); - } -} - - - -static void -thunar_abstract_icon_view_disconnect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (ui_manager, THUNAR_ABSTRACT_ICON_VIEW (standard_view)->priv->ui_merge_id); -G_GNUC_END_IGNORE_DEPRECATIONS -} - - - static GList* thunar_abstract_icon_view_get_selected_items (ThunarStandardView *standard_view) { @@ -415,57 +371,192 @@ thunar_abstract_icon_view_highlight_path (ThunarStandardView *standard_view, -static GtkAction* +/** + * thunar_abstract_icon_view_connect_accelerators: + * @standard_view : a #ThunarStandardView + * @accel_group : a #GtkAccelGroup to be used used for new menu items + * + * Connects all accelerators and corresponding default keys of this widget to the global accelerator list + * The concrete implementation depends on the concrete widget which is implementing this view + **/ +static void +thunar_abstract_icon_view_connect_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group) +{ + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + xfce_gtk_accel_map_add_entries (thunar_abstract_icon_view_action_entries, + G_N_ELEMENTS (thunar_abstract_icon_view_action_entries)); + xfce_gtk_accel_group_connect_action_entries (accel_group, + thunar_abstract_icon_view_action_entries, + G_N_ELEMENTS (thunar_abstract_icon_view_action_entries), + standard_view); +} + + + +/** + * thunar_abstract_icon_view_disconnect_accelerators: + * @standard_view : a #ThunarStandardView + * @accel_group : a #GtkAccelGroup to be used used for new menu items + * + * Disconnects all accelerators from the passed #GtkAccelGroup + **/ +static void +thunar_abstract_icon_view_disconnect_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group) +{ + /* Dont listen to the accel keys defined by the action entries any more */ + xfce_gtk_accel_group_disconnect_action_entries (accel_group, + thunar_abstract_icon_view_action_entries, + G_N_ELEMENTS (thunar_abstract_icon_view_action_entries)); +} + + + +/** + * thunar_abstract_icon_view_append_menu_items: + * @standard_view : a #ThunarStandardView + * @menu : the #GtkMenu to add the menu items + * @accel_group : a #GtkAccelGroup to be used used for new menu items + * + * Appends widget-specific menu items to a #GtkMenu and connects them to the passed #GtkAccelGroup + * Implements method 'append_menu_items' of #ThunarStandardView + **/ +static void +thunar_abstract_icon_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group) +{ + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + GtkWidget *submenu; + GtkWidget *item; + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_ABSTRACT_ICON_VIEW_ACTION_ARRANGE_ITEMS_MENU), NULL, GTK_MENU_SHELL (menu)); + submenu = gtk_menu_new(); + if (accel_group != NULL) + gtk_menu_set_accel_group (GTK_MENU (submenu), accel_group); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_NAME), G_OBJECT (standard_view), + abstract_icon_view->priv->sort_column == THUNAR_COLUMN_NAME, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_SIZE), G_OBJECT (standard_view), + abstract_icon_view->priv->sort_column == THUNAR_COLUMN_SIZE, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_TYPE), G_OBJECT (standard_view), + abstract_icon_view->priv->sort_column == THUNAR_COLUMN_TYPE, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_MTIME), G_OBJECT (standard_view), + abstract_icon_view->priv->sort_column == THUNAR_COLUMN_DATE_MODIFIED, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_ASCENDING), G_OBJECT (standard_view), + abstract_icon_view->priv->sort_order == GTK_SORT_ASCENDING, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_DESCENDING), G_OBJECT (standard_view), + abstract_icon_view->priv->sort_order == GTK_SORT_DESCENDING, GTK_MENU_SHELL (submenu)); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), GTK_WIDGET (submenu)); + gtk_widget_show (item); +} + + + +static const XfceGtkActionEntry* thunar_abstract_icon_view_gesture_action (ThunarAbstractIconView *abstract_icon_view) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS + GtkWidget *window; + + window = gtk_widget_get_toplevel (GTK_WIDGET (abstract_icon_view)); if (abstract_icon_view->priv->gesture_start_y - abstract_icon_view->priv->gesture_current_y > 40 && ABS (abstract_icon_view->priv->gesture_start_x - abstract_icon_view->priv->gesture_current_x) < 40) { - return gtk_ui_manager_get_action (THUNAR_STANDARD_VIEW (abstract_icon_view)->ui_manager, "/main-menu/go-menu/open-parent"); + return thunar_window_get_action_entry (THUNAR_WINDOW (window), THUNAR_WINDOW_ACTION_OPEN_PARENT); } else if (abstract_icon_view->priv->gesture_start_x - abstract_icon_view->priv->gesture_current_x > 40 && ABS (abstract_icon_view->priv->gesture_start_y - abstract_icon_view->priv->gesture_current_y) < 40) { - return gtk_ui_manager_get_action (THUNAR_STANDARD_VIEW (abstract_icon_view)->ui_manager, "/main-menu/go-menu/placeholder-go-history-actions/back"); + return thunar_window_get_action_entry (THUNAR_WINDOW (window), THUNAR_WINDOW_ACTION_BACK); } else if (abstract_icon_view->priv->gesture_current_x - abstract_icon_view->priv->gesture_start_x > 40 && ABS (abstract_icon_view->priv->gesture_start_y - abstract_icon_view->priv->gesture_current_y) < 40) { - return gtk_ui_manager_get_action (THUNAR_STANDARD_VIEW (abstract_icon_view)->ui_manager, "/main-menu/go-menu/placeholder-go-history-actions/forward"); + return thunar_window_get_action_entry (THUNAR_WINDOW (window), THUNAR_WINDOW_ACTION_FORWARD); } else if (abstract_icon_view->priv->gesture_current_y - abstract_icon_view->priv->gesture_start_y > 40 && ABS (abstract_icon_view->priv->gesture_start_x - abstract_icon_view->priv->gesture_current_x) < 40) { - return gtk_ui_manager_get_action (THUNAR_STANDARD_VIEW (abstract_icon_view)->ui_manager, "/main-menu/view-menu/reload"); + return thunar_window_get_action_entry (THUNAR_WINDOW (window), THUNAR_WINDOW_ACTION_RELOAD); } -G_GNUC_END_IGNORE_DEPRECATIONS - return NULL; } static void -thunar_abstract_icon_view_action_sort (GtkAction *action, - GtkAction *current, - ThunarStandardView *standard_view) +thunar_abstract_icon_view_action_sort_by_name (ThunarStandardView *standard_view) { - GtkSortType order; - gint column; + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), THUNAR_COLUMN_NAME, abstract_icon_view->priv->sort_order); +} -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* query the new sort column id */ - action = gtk_action_group_get_action (standard_view->action_group, "sort-by-name"); - column = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); - /* query the new sort order */ - action = gtk_action_group_get_action (standard_view->action_group, "sort-ascending"); - order = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - /* apply the new settings */ - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), column, order); +static void +thunar_abstract_icon_view_action_sort_by_size (ThunarStandardView *standard_view) +{ + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), THUNAR_COLUMN_SIZE, abstract_icon_view->priv->sort_order); +} + + + +static void +thunar_abstract_icon_view_action_sort_by_type (ThunarStandardView *standard_view) +{ + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), THUNAR_COLUMN_TYPE, abstract_icon_view->priv->sort_order); +} + + + +static void +thunar_abstract_icon_view_action_sort_by_date (ThunarStandardView *standard_view) +{ + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), THUNAR_COLUMN_DATE_MODIFIED, abstract_icon_view->priv->sort_order); +} + + + +static void +thunar_abstract_icon_view_action_sort_ascending (ThunarStandardView *standard_view) +{ + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), abstract_icon_view->priv->sort_column, GTK_SORT_ASCENDING); +} + + + +static void +thunar_abstract_icon_view_action_sort_descending (ThunarStandardView *standard_view) +{ + ThunarAbstractIconView *abstract_icon_view = THUNAR_ABSTRACT_ICON_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); + + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (standard_view->model), abstract_icon_view->priv->sort_column, GTK_SORT_DESCENDING); } @@ -491,10 +582,10 @@ thunar_abstract_icon_view_button_press_event (ExoIconView *view, GtkTreePath *path; GtkTreeIter iter; ThunarFile *file; - GtkAction *action; ThunarPreferences *preferences; gboolean in_tab; - const gchar *action_name; + ThunarLauncher *launcher; + GtkWidget *window; abstract_icon_view->priv->button_pressed = TRUE; @@ -543,25 +634,26 @@ thunar_abstract_icon_view_button_press_event (ExoIconView *view, /* determine the file for the path */ gtk_tree_model_get_iter (GTK_TREE_MODEL (THUNAR_STANDARD_VIEW (abstract_icon_view)->model), &iter, path); file = thunar_list_model_get_file (THUNAR_STANDARD_VIEW (abstract_icon_view)->model, &iter); - if (G_LIKELY (file != NULL) && thunar_file_is_directory (file)) + if (G_LIKELY (file != NULL)) { - /* lookup setting if we should open in a tab or a window */ - preferences = thunar_preferences_get (); - g_object_get (preferences, "misc-middle-click-in-tab", &in_tab, NULL); - g_object_unref (preferences); - - /* holding ctrl inverts the action */ - if ((event->state & GDK_CONTROL_MASK) != 0) - in_tab = !in_tab; - action_name = in_tab ? "open-in-new-tab" : "open-in-new-window"; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* emit the action */ - action = thunar_gtk_ui_manager_get_action_by_name (THUNAR_STANDARD_VIEW (abstract_icon_view)->ui_manager, action_name); - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS - + if (thunar_file_is_directory (file)) + { + /* lookup setting if we should open in a tab or a window */ + preferences = thunar_preferences_get (); + g_object_get (preferences, "misc-middle-click-in-tab", &in_tab, NULL); + g_object_unref (preferences); + + /* holding ctrl inverts the action */ + if ((event->state & GDK_CONTROL_MASK) != 0) + in_tab = !in_tab; + + window = gtk_widget_get_toplevel (GTK_WIDGET (abstract_icon_view)); + launcher = thunar_window_get_launcher (THUNAR_WINDOW (window)); + if (in_tab) + thunar_launcher_open_selected_folders_in_new_tabs (launcher); + else + thunar_launcher_open_selected_folders_in_new_windows (launcher); + } /* release the file reference */ g_object_unref (G_OBJECT (file)); } @@ -598,7 +690,8 @@ thunar_abstract_icon_view_button_release_event (ExoIconView *view, GdkEventButton *event, ThunarAbstractIconView *abstract_icon_view) { - GtkAction *action; + const XfceGtkActionEntry *action_entry; + GtkWidget *window; _thunar_return_val_if_fail (EXO_IS_ICON_VIEW (view), FALSE); _thunar_return_val_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view), FALSE); @@ -606,12 +699,12 @@ thunar_abstract_icon_view_button_release_event (ExoIconView *view, _thunar_return_val_if_fail (abstract_icon_view->priv->gesture_motion_id > 0, FALSE); _thunar_return_val_if_fail (abstract_icon_view->priv->gesture_release_id > 0, FALSE); - /* run the selected action (if any) */ - action = thunar_abstract_icon_view_gesture_action (abstract_icon_view); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS + window = gtk_widget_get_toplevel (GTK_WIDGET (abstract_icon_view)); + + /* execute the related callback (if any) */ + action_entry = thunar_abstract_icon_view_gesture_action (abstract_icon_view); + if (G_LIKELY (action_entry != NULL)) + ((void(*)(GtkWindow*))action_entry->callback)(GTK_WINDOW (window)); /* unregister the "expose-event" handler */ g_signal_handler_disconnect (G_OBJECT (view), abstract_icon_view->priv->gesture_expose_id); @@ -638,10 +731,9 @@ thunar_abstract_icon_view_draw (ExoIconView *view, cairo_t *cr, ThunarAbstractIconView *abstract_icon_view) { - GtkAction *action = NULL; - GdkPixbuf *gesture_icon = NULL; - gchar *icon_name; - gint x, y; + const XfceGtkActionEntry *action_entry = NULL; + GdkPixbuf *gesture_icon = NULL; + gint x, y; _thunar_return_val_if_fail (EXO_IS_ICON_VIEW (view), FALSE); _thunar_return_val_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view), FALSE); @@ -654,14 +746,11 @@ thunar_abstract_icon_view_draw (ExoIconView *view, cairo_paint (cr); /* determine the gesture action */ - action = thunar_abstract_icon_view_gesture_action (abstract_icon_view); - if (G_LIKELY (action != NULL)) + action_entry = thunar_abstract_icon_view_gesture_action (abstract_icon_view); + if (G_LIKELY (action_entry != NULL)) { - /* get the icon-name for the action */ - g_object_get (G_OBJECT (action), "icon-name", &icon_name, NULL); - gesture_icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default(), - icon_name, + action_entry->menu_item_icon_name, 32, GTK_ICON_LOOKUP_FORCE_SIZE, NULL); @@ -682,9 +771,6 @@ thunar_abstract_icon_view_draw (ExoIconView *view, /* release the stock abstract_icon */ g_object_unref (G_OBJECT (gesture_icon)); } - - /* release the stock id */ - g_free (icon_name); } return FALSE; @@ -754,7 +840,7 @@ thunar_abstract_icon_view_item_activated (ExoIconView *view, GtkTreePath *path, ThunarAbstractIconView *abstract_icon_view) { - GtkAction *action; + GtkWidget *window; _thunar_return_if_fail (THUNAR_IS_ABSTRACT_ICON_VIEW (abstract_icon_view)); @@ -765,12 +851,8 @@ thunar_abstract_icon_view_item_activated (ExoIconView *view, exo_icon_view_select_path (view, path); } -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* emit the "open" action */ - action = thunar_gtk_ui_manager_get_action_by_name (THUNAR_STANDARD_VIEW (abstract_icon_view)->ui_manager, "open"); - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS + window = gtk_widget_get_toplevel (GTK_WIDGET (abstract_icon_view)); + thunar_launcher_activate_selected_files (thunar_window_get_launcher (THUNAR_WINDOW (window)), THUNAR_LAUNCHER_CHANGE_DIRECTORY, NULL); } @@ -780,20 +862,12 @@ thunar_abstract_icon_view_sort_column_changed (GtkTreeSortable *sortable, ThunarAbstractIconView *abstract_icon_view) { GtkSortType order; - GtkAction *action; gint column; if (gtk_tree_sortable_get_sort_column_id (sortable, &column, &order)) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* apply the new sort column */ - action = gtk_action_group_get_action (THUNAR_STANDARD_VIEW (abstract_icon_view)->action_group, "sort-by-name"); - gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), column); - - /* apply the new sort order */ - action = gtk_action_group_get_action (THUNAR_STANDARD_VIEW (abstract_icon_view)->action_group, "sort-ascending"); - gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), order); -G_GNUC_END_IGNORE_DEPRECATIONS + abstract_icon_view->priv->sort_column = column; + abstract_icon_view->priv->sort_order = order; } } diff --git a/thunar/thunar-abstract-icon-view.h b/thunar/thunar-abstract-icon-view.h index 84a3d045..15d5a375 100644 --- a/thunar/thunar-abstract-icon-view.h +++ b/thunar/thunar-abstract-icon-view.h @@ -35,6 +35,18 @@ typedef struct _ThunarAbstractIconView ThunarAbstractIconView; #define THUNAR_IS_ABSTRACT_ICON_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), THUNAR_TYPE_ABSTRACT_ICON_VIEW)) #define THUNAR_ABSTRACT_ICON_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_ABSTRACT_ICON_VIEW, ThunarAbstractIconViewClass)) +/* #XfceGtkActionEntrys provided by this widget */ +typedef enum +{ + THUNAR_ABSTRACT_ICON_VIEW_ACTION_ARRANGE_ITEMS_MENU, + THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_NAME, + THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_SIZE, + THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_TYPE, + THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_BY_MTIME, + THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_ASCENDING, + THUNAR_ABSTRACT_ICON_VIEW_ACTION_SORT_DESCENDING, +} ThunarAbstractIconViewAction; + struct _ThunarAbstractIconViewClass { ThunarStandardViewClass __parent__; diff --git a/thunar/thunar-application.c b/thunar/thunar-application.c index 8730107d..7c6600bf 100644 --- a/thunar/thunar-application.c +++ b/thunar/thunar-application.c @@ -374,7 +374,6 @@ thunar_application_startup (GApplication *gapp) /* connect to the session manager */ application->session_client = thunar_session_client_new (opt_sm_client_id); - /* TODO: how do accel maps integrate with GAction/GMenu? Using GtkAction for now */ /* check if we have a saved accel map */ path = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, ACCEL_MAP_PATH); if (G_LIKELY (path != NULL)) diff --git a/thunar/thunar-component.c b/thunar/thunar-component.c index 29cd6849..126cbecf 100644 --- a/thunar/thunar-component.c +++ b/thunar/thunar-component.c @@ -85,22 +85,6 @@ thunar_component_class_init (gpointer klass) "selected-files", THUNARX_TYPE_FILE_INFO_LIST, EXO_PARAM_READWRITE)); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /** - * ThunarComponent:ui-manager: - * - * The UI manager used by the surrounding #ThunarWindow. The - * #ThunarComponent 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", - GTK_TYPE_UI_MANAGER, - EXO_PARAM_READWRITE)); -G_GNUC_END_IGNORE_DEPRECATIONS } @@ -160,52 +144,3 @@ thunar_component_restore_selection (ThunarComponent *component) thunar_component_set_selected_files (component, selected_files); thunar_g_file_list_free (selected_files); } - - - -/** - * thunar_component_get_ui_manager: - * @component : a #ThunarComponent instance. - * - * Returns the #GtkUIManager associated with @component or - * %NULL if @component has no #GtkUIManager associated with - * it. - * - * Return value: the #GtkUIManager associated with @component - * or %NULL. - **/ -GtkUIManager* -thunar_component_get_ui_manager (ThunarComponent *component) -{ - _thunar_return_val_if_fail (THUNAR_IS_COMPONENT (component), NULL); - return (*THUNAR_COMPONENT_GET_IFACE (component)->get_ui_manager) (component); -} - - - -/** - * thunar_component_set_ui_manager: - * @component : a #ThunarComponent instance. - * @ui_manager : a #GtkUIManager or %NULL. - * - * Installs a new #GtkUIManager for @component or resets the ::ui-manager - * property. - * - * Implementations of the #ThunarComponent interface must first disconnect - * from any previously set #GtkUIManager and then connect to the - * @ui_manager if not %NULL. - **/ -void -thunar_component_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager) -{ - _thunar_return_if_fail (THUNAR_IS_COMPONENT (component)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (ui_manager == NULL || GTK_IS_UI_MANAGER (ui_manager)); -G_GNUC_END_IGNORE_DEPRECATIONS - (*THUNAR_COMPONENT_GET_IFACE (component)->set_ui_manager) (component, ui_manager); -} - - - - diff --git a/thunar/thunar-component.h b/thunar/thunar-component.h index 17fe7056..abbb342d 100644 --- a/thunar/thunar-component.h +++ b/thunar/thunar-component.h @@ -40,10 +40,6 @@ struct _ThunarComponentIface GList *(*get_selected_files) (ThunarComponent *component); void (*set_selected_files) (ThunarComponent *component, GList *selected_files); - - GtkUIManager *(*get_ui_manager) (ThunarComponent *component); - void (*set_ui_manager) (ThunarComponent *component, - GtkUIManager *ui_manager); }; GType thunar_component_get_type (void) G_GNUC_CONST; @@ -54,10 +50,6 @@ void thunar_component_set_selected_files (ThunarComponent *component, void thunar_component_restore_selection (ThunarComponent *component); -GtkUIManager *thunar_component_get_ui_manager (ThunarComponent *component); -void thunar_component_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager); - G_END_DECLS; #endif /* !__THUNAR_COMPONENT_H__ */ diff --git a/thunar/thunar-details-view-ui.xml b/thunar/thunar-details-view-ui.xml deleted file mode 100644 index 990a9874..00000000 --- a/thunar/thunar-details-view-ui.xml +++ /dev/null @@ -1,21 +0,0 @@ -<ui> - - <!-- - Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - - Thunar details 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-items-actions"> - <menuitem action="setup-columns" /> - </placeholder> - </menu> - </menubar> - -</ui> - -<!-- vi: set ts=2 sw=2 et ai nocindent syntax=xml: --> diff --git a/thunar/thunar-details-view.c b/thunar/thunar-details-view.c index 68729828..bfd403ff 100644 --- a/thunar/thunar-details-view.c +++ b/thunar/thunar-details-view.c @@ -25,10 +25,11 @@ #include <thunar/thunar-column-editor.h> #include <thunar/thunar-details-view.h> -#include <thunar/thunar-details-view-ui.h> +#include <thunar/thunar-launcher.h> #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-private.h> #include <thunar/thunar-preferences.h> +#include <thunar/thunar-window.h> @@ -51,10 +52,6 @@ static void thunar_details_view_set_property (GObject const GValue *value, GParamSpec *pspec); static AtkObject *thunar_details_view_get_accessible (GtkWidget *widget); -static void thunar_details_view_connect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager); -static void thunar_details_view_disconnect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager); static GList *thunar_details_view_get_selected_items (ThunarStandardView *standard_view); static void thunar_details_view_select_all (ThunarStandardView *standard_view); static void thunar_details_view_unselect_all (ThunarStandardView *standard_view); @@ -103,11 +100,16 @@ static void thunar_details_view_row_changed (GtkTreeView static void thunar_details_view_columns_changed (ThunarColumnModel *column_model, ThunarDetailsView *details_view); static void thunar_details_view_zoom_level_changed (ThunarDetailsView *details_view); -static void thunar_details_view_action_setup_columns (GtkAction *action, - ThunarDetailsView *details_view); static gboolean thunar_details_view_get_fixed_columns (ThunarDetailsView *details_view); static void thunar_details_view_set_fixed_columns (ThunarDetailsView *details_view, gboolean fixed_columns); +static void thunar_details_view_connect_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group); +static void thunar_details_view_disconnect_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group); +static void thunar_details_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group); @@ -129,20 +131,19 @@ struct _ThunarDetailsView /* whether to use fixed column widths */ gboolean fixed_columns; - /* the UI manager merge id for the details view */ - guint ui_merge_id; - /* whether the most recent item activation used a mouse button press */ gboolean button_pressed; }; -static const GtkActionEntry action_entries[] = +static XfceGtkActionEntry thunar_details_view_action_entries[] = { - { "setup-columns", NULL, N_ ("Configure _Columns..."), NULL, N_ ("Configure the columns in the detailed list view"), G_CALLBACK (thunar_details_view_action_setup_columns), }, + { THUNAR_DETAILS_VIEW_ACTION_CONFIGURE_COLUMNS, "<Actions>/ThunarStandardView/configure-columns", "", XFCE_GTK_MENU_ITEM , N_ ("Configure _Columns..."), N_("Configure the columns in the detailed list view"), NULL, G_CALLBACK (thunar_show_column_editor), }, }; +#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_details_view_action_entries,G_N_ELEMENTS(thunar_details_view_action_entries),id) + G_DEFINE_TYPE (ThunarDetailsView, thunar_details_view, THUNAR_TYPE_STANDARD_VIEW) @@ -165,8 +166,6 @@ thunar_details_view_class_init (ThunarDetailsViewClass *klass) gtkwidget_class->get_accessible = thunar_details_view_get_accessible; thunarstandard_view_class = THUNAR_STANDARD_VIEW_CLASS (klass); - thunarstandard_view_class->connect_ui_manager = thunar_details_view_connect_ui_manager; - thunarstandard_view_class->disconnect_ui_manager = thunar_details_view_disconnect_ui_manager; thunarstandard_view_class->get_selected_items = thunar_details_view_get_selected_items; thunarstandard_view_class->select_all = thunar_details_view_select_all; thunarstandard_view_class->unselect_all = thunar_details_view_unselect_all; @@ -177,8 +176,13 @@ thunar_details_view_class_init (ThunarDetailsViewClass *klass) thunarstandard_view_class->get_path_at_pos = thunar_details_view_get_path_at_pos; thunarstandard_view_class->get_visible_range = thunar_details_view_get_visible_range; thunarstandard_view_class->highlight_path = thunar_details_view_highlight_path; + thunarstandard_view_class->append_menu_items = thunar_details_view_append_menu_items; + thunarstandard_view_class->connect_accelerators = thunar_details_view_connect_accelerators; + thunarstandard_view_class->disconnect_accelerators = thunar_details_view_disconnect_accelerators; thunarstandard_view_class->zoom_level_property_name = "last-details-view-zoom-level"; + xfce_gtk_translate_action_entries (thunar_details_view_action_entries, G_N_ELEMENTS (thunar_details_view_action_entries)); + /** * ThunarDetailsView:fixed-columns: * @@ -210,13 +214,6 @@ thunar_details_view_init (ThunarDetailsView *details_view) */ g_signal_connect (G_OBJECT (details_view), "notify::zoom-level", G_CALLBACK (thunar_details_view_zoom_level_changed), NULL); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the details view actions */ - gtk_action_group_add_actions (THUNAR_STANDARD_VIEW (details_view)->action_group, - action_entries, G_N_ELEMENTS (action_entries), - GTK_WIDGET (details_view)); -G_GNUC_END_IGNORE_DEPRECATIONS - /* create the tree view to embed */ tree_view = exo_tree_view_new (); g_signal_connect (G_OBJECT (tree_view), "notify::model", @@ -414,36 +411,6 @@ thunar_details_view_get_accessible (GtkWidget *widget) } -static void -thunar_details_view_connect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager) -{ - ThunarDetailsView *details_view = THUNAR_DETAILS_VIEW (standard_view); - GError *error = NULL; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - details_view->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_details_view_ui, - thunar_details_view_ui_length, &error); -G_GNUC_END_IGNORE_DEPRECATIONS - if (G_UNLIKELY (details_view->ui_merge_id == 0)) - { - g_error ("Failed to merge ThunarDetailsView menus: %s", error->message); - g_error_free (error); - } -} - - - -static void -thunar_details_view_disconnect_ui_manager (ThunarStandardView *standard_view, - GtkUIManager *ui_manager) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (ui_manager, THUNAR_DETAILS_VIEW (standard_view)->ui_merge_id); -G_GNUC_END_IGNORE_DEPRECATIONS -} - - static GList* thunar_details_view_get_selected_items (ThunarStandardView *standard_view) @@ -677,10 +644,10 @@ thunar_details_view_button_press_event (GtkTreeView *tree_view, GtkTreeViewColumn *column; GtkTreeViewColumn *name_column; ThunarFile *file; - GtkAction *action; ThunarPreferences *preferences; gboolean in_tab; - const gchar *action_name; + ThunarLauncher *launcher; + GtkWidget *window; /* check if the event is for the bin window */ if (G_UNLIKELY (event->window != gtk_tree_view_get_bin_window (tree_view))) @@ -782,27 +749,26 @@ thunar_details_view_button_press_event (GtkTreeView *tree_view, /* determine the file for the path */ gtk_tree_model_get_iter (GTK_TREE_MODEL (THUNAR_STANDARD_VIEW (details_view)->model), &iter, path); file = thunar_list_model_get_file (THUNAR_STANDARD_VIEW (details_view)->model, &iter); - if (G_LIKELY (file != NULL) && thunar_file_is_directory (file)) + if (G_LIKELY (file != NULL)) { - /* lookup setting if we should open in a tab or a window */ - preferences = thunar_preferences_get (); - g_object_get (preferences, "misc-middle-click-in-tab", &in_tab, NULL); - g_object_unref (preferences); - - /* holding ctrl inverts the action */ - if ((event->state & GDK_CONTROL_MASK) != 0) - in_tab = !in_tab; - - action_name = in_tab ? "open-in-new-tab" : "open-in-new-window"; - - action = thunar_gtk_ui_manager_get_action_by_name (THUNAR_STANDARD_VIEW (details_view)->ui_manager, action_name); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* emit the action */ - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS - + if (thunar_file_is_directory (file)) + { + /* lookup setting if we should open in a tab or a window */ + preferences = thunar_preferences_get (); + g_object_get (preferences, "misc-middle-click-in-tab", &in_tab, NULL); + g_object_unref (preferences); + + /* holding ctrl inverts the action */ + if ((event->state & GDK_CONTROL_MASK) != 0) + in_tab = !in_tab; + + window = gtk_widget_get_toplevel (GTK_WIDGET (details_view)); + launcher = thunar_window_get_launcher (THUNAR_WINDOW (window)); + if (in_tab) + thunar_launcher_open_selected_folders_in_new_tabs (launcher); + else + thunar_launcher_open_selected_folders_in_new_windows (launcher); + } /* release the file reference */ g_object_unref (G_OBJECT (file)); } @@ -845,7 +811,8 @@ thunar_details_view_row_activated (GtkTreeView *tree_view, ThunarDetailsView *details_view) { GtkTreeSelection *selection; - GtkAction *action; + ThunarLauncher *launcher; + GtkWidget *window; _thunar_return_if_fail (THUNAR_IS_DETAILS_VIEW (details_view)); @@ -857,12 +824,9 @@ thunar_details_view_row_activated (GtkTreeView *tree_view, gtk_tree_selection_select_path (selection, path); } -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* emit the "open" action */ - action = thunar_gtk_ui_manager_get_action_by_name (THUNAR_STANDARD_VIEW (details_view)->ui_manager, "open"); - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS + window = gtk_widget_get_toplevel (GTK_WIDGET (details_view)); + launcher = thunar_window_get_launcher (THUNAR_WINDOW (window)); + thunar_launcher_activate_selected_files (launcher, THUNAR_LAUNCHER_CHANGE_DIRECTORY, NULL); } @@ -880,18 +844,16 @@ thunar_details_view_select_cursor_row (GtkTreeView *tree_view, * default gtk signal handler there. */ - GtkAction *action; + ThunarLauncher *launcher; + GtkWidget *window; _thunar_return_val_if_fail (THUNAR_IS_DETAILS_VIEW (details_view), FALSE); g_signal_stop_emission_by_name(tree_view,"select-cursor-row"); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* emit the "open" action */ - action = thunar_gtk_ui_manager_get_action_by_name (THUNAR_STANDARD_VIEW (details_view)->ui_manager, "open"); - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS + window = gtk_widget_get_toplevel (GTK_WIDGET (details_view)); + launcher = thunar_window_get_launcher (THUNAR_WINDOW (window)); + thunar_launcher_activate_selected_files (launcher, THUNAR_LAUNCHER_CHANGE_DIRECTORY, NULL); return TRUE; } @@ -986,17 +948,69 @@ thunar_details_view_zoom_level_changed (ThunarDetailsView *details_view) +/** + * thunar_details_view_connect_accelerators: + * @standard_view : a #ThunarStandardView. + * @accel_group : a #GtkAccelGroup to be used used for new menu items + * + * Connects all accelerators and corresponding default keys of this widget to the global accelerator list + * The concrete implementation depends on the concrete widget which is implementing this view + **/ static void -thunar_details_view_action_setup_columns (GtkAction *action, - ThunarDetailsView *details_view) +thunar_details_view_connect_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group) { + ThunarDetailsView *details_view = THUNAR_DETAILS_VIEW (standard_view); + + _thunar_return_if_fail (THUNAR_IS_DETAILS_VIEW (details_view)); + + xfce_gtk_accel_map_add_entries (thunar_details_view_action_entries, G_N_ELEMENTS (thunar_details_view_action_entries)); + xfce_gtk_accel_group_connect_action_entries (accel_group, + thunar_details_view_action_entries, + G_N_ELEMENTS (thunar_details_view_action_entries), + standard_view); +} + + + +/** + * thunar_details_view_disconnect_accelerators: + * @standard_view : a #ThunarStandardView. + * @accel_group : a #GtkAccelGroup to be disconnected + * + * Dont listen to the accel keys defined by the action entries any more + **/ +static void +thunar_details_view_disconnect_accelerators (ThunarStandardView *standard_view, + GtkAccelGroup *accel_group) +{ + /* Dont listen to the accel keys defined by the action entries any more */ + xfce_gtk_accel_group_disconnect_action_entries (accel_group, + thunar_details_view_action_entries, + G_N_ELEMENTS (thunar_details_view_action_entries)); +} + + + +/** + * thunar_details_view_append_menu_items: + * @standard_view : a #ThunarStandardView. + * @menu : the #GtkMenu to add the menu items. + * @accel_group : a #GtkAccelGroup to be used used for new menu items + * + * Appends widget-specific menu items to a #GtkMenu and connects them to the passed #GtkAccelGroup + * Implements method 'append_menu_items' of #ThunarStandardView + **/ +static void +thunar_details_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group) +{ + ThunarDetailsView *details_view = THUNAR_DETAILS_VIEW (standard_view); + _thunar_return_if_fail (THUNAR_IS_DETAILS_VIEW (details_view)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - /* popup the column editor dialog */ - thunar_show_column_editor (details_view); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_DETAILS_VIEW_ACTION_CONFIGURE_COLUMNS), G_OBJECT (details_view), GTK_MENU_SHELL (menu)); } diff --git a/thunar/thunar-details-view.h b/thunar/thunar-details-view.h index bd83df53..240440db 100644 --- a/thunar/thunar-details-view.h +++ b/thunar/thunar-details-view.h @@ -34,6 +34,12 @@ typedef struct _ThunarDetailsView ThunarDetailsView; #define THUNAR_IS_DETAILS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_DETAILS_VIEW)) #define THUNAR_DETAILS_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_DETAILS_VIEW, ThunarDetailsViewClass)) +/* #XfceGtkActionEntrys provided by this widget */ +typedef enum +{ + THUNAR_DETAILS_VIEW_ACTION_CONFIGURE_COLUMNS, +} ThunarDetailsViewAction; + GType thunar_details_view_get_type (void) G_GNUC_CONST; G_END_DECLS; diff --git a/thunar/thunar-dnd.c b/thunar/thunar-dnd.c index fdb54ef4..92d7276d 100644 --- a/thunar/thunar-dnd.c +++ b/thunar/thunar-dnd.c @@ -29,7 +29,6 @@ #include <thunar/thunar-dialogs.h> #include <thunar/thunar-dnd.h> #include <thunar/thunar-gtk-extensions.h> -#include <thunar/thunar-menu-util.h> #include <thunar/thunar-private.h> @@ -154,7 +153,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS if (G_UNLIKELY (items != NULL)) { /* add menu items for all items */ - thunar_menu_util_add_items_to_menu (menu, items); + for (lp = items; lp != NULL; lp = lp->next) + thunar_gtk_menu_thunarx_menu_item_new (lp->data, GTK_MENU_SHELL (menu)); g_list_free (items); /* append another separator */ diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c index 18687ff5..c8ae011f 100644 --- a/thunar/thunar-file.c +++ b/thunar/thunar-file.c @@ -4141,6 +4141,74 @@ thunar_file_destroy (ThunarFile *file) /** + * thunar_file_compare: + * @a : the first #ThunarFile. + * @b : the second #ThunarFile. + * + * Compares items so that directories come before files and ancestors come + * before descendants. + * + * Return value: -1 if @file_a should be sorted before @file_b, 1 if + * @file_b should be sorted before @file_a, 0 if equal. + **/ +gint +thunar_file_compare (ThunarFile *a, + ThunarFile *b) +{ + GFile *file_a; + GFile *file_b; + GFile *parent_a; + GFile *parent_b; + gint ret = 0; + + file_a = thunar_file_get_file (a); + file_b = thunar_file_get_file (b); + + /* check whether the files are equal */ + if (g_file_equal (file_a, file_b)) + return 0; + + /* directories always come first */ + if (thunar_file_get_kind (a) == G_FILE_TYPE_DIRECTORY + && thunar_file_get_kind (b) != G_FILE_TYPE_DIRECTORY) + { + return -1; + } + else if (thunar_file_get_kind (a) != G_FILE_TYPE_DIRECTORY + && thunar_file_get_kind (b) == G_FILE_TYPE_DIRECTORY) + { + return 1; + } + + /* ancestors come first */ + if (g_file_has_prefix (file_b, file_a)) + return -1; + else if (g_file_has_prefix (file_a, file_b)) + return 1; + + parent_a = g_file_get_parent (file_a); + parent_b = g_file_get_parent (file_b); + + if (g_file_equal (parent_a, parent_b)) + { + /* compare siblings by their display name */ + ret = g_utf8_collate (thunar_file_get_display_name (a), + thunar_file_get_display_name (b)); + } + /* again, ancestors come first */ + else if (g_file_has_prefix (file_b, parent_a)) + ret = -1; + else if (g_file_has_prefix (file_a, parent_b)) + ret = 1; + + g_object_unref (parent_a); + g_object_unref (parent_b); + return ret; +} + + + +/** * thunar_file_compare_by_name: * @file_a : the first #ThunarFile. * @file_b : the second #ThunarFile. diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h index 2c744391..c9488d22 100644 --- a/thunar/thunar-file.h +++ b/thunar/thunar-file.h @@ -252,7 +252,8 @@ void thunar_file_reload_parent (ThunarFile void thunar_file_destroy (ThunarFile *file); - +gint thunar_file_compare (ThunarFile *file_a, + ThunarFile *file_b); gint thunar_file_compare_by_name (const ThunarFile *file_a, const ThunarFile *file_b, gboolean case_sensitive) G_GNUC_PURE; diff --git a/thunar/thunar-gtk-extensions.c b/thunar/thunar-gtk-extensions.c index f2a0c226..1ad715a3 100644 --- a/thunar/thunar-gtk-extensions.c +++ b/thunar/thunar-gtk-extensions.c @@ -31,70 +31,9 @@ #include <thunar/thunar-private.h> #include <thunar/thunar-util.h> +#include <thunarx/thunarx.h> - -/** - * thunar_gtk_action_set_tooltip: - * @action : a #GtkAction. - * @format : the format string for the tooltip. - * @... : the parameters for @format. - * - * Convenience function to set a tooltip for a #GtkAction. - **/ -void -thunar_gtk_action_set_tooltip (GtkAction *action, - const gchar *format, - ...) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - va_list var_args; - gchar *tooltip; - - _thunar_return_if_fail (g_utf8_validate (format, -1, NULL)); - _thunar_return_if_fail (GTK_IS_ACTION (action)); - - /* determine the tooltip */ - va_start (var_args, format); - tooltip = g_strdup_vprintf (format, var_args); - va_end (var_args); - - /* setup the tooltip for the action */ - gtk_action_set_tooltip (action, tooltip); - - /* release the tooltip */ - g_free (tooltip); -G_GNUC_END_IGNORE_DEPRECATIONS -} - - - -/** - * thunar_gtk_action_group_set_action_sensitive: - * @action_group : a #GtkActionGroup. - * @action_name : the name of a #GtkAction in @action_group. - * @sensitive : the new sensitivity. - * - * Convenience function to change the sensitivity of an action - * in @action_group (whose name is @action_name) to @sensitive. - **/ -void -thunar_gtk_action_group_set_action_sensitive (GtkActionGroup *action_group, - const gchar *action_name, - gboolean sensitive) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - GtkAction *action; - - _thunar_return_if_fail (GTK_IS_ACTION_GROUP (action_group)); - _thunar_return_if_fail (action_name != NULL && *action_name != '\0'); - - /* query the action from the group */ - action = gtk_action_group_get_action (action_group, action_name); - - /* apply the sensitivity to the action */ - gtk_action_set_sensitive (action, sensitive); -G_GNUC_END_IGNORE_DEPRECATIONS -} +#include <libxfce4ui/libxfce4ui.h> @@ -128,6 +67,65 @@ thunar_gtk_label_set_a11y_relation (GtkLabel *label, /** + * thunar_gtk_menu_thunarx_menu_item_new: + * @thunarx_menu_item : a #ThunarxMenuItem + * @menu_to_append_item : #GtkMenuShell on which the item should be appended, or NULL + * + * method to create a #GtkMenuItem from a #ThunarxMenuItem and append it to the passed #GtkMenuShell + * This method will as well add all sub-items in case the passed #ThunarxMenuItem is a submenu + * + * Return value: (transfer full): The new #GtkImageMenuItem. + **/ +GtkWidget* +thunar_gtk_menu_thunarx_menu_item_new (GObject *thunarx_menu_item, + GtkMenuShell *menu_to_append_item) +{ + gchar *name, *label_text, *tooltip_text, *icon_name, *accel_path; + gboolean sensitive; + GtkWidget *gtk_menu_item; + ThunarxMenu *thunarx_menu; + GList *children; + GList *lp; + GtkWidget *submenu; + + g_return_val_if_fail (THUNARX_IS_MENU_ITEM (thunarx_menu_item), NULL); + + g_object_get (G_OBJECT (thunarx_menu_item), + "name", &name, + "label", &label_text, + "tooltip", &tooltip_text, + "icon", &icon_name, + "sensitive", &sensitive, + "menu", &thunarx_menu, + NULL); + + accel_path = g_strconcat ("<Actions>/ThunarActions/", name, NULL); + gtk_menu_item = xfce_gtk_image_menu_item_new_from_icon_name (label_text, tooltip_text, accel_path, + G_CALLBACK (thunarx_menu_item_activate), + G_OBJECT (thunarx_menu_item), icon_name, menu_to_append_item); + + /* recursively add submenu items if any */ + if (gtk_menu_item != NULL && thunarx_menu != NULL) + { + children = thunarx_menu_get_items (thunarx_menu); + submenu = gtk_menu_new (); + for (lp = children; lp != NULL; lp = lp->next) + thunar_gtk_menu_thunarx_menu_item_new (lp->data, GTK_MENU_SHELL (submenu)); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (gtk_menu_item), submenu); + thunarx_menu_item_list_free (children); + } + g_free (name); + g_free (accel_path); + g_free (label_text); + g_free (tooltip_text); + g_free (icon_name); + + return gtk_menu_item; +} + + + +/** * thunar_gtk_menu_run: * @menu : a #GtkMenu. * @@ -221,43 +219,6 @@ thunar_gtk_menu_run_at_event (GtkMenu *menu, /** - * thunar_gtk_ui_manager_get_action_by_name: - * @ui_manager : a #GtkUIManager. - * @action_name : the name of a #GtkAction in @ui_manager. - * - * Looks up the #GtkAction with the given @action_name in all - * #GtkActionGroup<!---->s associated with @ui_manager. Returns - * %NULL if no such #GtkAction exists in @ui_manager. - * - * Return value: the #GtkAction of the given @action_name in - * @ui_manager or %NULL. - **/ -GtkAction* -thunar_gtk_ui_manager_get_action_by_name (GtkUIManager *ui_manager, - const gchar *action_name) -{ - GtkAction *action; - GList *lp; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_val_if_fail (GTK_IS_UI_MANAGER (ui_manager), NULL); - _thunar_return_val_if_fail (action_name != NULL, NULL); - - /* check all action groups associated with the ui manager */ - for (lp = gtk_ui_manager_get_action_groups (ui_manager); lp != NULL; lp = lp->next) - { - action = gtk_action_group_get_action (lp->data, action_name); - if (G_LIKELY (action != NULL)) - return action; - } -G_GNUC_END_IGNORE_DEPRECATIONS - - return NULL; -} - - - -/** * thunar_gtk_widget_set_tooltip: * @widget : a #GtkWidget for which to set the tooltip. * @format : a printf(3)-style format string. diff --git a/thunar/thunar-gtk-extensions.h b/thunar/thunar-gtk-extensions.h index 98e0c30f..73a6b8f2 100644 --- a/thunar/thunar-gtk-extensions.h +++ b/thunar/thunar-gtk-extensions.h @@ -24,28 +24,18 @@ G_BEGIN_DECLS; -void thunar_gtk_action_set_tooltip (GtkAction *action, - const gchar *format, - ...) G_GNUC_PRINTF (2, 3); - -void thunar_gtk_action_group_set_action_sensitive (GtkActionGroup *action_group, - const gchar *action_name, - gboolean sensitive); void thunar_gtk_label_set_a11y_relation (GtkLabel *label, GtkWidget *widget); - void thunar_gtk_menu_run (GtkMenu *menu); void thunar_gtk_menu_run_at_event (GtkMenu *menu, GdkEvent *event); - -GtkAction *thunar_gtk_ui_manager_get_action_by_name (GtkUIManager *ui_manager, - const gchar *action_name); - void thunar_gtk_widget_set_tooltip (GtkWidget *widget, const gchar *format, ...) G_GNUC_PRINTF (2, 3); +GtkWidget *thunar_gtk_menu_thunarx_menu_item_new (GObject *thunarx_menu_item, + GtkMenuShell *menu_to_append_item); GMountOperation *thunar_gtk_mount_operation_new (gpointer parent); diff --git a/thunar/thunar-history-action.c b/thunar/thunar-history-action.c deleted file mode 100644 index 5f2baab5..00000000 --- a/thunar/thunar-history-action.c +++ /dev/null @@ -1,364 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, 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-gtk-extensions.h> -#include <thunar/thunar-history-action.h> -#include <thunar/thunar-private.h> - - - -static GtkWidget *thunar_history_action_create_tool_item (GtkAction *action); -static void thunar_history_action_show_menu (GtkWidget *tool_item, - ThunarHistoryAction *history_action); - - - -struct _ThunarHistoryActionClass -{ - GtkActionClass __parent__; -}; - -struct _ThunarHistoryAction -{ - GtkAction __parent__; - - guint popup_delay; -}; - - - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS -G_DEFINE_TYPE (ThunarHistoryAction, thunar_history_action, GTK_TYPE_ACTION) -G_GNUC_END_IGNORE_DEPRECATIONS - - - -static void -thunar_history_action_class_init (ThunarHistoryActionClass *klass) -{ - GtkActionClass *gtkaction_class; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtkaction_class = GTK_ACTION_CLASS (klass); -G_GNUC_END_IGNORE_DEPRECATIONS - gtkaction_class->create_tool_item = thunar_history_action_create_tool_item; - - /** - * ThunarHistoryAction::show-menu: - * @history_action : a #ThunarHistoryAction. - * @menu : the #GtkMenu to which to add the items to display. - * - * Emitted by the @history_action right before the @menu is shown. - **/ - g_signal_new (I_("show-menu"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_MENU); -} - - - -static void -thunar_history_action_init (ThunarHistoryAction *actions_changed) -{ -} - - - -static gboolean -thunar_history_action_popup_delayed (gpointer data) -{ - GtkWidget *button = GTK_WIDGET (data); - ThunarHistoryAction *history_action; - - history_action = g_object_get_data (G_OBJECT (button), I_("thunar-history-action")); - thunar_history_action_show_menu (button, history_action); - history_action->popup_delay = 0; - - return FALSE; -} - - - -static gboolean -thunar_history_action_button_press_event (GtkWidget *toggle_button, - GdkEventButton *event, - GtkWidget *tool_item) -{ - ThunarHistoryAction *history_action; - - _thunar_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE); - _thunar_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE); - - history_action = g_object_get_data (G_OBJECT (toggle_button), I_("thunar-history-action")); - - if (event->button == 1) - { - /* shouldn't happen, but stop pending timeout */ - if (history_action->popup_delay != 0) - g_source_remove (history_action->popup_delay); - - /* schedule a popup for button press */ - history_action->popup_delay = g_timeout_add (500, thunar_history_action_popup_delayed, toggle_button); - } - else if (event->button == 3) - { - /* directy show the menu */ - thunar_history_action_show_menu (toggle_button, history_action); - } - - return FALSE; -} - - - -static gboolean -thunar_history_action_button_release_event (GtkWidget *toggle_button, - GdkEventButton *event, - GtkWidget *tool_item) -{ - ThunarHistoryAction *history_action; - - _thunar_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE); - _thunar_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), FALSE); - - if (event->button == 1) - { - history_action = g_object_get_data (G_OBJECT (toggle_button), I_("thunar-history-action")); - if (history_action->popup_delay != 0) - { - /* stop timeout */ - g_source_remove (history_action->popup_delay); - history_action->popup_delay = 0; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* activate event */ - gtk_action_activate (GTK_ACTION (history_action)); -G_GNUC_END_IGNORE_DEPRECATIONS - } - } - else - { - return TRUE; - } - - /* bit of a strange trick to get the button untoggeled */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), - gtk_widget_is_sensitive (toggle_button)); - - return FALSE; -} - - - -static gboolean -thunar_history_action_leave_notify_event (GtkWidget *toggle_button, - GdkEventCrossing *event, - ThunarHistoryAction *history_action) -{ - - GtkAllocation alloc; - - _thunar_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE); - _thunar_return_val_if_fail (THUNAR_IS_HISTORY_ACTION (history_action), FALSE); - - if (history_action->popup_delay != 0) - { - /* stop the timeout */ - g_source_remove (history_action->popup_delay); - history_action->popup_delay = 0; - - /* if the user dragged to the bottom, directly popup the menu */ - gtk_widget_get_allocation (toggle_button, &alloc); - if (event->x >= 0 - && event->x < alloc.width - && event->y >= alloc.height) - { - thunar_history_action_show_menu (toggle_button, history_action); - } - } - - return FALSE; -} - - - -static void -thunar_history_action_activate (GtkWidget *toggle_button, - ThunarHistoryAction *history_action) -{ - _thunar_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button)); - _thunar_return_if_fail (THUNAR_IS_HISTORY_ACTION (history_action)); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* activate event (only key events trigger this function) */ - gtk_action_activate (GTK_ACTION (history_action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* activate, so the code deactivates a bit later... */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), TRUE); -} - - - -static void -thunar_history_action_toolbar_configured (GtkWidget *tool_item, - GtkWidget *toggle_button) -{ - GtkWidget *icon; - GtkAction *action; - - gtk_button_set_relief (GTK_BUTTON (toggle_button), - gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (tool_item))); - - icon = gtk_bin_get_child (GTK_BIN (toggle_button)); - action = g_object_get_data (G_OBJECT (toggle_button), I_("thunar-history-action")); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_image_set_from_icon_name (GTK_IMAGE (icon), - gtk_action_get_icon_name (action), - gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (tool_item))); -G_GNUC_END_IGNORE_DEPRECATIONS -} - - - -static GtkWidget* -thunar_history_action_create_tool_item (GtkAction *action) -{ - GtkWidget *tool_item; - GtkWidget *button; - GtkWidget *icon; - - _thunar_return_val_if_fail (THUNAR_IS_HISTORY_ACTION (action), NULL); - - /* allocate the tool item with an empty menu */ - tool_item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL); - gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE); - - button = gtk_toggle_button_new (); - gtk_container_add (GTK_CONTAINER (tool_item), button); - gtk_button_set_relief (GTK_BUTTON (button), - gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (tool_item))); - gtk_widget_set_focus_on_click (button, FALSE); - gtk_widget_show (button); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - icon = gtk_image_new_from_icon_name (gtk_action_get_icon_name (action), - gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (tool_item))); -G_GNUC_END_IGNORE_DEPRECATIONS - gtk_container_add (GTK_CONTAINER (button), icon); - gtk_widget_show (icon); - - g_object_set_data (G_OBJECT (button), I_("thunar-history-action"), action); - - g_signal_connect (G_OBJECT (tool_item), "toolbar-reconfigured", - G_CALLBACK (thunar_history_action_toolbar_configured), button); - g_signal_connect (G_OBJECT (button), "button-press-event", - G_CALLBACK (thunar_history_action_button_press_event), tool_item); - g_signal_connect (G_OBJECT (button), "button-release-event", - G_CALLBACK (thunar_history_action_button_release_event), tool_item); - g_signal_connect (G_OBJECT (button), "leave-notify-event", - G_CALLBACK (thunar_history_action_leave_notify_event), action); - g_signal_connect (G_OBJECT (button), "activate", - G_CALLBACK (thunar_history_action_activate), action); - - return tool_item; -} - - - -static void -thunar_history_action_menu_deactivate (GtkWidget *toggle_button) -{ - /* untoggle the button */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), FALSE); -} - - - -static void -thunar_history_action_show_menu (GtkWidget *toggle_button, - ThunarHistoryAction *history_action) -{ - GtkWidget *menu; - - _thunar_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button)); - _thunar_return_if_fail (THUNAR_IS_HISTORY_ACTION (history_action)); - - /* allocate a new menu for the action */ - menu = gtk_menu_new (); - gtk_menu_attach_to_widget (GTK_MENU (menu), toggle_button, NULL); - g_signal_connect_swapped (G_OBJECT (menu), "deactivate", - G_CALLBACK (thunar_history_action_menu_deactivate), toggle_button); - - /* generate the menu items */ - g_signal_emit_by_name (G_OBJECT (history_action), "show-menu", menu); - - /* toggle the button */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_button), TRUE); - - /* run the menu (takes over the floating of menu) */ - thunar_gtk_menu_run (GTK_MENU (menu)); -} - - - -/** - * thunar_history_action_new: - * @name : the name for the action. - * @label : the label for the action. - * @tooltip : the tooltip for the action. - * @iconname : the icon name for the action. - * - * Allocates a new #ThunarHistoryAction with the specified - * parameters. - * - * Return value: the newly allocated #ThunarHistoryAction. - **/ -GtkAction* -thunar_history_action_new (const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *iconname) -{ - gchar *fulltip; - GtkAction *action; - - _thunar_return_val_if_fail (name != NULL, NULL); - - /* extend history tooltip with function of the button */ - fulltip = g_strconcat (tooltip, "\n", _("Right-click or pull down to show history"), NULL); - - action = g_object_new (THUNAR_TYPE_HISTORY_ACTION, - "name", name, - "label", label, - "tooltip", fulltip, - "icon-name", iconname, - NULL); - - g_free (fulltip); - - return action; -} - diff --git a/thunar/thunar-history-action.h b/thunar/thunar-history-action.h deleted file mode 100644 index dc069e03..00000000 --- a/thunar/thunar-history-action.h +++ /dev/null @@ -1,46 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __THUNAR_HISTORY_ACTION_H__ -#define __THUNAR_HISTORY_ACTION_H__ - -#include <exo/exo.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarHistoryActionClass ThunarHistoryActionClass; -typedef struct _ThunarHistoryAction ThunarHistoryAction; - -#define THUNAR_TYPE_HISTORY_ACTION (thunar_history_action_get_type ()) -#define THUNAR_HISTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_HISTORY_ACTION, ThunarHistoryAction)) -#define THUNAR_HISTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_HISTORY_ACTION, ThunarHistoryActionClass)) -#define THUNAR_IS_HISTORY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_HISTORY_ACTION)) -#define THUNAR_IS_HISTORY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_HISTORY_ACTION)) -#define THUNAR_HISTORY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_HISTORY_ACTION, ThunarHistoryActionClass)) - -GType thunar_history_action_get_type (void) G_GNUC_CONST; - -GtkAction *thunar_history_action_new (const gchar *name, - const gchar *label, - const gchar *tooltip, - const gchar *icon_name) G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_HISTORY_ACTION_H__ */ diff --git a/thunar/thunar-history.c b/thunar/thunar-history.c index 8e21047a..2c068190 100644 --- a/thunar/thunar-history.c +++ b/thunar/thunar-history.c @@ -22,23 +22,31 @@ #endif #include <thunar/thunar-gobject-extensions.h> -#include <thunar/thunar-history-action.h> +#include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-history.h> #include <thunar/thunar-icon-factory.h> #include <thunar/thunar-navigator.h> #include <thunar/thunar-private.h> #include <thunar/thunar-dialogs.h> +#include <libxfce4ui/libxfce4ui.h> + /* Property identifiers */ enum { PROP_0, - PROP_ACTION_GROUP, PROP_CURRENT_DIRECTORY, }; +/* Signal identifiers */ +enum +{ + HISTORY_CHANGED, + LAST_SIGNAL, +}; + static void thunar_history_navigator_init (ThunarNavigatorIface *iface); @@ -59,26 +67,12 @@ static void thunar_history_go_back (ThunarHistory GFile *goto_file); static void thunar_history_go_forward (ThunarHistory *history, GFile *goto_file); -static void thunar_history_action_back (GtkAction *action, - ThunarHistory *history); static void thunar_history_action_back_nth (GtkWidget *item, ThunarHistory *history); -static void thunar_history_action_forward (GtkAction *action, - ThunarHistory *history); static void thunar_history_action_forward_nth (GtkWidget *item, ThunarHistory *history); -static void thunar_history_show_menu (GtkAction *action, - GtkWidget *menu, - ThunarHistory *history); -static GtkActionGroup *thunar_history_get_action_group (const ThunarHistory *history); -static void thunar_history_set_action_group (ThunarHistory *history, - GtkActionGroup *action_group); -struct _ThunarHistoryClass -{ - GObjectClass __parent__; -}; struct _ThunarHistory { @@ -86,16 +80,11 @@ struct _ThunarHistory ThunarFile *current_directory; - GtkActionGroup *action_group; - - GtkAction *action_back; - GtkAction *action_forward; - GSList *back_list; GSList *forward_list; }; - +static guint history_signals[LAST_SIGNAL]; G_DEFINE_TYPE_WITH_CODE (ThunarHistory, thunar_history, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (THUNAR_TYPE_NAVIGATOR, thunar_history_navigator_init)) @@ -121,22 +110,6 @@ thunar_history_class_init (ThunarHistoryClass *klass) thunar_history_display_name_quark = g_quark_from_static_string ("thunar-history-display-name"); thunar_history_gfile_quark = g_quark_from_static_string ("thunar-history-gfile"); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /** - * ThunarHistory::action-group: - * - * The #GtkActionGroup to which the #ThunarHistory<!---->s - * actions "back" and "forward" should be connected. - **/ - g_object_class_install_property (gobject_class, - PROP_ACTION_GROUP, - g_param_spec_object ("action-group", - "action-group", - "action-group", - GTK_TYPE_ACTION_GROUP, - EXO_PARAM_READWRITE)); -G_GNUC_END_IGNORE_DEPRECATIONS - /** * ThunarHistory::current-directory: * @@ -145,6 +118,15 @@ G_GNUC_END_IGNORE_DEPRECATIONS g_object_class_override_property (gobject_class, PROP_CURRENT_DIRECTORY, "current-directory"); + + history_signals[HISTORY_CHANGED] = + g_signal_new (I_("history-changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarHistoryClass, history_changed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); } @@ -161,21 +143,7 @@ thunar_history_navigator_init (ThunarNavigatorIface *iface) static void thunar_history_init (ThunarHistory *history) { - /* create the "back" action */ - history->action_back = thunar_history_action_new ("back", _("Back"), _("Go to the previous visited folder"), "go-previous-symbolic"); - g_signal_connect (G_OBJECT (history->action_back), "activate", G_CALLBACK (thunar_history_action_back), history); - g_signal_connect (G_OBJECT (history->action_back), "show-menu", G_CALLBACK (thunar_history_show_menu), history); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_action_set_sensitive (history->action_back, FALSE); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* create the "forward" action */ - history->action_forward = thunar_history_action_new ("forward", _("Forward"), _("Go to the next visited folder"), "go-next-symbolic"); - g_signal_connect (G_OBJECT (history->action_forward), "activate", G_CALLBACK (thunar_history_action_forward), history); - g_signal_connect (G_OBJECT (history->action_forward), "show-menu", G_CALLBACK (thunar_history_show_menu), history); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_action_set_sensitive (history->action_forward, FALSE); -G_GNUC_END_IGNORE_DEPRECATIONS + } @@ -188,9 +156,6 @@ thunar_history_dispose (GObject *object) /* disconnect from the current directory */ thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (history), NULL); - /* disconnect from the action group */ - thunar_history_set_action_group (history, NULL); - (*G_OBJECT_CLASS (thunar_history_parent_class)->dispose) (object); } @@ -201,14 +166,6 @@ thunar_history_finalize (GObject *object) { ThunarHistory *history = THUNAR_HISTORY (object); - /* disconnect from the "forward" action */ - g_signal_handlers_disconnect_matched (G_OBJECT (history->action_forward), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, history); - g_object_unref (G_OBJECT (history->action_forward)); - - /* disconnect from the "back" action */ - g_signal_handlers_disconnect_matched (G_OBJECT (history->action_back), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, history); - g_object_unref (G_OBJECT (history->action_back)); - /* release the "forward" and "back" lists */ g_slist_free_full (history->forward_list, g_object_unref); g_slist_free_full (history->back_list, g_object_unref); @@ -228,10 +185,6 @@ thunar_history_get_property (GObject *object, switch (prop_id) { - case PROP_ACTION_GROUP: - g_value_set_object (value, thunar_history_get_action_group (history)); - break; - case PROP_CURRENT_DIRECTORY: g_value_set_object (value, thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (history))); break; @@ -254,10 +207,6 @@ thunar_history_set_property (GObject *object, switch (prop_id) { - case PROP_ACTION_GROUP: - thunar_history_set_action_group (history, g_value_get_object (value)); - break; - case PROP_CURRENT_DIRECTORY: thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (history), g_value_get_object (value)); break; @@ -320,9 +269,6 @@ thunar_history_set_current_directory (ThunarNavigator *navigator, else { /* clear the "forward" list */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_action_set_sensitive (history->action_forward, FALSE); -G_GNUC_END_IGNORE_DEPRECATIONS g_slist_free_full (history->forward_list, g_object_unref); history->forward_list = NULL; @@ -331,9 +277,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS { gfile = thunar_history_get_gfile (history->current_directory); history->back_list = g_slist_prepend (history->back_list, gfile); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_action_set_sensitive (history->action_back, TRUE); -G_GNUC_END_IGNORE_DEPRECATIONS g_object_unref (history->current_directory); } @@ -348,6 +291,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* notify listeners */ g_object_notify (G_OBJECT (history), "current-directory"); + g_signal_emit (G_OBJECT (history), history_signals[HISTORY_CHANGED], 0, history); } @@ -406,8 +350,7 @@ thunar_history_go_back (ThunarHistory *history, g_object_unref (lp->data); history->back_list = g_slist_delete_link (history->back_list, lp); } - - goto update_actions; + return; } /* prepend the previous current directory to the "forward" list */ @@ -452,14 +395,6 @@ thunar_history_go_back (ThunarHistory *history, /* tell the other modules to change the current directory */ if (G_LIKELY (history->current_directory != NULL)) thunar_navigator_change_directory (THUNAR_NAVIGATOR (history), history->current_directory); - - update_actions: - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the sensitivity of the actions */ - gtk_action_set_sensitive (history->action_back, (history->back_list != NULL)); - gtk_action_set_sensitive (history->action_forward, (history->forward_list != NULL)); -G_GNUC_END_IGNORE_DEPRECATIONS } @@ -489,8 +424,7 @@ thunar_history_go_forward (ThunarHistory *history, g_object_unref (lp->data); history->forward_list = g_slist_delete_link (history->forward_list, lp); } - - goto update_actions; + return; } /* prepend the previous current directory to the "back" list */ @@ -533,25 +467,13 @@ thunar_history_go_forward (ThunarHistory *history, /* tell the other modules to change the current directory */ if (G_LIKELY (history->current_directory != NULL)) thunar_navigator_change_directory (THUNAR_NAVIGATOR (history), history->current_directory); - - update_actions: - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the sensitivity of the actions */ - gtk_action_set_sensitive (history->action_back, (history->back_list != NULL)); - gtk_action_set_sensitive (history->action_forward, (history->forward_list != NULL)); -G_GNUC_END_IGNORE_DEPRECATIONS } -static void -thunar_history_action_back (GtkAction *action, - ThunarHistory *history) +void +thunar_history_action_back (ThunarHistory *history) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_HISTORY (history)); /* go back one step */ @@ -577,13 +499,9 @@ thunar_history_action_back_nth (GtkWidget *item, -static void -thunar_history_action_forward (GtkAction *action, - ThunarHistory *history) +void +thunar_history_action_forward (ThunarHistory *history) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_HISTORY (history)); /* go forward one step */ @@ -609,15 +527,16 @@ thunar_history_action_forward_nth (GtkWidget *item, -static void -thunar_history_show_menu (GtkAction *action, - GtkWidget *menu, - ThunarHistory *history) +void +thunar_history_show_menu (ThunarHistory *history, + ThunarHistoryMenuType type, + GtkWidget *parent) { ThunarIconFactory *icon_factory; GtkIconTheme *icon_theme; GCallback handler; GtkWidget *image; + GtkWidget *menu; GtkWidget *item; GdkPixbuf *icon; GSList *lp; @@ -626,18 +545,17 @@ thunar_history_show_menu (GtkAction *action, const gchar *icon_name; gchar *parse_name; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_MENU_SHELL (menu)); + _thunar_return_if_fail (GTK_IS_WIDGET (parent)); _thunar_return_if_fail (THUNAR_IS_HISTORY (history)); + menu = gtk_menu_new (); + /* determine the icon factory to use to load the icons */ - icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (menu)); + icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (parent)); icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); /* check if we have "Back" or "Forward" here */ - if (action == history->action_back) + if (type == THUNAR_HISTORY_MENU_BACK) { /* display the "back" list */ lp = history->back_list; @@ -653,20 +571,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* add menu items for all list items */ for (;lp != NULL; lp = lp->next) { - /* add an item for this file */ - display_name = g_object_get_qdata (G_OBJECT (lp->data), thunar_history_display_name_quark); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - item = gtk_image_menu_item_new_with_label (display_name); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_set_qdata (G_OBJECT (item), thunar_history_gfile_quark, lp->data); - g_signal_connect (G_OBJECT (item), "activate", handler, history); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - parse_name = g_file_get_parse_name (lp->data); - gtk_widget_set_tooltip_text (item, parse_name); - g_free (parse_name); - file = thunar_file_cache_lookup (lp->data); image = NULL; if (file != NULL) @@ -697,96 +602,37 @@ G_GNUC_END_IGNORE_DEPRECATIONS image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); } -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); -G_GNUC_END_IGNORE_DEPRECATIONS - } - - /* release the icon factory */ - g_object_unref (G_OBJECT (icon_factory)); -} - - - -/** - * thunar_history_get_action_group: - * @history : a #ThunarHistory. - * - * Returns the #GtkActionGroup to which @history - * is currently attached, or %NULL if @history is - * not attached to any #GtkActionGroup right now. - * - * Return value: the #GtkActionGroup to which - * @history is currently attached. - **/ -static GtkActionGroup* -thunar_history_get_action_group (const ThunarHistory *history) -{ - _thunar_return_val_if_fail (THUNAR_IS_HISTORY (history), NULL); - return history->action_group; -} - - - -/** - * thunar_history_set_action_group: - * @history : a #ThunarHistory. - * @action_group : a #GtkActionGroup or %NULL. - * - * Attaches @history to the specified @action_group, - * and thereby registers the actions "back" and - * "forward" provided by @history on the given - * @action_group. - **/ -static void -thunar_history_set_action_group (ThunarHistory *history, - GtkActionGroup *action_group) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_HISTORY (history)); - _thunar_return_if_fail (action_group == NULL || GTK_IS_ACTION_GROUP (action_group)); - /* verify that we don't already use that action group */ - if (G_UNLIKELY (history->action_group == action_group)) - return; + /* add an item for this file */ + display_name = g_object_get_qdata (G_OBJECT (lp->data), thunar_history_display_name_quark); + item = xfce_gtk_image_menu_item_new (display_name, parse_name, NULL, + NULL, NULL, image, GTK_MENU_SHELL (menu)); + g_object_set_qdata (G_OBJECT (item), thunar_history_gfile_quark, lp->data); + g_signal_connect (G_OBJECT (item), "activate", handler, history); - /* disconnect from the previous action group */ - if (G_UNLIKELY (history->action_group != NULL)) - { - gtk_action_group_remove_action (history->action_group, history->action_back); - gtk_action_group_remove_action (history->action_group, history->action_forward); - g_object_unref (G_OBJECT (history->action_group)); + g_free (parse_name); } - /* activate the new action group */ - history->action_group = action_group; - - /* connect to the new action group */ - if (G_LIKELY (action_group != NULL)) - { - g_object_ref (G_OBJECT (action_group)); - gtk_action_group_add_action_with_accel (action_group, history->action_back, "<alt>Left"); - gtk_action_group_add_action_with_accel (action_group, history->action_forward, "<alt>Right"); - } + gtk_widget_show_all (menu); + /* release the icon factory */ + g_object_unref (G_OBJECT (icon_factory)); - /* notify listeners */ - g_object_notify (G_OBJECT (history), "action-group"); -G_GNUC_END_IGNORE_DEPRECATIONS + /* run the menu (takes over the floating of menu) */ + gtk_menu_popup_at_widget (GTK_MENU (menu), parent, + GDK_GRAVITY_SOUTH_WEST, + GDK_GRAVITY_NORTH_WEST, + NULL); } ThunarHistory * -thunar_history_copy (ThunarHistory *history, - GtkActionGroup *action_group) +thunar_history_copy (ThunarHistory *history) { ThunarHistory *copy; GSList *lp; _thunar_return_val_if_fail (history == NULL || THUNAR_IS_HISTORY (history), NULL); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_val_if_fail (action_group == NULL || GTK_IS_ACTION_GROUP (action_group), NULL); -G_GNUC_END_IGNORE_DEPRECATIONS if (G_UNLIKELY (history == NULL)) return NULL; @@ -796,9 +642,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* take a ref on the current directory */ copy->current_directory = g_object_ref (history->current_directory); - /* set the action group */ - thunar_history_set_action_group (copy, action_group); - /* copy the back list */ for (lp = history->back_list; lp != NULL; lp = lp->next) copy->back_list = g_slist_append (copy->back_list, g_object_ref (G_OBJECT (lp->data))); @@ -807,18 +650,45 @@ G_GNUC_END_IGNORE_DEPRECATIONS for (lp = history->forward_list; lp != NULL; lp = lp->next) copy->forward_list = g_slist_append (copy->forward_list, g_object_ref (G_OBJECT (lp->data))); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the sensitivity of the actions */ - gtk_action_set_sensitive (copy->action_back, (copy->back_list != NULL)); - gtk_action_set_sensitive (copy->action_forward, (copy->forward_list != NULL)); -G_GNUC_END_IGNORE_DEPRECATIONS - return copy; } /** + * thunar_history_has_back: + * @history : a #ThunarHistory. + * + * Return value: TRUE if there is a backward history + **/ +gboolean +thunar_history_has_back (ThunarHistory *history) +{ + _thunar_return_val_if_fail (THUNAR_IS_HISTORY (history), FALSE); + + return history->back_list != NULL; +} + + + + +/** + * thunar_history_has_forward: + * @history : a #ThunarHistory. + * + * Return value: TRUE if there is a forward history + **/ +gboolean +thunar_history_has_forward (ThunarHistory *history) +{ + _thunar_return_val_if_fail (THUNAR_IS_HISTORY (history), FALSE); + + return history->forward_list != NULL; +} + + + +/** * thunar_file_history_peek_back: * @history : a #ThunarHistory. * diff --git a/thunar/thunar-history.h b/thunar/thunar-history.h index efef8ec1..ffae36e0 100644 --- a/thunar/thunar-history.h +++ b/thunar/thunar-history.h @@ -34,13 +34,35 @@ typedef struct _ThunarHistory ThunarHistory; #define THUNAR_IS_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_HISTORY)) #define THUNAR_HISTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_HISTORY, ThunarHistoryClass)) -GType thunar_history_get_type (void) G_GNUC_CONST; +typedef enum +{ + THUNAR_HISTORY_MENU_BACK, + THUNAR_HISTORY_MENU_FORWARD, + + +} ThunarHistoryMenuType; -ThunarHistory *thunar_history_copy (ThunarHistory *history, - GtkActionGroup *action_group); +struct _ThunarHistoryClass +{ + GObjectClass __parent__; + + /* external signals */ + void (*history_changed) (ThunarHistory *history, + const gchar *initial_text); +}; + +GType thunar_history_get_type (void) G_GNUC_CONST; -ThunarFile *thunar_history_peek_back (ThunarHistory *history); -ThunarFile *thunar_history_peek_forward (ThunarHistory *history); +ThunarHistory *thunar_history_copy (ThunarHistory *history); +gboolean thunar_history_has_back (ThunarHistory *history); +gboolean thunar_history_has_forward (ThunarHistory *history); +ThunarFile *thunar_history_peek_back (ThunarHistory *history); +ThunarFile *thunar_history_peek_forward (ThunarHistory *history); +void thunar_history_action_back (ThunarHistory *history); +void thunar_history_action_forward (ThunarHistory *history); +void thunar_history_show_menu (ThunarHistory *history, + ThunarHistoryMenuType type, + GtkWidget *parent); G_END_DECLS; diff --git a/thunar/thunar-launcher-ui.xml b/thunar/thunar-launcher-ui.xml deleted file mode 100644 index 4b168777..00000000 --- a/thunar/thunar-launcher-ui.xml +++ /dev/null @@ -1,58 +0,0 @@ -<ui> - - <!-- - Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - - Thunar launcher 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="file-menu"> - <placeholder name="placeholder-launcher"> - <menuitem action="open" /> - <menuitem action="open-in-new-tab" /> - <menuitem action="open-in-new-window" /> - <placeholder name="placeholder-applications" /> - <menuitem action="open-with-other" /> - <menu action="open-with-menu"> - <placeholder name="placeholder-applications" /> - <separator /> - <menuitem action="open-with-other-in-menu" /> - </menu> - <placeholder name="placeholder-actions" /> - </placeholder> - - <menu action="sendto-menu"> - <placeholder name="placeholder-sendto-actions"> - <menuitem action="sendto-desktop" /> - <separator /> - </placeholder> - </menu> - </menu> - </menubar> - - <popup action="file-context-menu"> - <placeholder name="placeholder-launcher"> - <menuitem action="open" /> - <menuitem action="open-in-new-tab" /> - <menuitem action="open-in-new-window" /> - <placeholder name="placeholder-applications" /> - <menuitem action="open-with-other" /> - <menu action="open-with-menu"> - <placeholder name="placeholder-applications" /> - <separator /> - <menuitem action="open-with-other-in-menu" /> - </menu> - <placeholder name="placeholder-actions" /> - </placeholder> - - <menu action="sendto-menu"> - <placeholder name="placeholder-sendto-actions"> - <menuitem action="sendto-desktop" /> - <separator /> - </placeholder> - </menu> - </popup> -</ui> diff --git a/thunar/thunar-launcher.c b/thunar/thunar-launcher.c index 20789fe7..ffee7e59 100644 --- a/thunar/thunar-launcher.c +++ b/thunar/thunar-launcher.c @@ -2,6 +2,7 @@ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> + * Copyright (c) 2020 Alexander Schwinn <alexxcons@xfce.org> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -32,22 +33,31 @@ #include <thunar/thunar-application.h> #include <thunar/thunar-browser.h> #include <thunar/thunar-chooser-dialog.h> +#include <thunar/thunar-clipboard-manager.h> +#include <thunar/thunar-create-dialog.h> #include <thunar/thunar-dialogs.h> #include <thunar/thunar-file-monitor.h> #include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> #include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-icon-factory.h> +#include <thunar/thunar-io-scan-directory.h> #include <thunar/thunar-launcher.h> -#include <thunar/thunar-launcher-ui.h> +#include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> +#include <thunar/thunar-properties-dialog.h> +#include <thunar/thunar-renamer-dialog.h> #include <thunar/thunar-sendto-model.h> +#include <thunar/thunar-shortcuts-pane.h> +#include <thunar/thunar-simple-job.h> #include <thunar/thunar-device-monitor.h> #include <thunar/thunar-util.h> #include <thunar/thunar-window.h> +#include <libxfce4ui/libxfce4ui.h> + -typedef struct _ThunarLauncherMountData ThunarLauncherMountData; typedef struct _ThunarLauncherPokeData ThunarLauncherPokeData; @@ -58,72 +68,93 @@ enum PROP_0, PROP_CURRENT_DIRECTORY, PROP_SELECTED_FILES, - PROP_UI_MANAGER, PROP_WIDGET, + PROP_SELECT_FILES_CLOSURE, N_PROPERTIES }; -static void thunar_launcher_component_init (ThunarComponentIface *iface); -static void thunar_launcher_navigator_init (ThunarNavigatorIface *iface); -static void thunar_launcher_dispose (GObject *object); -static void thunar_launcher_finalize (GObject *object); -static void thunar_launcher_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_launcher_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static ThunarFile *thunar_launcher_get_current_directory (ThunarNavigator *navigator); -static void thunar_launcher_set_current_directory (ThunarNavigator *navigator, - ThunarFile *current_directory); -static GList *thunar_launcher_get_selected_files (ThunarComponent *component); -static void thunar_launcher_set_selected_files (ThunarComponent *component, - GList *selected_files); -static GtkUIManager *thunar_launcher_get_ui_manager (ThunarComponent *component); -static void thunar_launcher_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager); -static void thunar_launcher_execute_files (ThunarLauncher *launcher, - GList *files); -static void thunar_launcher_open_files (ThunarLauncher *launcher, - GList *files); -static void thunar_launcher_open_paths (GAppInfo *app_info, - GList *file_list, - ThunarLauncher *launcher); -static void thunar_launcher_open_windows (ThunarLauncher *launcher, - GList *directories); -static void thunar_launcher_update (ThunarLauncher *launcher); -static void thunar_launcher_action_open (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_open_with_other (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_open_in_new_window (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_open_in_new_tab (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_sendto_desktop (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_action_sendto_device (GtkAction *action, - ThunarLauncher *launcher); -static void thunar_launcher_widget_destroyed (ThunarLauncher *launcher, - GtkWidget *widget); -static gboolean thunar_launcher_sendto_idle (gpointer user_data); -static void thunar_launcher_sendto_idle_destroy (gpointer user_data); -static void thunar_launcher_mount_data_free (ThunarLauncherMountData *data); -static void thunar_launcher_poke_files (ThunarLauncher *launcher, - ThunarLauncherPokeData *poke_data); -static void thunar_launcher_poke_files_finish (ThunarBrowser *browser, - ThunarFile *file, - ThunarFile *target_file, - GError *error, - gpointer user_data); -static ThunarLauncherPokeData *thunar_launcher_poke_data_new (GList *files); -static void thunar_launcher_poke_data_free (ThunarLauncherPokeData *data); -static GtkWidget *thunar_launcher_get_widget (const ThunarLauncher *launcher); - +static void thunar_launcher_component_init (ThunarComponentIface *iface); +static void thunar_launcher_navigator_init (ThunarNavigatorIface *iface); +static void thunar_launcher_dispose (GObject *object); +static void thunar_launcher_finalize (GObject *object); +static void thunar_launcher_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_launcher_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static ThunarFile *thunar_launcher_get_current_directory (ThunarNavigator *navigator); +static void thunar_launcher_set_current_directory (ThunarNavigator *navigator, + ThunarFile *current_directory); +static GList *thunar_launcher_get_selected_files (ThunarComponent *component); +static void thunar_launcher_set_selected_files (ThunarComponent *component, + GList *selected_files); +static void thunar_launcher_execute_files (ThunarLauncher *launcher, + GList *files); +static void thunar_launcher_open_file (ThunarLauncher *launcher, + ThunarFile *file, + GAppInfo *application_to_use); +static void thunar_launcher_open_files (ThunarLauncher *launcher, + GList *files, + GAppInfo *application_to_use); +static void thunar_launcher_open_paths (GAppInfo *app_info, + GList *file_list, + ThunarLauncher *launcher); +static void thunar_launcher_open_windows (ThunarLauncher *launcher, + GList *directories); +static void thunar_launcher_poke_files (ThunarLauncher *launcher, + GAppInfo *application_to_use, + ThunarLauncherFolderOpenAction folder_open_action); +static void thunar_launcher_poke_files_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer user_data); +static ThunarLauncherPokeData *thunar_launcher_poke_data_new (GList *files_to_poke, + GAppInfo *application_to_use, + ThunarLauncherFolderOpenAction folder_open_action); +static void thunar_launcher_poke_data_free (ThunarLauncherPokeData *data); +static void thunar_launcher_widget_destroyed (ThunarLauncher *launcher, + GtkWidget *widget); +static void thunar_launcher_action_open (ThunarLauncher *launcher); +static void thunar_launcher_action_open_in_new_tabs (ThunarLauncher *launcher); +static void thunar_launcher_action_open_in_new_windows (ThunarLauncher *launcher); +static void thunar_launcher_action_open_with_other (ThunarLauncher *launcher); +static void thunar_launcher_action_sendto_desktop (ThunarLauncher *launcher); +static void thunar_launcher_action_properties (ThunarLauncher *launcher); +static void thunar_launcher_action_sendto_device (ThunarLauncher *launcher, + GObject *object); +static void thunar_launcher_action_add_shortcuts (ThunarLauncher *launcher); +static void thunar_launcher_action_make_link (ThunarLauncher *launcher); +static void thunar_launcher_action_duplicate (ThunarLauncher *launcher); +static void thunar_launcher_action_rename (ThunarLauncher *launcher); +static void thunar_launcher_action_restore (ThunarLauncher *launcher); +static void thunar_launcher_action_move_to_trash (ThunarLauncher *launcher); +static void thunar_launcher_action_delete (ThunarLauncher *launcher); +static void thunar_launcher_action_trash_delete (ThunarLauncher *launcher); +static void thunar_launcher_action_empty_trash (ThunarLauncher *launcher); +static void thunar_launcher_action_cut (ThunarLauncher *launcher); +static void thunar_launcher_action_copy (ThunarLauncher *launcher); +static void thunar_launcher_action_paste_into_folder (ThunarLauncher *launcher); +static void thunar_launcher_sendto_device (ThunarLauncher *launcher, + ThunarDevice *device); +static void thunar_launcher_sendto_mount_finish (ThunarDevice *device, + const GError *error, + gpointer user_data); +static GtkWidget *thunar_launcher_build_sendto_submenu (ThunarLauncher *launcher); +static void thunar_launcher_menu_item_activated (ThunarLauncher *launcher, + GtkWidget *menu_item); +static void thunar_launcher_action_create_folder (ThunarLauncher *launcher); +static void thunar_launcher_action_create_document (ThunarLauncher *launcher, + GtkWidget *menu_item); +static GtkWidget *thunar_launcher_create_document_submenu_new(ThunarLauncher *launcher); +static GtkWidget *thunar_launcher_append_paste_item (ThunarLauncher *launcher, + GtkMenuShell *menu, + gboolean force); struct _ThunarLauncherClass { @@ -137,60 +168,74 @@ struct _ThunarLauncher ThunarFile *current_directory; GList *selected_files; - guint launcher_idle_id; + gint n_selected_files; + gint n_selected_directories; + gint n_selected_executables; + gint n_selected_regulars; + gboolean selection_trashable; + gboolean current_directory_selected; + gboolean single_folder_selected; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - guint ui_merge_id; - guint ui_addons_merge_id; + ThunarFile *single_folder; + ThunarFile *parent_folder; - GtkAction *action_open; - GtkAction *action_open_with_other; - GtkAction *action_open_in_new_window; - GtkAction *action_open_in_new_tab; - GtkAction *action_open_with_other_in_menu; - - GtkWidget *widget; + GClosure *select_files_closure; - ThunarDeviceMonitor *device_monitor; - ThunarSendtoModel *sendto_model; - guint sendto_idle_id; + ThunarPreferences *preferences; - ThunarFileMonitor *file_monitor; + /* Parent widget which holds the instance of the launcher */ + GtkWidget *widget; }; -struct _ThunarLauncherMountData -{ - ThunarLauncher *launcher; - GList *files; -}; +static GQuark thunar_launcher_appinfo_quark; +static GQuark thunar_launcher_device_quark; +static GQuark thunar_launcher_file_quark; struct _ThunarLauncherPokeData { - GList *files; - GList *resolved_files; - guint directories_in_tabs : 1; + GList *files_to_poke; + GList *files_poked; + GAppInfo *application_to_use; + ThunarLauncherFolderOpenAction folder_open_action; }; +static GParamSpec *launcher_props[N_PROPERTIES] = { NULL, }; - -static const GtkActionEntry action_entries[] = +static XfceGtkActionEntry thunar_launcher_action_entries[] = { - { "open", "document-open", N_ ("_Open"), "<control>O", NULL, G_CALLBACK (thunar_launcher_action_open), }, - { "open-in-new-tab", NULL, N_ ("Open in New _Tab"), "<control><shift>P", NULL, G_CALLBACK (thunar_launcher_action_open_in_new_tab), }, - { "open-in-new-window", NULL, N_ ("Open in New _Window"), "<control><shift>O", NULL, G_CALLBACK (thunar_launcher_action_open_in_new_window), }, - { "open-with-other", NULL, N_ ("Open With Other _Application..."), NULL, N_ ("Choose another application with which to open the selected file"), G_CALLBACK (thunar_launcher_action_open_with_other), }, - { "open-with-menu", NULL, N_ ("Open With"), NULL, NULL, NULL, }, - { "open-with-other-in-menu", NULL, N_ ("Open With Other _Application..."), NULL, N_ ("Choose another application with which to open the selected file"), G_CALLBACK (thunar_launcher_action_open_with_other), }, - { "sendto-desktop", "user-desktop", "", NULL, NULL, G_CALLBACK (thunar_launcher_action_sendto_desktop), }, + { THUNAR_LAUNCHER_ACTION_OPEN, "<Actions>/ThunarLauncher/open", "<Primary>O", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, "document-open", G_CALLBACK (thunar_launcher_action_open), }, + { THUNAR_LAUNCHER_ACTION_EXECUTE, "<Actions>/ThunarLauncher/execute", "", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, "system-run", G_CALLBACK (thunar_launcher_action_open), }, + { THUNAR_LAUNCHER_ACTION_OPEN_IN_TAB, "<Actions>/ThunarLauncher/open-in-new-tab", "<Primary><shift>P", XFCE_GTK_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_launcher_action_open_in_new_tabs), }, + { THUNAR_LAUNCHER_ACTION_OPEN_IN_WINDOW, "<Actions>/ThunarLauncher/open-in-new-window", "<Primary><shift>O", XFCE_GTK_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_launcher_action_open_in_new_windows), }, + { THUNAR_LAUNCHER_ACTION_OPEN_WITH_OTHER, "<Actions>/ThunarLauncher/open-with-other", "", XFCE_GTK_MENU_ITEM, N_ ("Open With Other _Application..."), N_ ("Choose another application with which to open the selected file"), NULL, G_CALLBACK (thunar_launcher_action_open_with_other), }, + + /* For backward compatibility the old accel paths are re-used. Currently not possible to automatically migrate to new accel paths. */ + /* Waiting for https://gitlab.gnome.org/GNOME/gtk/issues/2375 to be able to fix that */ + { THUNAR_LAUNCHER_ACTION_SENDTO_MENU, "<Actions>/ThunarWindow/sendto-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Send To"), NULL, NULL, NULL, }, + { THUNAR_LAUNCHER_ACTION_SENDTO_SHORTCUTS, "<Actions>/ThunarShortcutsPane/sendto-shortcuts", "", XFCE_GTK_MENU_ITEM, NULL, NULL, "bookmark-new", G_CALLBACK (thunar_launcher_action_add_shortcuts), }, + { THUNAR_LAUNCHER_ACTION_SENDTO_DESKTOP, "<Actions>/ThunarLauncher/sendto-desktop", "", XFCE_GTK_MENU_ITEM, NULL, NULL, "user-desktop", G_CALLBACK (thunar_launcher_action_sendto_desktop), }, + { THUNAR_LAUNCHER_ACTION_PROPERTIES, "<Actions>/ThunarStandardView/properties", "<Alt>Return", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Properties..."), N_ ("View the properties of the selected file"), "document-properties", G_CALLBACK (thunar_launcher_action_properties), }, + { THUNAR_LAUNCHER_ACTION_MAKE_LINK, "<Actions>/ThunarStandardView/make-link", "", XFCE_GTK_MENU_ITEM, N_ ("Ma_ke Link"), NULL, NULL, G_CALLBACK (thunar_launcher_action_make_link), }, + { THUNAR_LAUNCHER_ACTION_DUPLICATE, "<Actions>/ThunarStandardView/duplicate", "", XFCE_GTK_MENU_ITEM, N_ ("Du_plicate"), NULL, NULL, G_CALLBACK (thunar_launcher_action_duplicate), }, + { THUNAR_LAUNCHER_ACTION_RENAME, "<Actions>/ThunarStandardView/rename", "F2", XFCE_GTK_MENU_ITEM, N_ ("_Rename..."), NULL, NULL, G_CALLBACK (thunar_launcher_action_rename), }, + { THUNAR_LAUNCHER_ACTION_EMPTY_TRASH, "<Actions>/ThunarWindow/empty-trash", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Empty Trash"), N_ ("Delete all files and folders in the Trash"), NULL, G_CALLBACK (thunar_launcher_action_empty_trash), }, + { THUNAR_LAUNCHER_ACTION_CREATE_FOLDER, "<Actions>/ThunarStandardView/create-folder", "<Primary><shift>N", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Create _Folder..."), N_ ("Create an empty folder within the current folder"), "folder-new", G_CALLBACK (thunar_launcher_action_create_folder), }, + { THUNAR_LAUNCHER_ACTION_CREATE_DOCUMENT, "<Actions>/ThunarStandardView/create-document", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Create _Document"), N_ ("Create a new document from a template"), "document-new", G_CALLBACK (NULL), }, + + { THUNAR_LAUNCHER_ACTION_RESTORE, "<Actions>/ThunarLauncher/restore", "", XFCE_GTK_MENU_ITEM, N_ ("_Restore"), NULL, NULL, G_CALLBACK (thunar_launcher_action_restore), }, + { THUNAR_LAUNCHER_ACTION_MOVE_TO_TRASH, "<Actions>/ThunarLauncher/move-to-trash", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Mo_ve to Trash"), NULL, "user-trash", G_CALLBACK (thunar_launcher_action_move_to_trash), }, + { THUNAR_LAUNCHER_ACTION_DELETE, "<Actions>/ThunarLauncher/delete", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Delete"), NULL, "edit-delete", G_CALLBACK (thunar_launcher_action_delete), }, + { THUNAR_LAUNCHER_ACTION_TRASH_DELETE, "<Actions>/ThunarLauncher/trash-delete", "Delete", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_launcher_action_trash_delete), }, + { THUNAR_LAUNCHER_ACTION_TRASH_DELETE, "<Actions>/ThunarLauncher/trash-delete-2", "<Shift>Delete", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_launcher_action_trash_delete), }, + { THUNAR_LAUNCHER_ACTION_TRASH_DELETE, "<Actions>/ThunarLauncher/trash-delete-3", "KP_Delete", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_launcher_action_trash_delete), }, + { THUNAR_LAUNCHER_ACTION_TRASH_DELETE, "<Actions>/ThunarLauncher/trash-delete-4", "<Shift>KP_Delete", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_launcher_action_trash_delete), }, + { THUNAR_LAUNCHER_ACTION_PASTE, "<Actions>/ThunarLauncher/paste", "<Primary>V", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Paste"), N_ ("Move or copy files previously selected by a Cut or Copy command"), "edit-paste", G_CALLBACK (thunar_launcher_action_paste_into_folder), }, + { THUNAR_LAUNCHER_ACTION_PASTE_ALT, NULL, "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Paste Into Folder"), N_ ("Move or copy files previously selected by a Cut or Copy command into the selected folder"), "edit-paste", G_CALLBACK (thunar_launcher_action_paste_into_folder), }, + { THUNAR_LAUNCHER_ACTION_COPY, "<Actions>/ThunarLauncher/copy", "<Primary>C", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Copy"), N_ ("Prepare the selected files to be copied with a Paste command"), "edit-copy", G_CALLBACK (thunar_launcher_action_copy), }, + { THUNAR_LAUNCHER_ACTION_CUT, "<Actions>/ThunarLauncher/cut", "<Primary>X", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Cu_t"), N_ ("Prepare the selected files to be moved with a Paste command"), "edit-cut", G_CALLBACK (thunar_launcher_action_cut), }, }; -static GQuark thunar_launcher_handler_quark; - - - -static GParamSpec *launcher_props[N_PROPERTIES] = { NULL, }; - +#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_launcher_action_entries,G_N_ELEMENTS(thunar_launcher_action_entries),id) G_DEFINE_TYPE_WITH_CODE (ThunarLauncher, thunar_launcher, G_TYPE_OBJECT, @@ -206,8 +251,12 @@ thunar_launcher_class_init (ThunarLauncherClass *klass) GObjectClass *gobject_class; gpointer g_iface; - /* determine the "thunar-launcher-handler" quark */ - thunar_launcher_handler_quark = g_quark_from_static_string ("thunar-launcher-handler"); + /* determine all used quarks */ + thunar_launcher_appinfo_quark = g_quark_from_static_string ("thunar-launcher-appinfo"); + thunar_launcher_device_quark = g_quark_from_static_string ("thunar-launcher-device"); + thunar_launcher_file_quark = g_quark_from_static_string ("thunar-launcher-file"); + + xfce_gtk_translate_action_entries (thunar_launcher_action_entries, G_N_ELEMENTS (thunar_launcher_action_entries)); gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = thunar_launcher_dispose; @@ -225,7 +274,19 @@ thunar_launcher_class_init (ThunarLauncherClass *klass) "widget", "widget", GTK_TYPE_WIDGET, - EXO_PARAM_READWRITE); + EXO_PARAM_WRITABLE); + + /** + * ThunarLauncher:select-files-closure: + * + * The #GClosure which will be called if the selected file should be updated after a launcher operation + **/ + launcher_props[PROP_SELECT_FILES_CLOSURE] = + g_param_spec_pointer ("select-files-closure", + "select-files-closure", + "select-files-closure", + G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY); /* Override ThunarNavigator's properties */ g_iface = g_type_default_interface_peek (THUNAR_TYPE_NAVIGATOR); @@ -239,10 +300,6 @@ thunar_launcher_class_init (ThunarLauncherClass *klass) g_param_spec_override ("selected-files", g_object_interface_find_property (g_iface, "selected-files")); - launcher_props[PROP_UI_MANAGER] = - g_param_spec_override ("ui-manager", - g_object_interface_find_property (g_iface, "ui-manager")); - /* install properties */ g_object_class_install_properties (gobject_class, N_PROPERTIES, launcher_props); } @@ -254,8 +311,6 @@ thunar_launcher_component_init (ThunarComponentIface *iface) { iface->get_selected_files = thunar_launcher_get_selected_files; iface->set_selected_files = thunar_launcher_set_selected_files; - iface->get_ui_manager = thunar_launcher_get_ui_manager; - iface->set_ui_manager = thunar_launcher_set_ui_manager; } @@ -272,31 +327,11 @@ thunar_launcher_navigator_init (ThunarNavigatorIface *iface) static void thunar_launcher_init (ThunarLauncher *launcher) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the action group for the launcher actions */ - launcher->action_group = gtk_action_group_new ("ThunarLauncher"); - gtk_action_group_set_translation_domain (launcher->action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (launcher->action_group, action_entries, G_N_ELEMENTS (action_entries), launcher); - - /* determine references to our actions */ - launcher->action_open = gtk_action_group_get_action (launcher->action_group, "open"); - launcher->action_open_with_other = gtk_action_group_get_action (launcher->action_group, "open-with-other"); - launcher->action_open_in_new_window = gtk_action_group_get_action (launcher->action_group, "open-in-new-window"); - launcher->action_open_in_new_tab = gtk_action_group_get_action (launcher->action_group, "open-in-new-tab"); - launcher->action_open_with_other_in_menu = gtk_action_group_get_action (launcher->action_group, "open-with-other-in-menu"); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* setup the "Send To" support */ - launcher->sendto_model = thunar_sendto_model_get_default (); - - /* the "Send To" menu also displays removable devices from the device monitor */ - launcher->device_monitor = thunar_device_monitor_get (); - g_signal_connect_swapped (launcher->device_monitor, "device-added", G_CALLBACK (thunar_launcher_update), launcher); - g_signal_connect_swapped (launcher->device_monitor, "device-removed", G_CALLBACK (thunar_launcher_update), launcher); + launcher->selected_files = NULL; + launcher->select_files_closure = NULL; - /* update launcher actions when any monitored file changes */ - launcher->file_monitor = thunar_file_monitor_get_default (); - g_signal_connect_swapped (launcher->file_monitor, "file-changed", G_CALLBACK (thunar_launcher_update), launcher); + /* grab a reference on the preferences */ + launcher->preferences = thunar_preferences_get (); } @@ -308,13 +343,16 @@ thunar_launcher_dispose (GObject *object) /* reset our properties */ thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (launcher), NULL); - thunar_component_set_ui_manager (THUNAR_COMPONENT (launcher), NULL); thunar_launcher_set_widget (THUNAR_LAUNCHER (launcher), NULL); /* disconnect from the currently selected files */ thunar_g_file_list_free (launcher->selected_files); launcher->selected_files = NULL; + /* unref parent, if any */ + if (launcher->parent_folder != NULL) + g_object_unref (launcher->parent_folder); + (*G_OBJECT_CLASS (thunar_launcher_parent_class)->dispose) (object); } @@ -325,27 +363,8 @@ thunar_launcher_finalize (GObject *object) { ThunarLauncher *launcher = THUNAR_LAUNCHER (object); - /* be sure to cancel the sendto idle source */ - if (G_UNLIKELY (launcher->sendto_idle_id != 0)) - g_source_remove (launcher->sendto_idle_id); - - /* be sure to cancel the launcher idle source */ - if (G_UNLIKELY (launcher->launcher_idle_id != 0)) - g_source_remove (launcher->launcher_idle_id); - - /* release the reference on the action group */ - g_object_unref (launcher->action_group); - - /* disconnect from the device monitor used for the "Send To" menu */ - g_signal_handlers_disconnect_by_func (launcher->device_monitor, thunar_launcher_update, launcher); - g_object_unref (launcher->device_monitor); - - /* release the reference on the sendto model */ - g_object_unref (launcher->sendto_model); - - /* disconnect from the file monitor */ - g_signal_handlers_disconnect_by_func (launcher->file_monitor, thunar_launcher_update, launcher); - g_object_unref (launcher->file_monitor); + /* release the preferences reference */ + g_object_unref (launcher->preferences); (*G_OBJECT_CLASS (thunar_launcher_parent_class)->finalize) (object); } @@ -368,14 +387,6 @@ thunar_launcher_get_property (GObject *object, g_value_set_boxed (value, thunar_component_get_selected_files (THUNAR_COMPONENT (object))); break; - case PROP_UI_MANAGER: - g_value_set_object (value, thunar_component_get_ui_manager (THUNAR_COMPONENT (object))); - break; - - case PROP_WIDGET: - g_value_set_object (value, thunar_launcher_get_widget (THUNAR_LAUNCHER (object))); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -390,6 +401,8 @@ thunar_launcher_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { + ThunarLauncher *launcher = THUNAR_LAUNCHER (object); + switch (prop_id) { case PROP_CURRENT_DIRECTORY: @@ -400,12 +413,12 @@ thunar_launcher_set_property (GObject *object, thunar_component_set_selected_files (THUNAR_COMPONENT (object), g_value_get_boxed (value)); break; - case PROP_UI_MANAGER: - thunar_component_set_ui_manager (THUNAR_COMPONENT (object), g_value_get_object (value)); + case PROP_WIDGET: + thunar_launcher_set_widget (launcher, g_value_get_object (value)); break; - case PROP_WIDGET: - thunar_launcher_set_widget (THUNAR_LAUNCHER (object), g_value_get_object (value)); + case PROP_SELECT_FILES_CLOSURE: + launcher->select_files_closure = g_value_get_pointer (value); break; default: @@ -429,6 +442,7 @@ thunar_launcher_set_current_directory (ThunarNavigator *navigator, ThunarFile *current_directory) { ThunarLauncher *launcher = THUNAR_LAUNCHER (navigator); + GList *selected_files = NULL; /* disconnect from the previous directory */ if (G_LIKELY (launcher->current_directory != NULL)) @@ -439,7 +453,17 @@ thunar_launcher_set_current_directory (ThunarNavigator *navigator, /* connect to the new directory */ if (G_LIKELY (current_directory != NULL)) - g_object_ref (G_OBJECT (current_directory)); + { + g_object_ref (G_OBJECT (current_directory)); + + /* set selected files with current directory, if not initialized yet*/ + if (launcher->selected_files == NULL) + { + selected_files = g_list_append (selected_files, current_directory); + thunar_launcher_set_selected_files (THUNAR_COMPONENT (navigator), selected_files); + g_list_free (selected_files); + } + } /* notify listeners */ g_object_notify_by_pspec (G_OBJECT (launcher), launcher_props[PROP_CURRENT_DIRECTORY]); @@ -460,98 +484,161 @@ thunar_launcher_set_selected_files (ThunarComponent *component, GList *selected_files) { ThunarLauncher *launcher = THUNAR_LAUNCHER (component); - GList *np; - GList *op; + GList *lp; - /* compare the old and the new list of selected files */ - for (np = selected_files, op = launcher->selected_files; np != NULL && op != NULL; np = np->next, op = op->next) - if (G_UNLIKELY (np->data != op->data)) - break; + /* disconnect from the previously selected files */ + thunar_g_file_list_free (launcher->selected_files); + + /* connect to the new selected files list */ + launcher->selected_files = thunar_g_file_list_copy (selected_files); - /* check if the list of selected files really changed */ - if (G_UNLIKELY (np != NULL || op != NULL)) + /* notify listeners */ + g_object_notify_by_pspec (G_OBJECT (launcher), launcher_props[PROP_SELECTED_FILES]); + + /* unref previous parent, if any */ + if (launcher->parent_folder != NULL) { - /* disconnect from the previously selected files */ - thunar_g_file_list_free (launcher->selected_files); + g_object_unref (launcher->parent_folder); + launcher->parent_folder = NULL; + } - /* connect to the new selected files list */ + /* if nothing is selected, the current directory is considered to be the selection */ + if (selected_files == NULL || g_list_length (selected_files) == 0) + { + if (launcher->current_directory != NULL) + launcher->selected_files = g_list_append (launcher->selected_files, launcher->current_directory); + } + else + { launcher->selected_files = thunar_g_file_list_copy (selected_files); + } - /* update the launcher actions */ - thunar_launcher_update (launcher); + launcher->selection_trashable = TRUE; + launcher->n_selected_files = 0; + launcher->n_selected_directories = 0; + launcher->n_selected_executables = 0; + launcher->n_selected_regulars = 0; - /* notify listeners */ - g_object_notify_by_pspec (G_OBJECT (launcher), launcher_props[PROP_SELECTED_FILES]); - } -} + /* determine the number of files/directories/executables */ + for (lp = launcher->selected_files; lp != NULL; lp = lp->next, ++launcher->n_selected_files) + { + /* Keep a reference on all selected files */ + g_object_ref (lp->data); + if (thunar_file_is_directory (lp->data) + || thunar_file_is_shortcut (lp->data) + || thunar_file_is_mountable (lp->data)) + { + ++launcher->n_selected_directories; + } + else + { + if (thunar_file_is_executable (lp->data)) + ++launcher->n_selected_executables; + ++launcher->n_selected_regulars; + } + if (!thunar_file_can_be_trashed (lp->data)) + launcher->selection_trashable = FALSE; + } -static GtkUIManager* -thunar_launcher_get_ui_manager (ThunarComponent *component) -{ - return THUNAR_LAUNCHER (component)->ui_manager; + launcher->single_folder_selected = (launcher->n_selected_directories == 1 && launcher->n_selected_files == 1); + if (launcher->single_folder_selected) + { + /* grab the folder of the first selected item */ + launcher->single_folder = THUNAR_FILE (launcher->selected_files->data); + if (launcher->current_directory != NULL) + launcher->current_directory_selected = g_file_equal (thunar_file_get_file (THUNAR_FILE (launcher->selected_files->data)), thunar_file_get_file (launcher->current_directory)); + } + else + { + launcher->single_folder = NULL; + launcher->current_directory_selected = FALSE; + } + + if (launcher->selected_files != NULL) + { + /* just grab the folder of the first selected item */ + launcher->parent_folder = thunar_file_get_parent (THUNAR_FILE (launcher->selected_files->data), NULL); + } + else + { + launcher->parent_folder = NULL; + } } -static void -thunar_launcher_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager) + /** + * thunar_launcher_set_widget: + * @launcher : a #ThunarLauncher. + * @widget : a #GtkWidget or %NULL. + * + * Associates @launcher with @widget. + **/ +void +thunar_launcher_set_widget (ThunarLauncher *launcher, + GtkWidget *widget) { - ThunarLauncher *launcher = THUNAR_LAUNCHER (component); - GError *error = NULL; + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + _thunar_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget)); - /* disconnect from the previous UI manager */ - if (G_UNLIKELY (launcher->ui_manager != NULL)) + /* disconnect from the previous widget */ + if (G_UNLIKELY (launcher->widget != NULL)) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* drop our action group from the previous UI manager */ - gtk_ui_manager_remove_action_group (launcher->ui_manager, launcher->action_group); - - /* unmerge our addons ui controls from the previous UI manager */ - if (G_LIKELY (launcher->ui_addons_merge_id != 0)) - { - gtk_ui_manager_remove_ui (launcher->ui_manager, launcher->ui_addons_merge_id); - launcher->ui_addons_merge_id = 0; - } + g_signal_handlers_disconnect_by_func (G_OBJECT (launcher->widget), thunar_launcher_widget_destroyed, launcher); + g_object_unref (G_OBJECT (launcher->widget)); + } - /* unmerge our ui controls from the previous UI manager */ - gtk_ui_manager_remove_ui (launcher->ui_manager, launcher->ui_merge_id); -G_GNUC_END_IGNORE_DEPRECATIONS + launcher->widget = widget; - /* drop the reference on the previous UI manager */ - g_object_unref (G_OBJECT (launcher->ui_manager)); + /* connect to the new widget */ + if (G_LIKELY (widget != NULL)) + { + g_object_ref (G_OBJECT (widget)); + g_signal_connect_swapped (G_OBJECT (widget), "destroy", G_CALLBACK (thunar_launcher_widget_destroyed), launcher); } - /* activate the new UI manager */ - launcher->ui_manager = ui_manager; + /* notify listeners */ + g_object_notify_by_pspec (G_OBJECT (launcher), launcher_props[PROP_WIDGET]); +} - /* connect to the new UI manager */ - if (G_LIKELY (ui_manager != NULL)) - { - /* we keep a reference on the new manager */ - g_object_ref (G_OBJECT (ui_manager)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* add our action group to the new manager */ - gtk_ui_manager_insert_action_group (ui_manager, launcher->action_group, -1); - /* merge our UI control items with the new manager */ - launcher->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_launcher_ui, thunar_launcher_ui_length, &error); -G_GNUC_END_IGNORE_DEPRECATIONS - if (G_UNLIKELY (launcher->ui_merge_id == 0)) - { - g_error ("Failed to merge ThunarLauncher menus: %s", error->message); - g_error_free (error); - } +static void +thunar_launcher_menu_item_activated (ThunarLauncher *launcher, + GtkWidget *menu_item) +{ + GAppInfo *app_info; - /* update the user interface */ - thunar_launcher_update (launcher); - } + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - /* notify listeners */ - g_object_notify_by_pspec (G_OBJECT (launcher), launcher_props[PROP_UI_MANAGER]); + if (G_UNLIKELY (launcher->selected_files == NULL)) + return; + + /* if we have a mime handler associated with the menu_item, we pass it to the launcher (g_object_get_qdata will return NULL otherwise)*/ + app_info = g_object_get_qdata (G_OBJECT (menu_item), thunar_launcher_appinfo_quark); + thunar_launcher_activate_selected_files (launcher, THUNAR_LAUNCHER_CHANGE_DIRECTORY, app_info); +} + + + +/** + * thunar_launcher_activate_selected_files: + * @launcher : a #ThunarLauncher instance + * @action : the #ThunarLauncherFolderOpenAction to use, if there are folders among the selected files + * @app_info : a #GAppInfo instance + * + * Will try to open all selected files with the provided #GAppInfo + **/ +void +thunar_launcher_activate_selected_files (ThunarLauncher *launcher, + ThunarLauncherFolderOpenAction action, + GAppInfo *app_info) +{ + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + thunar_launcher_poke_files (launcher, app_info, action); } @@ -590,8 +677,23 @@ thunar_launcher_g_app_info_hash (gconstpointer app_info) static void +thunar_launcher_open_file (ThunarLauncher *launcher, + ThunarFile *file, + GAppInfo *application_to_use) +{ + GList *files = NULL; + + files = g_list_append (files, file); + thunar_launcher_open_files (launcher, files, application_to_use); + g_list_free (files); +} + + + +static void thunar_launcher_open_files (ThunarLauncher *launcher, - GList *files) + GList *files, + GAppInfo *application_to_use) { GHashTable *applications; GAppInfo *app_info; @@ -599,7 +701,7 @@ thunar_launcher_open_files (ThunarLauncher *launcher, GList *lp; /* allocate a hash table to associate applications to URIs. since GIO allocates - * new GAppInfo objects every time, g_direct_hash does not work. we therefor use + * new GAppInfo objects every time, g_direct_hash does not work. we therefore use * a fake hash function to always hit the collision list of the hash table and * avoid storing multiple equal GAppInfos by means of g_app_info_equal(). */ applications = g_hash_table_new_full (thunar_launcher_g_app_info_hash, @@ -609,8 +711,17 @@ thunar_launcher_open_files (ThunarLauncher *launcher, for (lp = files; lp != NULL; lp = lp->next) { - /* determine the default application for the MIME type */ - app_info = thunar_file_get_default_handler (lp->data); + /* Because we created the hash_table with g_hash_table_new_full + * g_object_unref on each hash_table key and value will be called by g_hash_table_destroy */ + if (application_to_use) + { + app_info = g_app_info_dup (application_to_use); + } + else + { + /* determine the default application for the MIME type */ + app_info = thunar_file_get_default_handler (lp->data); + } /* check if we have an application here */ if (G_LIKELY (app_info != NULL)) @@ -660,7 +771,7 @@ thunar_launcher_open_paths (GAppInfo *app_info, guint n; /* determine the screen on which to launch the application */ - screen = (launcher->widget != NULL) ? gtk_widget_get_screen (launcher->widget) : NULL; + screen = gtk_widget_get_screen (launcher->widget); /* create launch context */ context = gdk_display_get_app_launch_context (gdk_screen_get_display (screen)); @@ -720,7 +831,7 @@ thunar_launcher_open_windows (ThunarLauncher *launcher, if (G_UNLIKELY (n > 1)) { /* open a message dialog */ - window = (launcher->widget != NULL) ? gtk_widget_get_toplevel (launcher->widget) : NULL; + window = gtk_widget_get_toplevel (launcher->widget); dialog = gtk_message_dialog_new ((GtkWindow *) window, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, @@ -730,8 +841,7 @@ thunar_launcher_open_windows (ThunarLauncher *launcher, gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), ngettext ("This will open %d separate file manager window.", "This will open %d separate file manager windows.", - n), - n); + n), n); label = g_strdup_printf (ngettext ("Open %d New Window", "Open %d New Windows", n), n); gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL); gtk_dialog_add_button (GTK_DIALOG (dialog), label, GTK_RESPONSE_YES); @@ -748,7 +858,7 @@ thunar_launcher_open_windows (ThunarLauncher *launcher, application = thunar_application_get (); /* determine the screen on which to open the new windows */ - screen = (launcher->widget != NULL) ? gtk_widget_get_screen (launcher->widget) : NULL; + screen = gtk_widget_get_screen (launcher->widget); /* open all requested windows */ for (lp = directories; lp != NULL; lp = lp->next) @@ -761,485 +871,20 @@ thunar_launcher_open_windows (ThunarLauncher *launcher, -static gboolean -thunar_launcher_update_idle (gpointer data) -{ - ThunarLauncher *launcher = THUNAR_LAUNCHER (data); - const gchar *context_menu_path; - const gchar *file_menu_path; - GtkAction *action; - gboolean default_is_open_with_other = FALSE; - GList *applications; - GList *actions; - GList *lp; - gchar *tooltip; - gchar *label; - gchar *name; - gint n_directories = 0; - gint n_executables = 0; - gint n_regulars = 0; - gint n_selected_files = 0; - gint n; - - /* verify that we're connected to an UI manager */ - if (G_UNLIKELY (launcher->ui_manager == NULL)) - return FALSE; - -THUNAR_THREADS_ENTER - - /* drop the previous addons ui controls from the UI manager */ - if (G_LIKELY (launcher->ui_addons_merge_id != 0)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (launcher->ui_manager, launcher->ui_addons_merge_id); - gtk_ui_manager_ensure_update (launcher->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS - launcher->ui_addons_merge_id = 0; - } - - /* reset the application set for the "Open" action */ - g_object_set_qdata (G_OBJECT (launcher->action_open), thunar_launcher_handler_quark, NULL); - - /* determine the number of files/directories/executables */ - for (lp = launcher->selected_files; lp != NULL; lp = lp->next, ++n_selected_files) - { - if (thunar_file_is_directory (lp->data) - || thunar_file_is_shortcut (lp->data) - || thunar_file_is_mountable (lp->data)) - { - ++n_directories; - } - else - { - if (thunar_file_is_executable (lp->data)) - ++n_executables; - ++n_regulars; - } - } - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* Prepare "Open" label and icon */ - gtk_action_set_label (launcher->action_open, _("_Open")); - gtk_action_set_icon_name (launcher->action_open, "document-open"); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* Only directories got selected */ - if (n_selected_files == n_directories && n_directories >= 1) - { - if (n_directories > 1) - { - /* turn "Open New Window" into "Open in n New Windows" */ - label = g_strdup_printf (ngettext ("Open in %d New _Window", "Open in %d New _Windows", n_directories), n_directories); - tooltip = g_strdup_printf (ngettext ("Open the selected directory in %d new window", - "Open the selected directories in %d new windows", - n_directories), n_directories); - g_object_set (G_OBJECT (launcher->action_open_in_new_window), - "label", label, - "tooltip", tooltip, - NULL); - g_free (tooltip); - g_free (label); - - /* turn "Open in New Tab" into "Open in x New Tabs" */ - label = g_strdup_printf (ngettext ("Open in %d New _Tab", "Open in %d New _Tabs", n_directories), n_directories); - tooltip = g_strdup_printf (ngettext ("Open the selected directory in %d new tab", - "Open the selected directories in %d new tabs", - n_directories), n_directories); - g_object_set (G_OBJECT (launcher->action_open_in_new_tab), - "label", label, - "tooltip", tooltip, - NULL); - g_free (tooltip); - g_free (label); - } - else if (n_directories == 1) - { - /* prepare "Open in New Window" */ - g_object_set (G_OBJECT (launcher->action_open_in_new_window), - "label", _("Open in New _Window"), - "tooltip", _("Open the selected directory in a new window"), - NULL); - - /* prepare "Open in New Tab" */ - g_object_set (G_OBJECT (launcher->action_open_in_new_tab), - "label", _("Open in New _Tab"), - "tooltip", _("Open the selected directory in a new tab"), - NULL); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* set tooltip that makes sence */ - gtk_action_set_tooltip (launcher->action_open, _("Open the selected directory")); - } - - /* Show Window/Tab action if there are only directories selected */ - gtk_action_set_visible (launcher->action_open_in_new_window, n_directories > 0); - gtk_action_set_visible (launcher->action_open_in_new_tab, n_directories > 0); - - /* Show open if there is exactly 1 directory selected */ - gtk_action_set_visible (launcher->action_open, n_directories == 1); - gtk_action_set_sensitive (launcher->action_open, TRUE); - } - else /* not only directories got selected */ - { - /* Hide New Window and Tab action */ - gtk_action_set_visible (launcher->action_open_in_new_window, FALSE); - gtk_action_set_visible (launcher->action_open_in_new_tab, FALSE); - } - - /* drop all previous addon actions from the action group */ - actions = gtk_action_group_list_actions (launcher->action_group); - for (lp = actions; lp != NULL; lp = lp->next) - if (strncmp (gtk_action_get_name (lp->data), "thunar-launcher-addon-", 22) == 0) - gtk_action_group_remove_action (launcher->action_group, lp->data); - g_list_free (actions); - - /* allocate a new merge id from the UI manager */ - launcher->ui_addons_merge_id = gtk_ui_manager_new_merge_id (launcher->ui_manager); - - /* make the "Open" action sensitive */ - gtk_action_set_sensitive (launcher->action_open, TRUE); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* determine the set of applications that work for all selected files */ - applications = thunar_file_list_get_applications (launcher->selected_files); - - /* reset the desktop actions list */ - actions = NULL; - - /* check if we have only executable files in the selection */ - if (G_UNLIKELY (n_executables == n_selected_files)) - { - /* turn the "Open" action into "Execute" */ - g_object_set (G_OBJECT (launcher->action_open), - "label", _("_Execute"), - "icon-name", "system-run", - "tooltip", ngettext ("Execute the selected file", "Execute the selected files", n_selected_files), - NULL); - } - else if (G_LIKELY (n_directories >= 1)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* Normal open action, because there are also directories included */ - gtk_action_set_visible (launcher->action_open, TRUE); - gtk_action_set_sensitive (launcher->action_open, n_selected_files > 0); - gtk_action_set_tooltip (launcher->action_open, - ngettext ("Open the selected file", - "Open the selected files", - n_selected_files)); -G_GNUC_END_IGNORE_DEPRECATIONS - } - else if (G_LIKELY (applications != NULL)) - { - /* turn the "Open" action into "Open With DEFAULT" */ - label = g_strdup_printf (_("_Open With \"%s\""), g_app_info_get_name (applications->data)); - tooltip = g_strdup_printf (ngettext ("Use \"%s\" to open the selected file", - "Use \"%s\" to open the selected files", - n_selected_files), g_app_info_get_name (applications->data)); - g_object_set (G_OBJECT (launcher->action_open), - "label", label, - "tooltip", tooltip, - NULL); - g_free (tooltip); - g_free (label); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* load default application icon */ - gtk_action_set_stock_id (launcher->action_open, NULL); - gtk_action_set_gicon (launcher->action_open, g_app_info_get_icon (applications->data)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* remember the default application for the "Open" action */ - g_object_set_qdata_full (G_OBJECT (launcher->action_open), thunar_launcher_handler_quark, applications->data, g_object_unref); - - /* FIXME Add the desktop actions for this application. - * Unfortunately this is not supported by GIO directly */ - - /* drop the default application from the list */ - applications = g_list_delete_link (applications, applications); - } - else if (G_UNLIKELY (n_selected_files == 1)) - { - /* turn the "Open" action into "Open With Other Application" */ - g_object_set (G_OBJECT (launcher->action_open), - "label", _("_Open With Other Application..."), - "tooltip", _("Choose another application with which to open the selected file"), - NULL); - default_is_open_with_other = TRUE; - } - else - { - /* we can only show a generic "Open" action */ - g_object_set (G_OBJECT (launcher->action_open), - "label", _("_Open With Default Applications"), - "tooltip", ngettext ("Open the selected file with the default application", - "Open the selected files with the default applications", n_selected_files), - NULL); - } - - /* FIXME Add desktop actions here. Unfortunately they are not supported by - * GIO, so we'll have to roll our own thing here */ - - /* place the other applications in the "Open With" submenu if we have more than 2 other applications, or the - * default action for the file is "Execute", in which case the "Open With" actions aren't that relevant either - */ - if (G_UNLIKELY (g_list_length (applications) > 2 || n_executables == n_selected_files) ) - { - /* determine the base paths for the actions */ - file_menu_path = "/main-menu/file-menu/placeholder-launcher/open-with-menu/placeholder-applications"; - context_menu_path = "/file-context-menu/placeholder-launcher/open-with-menu/placeholder-applications"; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* show the "Open With Other Application" in the submenu and hide the toplevel one */ - gtk_action_set_visible (launcher->action_open_with_other, FALSE); - gtk_action_set_visible (launcher->action_open_with_other_in_menu, (n_selected_files == 1)); -G_GNUC_END_IGNORE_DEPRECATIONS - } - else - { - /* determine the base paths for the actions */ - file_menu_path = "/main-menu/file-menu/placeholder-launcher/placeholder-applications"; - context_menu_path = "/file-context-menu/placeholder-launcher/placeholder-applications"; - - /* add a separator if we have more than one additional application */ - if (G_LIKELY (applications != NULL)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* add separator after the DEFAULT/execute action */ - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - file_menu_path, "separator", NULL, - GTK_UI_MANAGER_SEPARATOR, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - context_menu_path, "separator", NULL, - GTK_UI_MANAGER_SEPARATOR, FALSE); - } - - /* show the toplevel "Open With Other Application" (if not already done by the "Open" action) */ - gtk_action_set_visible (launcher->action_open_with_other, !default_is_open_with_other && (n_selected_files == 1)); - gtk_action_set_visible (launcher->action_open_with_other_in_menu, FALSE); - } -G_GNUC_END_IGNORE_DEPRECATIONS - - /* add actions for all remaining applications */ - if (G_LIKELY (applications != NULL)) - { - /* process all applications and determine the desktop actions */ - for (lp = applications, n = 0; lp != NULL; lp = lp->next, ++n) - { - /* FIXME Determine the desktop actions for this application. - * Unfortunately this is not supported by GIO directly. */ - - /* generate a unique label, unique id and tooltip for the application's action */ - name = g_strdup_printf ("thunar-launcher-addon-application%d-%p", n, launcher); - label = g_strdup_printf (_("Open With \"%s\""), g_app_info_get_name (lp->data)); - tooltip = g_strdup_printf (ngettext ("Use \"%s\" to open the selected file", - "Use \"%s\" to open the selected files", - n_selected_files), g_app_info_get_name (lp->data)); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* allocate a new action for the application */ - action = gtk_action_new (name, label, tooltip, NULL); - gtk_action_set_gicon (action, g_app_info_get_icon (lp->data)); - gtk_action_group_add_action (launcher->action_group, action); - g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_open), launcher); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - file_menu_path, name, name, - GTK_UI_MANAGER_MENUITEM, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - context_menu_path, name, name, - GTK_UI_MANAGER_MENUITEM, FALSE); - g_object_unref (G_OBJECT (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* cleanup */ - g_free (tooltip); - g_free (label); - g_free (name); - } - - /* cleanup */ - g_list_free (applications); - } - /* schedule an update of the "Send To" menu */ - if (G_LIKELY (launcher->sendto_idle_id == 0)) - { - launcher->sendto_idle_id = g_idle_add_full (G_PRIORITY_LOW, thunar_launcher_sendto_idle, - launcher, thunar_launcher_sendto_idle_destroy); - } - -THUNAR_THREADS_LEAVE - - return FALSE; -} - - - -static void -thunar_launcher_update_idle_destroy (gpointer data) -{ - THUNAR_LAUNCHER (data)->launcher_idle_id = 0; -} - - - -static void -thunar_launcher_update_check (ThunarLauncher *launcher, - GtkWidget *menu) -{ - _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - _thunar_return_if_fail (menu == NULL || GTK_IS_MENU (menu)); - - /* check if the menu is in a dirty state */ - if (launcher->launcher_idle_id != 0) - { - /* stop the timeout */ - g_source_remove (launcher->launcher_idle_id); - - /* force an update */ - thunar_launcher_update_idle (launcher); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* ui update */ - gtk_ui_manager_ensure_update (launcher->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* make sure the menu is positioned correctly after the - * interface update */ - if (menu != NULL) - gtk_menu_reposition (GTK_MENU (menu)); - } -} - - - static void -thunar_launcher_update (ThunarLauncher *launcher) +thunar_launcher_poke_files (ThunarLauncher *launcher, + GAppInfo *application_to_use, + ThunarLauncherFolderOpenAction folder_open_action) { - GSList *proxies, *lp; - GtkWidget *menu; - gboolean instant_update; - - _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - proxies = gtk_action_get_proxies (launcher->action_open); -G_GNUC_END_IGNORE_DEPRECATIONS - instant_update = (proxies == NULL); - for (lp = proxies; lp != NULL; lp = lp->next) - { - menu = gtk_widget_get_ancestor (lp->data, GTK_TYPE_MENU); - if (G_LIKELY (menu != NULL)) - { - /* instant update if a menu is visible */ - if (gtk_widget_get_visible (menu)) - instant_update = TRUE; - - /* watch menu changes */ - g_signal_handlers_disconnect_by_func (G_OBJECT (menu), G_CALLBACK (thunar_launcher_update_check), launcher); - g_signal_connect_swapped (G_OBJECT (menu), "show", G_CALLBACK (thunar_launcher_update_check), launcher); - } - } - - /* stop pending timeouts */ - if (launcher->launcher_idle_id != 0) - g_source_remove (launcher->launcher_idle_id); - - if (instant_update) - { - /* directly update without interruption */ - thunar_launcher_update_idle (launcher); - } - else - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* assume all actions are working */ - gtk_action_set_sensitive (launcher->action_open, TRUE); - gtk_action_set_visible (launcher->action_open_with_other, TRUE); - gtk_action_set_visible (launcher->action_open_in_new_window, TRUE); - gtk_action_set_visible (launcher->action_open_in_new_tab, TRUE); - gtk_action_set_visible (launcher->action_open_with_other_in_menu, TRUE); -G_GNUC_END_IGNORE_DEPRECATIONS - /* delayed update */ - launcher->launcher_idle_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, 5, thunar_launcher_update_idle, - launcher, thunar_launcher_update_idle_destroy); - } -} - - - -static void -thunar_launcher_open_file (ThunarLauncher *launcher, - ThunarFile *file) -{ - GList files; + ThunarLauncherPokeData *poke_data; _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - _thunar_return_if_fail (THUNAR_IS_FILE (file)); - files.data = file; - files.next = NULL; - files.prev = NULL; + poke_data = thunar_launcher_poke_data_new (launcher->selected_files, application_to_use, folder_open_action); - if (thunar_file_is_directory (file)) - { - /* check if we're in a regular view (i.e. current_directory is set) */ - if (G_LIKELY (launcher->current_directory != NULL)) - { - /* we want to open one directory, so just emit "change-directory" here */ - thunar_navigator_change_directory (THUNAR_NAVIGATOR (launcher), file); - } - else - { - /* open the selected directory in a new window */ - thunar_launcher_open_windows (launcher, &files); - } - } - else - { - if (thunar_file_is_executable (file)) - { - /* try to execute the file */ - thunar_launcher_execute_files (launcher, &files); - } - else - { - /* try to open the file using its default application */ - thunar_launcher_open_files (launcher, &files); - } - } -} - - - -static void -thunar_launcher_poke_file_finish (ThunarBrowser *browser, - ThunarFile *file, - ThunarFile *target_file, - GError *error, - gpointer ignored) -{ - if (error == NULL) - { - thunar_launcher_open_file (THUNAR_LAUNCHER (browser), target_file); - } - else - { - thunar_dialogs_show_error (THUNAR_LAUNCHER (browser)->widget, error, - _("Failed to open \"%s\""), - thunar_file_get_display_name (file)); - } -} - - - -static void -thunar_launcher_poke_files (ThunarLauncher *launcher, - ThunarLauncherPokeData *poke_data) -{ - _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - _thunar_return_if_fail (poke_data != NULL); - _thunar_return_if_fail (poke_data->files != NULL); - - thunar_browser_poke_file (THUNAR_BROWSER (launcher), poke_data->files->data, + // We will only poke one file at a time, in order to dont use all available CPU's + // TODO: Check if that could cause slowness + thunar_browser_poke_file (THUNAR_BROWSER (launcher), poke_data->files_to_poke->data, launcher->widget, thunar_launcher_poke_files_finish, poke_data); } @@ -1255,6 +900,7 @@ thunar_launcher_poke_files_finish (ThunarBrowser *browser, { ThunarLauncherPokeData *poke_data = user_data; gboolean executable = TRUE; + gboolean open_new_window_as_tab = TRUE; GList *directories = NULL; GList *files = NULL; GList *lp; @@ -1262,24 +908,23 @@ thunar_launcher_poke_files_finish (ThunarBrowser *browser, _thunar_return_if_fail (THUNAR_IS_BROWSER (browser)); _thunar_return_if_fail (THUNAR_IS_FILE (file)); _thunar_return_if_fail (poke_data != NULL); - _thunar_return_if_fail (poke_data->files != NULL); + _thunar_return_if_fail (poke_data->files_to_poke != NULL); /* check if poking succeeded */ if (error == NULL) { /* add the resolved file to the list of file to be opened/executed later */ - poke_data->resolved_files = g_list_prepend (poke_data->resolved_files, - g_object_ref (target_file)); + poke_data->files_poked = g_list_prepend (poke_data->files_poked,g_object_ref (target_file)); } /* release and remove the just poked file from the list */ - g_object_unref (poke_data->files->data); - poke_data->files = g_list_delete_link (poke_data->files, poke_data->files); + g_object_unref (poke_data->files_to_poke->data); + poke_data->files_to_poke = g_list_delete_link (poke_data->files_to_poke, poke_data->files_to_poke); - if (poke_data->files == NULL) + if (poke_data->files_to_poke == NULL) { /* separate files and directories in the selected files list */ - for (lp = poke_data->resolved_files; lp != NULL; lp = lp->next) + for (lp = poke_data->files_poked; lp != NULL; lp = lp->next) { if (thunar_file_is_directory (lp->data)) { @@ -1299,17 +944,40 @@ thunar_launcher_poke_files_finish (ThunarBrowser *browser, /* check if we have any directories to process */ if (G_LIKELY (directories != NULL)) { - if (poke_data->directories_in_tabs) + if (poke_data->application_to_use != NULL) + { + /* open them separately, using some specific application */ + for (lp = directories; lp != NULL; lp = lp->next) + thunar_launcher_open_file (THUNAR_LAUNCHER (browser), lp->data, poke_data->application_to_use); + } + else if (poke_data->folder_open_action == THUNAR_LAUNCHER_OPEN_AS_NEW_TAB) { - /* open new tabs */ for (lp = directories; lp != NULL; lp = lp->next) thunar_navigator_open_new_tab (THUNAR_NAVIGATOR (browser), lp->data); } - else + else if (poke_data->folder_open_action == THUNAR_LAUNCHER_OPEN_AS_NEW_WINDOW) { - /* open new windows for all directories */ thunar_launcher_open_windows (THUNAR_LAUNCHER (browser), directories); } + else if (poke_data->folder_open_action == THUNAR_LAUNCHER_CHANGE_DIRECTORY) + { + /* If multiple directories are passed, we assume that we should open them all */ + if (directories->next == NULL) + thunar_navigator_change_directory (THUNAR_NAVIGATOR (browser), directories->data); + else + { + g_object_get (G_OBJECT (THUNAR_LAUNCHER (browser)->preferences), "misc-open-new-window-as-tab", &open_new_window_as_tab, NULL); + if (open_new_window_as_tab) + { + for (lp = directories; lp != NULL; lp = lp->next) + thunar_navigator_open_new_tab (THUNAR_NAVIGATOR (browser), lp->data); + } + else + thunar_launcher_open_windows (THUNAR_LAUNCHER (browser), directories); + } + } + else + g_warning("'folder_open_action' was not defined"); g_list_free (directories); } @@ -1324,250 +992,500 @@ thunar_launcher_poke_files_finish (ThunarBrowser *browser, } else { - /* try to open all files using their default applications */ - thunar_launcher_open_files (THUNAR_LAUNCHER (browser), files); + /* try to open all files */ + thunar_launcher_open_files (THUNAR_LAUNCHER (browser), files, poke_data->application_to_use); } /* cleanup */ g_list_free (files); } - /* free all files allocated for the poke data */ + /* free the poke data */ thunar_launcher_poke_data_free (poke_data); } else { /* we need to continue this until all files have been resolved */ - thunar_launcher_poke_files (THUNAR_LAUNCHER (browser), poke_data); + // We will only poke one file at a time, in order to dont use all available CPU's + // TODO: Check if that could cause slowness + thunar_browser_poke_file (browser, poke_data->files_to_poke->data, + (THUNAR_LAUNCHER (browser))->widget, thunar_launcher_poke_files_finish, poke_data); } } +static ThunarLauncherPokeData * +thunar_launcher_poke_data_new (GList *files_to_poke, + GAppInfo *application_to_use, + ThunarLauncherFolderOpenAction folder_open_action) +{ + ThunarLauncherPokeData *data; + + data = g_slice_new0 (ThunarLauncherPokeData); + data->files_to_poke = thunar_g_file_list_copy (files_to_poke); + data->files_poked = NULL; + data->application_to_use = application_to_use; + + /* keep a reference on the appdata */ + if (application_to_use != NULL) + g_object_ref (application_to_use); + data->folder_open_action = folder_open_action; + + return data; +} + + + static void -thunar_launcher_action_open (GtkAction *action, - ThunarLauncher *launcher) +thunar_launcher_poke_data_free (ThunarLauncherPokeData *data) { - ThunarLauncherPokeData *poke_data; - GAppInfo *app_info; - GList *selected_paths; + _thunar_return_if_fail (data != NULL); + + thunar_g_file_list_free (data->files_to_poke); + thunar_g_file_list_free (data->files_poked); + + if (data->application_to_use != NULL) + g_object_unref (data->application_to_use); + g_slice_free (ThunarLauncherPokeData, data); +} + + + +void thunar_launcher_open_selected_folders_in_new_tabs (ThunarLauncher *launcher) +{ + GList *lp; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - /* force update if still dirty */ - thunar_launcher_update_check (launcher, NULL); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (!gtk_action_get_sensitive (action)) - return; -G_GNUC_END_IGNORE_DEPRECATIONS + for (lp = launcher->selected_files; lp != NULL; lp = lp->next) + _thunar_return_if_fail (thunar_file_is_directory (THUNAR_FILE (lp->data))); - /* check if we have a mime handler associated with the action */ - app_info = g_object_get_qdata (G_OBJECT (action), thunar_launcher_handler_quark); - if (G_LIKELY (app_info != NULL)) - { - /* try to open the selected files using the given application */ - selected_paths = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); - thunar_launcher_open_paths (app_info, selected_paths, launcher); - thunar_g_file_list_free (selected_paths); - } - else if (launcher->selected_files != NULL) - { - if (launcher->selected_files->next == NULL) - { - thunar_browser_poke_file (THUNAR_BROWSER (launcher), - launcher->selected_files->data, launcher->widget, - thunar_launcher_poke_file_finish, NULL); - } - else - { - /* resolve files one after another until none is left. Open/execute - * the resolved files/directories when all this is done at a later - * stage */ - poke_data = thunar_launcher_poke_data_new (launcher->selected_files); - thunar_launcher_poke_files (launcher, poke_data); - } - } + thunar_launcher_poke_files (launcher, NULL, THUNAR_LAUNCHER_OPEN_AS_NEW_TAB); } static void -thunar_launcher_action_open_with_other (GtkAction *action, - ThunarLauncher *launcher) +thunar_launcher_widget_destroyed (ThunarLauncher *launcher, + GtkWidget *widget) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + _thunar_return_if_fail (launcher->widget == widget); + _thunar_return_if_fail (GTK_IS_WIDGET (widget)); - /* force update if still dirty */ - thunar_launcher_update_check (launcher, NULL); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (!gtk_action_get_visible (action)) - return; -G_GNUC_END_IGNORE_DEPRECATIONS + /* just reset the widget property for the launcher */ + thunar_launcher_set_widget (launcher, NULL); +} - /* verify that we have atleast one selected file */ - if (G_LIKELY (launcher->selected_files != NULL)) - { - /* popup the chooser dialog for the first selected file */ - thunar_show_chooser_dialog (launcher->widget, launcher->selected_files->data, TRUE); - } + + +/** + * thunar_launcher_open_selected_folders_in_new_windows: + * @launcher : a #ThunarLauncher instance + * + * Will open each selected folder in a new window + **/ +void thunar_launcher_open_selected_folders_in_new_windows (ThunarLauncher *launcher) +{ + GList *lp; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + for (lp = launcher->selected_files; lp != NULL; lp = lp->next) + _thunar_return_if_fail (thunar_file_is_directory (THUNAR_FILE (lp->data))); + + thunar_launcher_poke_files (launcher, NULL, THUNAR_LAUNCHER_OPEN_AS_NEW_WINDOW); } static void -thunar_launcher_action_open_in_new_window (GtkAction *action, - ThunarLauncher *launcher) +thunar_launcher_action_open (ThunarLauncher *launcher) { - ThunarLauncherPokeData *poke_data; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - /* force update if still dirty */ - thunar_launcher_update_check (launcher, NULL); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (!gtk_action_get_visible (action)) + if (G_UNLIKELY (launcher->selected_files == NULL)) return; -G_GNUC_END_IGNORE_DEPRECATIONS - /* open the selected directories in new windows */ - poke_data = thunar_launcher_poke_data_new (launcher->selected_files); - thunar_launcher_poke_files (launcher, poke_data); + thunar_launcher_activate_selected_files (launcher, THUNAR_LAUNCHER_CHANGE_DIRECTORY, NULL); } +/** + * thunar_launcher_action_open_in_new_tabs: + * @launcher : a #ThunarLauncher instance + * + * Will open each selected folder in a new tab + **/ static void -thunar_launcher_action_open_in_new_tab (GtkAction *action, - ThunarLauncher *launcher) +thunar_launcher_action_open_in_new_tabs (ThunarLauncher *launcher) { - ThunarLauncherPokeData *poke_data; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - /* force update if still dirty */ - thunar_launcher_update_check (launcher, NULL); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (!gtk_action_get_visible (action)) + if (G_UNLIKELY (launcher->selected_files == NULL)) return; -G_GNUC_END_IGNORE_DEPRECATIONS - /* open all selected directories in a new tab */ - poke_data = thunar_launcher_poke_data_new (launcher->selected_files); - poke_data->directories_in_tabs = TRUE; - thunar_launcher_poke_files (launcher, poke_data); + thunar_launcher_open_selected_folders_in_new_tabs (launcher); } static void -thunar_launcher_action_sendto_desktop (GtkAction *action, - ThunarLauncher *launcher) +thunar_launcher_action_open_in_new_windows (ThunarLauncher *launcher) { - ThunarApplication *application; - GFile *desktop_file; - GList *files; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - /* determine the source files */ - files = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); - if (G_UNLIKELY (files == NULL)) + if (G_UNLIKELY (launcher->selected_files == NULL)) return; - /* determine the file to the ~/Desktop folder */ - desktop_file = thunar_g_file_new_for_desktop (); + thunar_launcher_open_selected_folders_in_new_windows (launcher); +} - /* launch the link job */ - application = thunar_application_get (); - thunar_application_link_into (application, launcher->widget, files, desktop_file, NULL); - g_object_unref (G_OBJECT (application)); - /* cleanup */ - g_object_unref (desktop_file); - thunar_g_file_list_free (files); + +static void +thunar_launcher_action_open_with_other (ThunarLauncher *launcher) +{ + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->n_selected_files == 1) + thunar_show_chooser_dialog (launcher->widget, launcher->selected_files->data, TRUE); } -static ThunarLauncherMountData * -thunar_launcher_mount_data_new (ThunarLauncher *launcher, - GList *files) +/** + * thunar_launcher_append_accelerators: + * @launcher : a #ThunarLauncher. + * @accel_group : a #GtkAccelGroup to be used used for new menu items + * + * Connects all accelerators and corresponding default keys of this widget to the global accelerator list + **/ +void thunar_launcher_append_accelerators (ThunarLauncher *launcher, + GtkAccelGroup *accel_group) { - ThunarLauncherMountData *data; + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); + xfce_gtk_accel_map_add_entries (thunar_launcher_action_entries, G_N_ELEMENTS (thunar_launcher_action_entries)); + xfce_gtk_accel_group_connect_action_entries (accel_group, + thunar_launcher_action_entries, + G_N_ELEMENTS (thunar_launcher_action_entries), + launcher); +} - data = g_slice_new0 (ThunarLauncherMountData); - data->launcher = g_object_ref (launcher); - data->files = thunar_g_file_list_copy (files); - return data; + +static gboolean +thunar_launcher_show_trash (ThunarLauncher *launcher) +{ + /* If the folder is read only, always show trash insensitive */ + /* If we are outside waste basket, the selection is trashable and we support trash, show trash */ + return !thunar_file_is_writable (launcher->parent_folder) || ( !thunar_file_is_trashed (launcher->parent_folder) && launcher->selection_trashable && thunar_g_vfs_is_uri_scheme_supported ("trash")); } -static void -thunar_launcher_mount_data_free (ThunarLauncherMountData *data) +/** + * thunar_launcher_append_paste_item: + * @launcher : a #ThunarLauncher instance + * @menu : #GtkMenuShell on which the paste item should be appended + * @force : Append a 'paste' #GtkMenuItem, even if multiple folders are selected + * + * Will append a 'paste' #GtkMenuItem to the provided #GtkMenuShell + * + * Return value: (transfer full): The new #GtkMenuItem, or NULL + **/ +static GtkWidget* +thunar_launcher_append_paste_item (ThunarLauncher *launcher, + GtkMenuShell *menu, + gboolean force) { - _thunar_return_if_fail (data != NULL); - _thunar_return_if_fail (THUNAR_IS_LAUNCHER (data->launcher)); + GtkWidget *item = NULL; + ThunarClipboardManager *clipboard; + const XfceGtkActionEntry *action_entry = get_action_entry (THUNAR_LAUNCHER_ACTION_PASTE); + + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); + _thunar_return_val_if_fail (action_entry != NULL, NULL); + + if (!force && !launcher->single_folder_selected) + return NULL; - g_object_unref (data->launcher); - thunar_g_file_list_free (data->files); - g_slice_free (ThunarLauncherMountData, data); + /* grab a reference on the clipboard manager for this display */ + clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (launcher->widget)); + + /* Some single folder is selected, but its not the current directory */ + if (launcher->single_folder_selected && !launcher->current_directory_selected) + { + item = xfce_gtk_menu_item_new_from_action_entry (action_entry, G_OBJECT (launcher), GTK_MENU_SHELL (menu)); + gtk_widget_set_sensitive (item, thunar_clipboard_manager_get_can_paste (clipboard) && thunar_file_is_writable (launcher->single_folder)); + } + else + { + item = xfce_gtk_menu_item_new_from_action_entry (action_entry, G_OBJECT (launcher), GTK_MENU_SHELL (menu)); + gtk_widget_set_sensitive (item, thunar_clipboard_manager_get_can_paste (clipboard) && thunar_file_is_writable (launcher->current_directory)); + } + g_object_unref (clipboard); + return item; } -static ThunarLauncherPokeData * -thunar_launcher_poke_data_new (GList *files) +/** + * thunar_launcher_append_menu_item: + * @launcher : Instance of a #ThunarLauncher + * @menu : #GtkMenuShell to which the item should be added + * @action : #ThunarLauncherAction to select which item should be added + * @force : force to generate the item. If it cannot be used, it will be shown as insensitive + * + * Adds the selected, widget specific #GtkMenuItem to the passed #GtkMenuShell + * + * Return value: (transfer none): The added #GtkMenuItem + **/ +GtkWidget* +thunar_launcher_append_menu_item (ThunarLauncher *launcher, + GtkMenuShell *menu, + ThunarLauncherAction action, + gboolean force) { - ThunarLauncherPokeData *data; + GtkWidget *item = NULL; + GtkWidget *submenu; + gchar *label_text; + gchar *tooltip_text; + const XfceGtkActionEntry *action_entry = get_action_entry (action); + gboolean show_delete_item; + gboolean can_be_used; - data = g_slice_new0 (ThunarLauncherPokeData); - data->files = thunar_g_file_list_copy (files); - data->resolved_files = NULL; - data->directories_in_tabs = FALSE; + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); + _thunar_return_val_if_fail (action_entry != NULL, NULL); - return data; + /* This may occur when the thunar-window is build */ + if (G_UNLIKELY (launcher->selected_files == NULL)) + return NULL; + + switch (action) + { + case THUNAR_LAUNCHER_ACTION_OPEN: /* aka "activate" */ + return xfce_gtk_image_menu_item_new_from_icon_name (_("_Open"), ngettext ("Open the selected file", "Open the selected files", launcher->n_selected_files), + action_entry->accel_path, action_entry->callback, G_OBJECT (launcher), action_entry->menu_item_icon_name, menu); + + case THUNAR_LAUNCHER_ACTION_EXECUTE: + return xfce_gtk_image_menu_item_new_from_icon_name (_("_Execute"), ngettext ("Execute the selected file", "Execute the selected files", launcher->n_selected_files), + action_entry->accel_path, action_entry->callback, G_OBJECT (launcher), action_entry->menu_item_icon_name, menu); + + case THUNAR_LAUNCHER_ACTION_OPEN_IN_TAB: + label_text = g_strdup_printf (ngettext ("Open in %d New _Tab", "Open in %d New _Tabs", launcher->n_selected_files), launcher->n_selected_files); + tooltip_text = g_strdup_printf (ngettext ("Open the selected directory in %d new tab", + "Open the selected directories in %d new tabs", launcher->n_selected_files), launcher->n_selected_files); + item = xfce_gtk_menu_item_new (label_text, tooltip_text, action_entry->accel_path, action_entry->callback, G_OBJECT (launcher), menu); + g_free (tooltip_text); + g_free (label_text); + return item; + + case THUNAR_LAUNCHER_ACTION_OPEN_IN_WINDOW: + label_text = g_strdup_printf (ngettext ("Open in %d New _Window", "Open in %d New _Windows", launcher->n_selected_files), launcher->n_selected_files); + tooltip_text = g_strdup_printf (ngettext ("Open the selected directory in %d new window", + "Open the selected directories in %d new windows",launcher->n_selected_files), launcher->n_selected_files); + item = xfce_gtk_menu_item_new (label_text, tooltip_text, action_entry->accel_path, action_entry->callback, G_OBJECT (launcher), menu); + g_free (tooltip_text); + g_free (label_text); + return item; + + case THUNAR_LAUNCHER_ACTION_OPEN_WITH_OTHER: + return xfce_gtk_menu_item_new (action_entry->menu_item_label_text, action_entry->menu_item_tooltip_text, + action_entry->accel_path, action_entry->callback, G_OBJECT (launcher), menu); + + case THUNAR_LAUNCHER_ACTION_SENDTO_MENU: + can_be_used = launcher->current_directory_selected == FALSE; + if (!can_be_used && !force) + return NULL; + item = xfce_gtk_menu_item_new_from_action_entry (action_entry, G_OBJECT (launcher), GTK_MENU_SHELL (menu)); + submenu = thunar_launcher_build_sendto_submenu (launcher); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + return item; + + case THUNAR_LAUNCHER_ACTION_MAKE_LINK: + can_be_used = thunar_file_is_writable (launcher->current_directory) && + launcher->current_directory_selected == FALSE && + thunar_file_is_trashed (launcher->current_directory) == FALSE;; + if (!can_be_used && !force) + return NULL; + + label_text = ngettext ("Ma_ke Link", "Ma_ke Links", launcher->n_selected_files); + tooltip_text = ngettext ("Create a symbolic link for the selected file", + "Create a symbolic link for each selected file", launcher->n_selected_files); + item = xfce_gtk_menu_item_new (label_text, tooltip_text, action_entry->accel_path, action_entry->callback, + G_OBJECT (launcher), menu); + gtk_widget_set_sensitive (item, can_be_used); + return item; + + case THUNAR_LAUNCHER_ACTION_DUPLICATE: + can_be_used = thunar_file_is_writable (launcher->current_directory) && + launcher->current_directory_selected == FALSE && + thunar_file_is_trashed (launcher->current_directory) == FALSE; + if (!can_be_used && !force) + return NULL; + item = xfce_gtk_menu_item_new (action_entry->menu_item_label_text, action_entry->menu_item_tooltip_text, + action_entry->accel_path, action_entry->callback, G_OBJECT (launcher), menu); + gtk_widget_set_sensitive (item, can_be_used); + return item; + + case THUNAR_LAUNCHER_ACTION_RENAME: + can_be_used = thunar_file_is_writable (launcher->current_directory) && + launcher->current_directory_selected == FALSE && + thunar_file_is_trashed (launcher->current_directory) == FALSE; + if (!can_be_used && !force) + return NULL; + tooltip_text = ngettext ("Rename the selected file", + "Rename the selected files", launcher->n_selected_files); + item = xfce_gtk_menu_item_new (action_entry->menu_item_label_text, tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), menu); + gtk_widget_set_sensitive (item, can_be_used); + return item; + + case THUNAR_LAUNCHER_ACTION_RESTORE: + if (launcher->current_directory_selected == FALSE && thunar_file_is_trashed (launcher->current_directory)) + { + tooltip_text = ngettext ("Restore the selected file to its original location", + "Restore the selected files to its original location", launcher->n_selected_files); + item = xfce_gtk_menu_item_new (action_entry->menu_item_label_text, tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), menu); + gtk_widget_set_sensitive (item, thunar_file_is_writable (launcher->current_directory)); + return item; + } + return NULL; + + case THUNAR_LAUNCHER_ACTION_MOVE_TO_TRASH: + if (!thunar_launcher_show_trash (launcher)) + return NULL; + + can_be_used = launcher->parent_folder != NULL && + !launcher->current_directory_selected; + if (!can_be_used && !force) + return NULL; + + tooltip_text = ngettext ("Move the selected file to the Trash", + "Move the selected files to the Trash", launcher->n_selected_files); + item = xfce_gtk_image_menu_item_new_from_icon_name (action_entry->menu_item_label_text, tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), action_entry->menu_item_icon_name, menu); + gtk_widget_set_sensitive (item, can_be_used); + return item; + + + case THUNAR_LAUNCHER_ACTION_DELETE: + g_object_get (G_OBJECT (launcher->preferences), "misc-show-delete-action", &show_delete_item, NULL); + if (thunar_launcher_show_trash (launcher) && !show_delete_item) + return NULL; + + can_be_used = launcher->parent_folder != NULL && + !launcher->current_directory_selected; + if (!can_be_used && !force) + return NULL; + + tooltip_text = ngettext ("Permanently delete the selected file", + "Permanently delete the selected files", launcher->n_selected_files); + item = xfce_gtk_image_menu_item_new_from_icon_name (action_entry->menu_item_label_text, tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), action_entry->menu_item_icon_name, menu); + gtk_widget_set_sensitive (item, can_be_used); + return item; + + case THUNAR_LAUNCHER_ACTION_EMPTY_TRASH: + if (launcher->single_folder_selected == TRUE) + { + if (thunar_file_is_root (launcher->single_folder) && thunar_file_is_trashed (launcher->single_folder)) + { + item = xfce_gtk_image_menu_item_new_from_icon_name (action_entry->menu_item_label_text, action_entry->menu_item_tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), action_entry->menu_item_icon_name, menu); + gtk_widget_set_sensitive (item, thunar_file_get_item_count (launcher->single_folder) > 0); + } + } + return NULL; + + case THUNAR_LAUNCHER_ACTION_CREATE_FOLDER: + if (thunar_file_is_trashed (launcher->current_directory)) + return NULL; + return xfce_gtk_menu_item_new_from_action_entry (action_entry, G_OBJECT (launcher), GTK_MENU_SHELL (menu)); + + case THUNAR_LAUNCHER_ACTION_CREATE_DOCUMENT: + if (thunar_file_is_trashed (launcher->current_directory)) + return NULL; + item = xfce_gtk_menu_item_new_from_action_entry (action_entry, G_OBJECT (launcher), GTK_MENU_SHELL (menu)); + submenu = thunar_launcher_create_document_submenu_new (launcher); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + return item; + + case THUNAR_LAUNCHER_ACTION_CUT: + can_be_used = launcher->current_directory_selected == FALSE && + launcher->parent_folder != NULL; + if (!can_be_used && !force) + return NULL; + tooltip_text = ngettext ("Prepare the selected file to be moved with a Paste command", + "Prepare the selected files to be moved with a Paste command", launcher->n_selected_files); + item = xfce_gtk_image_menu_item_new_from_icon_name (action_entry->menu_item_label_text, tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), action_entry->menu_item_icon_name, menu); + gtk_widget_set_sensitive (item, can_be_used); + return item; + + case THUNAR_LAUNCHER_ACTION_COPY: + can_be_used = launcher->current_directory_selected == FALSE; + if (!can_be_used && !force) + return NULL; + tooltip_text = ngettext ("Prepare the selected file to be copied with a Paste command", + "Prepare the selected files to be copied with a Paste command", launcher->n_selected_files); + item = xfce_gtk_image_menu_item_new_from_icon_name (action_entry->menu_item_label_text, tooltip_text, action_entry->accel_path, + action_entry->callback, G_OBJECT (launcher), action_entry->menu_item_icon_name, menu); + gtk_widget_set_sensitive (item, can_be_used); + return item; + + case THUNAR_LAUNCHER_ACTION_PASTE: + return thunar_launcher_append_paste_item (launcher, menu, FALSE); + + default: + return xfce_gtk_menu_item_new_from_action_entry (action_entry, G_OBJECT (launcher), GTK_MENU_SHELL (menu)); + } + return NULL; } + static void -thunar_launcher_poke_data_free (ThunarLauncherPokeData *data) +thunar_launcher_action_sendto_desktop (ThunarLauncher *launcher) { - _thunar_return_if_fail (data != NULL); + ThunarApplication *application; + GFile *desktop_file; + GList *files; - thunar_g_file_list_free (data->files); - thunar_g_file_list_free (data->resolved_files); - g_slice_free (ThunarLauncherPokeData, data); + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + /* determine the source paths */ + files = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); + if (G_UNLIKELY (files == NULL)) + return; + + /* determine the file to the ~/Desktop folder */ + desktop_file = thunar_g_file_new_for_desktop (); + + /* launch the link job */ + application = thunar_application_get (); + thunar_application_link_into (application, launcher->widget, files, desktop_file, NULL); + g_object_unref (G_OBJECT (application)); + + /* cleanup */ + g_object_unref (desktop_file); + thunar_g_file_list_free (files); } static void thunar_launcher_sendto_device (ThunarLauncher *launcher, - ThunarDevice *device, - GList *files) + ThunarDevice *device) { ThunarApplication *application; GFile *mount_point; + GList *files; _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); _thunar_return_if_fail (THUNAR_IS_DEVICE (device)); @@ -1575,6 +1493,11 @@ thunar_launcher_sendto_device (ThunarLauncher *launcher, if (!thunar_device_is_mounted (device)) return; + /* determine the source paths */ + files = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); + if (G_UNLIKELY (files == NULL)) + return; + mount_point = thunar_device_get_root (device); if (mount_point != NULL) { @@ -1582,9 +1505,11 @@ thunar_launcher_sendto_device (ThunarLauncher *launcher, application = thunar_application_get (); thunar_application_copy_into (application, launcher->widget, files, mount_point, NULL); g_object_unref (application); - g_object_unref (mount_point); } + + /* cleanup */ + thunar_g_file_list_free (files); } @@ -1594,61 +1519,46 @@ thunar_launcher_sendto_mount_finish (ThunarDevice *device, const GError *error, gpointer user_data) { - ThunarLauncherMountData *data = user_data; - gchar *device_name; + ThunarLauncher *launcher = user_data; + gchar *device_name; _thunar_return_if_fail (THUNAR_IS_DEVICE (device)); _thunar_return_if_fail (user_data != NULL); - _thunar_return_if_fail (THUNAR_IS_LAUNCHER (data->launcher)); + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (user_data)); if (error != NULL) { /* tell the user that we were unable to mount the device, which is * required to send files to it */ device_name = thunar_device_get_name (device); - thunar_dialogs_show_error (data->launcher->widget, error, _("Failed to mount \"%s\""), device_name); + thunar_dialogs_show_error (launcher->widget, error, _("Failed to mount \"%s\""), device_name); g_free (device_name); } else { - thunar_launcher_sendto_device (data->launcher, device, data->files); + thunar_launcher_sendto_device (launcher, device); } - - thunar_launcher_mount_data_free (data); } static void -thunar_launcher_action_sendto_device (GtkAction *action, - ThunarLauncher *launcher) +thunar_launcher_action_sendto_device (ThunarLauncher *launcher, + GObject *object) { - ThunarLauncherMountData *data; - GMountOperation *mount_operation; - ThunarDevice *device; - GList *files; + GMountOperation *mount_operation; + ThunarDevice *device; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - /* determine the source paths */ - files = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); - if (G_UNLIKELY (files == NULL)) - return; - /* determine the device to which to send */ - device = g_object_get_qdata (G_OBJECT (action), thunar_launcher_handler_quark); + device = g_object_get_qdata (G_OBJECT (object), thunar_launcher_device_quark); if (G_UNLIKELY (device == NULL)) return; /* make sure to mount the device first, if it's not already mounted */ if (!thunar_device_is_mounted (device)) { - /* allocate mount data */ - data = thunar_launcher_mount_data_new (launcher, files); - /* allocate a GTK+ mount operation */ mount_operation = thunar_gtk_mount_operation_new (launcher->widget); @@ -1657,280 +1567,1054 @@ G_GNUC_END_IGNORE_DEPRECATIONS mount_operation, NULL, thunar_launcher_sendto_mount_finish, - data); + launcher); g_object_unref (mount_operation); } else { - thunar_launcher_sendto_device (launcher, device, files); + thunar_launcher_sendto_device (launcher, device); } - - /* cleanup */ - thunar_g_file_list_free (files); } - static void -thunar_launcher_widget_destroyed (ThunarLauncher *launcher, - GtkWidget *widget) +thunar_launcher_action_add_shortcuts (ThunarLauncher *launcher) { + GList *lp; + GtkWidget *window; + const GtkWidget *sidepane; + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - _thunar_return_if_fail (launcher->widget == widget); - _thunar_return_if_fail (GTK_IS_WIDGET (widget)); - /* just reset the widget property for the launcher */ - thunar_launcher_set_widget (launcher, NULL); + /* determine the toplevel window we belong to */ + window = gtk_widget_get_toplevel (launcher->widget); + if (THUNAR_IS_WINDOW (window) == FALSE) + return; + if (thunar_window_has_shortcut_sidepane (THUNAR_WINDOW (window)) == FALSE) + return; + + sidepane = thunar_window_get_sidepane (THUNAR_WINDOW (window)); + if (sidepane != NULL && THUNAR_IS_SHORTCUTS_PANE (sidepane)) + { + for (lp = launcher->selected_files; lp != NULL; lp = lp->next) + thunar_shortcuts_pane_add_shortcut (THUNAR_SHORTCUTS_PANE (sidepane), lp->data); + } + } -static gboolean -thunar_launcher_sendto_idle (gpointer user_data) -{ - ThunarLauncher *launcher = THUNAR_LAUNCHER (user_data); - const gchar *label; - GtkAction *action; - gboolean linkable = TRUE; - GIcon *icon; - GList *handlers; - GList *devices; - GList *lp; - gchar *name; - gchar *tooltip; - gchar *device_name; - gint n_selected_files; - gint n = 0; - gboolean got_devices = FALSE; - const gchar *file_menu_path; - const gchar *context_menu_path; - - /* verify that we have an UI manager */ - if (launcher->ui_manager == NULL) - return FALSE; +static GtkWidget* +thunar_launcher_build_sendto_submenu (ThunarLauncher *launcher) +{ + GList *lp; + gboolean linkable = TRUE; + gchar *label_text; + gchar *tooltip_text; + GtkWidget *image; + GtkWidget *item; + GtkWidget *submenu; + GtkWidget *window; + GList *devices; + GList *appinfo_list; + GIcon *icon; + ThunarDeviceMonitor *device_monitor; + ThunarSendtoModel *sendto_model; + const XfceGtkActionEntry *action_entry; + + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); -THUNAR_THREADS_ENTER + submenu = gtk_menu_new(); - /* determine the number of selected files and check whether atleast one of these - * files is located in the trash (to en-/disable the "sendto-desktop" action). - */ - for (lp = launcher->selected_files, n_selected_files = 0; lp != NULL; lp = lp->next, ++n_selected_files) + /* show "sent to shortcut" if only directories are selected */ + if (launcher->n_selected_directories > 0 && launcher->n_selected_directories == launcher->n_selected_files) { - /* check if this file is in trash */ - if (G_UNLIKELY (linkable)) - linkable = !thunar_file_is_trashed (lp->data); + /* determine the toplevel window we belong to */ + window = gtk_widget_get_toplevel (launcher->widget); + if (THUNAR_IS_WINDOW (window) && thunar_window_has_shortcut_sidepane (THUNAR_WINDOW (window))) + { + action_entry = get_action_entry (THUNAR_LAUNCHER_ACTION_SENDTO_SHORTCUTS); + if (action_entry != NULL) + { + label_text = ngettext ("Side Pane (Create Shortcut)", "Side Pane (Create Shortcuts)", launcher->n_selected_files); + tooltip_text = ngettext ("Add the selected folder to the shortcuts side pane", + "Add the selected folders to the shortcuts side pane", launcher->n_selected_files); + item = xfce_gtk_image_menu_item_new_from_icon_name (label_text, tooltip_text, action_entry->accel_path, action_entry->callback, + G_OBJECT (launcher), action_entry->menu_item_icon_name, GTK_MENU_SHELL (submenu)); + } + } } -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the "Desktop (Create Link)" sendto action */ - action = gtk_action_group_get_action (launcher->action_group, "sendto-desktop"); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_set (G_OBJECT (action), - "label", ngettext ("Desktop (Create Link)", "Desktop (Create Links)", n_selected_files), - "tooltip", ngettext ("Create a link to the selected file on the desktop", - "Create links to the selected files on the desktop", - n_selected_files), - "visible", (linkable && n_selected_files > 0), - NULL); - - /* re-add the content to "Send To" if we have any files */ - if (G_LIKELY (n_selected_files > 0)) + /* Check whether at least one files is located in the trash (to en-/disable the "sendto-desktop" action). */ + for (lp = launcher->selected_files; lp != NULL; lp = lp->next) + { + if (G_UNLIKELY (thunar_file_is_trashed (lp->data))) + linkable = FALSE; + } + if (linkable) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* drop all previous sendto actions from the action group */ - handlers = gtk_action_group_list_actions (launcher->action_group); - for (lp = handlers; lp != NULL; lp = lp->next) - if (strncmp (gtk_action_get_name (lp->data), "thunar-launcher-sendto", 22) == 0) - gtk_action_group_remove_action (launcher->action_group, lp->data); - g_list_free (handlers); - - /* allocate a new merge id from the UI manager (if not already done) */ - if (G_UNLIKELY (launcher->ui_addons_merge_id == 0)) - launcher->ui_addons_merge_id = gtk_ui_manager_new_merge_id (launcher->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* determine the currently active devices */ - devices = thunar_device_monitor_get_devices (launcher->device_monitor); - got_devices = (devices != NULL); - - /* paths in ui */ - file_menu_path = "/main-menu/file-menu/sendto-menu/placeholder-sendto-actions"; - context_menu_path = "/file-context-menu/sendto-menu/placeholder-sendto-actions"; - - /* add removable (and writable) drives and media */ - for (lp = devices; lp != NULL; lp = lp->next, ++n) + action_entry = get_action_entry (THUNAR_LAUNCHER_ACTION_SENDTO_DESKTOP); + if (action_entry != NULL) { - /* generate a unique name and tooltip for the device */ - device_name = thunar_device_get_name (lp->data); - name = g_strdup_printf ("thunar-launcher-sendto%d-%p", n, launcher); - tooltip = g_strdup_printf (ngettext ("Send the selected file to \"%s\"", - "Send the selected files to \"%s\"", - n_selected_files), device_name); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* allocate a new action for the device */ - action = gtk_action_new (name, device_name, tooltip, NULL); - g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref); - g_object_set_data (G_OBJECT (lp->data), "skip-app-info-update", GUINT_TO_POINTER (1)); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_sendto_device), launcher); - gtk_action_group_add_action (launcher->action_group, action); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - file_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - context_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - g_object_unref (action); - - icon = thunar_device_get_icon (lp->data); + label_text = ngettext ("Desktop (Create Link)", "Desktop (Create Links)", launcher->n_selected_files); + tooltip_text = ngettext ("Create a link to the selected file on the desktop", + "Create links to the selected files on the desktop", launcher->n_selected_files); + item = xfce_gtk_image_menu_item_new_from_icon_name (label_text, tooltip_text, action_entry->accel_path, action_entry->callback, + G_OBJECT (launcher), action_entry->menu_item_icon_name, GTK_MENU_SHELL (submenu)); + } + } + + item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); + gtk_widget_show (item); + + /* determine the currently active devices */ + device_monitor = thunar_device_monitor_get (); + devices = thunar_device_monitor_get_devices (device_monitor); + g_object_unref (device_monitor); + + /* add removable (and writable) drives and media */ + for (lp = devices; lp != NULL; lp = lp->next) + { + /* generate a unique name and tooltip for the device */ + label_text = thunar_device_get_name (lp->data); + tooltip_text = g_strdup_printf (ngettext ("Send the selected file to \"%s\"", + "Send the selected files to \"%s\"", launcher->n_selected_files), label_text); + icon = thunar_device_get_icon (lp->data); + image = NULL; + if (G_LIKELY (icon != NULL)) + { + image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU); + g_object_unref (icon); + } + item = xfce_gtk_image_menu_item_new (label_text, tooltip_text, NULL, G_CALLBACK (thunar_launcher_action_sendto_device), + G_OBJECT (launcher), image, GTK_MENU_SHELL (submenu)); + g_object_set_qdata_full (G_OBJECT (item), thunar_launcher_device_quark, lp->data, g_object_unref); + g_object_set_data (G_OBJECT (lp->data), "skip-app-info-update", GUINT_TO_POINTER (1)); + + /* cleanup */ + g_free (tooltip_text); + g_free (label_text); + } + + /* free the devices list */ + g_list_free (devices); + + item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); + gtk_widget_show (item); + + /* determine the sendto appInfos for the selected files */ + sendto_model = thunar_sendto_model_get_default (); + appinfo_list = thunar_sendto_model_get_matching (sendto_model, launcher->selected_files); + g_object_unref (sendto_model); + + if (G_LIKELY (appinfo_list != NULL)) + { + /* add all handlers to the user interface */ + for (lp = appinfo_list; lp != NULL; lp = lp->next) + { + /* generate a unique name and tooltip for the handler */ + label_text = (gchar*)g_app_info_get_name (lp->data); + tooltip_text = g_strdup_printf (ngettext ("Send the selected file to \"%s\"", + "Send the selected files to \"%s\"", launcher->n_selected_files), label_text); + + icon = g_app_info_get_icon (lp->data); + image = NULL; if (G_LIKELY (icon != NULL)) { - gtk_action_set_gicon (action, icon); + image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU); g_object_unref (icon); } -G_GNUC_END_IGNORE_DEPRECATIONS + item = xfce_gtk_image_menu_item_new (label_text, tooltip_text, NULL, G_CALLBACK (thunar_launcher_menu_item_activated), + G_OBJECT (launcher), image, GTK_MENU_SHELL (submenu)); + g_object_set_qdata_full (G_OBJECT (item), thunar_launcher_appinfo_quark, lp->data, g_object_unref); /* cleanup */ - g_free (name); - g_free (tooltip); - g_free (device_name); + g_free (tooltip_text); } - /* free the devices list */ - g_list_free (devices); + /* release the appinfo list */ + g_list_free (appinfo_list); + } - /* determine the sendto handlers for the selected files */ - handlers = thunar_sendto_model_get_matching (launcher->sendto_model, launcher->selected_files); - if (G_LIKELY (handlers != NULL)) - { - if (got_devices) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* add separator between the devices and actions action */ - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - file_menu_path, "separator", NULL, - GTK_UI_MANAGER_SEPARATOR, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - context_menu_path, "separator", NULL, - GTK_UI_MANAGER_SEPARATOR, FALSE); -G_GNUC_END_IGNORE_DEPRECATIONS - } + return submenu; +} - /* add all handlers to the user interface */ - for (lp = handlers; lp != NULL; lp = lp->next, ++n) - { - /* generate a unique name and tooltip for the handler */ - label = g_app_info_get_name (lp->data); - name = g_strdup_printf ("thunar-launcher-sendto%d-%p", n, launcher); - tooltip = g_strdup_printf (ngettext ("Send the selected file to \"%s\"", - "Send the selected files to \"%s\"", - n_selected_files), label); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* allocate a new action for the handler */ - action = gtk_action_new (name, label, tooltip, NULL); - gtk_action_set_gicon (action, g_app_info_get_icon (lp->data)); - g_object_set_qdata_full (G_OBJECT (action), thunar_launcher_handler_quark, lp->data, g_object_unref); - g_object_set_data (G_OBJECT (lp->data), "skip-app-info-update", GUINT_TO_POINTER (1)); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_launcher_action_open), launcher); - gtk_action_group_add_action (launcher->action_group, action); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - file_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - gtk_ui_manager_add_ui (launcher->ui_manager, launcher->ui_addons_merge_id, - context_menu_path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE); - g_object_unref (G_OBJECT (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* cleanup */ - g_free (tooltip); - g_free (name); - } - /* release the handler list */ - g_list_free (handlers); + +static void +thunar_launcher_action_properties (ThunarLauncher *launcher) +{ + GtkWidget *toplevel; + GtkWidget *dialog; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + /* popup the files dialog */ + toplevel = gtk_widget_get_toplevel (launcher->widget); + if (G_LIKELY (toplevel != NULL)) + { + dialog = thunar_properties_dialog_new (GTK_WINDOW (toplevel)); + + /* check if no files are currently selected */ + if (launcher->selected_files == NULL) + { + /* if we don't have any files selected, we just popup the properties dialog for the current folder. */ + thunar_properties_dialog_set_file (THUNAR_PROPERTIES_DIALOG (dialog), launcher->current_directory); } + else + { + /* popup the properties dialog for all file(s) */ + thunar_properties_dialog_set_files (THUNAR_PROPERTIES_DIALOG (dialog), launcher->selected_files); + } + gtk_widget_show (dialog); } +} -THUNAR_THREADS_LEAVE - return FALSE; + +static void +thunar_launcher_action_make_link (ThunarLauncher *launcher) +{ + ThunarApplication *application; + GList *g_files = NULL; + GList *lp; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (G_UNLIKELY (launcher->current_directory == NULL)) + return; + if (launcher->current_directory_selected == TRUE || thunar_file_is_trashed (launcher->current_directory)) + return; + + for (lp = launcher->selected_files; lp != NULL; lp = lp->next) + { + g_files = g_list_append (g_files, thunar_file_get_file (lp->data)); + } + /* link the selected files into the current directory, which effectively + * creates new unique links for the files. + */ + application = thunar_application_get (); + thunar_application_link_into (application, launcher->widget, g_files, + thunar_file_get_file (launcher->current_directory), launcher->select_files_closure); + g_object_unref (G_OBJECT (application)); + g_list_free (g_files); } static void -thunar_launcher_sendto_idle_destroy (gpointer user_data) +thunar_launcher_action_duplicate (ThunarLauncher *launcher) { - THUNAR_LAUNCHER (user_data)->sendto_idle_id = 0; + ThunarApplication *application; + GList *selected_files; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (G_UNLIKELY (launcher->current_directory == NULL)) + return; + if (launcher->current_directory_selected == TRUE || thunar_file_is_trashed (launcher->current_directory)) + return; + + /* determine the selected files for the view */ + selected_files = thunar_file_list_to_thunar_g_file_list (launcher->selected_files); + if (G_LIKELY (selected_files != NULL)) + { + /* copy the selected files into the current directory, which effectively + * creates duplicates of the files. + */ + application = thunar_application_get (); + thunar_application_copy_into (application, launcher->widget, selected_files, + thunar_file_get_file (launcher->current_directory), launcher->select_files_closure); + g_object_unref (G_OBJECT (application)); + + /* clean up */ + thunar_g_file_list_free (selected_files); + } } /** - * thunar_launcher_new: + * thunar_launcher_append_custom_actions: + * @launcher : a #ThunarLauncher instance + * @menu : #GtkMenuShell on which the custom actions should be appended * - * Allocates a new #ThunarLauncher instance. + * Will append all custom actions which match the file-type to the provided #GtkMenuShell * - * Return value: the newly allocated #ThunarLauncher. + * Return value: TRUE if any custom action was added **/ -ThunarLauncher* -thunar_launcher_new (void) +gboolean +thunar_launcher_append_custom_actions (ThunarLauncher *launcher, + GtkMenuShell *menu) +{ + gboolean uca_added = FALSE; + GtkWidget *window; + GtkWidget *gtk_menu_item; + ThunarxProviderFactory *provider_factory; + GList *providers; + GList *thunarx_menu_items = NULL; + GList *lp_provider; + GList *lp_item; + + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU (menu), FALSE); + + /* determine the toplevel window we belong to */ + window = gtk_widget_get_toplevel (launcher->widget); + + /* load the menu providers from the provider factory */ + provider_factory = thunarx_provider_factory_get_default (); + providers = thunarx_provider_factory_list_providers (provider_factory, THUNARX_TYPE_MENU_PROVIDER); + g_object_unref (provider_factory); + + if (G_UNLIKELY (providers == NULL)) + return FALSE; + + /* This may occur when the thunar-window is build */ + if (G_UNLIKELY (launcher->selected_files == NULL)) + return FALSE; + + /* load the menu items offered by the menu providers */ + for (lp_provider = providers; lp_provider != NULL; lp_provider = lp_provider->next) + { + if (launcher->single_folder_selected) + thunarx_menu_items = thunarx_menu_provider_get_folder_menu_items (lp_provider->data, window, THUNARX_FILE_INFO (launcher->single_folder)); + else + thunarx_menu_items = thunarx_menu_provider_get_file_menu_items (lp_provider->data, window, launcher->selected_files); + for (lp_item = thunarx_menu_items; lp_item != NULL; lp_item = lp_item->next) + { + gtk_menu_item = thunar_gtk_menu_thunarx_menu_item_new (lp_item->data, menu); + + /* Each thunarx_menu_item will be destroyed together with its related gtk_menu_item*/ + g_signal_connect_swapped (G_OBJECT (gtk_menu_item), "destroy", G_CALLBACK (g_object_unref), lp_item->data); + uca_added = TRUE; + } + g_list_free (thunarx_menu_items); + } + g_list_free_full (providers, g_object_unref); + return uca_added; +} + + + +gboolean +thunar_launcher_check_uca_key_activation (ThunarLauncher *launcher, + GdkEventKey *key_event) +{ + GtkWidget *window; + ThunarxProviderFactory *provider_factory; + GList *providers; + GList *thunarx_menu_items = NULL; + GList *lp_provider; + GList *lp_item; + GtkAccelKey uca_key; + gchar *name, *accel_path; + gboolean uca_activated = FALSE; + + /* determine the toplevel window we belong to */ + window = gtk_widget_get_toplevel (launcher->widget); + + /* load the menu providers from the provider factory */ + provider_factory = thunarx_provider_factory_get_default (); + providers = thunarx_provider_factory_list_providers (provider_factory, THUNARX_TYPE_MENU_PROVIDER); + g_object_unref (provider_factory); + + if (G_UNLIKELY (providers == NULL)) + return uca_activated; + + /* load the menu items offered by the menu providers */ + for (lp_provider = providers; lp_provider != NULL; lp_provider = lp_provider->next) + { + if (launcher->single_folder_selected) + thunarx_menu_items = thunarx_menu_provider_get_folder_menu_items (lp_provider->data, window, THUNARX_FILE_INFO (launcher->single_folder)); + else + thunarx_menu_items = thunarx_menu_provider_get_file_menu_items (lp_provider->data, window, launcher->selected_files); + for (lp_item = thunarx_menu_items; lp_item != NULL; lp_item = lp_item->next) + { + g_object_get (G_OBJECT (lp_item->data), "name", &name, NULL); + accel_path = g_strconcat ("<Actions>/ThunarActions/", name, NULL); + if (gtk_accel_map_lookup_entry (accel_path, &uca_key) == TRUE) + { + if (key_event->keyval == uca_key.accel_key) + { + if ((key_event->state & gtk_accelerator_get_default_mod_mask ()) == uca_key.accel_mods) + { + thunarx_menu_item_activate (lp_item->data); + uca_activated = TRUE; + } + } + } + g_free (name); + g_free (accel_path); + g_object_unref (lp_item->data); + } + g_list_free (thunarx_menu_items); + } + g_list_free_full (providers, g_object_unref); + return uca_activated; +} + + + +static void +thunar_launcher_rename_error (ExoJob *job, + GError *error, + GtkWidget *widget) +{ + GArray *param_values; + ThunarFile *file; + + _thunar_return_if_fail (EXO_IS_JOB (job)); + _thunar_return_if_fail (error != NULL); + + param_values = thunar_simple_job_get_param_values (THUNAR_SIMPLE_JOB (job)); + file = g_value_get_object (&g_array_index (param_values, GValue, 0)); + + thunar_dialogs_show_error (GTK_WIDGET (widget), error, + _("Failed to rename \"%s\""), + thunar_file_get_display_name (file)); + g_object_unref (file); +} + + + +static void +thunar_launcher_rename_finished (ExoJob *job, + GtkWidget *widget) +{ + _thunar_return_if_fail (EXO_IS_JOB (job)); + + /* destroy the job */ + g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, widget); + g_object_unref (job); +} + + + +static void +thunar_launcher_action_rename (ThunarLauncher *launcher) +{ + ThunarJob *job; + GtkWidget *window; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->selected_files == NULL || g_list_length (launcher->selected_files) == 0) + return; + if (launcher->current_directory_selected == TRUE || thunar_file_is_trashed (launcher->current_directory)) + return; + + /* get the window */ + window = gtk_widget_get_toplevel (launcher->widget); + + /* start renaming if we have exactly one selected file */ + if (g_list_length (launcher->selected_files) == 1) + { + /* run the rename dialog */ + job = thunar_dialogs_show_rename_file (GTK_WINDOW (window), THUNAR_FILE (launcher->selected_files->data)); + if (G_LIKELY (job != NULL)) + { + g_signal_connect (job, "error", G_CALLBACK (thunar_launcher_rename_error), launcher->widget); + g_signal_connect (job, "finished", G_CALLBACK (thunar_launcher_rename_finished), launcher->widget); + } + } + else + { + /* display the bulk rename dialog */ + thunar_show_renamer_dialog (GTK_WIDGET (window), launcher->current_directory, launcher->selected_files, FALSE, NULL); + } +} + + + +static void +thunar_launcher_action_restore (ThunarLauncher *launcher) +{ + ThunarApplication *application; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->current_directory_selected == TRUE || !thunar_file_is_trashed (launcher->current_directory)) + return; + + /* restore the selected files */ + application = thunar_application_get (); + thunar_application_restore_files (application, launcher->widget, launcher->selected_files, NULL); + g_object_unref (G_OBJECT (application)); +} + + +static void +thunar_launcher_action_move_to_trash (ThunarLauncher *launcher) +{ + ThunarApplication *application; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->parent_folder == NULL || launcher->current_directory_selected) + return; + + application = thunar_application_get (); + thunar_application_unlink_files (application, launcher->widget, launcher->selected_files, FALSE); + g_object_unref (G_OBJECT (application)); +} + + + +static void +thunar_launcher_action_delete (ThunarLauncher *launcher) +{ + ThunarApplication *application; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->parent_folder == NULL || launcher->current_directory_selected) + return; + + application = thunar_application_get (); + thunar_application_unlink_files (application, launcher->widget, launcher->selected_files, TRUE); + g_object_unref (G_OBJECT (application)); +} + + + +static void +thunar_launcher_action_trash_delete (ThunarLauncher *launcher) +{ + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (thunar_g_vfs_is_uri_scheme_supported ("trash")) + thunar_launcher_action_move_to_trash (launcher); + else + thunar_launcher_action_delete (launcher); +} + + + +static void +thunar_launcher_action_empty_trash (ThunarLauncher *launcher) +{ + ThunarApplication *application; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->single_folder_selected == FALSE) + return; + if (!thunar_file_is_root (launcher->single_folder) || !thunar_file_is_trashed (launcher->single_folder)) + return; + + application = thunar_application_get (); + thunar_application_empty_trash (application, launcher->widget, NULL); + g_object_unref (G_OBJECT (application)); +} + + + +static void +thunar_launcher_action_create_folder (ThunarLauncher *launcher) { - return g_object_new (THUNAR_TYPE_LAUNCHER, NULL); + ThunarApplication *application; + GList path_list; + gchar *name; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + _thunar_return_if_fail (launcher->single_folder_selected); + _thunar_return_if_fail (launcher->single_folder != NULL); + + if (thunar_file_is_trashed (launcher->single_folder)) + return; + + /* ask the user to enter a name for the new folder */ + name = thunar_show_create_dialog (launcher->widget, + "inode/directory", + _("New Folder"), + _("Create New Folder")); + if (G_LIKELY (name != NULL)) + { + /* fake the path list */ + path_list.data = g_file_resolve_relative_path (thunar_file_get_file (launcher->current_directory), name); + path_list.next = path_list.prev = NULL; + + /* launch the operation */ + application = thunar_application_get (); + thunar_application_mkdir (application, launcher->widget, &path_list, launcher->select_files_closure); + g_object_unref (G_OBJECT (application)); + + /* release the path */ + g_object_unref (path_list.data); + + /* release the file name */ + g_free (name); + } +} + + + +static void +thunar_launcher_action_create_document (ThunarLauncher *launcher, + GtkWidget *menu_item) +{ + ThunarApplication *application; + GList target_path_list; + gchar *name; + gchar *title; + ThunarFile *template_file; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + _thunar_return_if_fail (launcher->single_folder_selected); + _thunar_return_if_fail (launcher->single_folder != NULL); + + if (thunar_file_is_trashed (launcher->single_folder)) + return; + + template_file = g_object_get_qdata (G_OBJECT (menu_item), thunar_launcher_file_quark); + + if (template_file != NULL) + { + /* generate a title for the create dialog */ + title = g_strdup_printf (_("Create Document from template \"%s\""), + thunar_file_get_display_name (template_file)); + + /* ask the user to enter a name for the new document */ + name = thunar_show_create_dialog (launcher->widget, + thunar_file_get_content_type (THUNAR_FILE (template_file)), + thunar_file_get_display_name (template_file), + title); + /* cleanup */ + g_free (title); + } + else + { + /* ask the user to enter a name for the new empty file */ + name = thunar_show_create_dialog (launcher->widget, + "text/plain", + _("New Empty File"), + _("New Empty File...")); + } + + if (G_LIKELY (name != NULL)) + { + if (G_LIKELY (launcher->parent_folder != NULL)) + { + /* fake the target path list */ + target_path_list.data = g_file_get_child (thunar_file_get_file (launcher->current_directory), name); + target_path_list.next = NULL; + target_path_list.prev = NULL; + + /* launch the operation */ + application = thunar_application_get (); + thunar_application_creat (application, launcher->widget, &target_path_list, + template_file != NULL ? thunar_file_get_file (template_file) : NULL, + launcher->select_files_closure); + g_object_unref (G_OBJECT (application)); + + /* release the target path */ + g_object_unref (target_path_list.data); + } + + /* release the file name */ + g_free (name); + } +} + + + +/* helper method in order to find the parent menu for a menu item */ +static GtkWidget * +thunar_launcher_create_document_submenu_templates_find_parent_menu (ThunarFile *file, + GList *dirs, + GList *items) +{ + GtkWidget *parent_menu = NULL; + GFile *parent; + GList *lp; + GList *ip; + + /* determine the parent of the file */ + parent = g_file_get_parent (thunar_file_get_file (file)); + + /* check if the file has a parent at all */ + if (parent == NULL) + return NULL; + + /* iterate over all dirs and menu items */ + for (lp = g_list_first (dirs), ip = g_list_first (items); + parent_menu == NULL && lp != NULL && ip != NULL; + lp = lp->next, ip = ip->next) + { + /* check if the current dir/item is the parent of our file */ + if (g_file_equal (parent, thunar_file_get_file (lp->data))) + { + /* we want to insert an item for the file in this menu */ + parent_menu = gtk_menu_item_get_submenu (ip->data); + } + } + + /* destroy the parent GFile */ + g_object_unref (parent); + + return parent_menu; +} + + + +/* recursive helper method in order to create menu items for all available templates */ +static gboolean +thunar_launcher_create_document_submenu_templates (ThunarLauncher *launcher, + GtkWidget *create_file_submenu, + GList *files) +{ + ThunarIconFactory *icon_factory; + ThunarFile *file; + GdkPixbuf *icon; + GtkWidget *parent_menu; + GtkWidget *submenu; + GtkWidget *image; + GtkWidget *item; + GList *lp; + GList *dirs = NULL; + GList *items = NULL; + + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), FALSE); + + /* do nothing if there is no menu */ + if (create_file_submenu == NULL) + return FALSE; + + /* get the icon factory */ + icon_factory = thunar_icon_factory_get_default (); + + /* sort items so that directories come before files and ancestors come + * before descendants */ + files = g_list_sort (files, (GCompareFunc) (void (*)(void)) thunar_file_compare); + + for (lp = g_list_first (files); lp != NULL; lp = lp->next) + { + file = lp->data; + + /* determine the parent menu for this file/directory */ + parent_menu = thunar_launcher_create_document_submenu_templates_find_parent_menu (file, dirs, items); + if (parent_menu == NULL) + parent_menu = create_file_submenu; + + /* determine the icon for this file/directory */ + icon = thunar_icon_factory_load_file_icon (icon_factory, file, THUNAR_FILE_ICON_STATE_DEFAULT, 16); + + /* allocate an image based on the icon */ + image = gtk_image_new_from_pixbuf (icon); + + item = xfce_gtk_image_menu_item_new (thunar_file_get_display_name (file), NULL, NULL, NULL, NULL, image, GTK_MENU_SHELL (parent_menu)); + if (thunar_file_is_directory (file)) + { + /* allocate a new submenu for the directory */ + submenu = gtk_menu_new (); + + /* allocate a new menu item for the directory */ + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + + /* prepend the directory, its item and the parent menu it should + * later be added to to the respective lists */ + dirs = g_list_prepend (dirs, file); + items = g_list_prepend (items, item); + } + else + { + g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_launcher_action_create_document), launcher); + g_object_set_qdata_full (G_OBJECT (item), thunar_launcher_file_quark, g_object_ref (file), g_object_unref); + } + /* release the icon reference */ + g_object_unref (icon); + } + + /* destroy lists */ + g_list_free (dirs); + g_list_free (items); + + /* release the icon factory */ + g_object_unref (icon_factory); + + /* let the job destroy the file list */ + return FALSE; } /** - * thunar_launcher_get_widget: - * @launcher : a #ThunarLauncher. + * thunar_launcher_create_document_submenu_new: + * @launcher : a #ThunarLauncher instance * - * Returns the #GtkWidget currently associated with @launcher. + * Will create a complete 'create_document* #GtkMenu and return it * - * Return value: the widget associated with @launcher. + * Return value: (transfer full): the created #GtkMenu **/ static GtkWidget* -thunar_launcher_get_widget (const ThunarLauncher *launcher) +thunar_launcher_create_document_submenu_new (ThunarLauncher *launcher) { + GList *files = NULL; + GFile *home_dir; + GFile *templates_dir = NULL; + const gchar *path; + gchar *template_path; + gchar *label_text; + GtkWidget *submenu; + GtkWidget *item; + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); - return launcher->widget; + + home_dir = thunar_g_file_new_for_home (); + path = g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES); + + if (G_LIKELY (path != NULL)) + templates_dir = g_file_new_for_path (path); + + /* If G_USER_DIRECTORY_TEMPLATES not found, set "~/Templates" directory as default */ + if (G_UNLIKELY (path == NULL) || G_UNLIKELY (g_file_equal (templates_dir, home_dir))) + { + if (templates_dir != NULL) + g_object_unref (templates_dir); + templates_dir = g_file_resolve_relative_path (home_dir, "Templates"); + } + + if (G_LIKELY (templates_dir != NULL)) + { + /* load the ThunarFiles */ + files = thunar_io_scan_directory (NULL, templates_dir, G_FILE_QUERY_INFO_NONE, TRUE, FALSE, TRUE, NULL); + } + + submenu = gtk_menu_new(); + if (files == NULL) + { + template_path = g_file_get_path (templates_dir); + label_text = g_strdup_printf (_("No templates installed in \"%s\""), template_path); + item = xfce_gtk_image_menu_item_new (label_text, NULL, NULL, NULL, NULL, NULL, GTK_MENU_SHELL (submenu)); + gtk_widget_set_sensitive (item, FALSE); + g_free (template_path); + g_free (label_text); + } + else + { + thunar_launcher_create_document_submenu_templates (launcher, submenu, files); + thunar_g_file_list_free (files); + } + + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_image_menu_item_new_from_icon_name (_("_Empty File"), NULL, NULL, G_CALLBACK (thunar_launcher_action_create_document), + G_OBJECT (launcher), "text-x-generic", GTK_MENU_SHELL (submenu)); + + + g_object_unref (templates_dir); + g_object_unref (home_dir); + + return submenu; +} + + + +static void +thunar_launcher_action_cut (ThunarLauncher *launcher) +{ + ThunarClipboardManager *clipboard; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->current_directory_selected || launcher->parent_folder == NULL) + return; + + clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (launcher->widget)); + thunar_clipboard_manager_cut_files (clipboard, launcher->selected_files); + g_object_unref (G_OBJECT (clipboard)); +} + + + +static void +thunar_launcher_action_copy (ThunarLauncher *launcher) +{ + ThunarClipboardManager *clipboard; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->current_directory_selected) + return; + + clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (launcher->widget)); + thunar_clipboard_manager_copy_files (clipboard, launcher->selected_files); + g_object_unref (G_OBJECT (clipboard)); +} + + + +static void +thunar_launcher_action_paste_into_folder (ThunarLauncher *launcher) +{ + ThunarClipboardManager *clipboard; + ThunarFile *folder_to_paste; + + _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); + + if (launcher->current_directory_selected) + folder_to_paste = launcher->current_directory; + else if (launcher->single_folder_selected) + folder_to_paste = launcher->single_folder; + else + folder_to_paste = launcher->current_directory; /* Fallback if e.g. non directory files, or many folders are selected */ + + /* paste files from the clipboard to the folder */ + clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (launcher->widget)); + thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_file (folder_to_paste), launcher->widget, launcher->select_files_closure); + g_object_unref (G_OBJECT (clipboard)); +} + + + +static GtkWidget* +thunar_launcher_build_application_submenu (ThunarLauncher *launcher, + GList *applications) +{ + GList *lp; + GtkWidget *submenu; + GtkWidget *image; + GtkWidget *item; + gchar *label_text; + gchar *tooltip_text; + + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); + + submenu = gtk_menu_new(); + /* add open with subitem per application */ + for (lp = applications; lp != NULL; lp = lp->next) + { + label_text = g_strdup_printf (_("Open With \"%s\""), g_app_info_get_name (lp->data)); + tooltip_text = g_strdup_printf (ngettext ("Use \"%s\" to open the selected file", + "Use \"%s\" to open the selected files", + launcher->n_selected_files), g_app_info_get_name (lp->data)); + image = gtk_image_new_from_gicon (g_app_info_get_icon (lp->data), GTK_ICON_SIZE_MENU); + item = xfce_gtk_image_menu_item_new (label_text, tooltip_text, NULL, G_CALLBACK (thunar_launcher_menu_item_activated), G_OBJECT (launcher), image, GTK_MENU_SHELL (submenu)); + g_object_set_qdata_full (G_OBJECT (item), thunar_launcher_appinfo_quark, g_object_ref (lp->data), g_object_unref); + g_free (tooltip_text); + g_free (label_text); + } + + if (launcher->n_selected_files == 1) + { + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_launcher_append_menu_item (launcher, GTK_MENU_SHELL (submenu), THUNAR_LAUNCHER_ACTION_OPEN_WITH_OTHER, FALSE); + } + + return submenu; } /** - * thunar_launcher_set_widget: - * @launcher : a #ThunarLauncher. - * @widget : a #GtkWidget or %NULL. + * thunar_launcher_append_open_section: + * @launcher : a #ThunarLauncher instance + * @menu : #GtkMenuShell on which the open section should be appended + * @support_tabs : Set to TRUE if 'open in new tab' should be shown + * @support_change_directory : Set to TRUE if 'open' should be shown + * @force : Append the open section, even if the selected folder is the current folder * - * Associates @launcher with @widget. + * Will append the section "open/open in new window/open in new tab/open with" to the provided #GtkMenuShell + * + * Return value: TRUE if the section was added **/ -void -thunar_launcher_set_widget (ThunarLauncher *launcher, - GtkWidget *widget) +gboolean +thunar_launcher_append_open_section (ThunarLauncher *launcher, + GtkMenuShell *menu, + gboolean support_tabs, + gboolean support_change_directory, + gboolean force) { - _thunar_return_if_fail (THUNAR_IS_LAUNCHER (launcher)); - _thunar_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget)); + GList *applications; + gchar *label_text; + gchar *tooltip_text; + GtkWidget *image; + GtkWidget *menu_item; + GtkWidget *submenu; - /* disconnect from the previous widget */ - if (G_UNLIKELY (launcher->widget != NULL)) + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), FALSE); + + /* Usually it is not required to open the current directory */ + if (launcher->current_directory_selected && !force) + return FALSE; + + /* determine the set of applications that work for all selected files */ + applications = thunar_file_list_get_applications (launcher->selected_files); + + /* Execute OR Open OR OpenWith */ + if (G_UNLIKELY (launcher->n_selected_executables == launcher->n_selected_files)) + thunar_launcher_append_menu_item (launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_EXECUTE, FALSE); + else if (G_LIKELY (launcher->n_selected_directories >= 1)) { - g_signal_handlers_disconnect_by_func (G_OBJECT (launcher->widget), thunar_launcher_widget_destroyed, launcher); - g_object_unref (G_OBJECT (launcher->widget)); + if (support_change_directory) + thunar_launcher_append_menu_item (launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_OPEN, FALSE); } + else if (G_LIKELY (applications != NULL)) + { + label_text = g_strdup_printf (_("_Open With \"%s\""), g_app_info_get_name (applications->data)); + tooltip_text = g_strdup_printf (ngettext ("Use \"%s\" to open the selected file", + "Use \"%s\" to open the selected files", + launcher->n_selected_files), g_app_info_get_name (applications->data)); - /* activate the new widget */ - launcher->widget = widget; + image = gtk_image_new_from_gicon (g_app_info_get_icon (applications->data), GTK_ICON_SIZE_MENU); + menu_item = xfce_gtk_image_menu_item_new (label_text, tooltip_text, NULL, G_CALLBACK (thunar_launcher_menu_item_activated), + G_OBJECT (launcher), image, menu); - /* connect to the new widget */ - if (G_LIKELY (widget != NULL)) + /* remember the default application for the "Open" action as quark */ + g_object_set_qdata_full (G_OBJECT (menu_item), thunar_launcher_appinfo_quark, applications->data, g_object_unref); + g_free (tooltip_text); + g_free (label_text); + + /* drop the default application from the list */ + applications = g_list_delete_link (applications, applications); + } + else { - g_object_ref (G_OBJECT (widget)); - g_signal_connect_swapped (G_OBJECT (widget), "destroy", G_CALLBACK (thunar_launcher_widget_destroyed), launcher); + /* we can only show a generic "Open" action */ + label_text = g_strdup_printf (_("_Open With Default Applications")); + tooltip_text = g_strdup_printf (ngettext ("Open the selected file with the default application", + "Open the selected files with the default applications", launcher->n_selected_files)); + xfce_gtk_menu_item_new (label_text, tooltip_text, NULL, G_CALLBACK (thunar_launcher_menu_item_activated), G_OBJECT (launcher), menu); + g_free (tooltip_text); + g_free (label_text); } - /* notify listeners */ - g_object_notify_by_pspec (G_OBJECT (launcher), launcher_props[PROP_WIDGET]); + if (G_LIKELY (applications != NULL)) + { + menu_item = xfce_gtk_menu_item_new (_("Open With"), + _("Choose another application with which to open the selected file"), + NULL, NULL, NULL, menu); + submenu = thunar_launcher_build_application_submenu (launcher, applications); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu); + } + + if (launcher->n_selected_files == launcher->n_selected_directories && launcher->n_selected_directories >= 1) + { + if (support_tabs) + thunar_launcher_append_menu_item (launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_OPEN_IN_TAB, FALSE); + thunar_launcher_append_menu_item (launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_OPEN_IN_WINDOW, FALSE); + } + + g_list_free_full (applications, g_object_unref); + return TRUE; } +/** + * thunar_launcher_get_widget: + * @launcher : a #ThunarLauncher instance + * + * Will return the parent widget of this #ThunarLauncher + * + * Return value: (transfer none): the parent widget of this #ThunarLauncher + **/ +GtkWidget* +thunar_launcher_get_widget (ThunarLauncher *launcher) +{ + _thunar_return_val_if_fail (THUNAR_IS_LAUNCHER (launcher), NULL); + return launcher->widget; +} diff --git a/thunar/thunar-launcher.h b/thunar/thunar-launcher.h index aca70042..44998380 100644 --- a/thunar/thunar-launcher.h +++ b/thunar/thunar-launcher.h @@ -1,6 +1,7 @@ /* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2020 Alexander Schwinn <alexxcons@xfce.org> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -34,13 +35,65 @@ typedef struct _ThunarLauncher ThunarLauncher; #define THUNAR_IS_LAUNCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_LAUNCHER)) #define THUNAR_LAUNCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_LAUNCHER, ThunarLauncherClass)) -GType thunar_launcher_get_type (void) G_GNUC_CONST; +/* #XfceGtkActionEntrys provided by this widget */ +typedef enum +{ + THUNAR_LAUNCHER_ACTION_OPEN, + THUNAR_LAUNCHER_ACTION_EXECUTE, + THUNAR_LAUNCHER_ACTION_OPEN_IN_TAB, + THUNAR_LAUNCHER_ACTION_OPEN_IN_WINDOW, + THUNAR_LAUNCHER_ACTION_OPEN_WITH_OTHER, + THUNAR_LAUNCHER_ACTION_SENDTO_MENU, + THUNAR_LAUNCHER_ACTION_SENDTO_SHORTCUTS, + THUNAR_LAUNCHER_ACTION_SENDTO_DESKTOP, + THUNAR_LAUNCHER_ACTION_PROPERTIES, + THUNAR_LAUNCHER_ACTION_MAKE_LINK, + THUNAR_LAUNCHER_ACTION_DUPLICATE, + THUNAR_LAUNCHER_ACTION_RENAME, + THUNAR_LAUNCHER_ACTION_EMPTY_TRASH, + THUNAR_LAUNCHER_ACTION_CREATE_FOLDER, + THUNAR_LAUNCHER_ACTION_CREATE_DOCUMENT, + THUNAR_LAUNCHER_ACTION_RESTORE, + THUNAR_LAUNCHER_ACTION_MOVE_TO_TRASH, + THUNAR_LAUNCHER_ACTION_DELETE, + THUNAR_LAUNCHER_ACTION_TRASH_DELETE, + THUNAR_LAUNCHER_ACTION_PASTE, + THUNAR_LAUNCHER_ACTION_PASTE_ALT, + THUNAR_LAUNCHER_ACTION_COPY, + THUNAR_LAUNCHER_ACTION_CUT, +} ThunarLauncherAction; -ThunarLauncher *thunar_launcher_new (void) G_GNUC_MALLOC; - -void thunar_launcher_set_widget (ThunarLauncher *launcher, - GtkWidget *widget); +typedef enum +{ + THUNAR_LAUNCHER_CHANGE_DIRECTORY, + THUNAR_LAUNCHER_OPEN_AS_NEW_TAB, + THUNAR_LAUNCHER_OPEN_AS_NEW_WINDOW +} ThunarLauncherFolderOpenAction; +GType thunar_launcher_get_type (void) G_GNUC_CONST; +void thunar_launcher_activate_selected_files (ThunarLauncher *launcher, + ThunarLauncherFolderOpenAction action, + GAppInfo *app_info); +void thunar_launcher_open_selected_folders_in_new_tabs (ThunarLauncher *launcher); +void thunar_launcher_open_selected_folders_in_new_windows (ThunarLauncher *launcher); +void thunar_launcher_set_widget (ThunarLauncher *launcher, + GtkWidget *widget); +GtkWidget *thunar_launcher_get_widget (ThunarLauncher *launcher); +void thunar_launcher_append_accelerators (ThunarLauncher *launcher, + GtkAccelGroup *accel_group); +GtkWidget *thunar_launcher_append_menu_item (ThunarLauncher *launcher, + GtkMenuShell *menu, + ThunarLauncherAction action, + gboolean force); +gboolean thunar_launcher_append_open_section (ThunarLauncher *launcher, + GtkMenuShell *menu, + gboolean support_tabs, + gboolean support_change_directory, + gboolean force); +gboolean thunar_launcher_append_custom_actions (ThunarLauncher *launcher, + GtkMenuShell *menu); +gboolean thunar_launcher_check_uca_key_activation (ThunarLauncher *launcher, + GdkEventKey *key_event); G_END_DECLS; #endif /* !__THUNAR_LAUNCHER_H__ */ diff --git a/thunar/thunar-location-buttons.c b/thunar/thunar-location-buttons.c index eed9dffa..f6017a13 100644 --- a/thunar/thunar-location-buttons.c +++ b/thunar/thunar-location-buttons.c @@ -27,6 +27,7 @@ #include <thunar/thunar-application.h> #include <thunar/thunar-clipboard-manager.h> +#include <thunar/thunar-menu.h> #include <thunar/thunar-create-dialog.h> #include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gobject-extensions.h> @@ -122,22 +123,6 @@ static gboolean thunar_location_buttons_context_menu (Thuna ThunarLocationButtons *buttons); static void thunar_location_buttons_gone (ThunarLocationButton *button, ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_create_folder (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_down_folder (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_empty_trash (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_open (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_open_in_new_tab (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_open_in_new_window (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_paste_into_folder (GtkAction *action, - ThunarLocationButtons *buttons); -static void thunar_location_buttons_action_properties (GtkAction *action, - ThunarLocationButtons *buttons); @@ -152,8 +137,6 @@ struct _ThunarLocationButtons { GtkContainer __parent__; - GtkActionGroup *action_group; - GtkWidget *left_slider; GtkWidget *right_slider; GtkWidget *filler_widget; @@ -163,6 +146,7 @@ struct _ThunarLocationButtons gint slider_width; gboolean ignore_click : 1; + ThunarLauncher *launcher; GList *list; GList *fake_root_button; GList *first_visible_button; @@ -177,21 +161,6 @@ static GQuark thunar_file_quark = 0; -static const GtkActionEntry action_entries[] = -{ - { "location-buttons-down-folder", NULL, "Down Folder", "<alt>Down", NULL, G_CALLBACK (thunar_location_buttons_action_down_folder), }, - { "location-buttons-context-menu", NULL, "Context Menu", NULL, "", NULL, }, - { "location-buttons-open", "document-open", N_("_Open"), "", NULL, G_CALLBACK (thunar_location_buttons_action_open), }, - { "location-buttons-open-in-new-tab", NULL, N_("Open in New Tab"), "", NULL, G_CALLBACK (thunar_location_buttons_action_open_in_new_tab), }, - { "location-buttons-open-in-new-window", NULL, N_("Open in New Window"), "", NULL, G_CALLBACK (thunar_location_buttons_action_open_in_new_window), }, - { "location-buttons-create-folder", "folder-new", N_("Create _Folder..."), "", NULL, G_CALLBACK (thunar_location_buttons_action_create_folder), }, - { "location-buttons-empty-trash", NULL, N_("_Empty Trash"), "", N_("Delete all files and folders in the Trash"), G_CALLBACK (thunar_location_buttons_action_empty_trash), }, - { "location-buttons-paste-into-folder", "edit-paste", N_("Paste Into Folder"), "", NULL, G_CALLBACK (thunar_location_buttons_action_paste_into_folder), }, - { "location-buttons-properties", "document-properties", N_("_Properties..."), "", NULL, G_CALLBACK (thunar_location_buttons_action_properties), }, -}; - - - G_DEFINE_TYPE_WITH_CODE (ThunarLocationButtons, thunar_location_buttons, GTK_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (THUNAR_TYPE_NAVIGATOR, thunar_location_buttons_navigator_init)) @@ -265,14 +234,6 @@ thunar_location_buttons_init (ThunarLocationButtons *buttons) { GtkWidget *icon; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the action group for the location buttons */ - buttons->action_group = gtk_action_group_new ("ThunarLocationButtons"); - gtk_action_group_set_accel_group (buttons->action_group, gtk_accel_group_new ()); - gtk_action_group_set_translation_domain (buttons->action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (buttons->action_group, action_entries, G_N_ELEMENTS (action_entries), buttons); -G_GNUC_END_IGNORE_DEPRECATIONS - gtk_widget_set_has_window (GTK_WIDGET (buttons), FALSE); gtk_widget_set_redraw_on_allocate (GTK_WIDGET (buttons), FALSE); @@ -324,6 +285,10 @@ G_GNUC_END_IGNORE_DEPRECATIONS "path-bar-button"); gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (buttons->filler_widget)), "path-bar-button"); + + buttons->launcher = g_object_new (THUNAR_TYPE_LAUNCHER, "widget", GTK_WIDGET (buttons), NULL); + g_signal_connect_swapped (G_OBJECT (buttons->launcher), "change-directory", G_CALLBACK (thunar_location_buttons_set_current_directory), buttons); + g_signal_connect_swapped (G_OBJECT (buttons->launcher), "open-new-tab", G_CALLBACK (thunar_navigator_open_new_tab), buttons); } @@ -341,9 +306,6 @@ thunar_location_buttons_finalize (GObject *object) /* release from the current_directory */ thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (buttons), NULL); - /* release our action group */ - g_object_unref (G_OBJECT (buttons->action_group)); - (*G_OBJECT_CLASS (thunar_location_buttons_parent_class)->finalize) (object); } @@ -1225,315 +1187,60 @@ static gboolean thunar_location_buttons_context_menu (ThunarLocationButton *button, ThunarLocationButtons *buttons) { - ThunarClipboardManager *clipboard; - const gchar *display_name; - ThunarFile *file; - GtkAction *action; - GtkWidget *menu, *item; + ThunarFile *file; + GtkWidget *window; + GList *files = NULL; + ThunarMenu *context_menu; + gboolean is_current_directory; _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons), FALSE); _thunar_return_val_if_fail (THUNAR_IS_LOCATION_BUTTON (button), FALSE); /* determine the file for the button */ file = thunar_location_button_get_file (button); - if (G_LIKELY (file != NULL)) - { - menu = gtk_menu_new (); - - /* determine the display name of the file */ - display_name = thunar_file_get_display_name (file); - - /* be sure to keep a reference on the navigation bar */ - g_object_ref (G_OBJECT (buttons)); - - /* grab a reference on the clipboard manager for this display */ - clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons))); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the "Open" action */ - action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open"); - thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in this window"), display_name); - g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref); - gtk_action_set_sensitive (action, (file != buttons->current_directory)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); - - /* setup the "Open in New Tab" action */ - action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open-in-new-tab"); - thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in a new tab"), display_name); - g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); - - /* setup the "Open in New Window" action */ - action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open-in-new-window"); - thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in a new window"), display_name); - g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); - - /* setup the "Create Folder..." action */ - action = gtk_action_group_get_action (buttons->action_group, "location-buttons-create-folder"); - thunar_gtk_action_set_tooltip (action, _("Create a new folder in \"%s\""), display_name); - g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref); - gtk_action_set_sensitive (action, thunar_file_is_writable (file)); - gtk_action_set_visible (action, !thunar_file_is_trashed (file)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); - - /* setup the "Empty Trash" action */ - action = gtk_action_group_get_action (buttons->action_group, "location-buttons-empty-trash"); - gtk_action_set_visible (action, (thunar_file_is_root (file) && thunar_file_is_trashed (file))); - gtk_action_set_sensitive (action, (thunar_file_get_item_count (file) > 0)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - item = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the "Paste Into Folder" action */ - action = gtk_action_group_get_action (buttons->action_group, "location-buttons-paste-into-folder"); - thunar_gtk_action_set_tooltip (action, _("Move or copy files previously selected by a Cut or Copy command into \"%s\""), display_name); - g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref); - gtk_action_set_sensitive (action, thunar_clipboard_manager_get_can_paste (clipboard)); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); - - item = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* setup the "Properties..." action */ - action = gtk_action_group_get_action (buttons->action_group, "location-buttons-properties"); - thunar_gtk_action_set_tooltip (action, _("View the properties of the folder \"%s\""), display_name); - g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* run the menu (takes over the floating of menu) */ - thunar_gtk_menu_run (GTK_MENU (menu)); - - /* cleanup */ - g_object_unref (buttons); - g_object_unref (clipboard); - - return TRUE; - } - - return FALSE; -} - - - -static void -thunar_location_buttons_action_create_folder (GtkAction *action, - ThunarLocationButtons *buttons) -{ - ThunarApplication *application; - ThunarFile *directory; - GList path_list; - gchar *name; - - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* determine the directory for the action */ - directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark); - if (G_UNLIKELY (directory == NULL)) - return; - - /* ask the user to enter a name for the new folder */ - name = thunar_show_create_dialog (GTK_WIDGET (buttons), - "inode/directory", - _("New Folder"), - _("Create New Folder")); - if (G_LIKELY (name != NULL)) - { - /* fake the path list */ - path_list.data = g_file_resolve_relative_path (thunar_file_get_file (directory), name); - path_list.next = path_list.prev = NULL; - - /* launch the operation */ - application = thunar_application_get (); - thunar_application_mkdir (application, GTK_WIDGET (buttons), &path_list, NULL); - g_object_unref (G_OBJECT (application)); - - /* release the path */ - g_object_unref (path_list.data); - - /* release the file name */ - g_free (name); - } -} - - - -static void -thunar_location_buttons_action_down_folder (GtkAction *action, - ThunarLocationButtons *buttons) -{ - GList *lp; - - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* lookup the active button */ - for (lp = buttons->list; lp != NULL; lp = lp->next) - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lp->data))) - { - /* check if we have a folder below that one */ - if (G_LIKELY (lp->prev != NULL)) - { - /* enter that folder */ - gtk_button_clicked (GTK_BUTTON (lp->prev->data)); - } - - break; - } -} - - - -static void -thunar_location_buttons_action_empty_trash (GtkAction *action, - ThunarLocationButtons *buttons) -{ - ThunarApplication *application; - - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* launch the operation */ - application = thunar_application_get (); - thunar_application_empty_trash (application, GTK_WIDGET (buttons), NULL); - g_object_unref (G_OBJECT (application)); -} - - - -static void -thunar_location_buttons_action_open (GtkAction *action, - ThunarLocationButtons *buttons) -{ - ThunarFile *directory; - - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* determine the directory for the action */ - directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark); - if (G_LIKELY (directory != NULL && thunar_file_is_directory (directory))) - { - /* open the folder in this window */ - thunar_navigator_change_directory (THUNAR_NAVIGATOR (buttons), directory); - } -} - - - -static void -thunar_location_buttons_action_open_in_new_tab (GtkAction *action, - ThunarLocationButtons *buttons) -{ - ThunarFile *directory; - - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* determine the directory for the action */ - directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark); - if (G_LIKELY (directory != NULL)) - { - /* open tab in thsi window */ - thunar_navigator_open_new_tab (THUNAR_NAVIGATOR (buttons), directory); - } -} - - - -static void -thunar_location_buttons_action_open_in_new_window (GtkAction *action, - ThunarLocationButtons *buttons) -{ - ThunarApplication *application; - ThunarFile *directory; + if (G_UNLIKELY (file == NULL)) + return FALSE; - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS + files = g_list_append (files, file); + g_object_set (G_OBJECT (buttons->launcher), "current-directory", file, NULL); + g_object_set (G_OBJECT (buttons->launcher), "selected-files", files, NULL); - /* determine the directory for the action */ - directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark); - if (G_LIKELY (directory != NULL)) + is_current_directory = g_file_equal (thunar_file_get_file (file), thunar_file_get_file (buttons->current_directory)); + context_menu = g_object_new (THUNAR_TYPE_MENU, "menu-type", THUNAR_MENU_TYPE_CONTEXT, + "launcher", buttons->launcher, + "force-section-open", TRUE, + "change_directory-support-disabled", is_current_directory, NULL); + if (is_current_directory) { - /* open a new window for the directory */ - application = thunar_application_get (); - thunar_application_open_window (application, directory, gtk_widget_get_screen (GTK_WIDGET (buttons)), NULL, TRUE); - g_object_unref (G_OBJECT (application)); + /* context menu on current directory */ + thunar_menu_add_sections (context_menu, THUNAR_MENU_SECTION_OPEN + | THUNAR_MENU_SECTION_SENDTO + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_CREATE_NEW_FILES + | THUNAR_MENU_SECTION_EMPTY_TRASH + | THUNAR_MENU_SECTION_RESTORE + | THUNAR_MENU_SECTION_RENAME + | THUNAR_MENU_SECTION_CUSTOM_ACTIONS + | THUNAR_MENU_SECTION_PROPERTIES); } -} - - - -static void -thunar_location_buttons_action_paste_into_folder (GtkAction *action, - ThunarLocationButtons *buttons) -{ - ThunarClipboardManager *clipboard; - ThunarFile *directory; - - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* determine the directory for the action */ - directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark); - if (G_LIKELY (directory != NULL)) + else { - /* paste files from the clipboard to the folder represented by this button */ - clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons))); - thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_file (directory), GTK_WIDGET (buttons), NULL); - g_object_unref (G_OBJECT (clipboard)); + /* context menu on some other pathbar element */ + thunar_menu_add_sections (context_menu, THUNAR_MENU_SECTION_OPEN + | THUNAR_MENU_SECTION_SENDTO + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_EMPTY_TRASH + | THUNAR_MENU_SECTION_RESTORE + | THUNAR_MENU_SECTION_RENAME + | THUNAR_MENU_SECTION_CUSTOM_ACTIONS + | THUNAR_MENU_SECTION_PROPERTIES); } -} + thunar_menu_hide_accel_labels (context_menu); + gtk_widget_show_all (GTK_WIDGET (context_menu)); + window = gtk_widget_get_toplevel (GTK_WIDGET (buttons)); + thunar_window_redirect_menu_tooltips_to_statusbar (THUNAR_WINDOW (window), GTK_MENU (context_menu)); - - -static void -thunar_location_buttons_action_properties (GtkAction *action, - ThunarLocationButtons *buttons) -{ - ThunarFile *directory; - GtkWidget *toplevel; - GtkWidget *dialog; - - _thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons)); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* determine the directory for the action */ - directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark); - if (G_LIKELY (directory != NULL)) - { - /* determine the toplevel window */ - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (buttons)); - if (G_LIKELY (toplevel != NULL && gtk_widget_get_toplevel (toplevel))) - { - /* popup the properties dialog */ - dialog = thunar_properties_dialog_new (GTK_WINDOW (toplevel)); - thunar_properties_dialog_set_file (THUNAR_PROPERTIES_DIALOG (dialog), directory); - gtk_widget_show (dialog); - } - } + thunar_gtk_menu_run (GTK_MENU (context_menu)); + g_list_free (files); + return TRUE; } - diff --git a/thunar/thunar-menu-util.c b/thunar/thunar-menu-util.c deleted file mode 100644 index 5caacc41..00000000 --- a/thunar/thunar-menu-util.c +++ /dev/null @@ -1,185 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2017 Andre Miranda <andreldm@xfce.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <thunar/thunar-menu-util.h> - -#include <thunarx/thunarx.h> - - - -static void -extension_action_callback (GtkAction *action, - gpointer callback_data) -{ - thunarx_menu_item_activate (THUNARX_MENU_ITEM (callback_data)); -} - - - -static GtkAction * -action_from_menu_item (GObject *item) -{ - gchar *name, *label, *tooltip, *icon_str; - gboolean sensitive, priority; - GtkAction *action; - - g_return_val_if_fail (THUNARX_IS_MENU_ITEM (item), NULL); - - g_object_get (G_OBJECT (item), - "name", &name, - "label", &label, - "tooltip", &tooltip, - "icon", &icon_str, - "sensitive", &sensitive, - "priority", &priority, - NULL); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - action = gtk_action_new (name, label, tooltip, NULL); - - if (icon_str != NULL) - { - GIcon *icon = g_icon_new_for_string (icon_str, NULL); - - if (icon) - { - gtk_action_set_gicon (action, icon); - g_object_unref (icon); - } - } - - gtk_action_set_sensitive (action, sensitive); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_set (action, "is-important", priority, NULL); - - g_signal_connect_data (action, "activate", - G_CALLBACK (extension_action_callback), - g_object_ref (item), - (GClosureNotify) (void (*)(void)) g_object_unref, 0); - - g_free (name); - g_free (label); - g_free (tooltip); - g_free (icon_str); - - return action; -} - - - -void -thunar_menu_util_add_items_to_ui_manager (GtkUIManager *ui_manager, - GtkActionGroup *action_group, - gint merge_id, - const gchar *path, - GList *items) -{ - GList *lp; - GtkAction *action; - ThunarxMenu *menu; - char *subpath; - char *action_path; - GList *children; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* add the menu items to the UI manager */ - for (lp = items; lp != NULL; lp = lp->next) - { - action = action_from_menu_item (G_OBJECT (lp->data)); - g_object_get (G_OBJECT (lp->data), "menu", &menu, NULL); - - /* add the action to the action group */ - gtk_action_group_add_action (action_group, action); - - /* add the action to the UI manager */ - gtk_ui_manager_add_ui (ui_manager, merge_id, path, - gtk_action_get_name (GTK_ACTION (action)), - gtk_action_get_name (GTK_ACTION (action)), - (menu != NULL) ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM, FALSE); - - /* TODO: Receive action path from plugin as generic data as below or create a property in ThunarxMenuItem? */ - action_path = g_object_steal_data (G_OBJECT (lp->data), "action_path"); - if (action_path) - { - gtk_action_set_accel_path (action, action_path); - g_free (action_path); - } - - /* add submenu items if any */ - if (menu != NULL) { - children = thunarx_menu_get_items (menu); - subpath = g_build_path ("/", path, gtk_action_get_name (action), NULL); - - thunar_menu_util_add_items_to_ui_manager (ui_manager, action_group, merge_id, - subpath, children); - - thunarx_menu_item_list_free (children); - g_free (subpath); - } -G_GNUC_END_IGNORE_DEPRECATIONS - - /* release the reference on item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); - } -} - - - -void -thunar_menu_util_add_items_to_menu (GtkWidget *menu, - GList *items) -{ - GList *lp; - GtkAction *action; - GtkWidget *item; - GtkWidget *submenu; - ThunarxMenu *thunarx_menu; - GList *children; - - /* add the menu items to the UI manager */ - for (lp = items; lp != NULL; lp = lp->next) - { - action = action_from_menu_item (G_OBJECT (lp->data)); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - item = gtk_action_create_menu_item (action); -G_GNUC_END_IGNORE_DEPRECATIONS - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* add submenu items if any */ - g_object_get (G_OBJECT (lp->data), "menu", &thunarx_menu, NULL); - if (thunarx_menu != NULL) { - children = thunarx_menu_get_items (thunarx_menu); - - submenu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - - thunar_menu_util_add_items_to_menu (submenu, children); - - thunarx_menu_item_list_free (children); - } - - /* release the reference on item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); - } -} diff --git a/thunar/thunar-menu-util.h b/thunar/thunar-menu-util.h deleted file mode 100644 index 68efe81b..00000000 --- a/thunar/thunar-menu-util.h +++ /dev/null @@ -1,39 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2017 Andre Miranda <andreldm@xfce.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __THUNAR_MENU_UTIL_H__ -#define __THUNAR_MENU_UTIL_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -void thunar_menu_util_add_items_to_ui_manager (GtkUIManager *ui_manager, - GtkActionGroup *action_group, - gint merge_id, - const gchar *path, - GList *items); - -void thunar_menu_util_add_items_to_menu (GtkWidget *menu, - GList *items); - -G_END_DECLS - -#endif /* !__THUNAR_MENU_UTIL_H__ */ diff --git a/thunar/thunar-menu.c b/thunar/thunar-menu.c new file mode 100644 index 00000000..4363ccc8 --- /dev/null +++ b/thunar/thunar-menu.c @@ -0,0 +1,355 @@ +/*- + * Copyright (c) 2020 Alexander Schwinn <alexxcons@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, 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-menu.h> + +#include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-launcher.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-window.h> + +/* property identifiers */ +enum +{ + PROP_0, + PROP_MENU_TYPE, + PROP_LAUNCHER, + PROP_FORCE_SECTION_OPEN, + PROP_TAB_SUPPORT_DISABLED, + PROP_CHANGE_DIRECTORY_SUPPORT_DISABLED, +}; + +static void thunar_menu_finalize (GObject *object); +static void thunar_menu_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_menu_set_property (GObject *object, + guint prop_uid, + const GValue *value, + GParamSpec *pspec); + +struct _ThunarMenuClass +{ + GtkMenuClass __parent__; +}; + +struct _ThunarMenu +{ + GtkMenu __parent__; + ThunarLauncher *launcher; + + /* true, if the 'open' section should be forced */ + gboolean force_section_open; + + /* true, if 'open as new tab' should not be shown */ + gboolean tab_support_disabled; + + /* true, if 'open' for folders, which would result in changing the directory, should not be shown */ + gboolean change_directory_support_disabled; + + /* detailed type of the thunar menu */ + ThunarMenuType type; +}; + + + +static GQuark thunar_menu_handler_quark; + +G_DEFINE_TYPE (ThunarMenu, thunar_menu, GTK_TYPE_MENU) + + + +static void +thunar_menu_class_init (ThunarMenuClass *klass) +{ + GObjectClass *gobject_class; + + /* determine the "thunar-menu-handler" quark */ + thunar_menu_handler_quark = g_quark_from_static_string ("thunar-menu-handler"); + + gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = thunar_menu_finalize; + gobject_class->get_property = thunar_menu_get_property; + gobject_class->set_property = thunar_menu_set_property; + + g_object_class_install_property (gobject_class, + PROP_MENU_TYPE, + g_param_spec_int ("menu-type", + "menu-type", + "menu-type", + 0, 1, 0, // min, max, default + G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (gobject_class, + PROP_LAUNCHER, + g_param_spec_object ("launcher", + "launcher", + "launcher", + THUNAR_TYPE_LAUNCHER, + G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (gobject_class, + PROP_FORCE_SECTION_OPEN, + g_param_spec_boolean ("force-section-open", + "force-section-open", + "force-section-open", + FALSE, + G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (gobject_class, + PROP_TAB_SUPPORT_DISABLED, + g_param_spec_boolean ("tab-support-disabled", + "tab-support-disabled", + "tab-support-disabled", + FALSE, + G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (gobject_class, + PROP_CHANGE_DIRECTORY_SUPPORT_DISABLED, + g_param_spec_boolean ("change_directory-support-disabled", + "change_directory-support-disabled", + "change_directory-support-disabled", + FALSE, + G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY)); +} + + + +static void +thunar_menu_init (ThunarMenu *menu) +{ + menu->force_section_open = FALSE; + menu->type = FALSE; + menu->tab_support_disabled = FALSE; + menu->change_directory_support_disabled = FALSE; +} + + + +static void +thunar_menu_finalize (GObject *object) +{ + ThunarMenu *menu = THUNAR_MENU (object); + + g_object_unref (menu->launcher); + + (*G_OBJECT_CLASS (thunar_menu_parent_class)->finalize) (object); +} + + + +static void +thunar_menu_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_menu_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ThunarMenu *menu = THUNAR_MENU (object); + + switch (prop_id) + { + case PROP_MENU_TYPE: + menu->type = g_value_get_int (value); + break; + + case PROP_LAUNCHER: + menu->launcher = g_value_dup_object (value); + g_object_ref (G_OBJECT (menu->launcher)); + break; + + case PROP_FORCE_SECTION_OPEN: + menu->force_section_open = g_value_get_boolean (value); + break; + + case PROP_TAB_SUPPORT_DISABLED: + menu->tab_support_disabled = g_value_get_boolean (value); + break; + + case PROP_CHANGE_DIRECTORY_SUPPORT_DISABLED: + menu->change_directory_support_disabled = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +/** + * thunar_menu_add_sections: + * @menu : a #ThunarMenu instance + * @menu_sections : bit enumeration of #ThunarMenuSections which should be added to the #ThunarMenu + * + * Method to add different sections of #GtkMenuItems to the #ThunarMenu, + * according to the selected #ThunarMenuSections + * + * Return value: TRUE if any #GtkMenuItem was added + **/ +gboolean +thunar_menu_add_sections (ThunarMenu *menu, + ThunarMenuSections menu_sections) +{ + GtkWidget *window; + gboolean item_added; + gboolean is_window_menu = menu->type == THUNAR_MENU_TYPE_WINDOW; + + _thunar_return_val_if_fail (THUNAR_IS_MENU (menu), FALSE); + + if (menu_sections & THUNAR_MENU_SECTION_OPEN) + { + if (thunar_launcher_append_open_section (menu->launcher, GTK_MENU_SHELL (menu), !menu->tab_support_disabled, !menu->change_directory_support_disabled, menu->force_section_open)) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + + if (menu_sections & THUNAR_MENU_SECTION_SENDTO) + { + item_added = thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_SENDTO_MENU, FALSE) != NULL; + if (item_added) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + if (menu_sections & THUNAR_MENU_SECTION_CREATE_NEW_FILES) + { + item_added = FALSE; + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_CREATE_FOLDER, is_window_menu) != NULL); + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_CREATE_DOCUMENT, is_window_menu) != NULL); + if (item_added) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + item_added = FALSE; + if (menu_sections & THUNAR_MENU_SECTION_CUT) + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_CUT, is_window_menu) != NULL); + if (menu_sections & THUNAR_MENU_SECTION_COPY_PASTE) + { + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_COPY, is_window_menu) != NULL); + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_PASTE, is_window_menu) != NULL); + } + if (item_added) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + + if (menu_sections & THUNAR_MENU_SECTION_TRASH_DELETE) + { + item_added = FALSE; + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_MOVE_TO_TRASH, is_window_menu) != NULL); + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_DELETE, is_window_menu) != NULL); + if (item_added) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + if (menu_sections & THUNAR_MENU_SECTION_EMPTY_TRASH) + { + if (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_EMPTY_TRASH, FALSE) != NULL ) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + if (menu_sections & THUNAR_MENU_SECTION_RESTORE) + { + if (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_RESTORE, FALSE) != NULL) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + + item_added = FALSE; + if (menu_sections & THUNAR_MENU_SECTION_DUPLICATE) + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_DUPLICATE, is_window_menu) != NULL); + if (menu_sections & THUNAR_MENU_SECTION_MAKELINK) + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_MAKE_LINK, is_window_menu) != NULL); + if (menu_sections & THUNAR_MENU_SECTION_RENAME) + item_added |= (thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_RENAME, is_window_menu) != NULL); + if (item_added) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + + if (menu_sections & THUNAR_MENU_SECTION_CUSTOM_ACTIONS) + { + if (thunar_launcher_append_custom_actions (menu->launcher, GTK_MENU_SHELL (menu))) + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + + if (menu_sections & THUNAR_MENU_SECTION_ZOOM) + { + window = thunar_launcher_get_widget (menu->launcher); + if (THUNAR_IS_WINDOW (window)) + { + thunar_window_append_menu_item (THUNAR_WINDOW (window), GTK_MENU_SHELL (menu), THUNAR_WINDOW_ACTION_ZOOM_IN); + thunar_window_append_menu_item (THUNAR_WINDOW (window), GTK_MENU_SHELL (menu), THUNAR_WINDOW_ACTION_ZOOM_OUT); + thunar_window_append_menu_item (THUNAR_WINDOW (window), GTK_MENU_SHELL (menu), THUNAR_WINDOW_ACTION_ZOOM_RESET); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } + } + + if (menu_sections & THUNAR_MENU_SECTION_PROPERTIES) + thunar_launcher_append_menu_item (menu->launcher, GTK_MENU_SHELL (menu), THUNAR_LAUNCHER_ACTION_PROPERTIES, FALSE); + + return TRUE; +} + + + +/** + * thunar_menu_get_launcher: + * @menu : a #ThunarMenu instance + * + * Return value: (transfer none): The launcher of this #ThunarMenu instance + **/ +GtkWidget* +thunar_menu_get_launcher (ThunarMenu *menu) +{ + _thunar_return_val_if_fail (THUNAR_IS_MENU (menu), NULL); + return GTK_WIDGET (menu->launcher); +} + + + +/** + * thunar_menu_hide_accel_labels: + * @menu : a #ThunarMenu instance + * + * Will hide the accel_labels of all menu items of this menu + **/ +void +thunar_menu_hide_accel_labels (ThunarMenu *menu) +{ + _thunar_return_if_fail (THUNAR_IS_MENU (menu)); + + for (GList* lp = gtk_container_get_children (GTK_CONTAINER (menu)); lp != NULL; lp = lp->next) + xfce_gtk_menu_item_set_accel_label (lp->data, NULL); +} diff --git a/thunar/thunar-menu.h b/thunar/thunar-menu.h new file mode 100644 index 00000000..16272592 --- /dev/null +++ b/thunar/thunar-menu.h @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2020 Alexander Schwinn <alexxcons@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __THUNAR_MENU_H__ +#define __THUNAR_MENU_H__ + +#include <gtk/gtk.h> + +#include <thunar/thunar-file.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarMenuClass ThunarMenuClass; +typedef struct _ThunarMenu ThunarMenu; + +#define THUNAR_TYPE_MENU (thunar_menu_get_type ()) +#define THUNAR_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_MENU, ThunarMenu)) +#define THUNAR_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_MENU, ThunarMenuClass)) +#define THUNAR_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_MENU)) +#define THUNAR_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_MENU)) +#define THUNAR_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_MENU, ThunarMenu)) + +/* For window menu, some items are shown insensitive, instead of hidden */ +typedef enum +{ + THUNAR_MENU_TYPE_WINDOW, + THUNAR_MENU_TYPE_CONTEXT, +} ThunarMenuType; + +/* Bundles of #GtkMenuItems, which can be created by this widget */ +typedef enum +{ + THUNAR_MENU_SECTION_OPEN = 1 << 0, + THUNAR_MENU_SECTION_SENDTO = 1 << 1, + THUNAR_MENU_SECTION_CREATE_NEW_FILES = 1 << 2, + THUNAR_MENU_SECTION_CUT = 1 << 3, + THUNAR_MENU_SECTION_COPY_PASTE = 1 << 4, + THUNAR_MENU_SECTION_TRASH_DELETE = 1 << 5, + THUNAR_MENU_SECTION_EMPTY_TRASH = 1 << 6, + THUNAR_MENU_SECTION_RESTORE = 1 << 7, + THUNAR_MENU_SECTION_DUPLICATE = 1 << 8, + THUNAR_MENU_SECTION_MAKELINK = 1 << 9, + THUNAR_MENU_SECTION_RENAME = 1 << 10, + THUNAR_MENU_SECTION_CUSTOM_ACTIONS = 1 << 11, + THUNAR_MENU_SECTION_ZOOM = 1 << 12, + THUNAR_MENU_SECTION_PROPERTIES = 1 << 13, + +} ThunarMenuSections; + + +GType thunar_menu_get_type (void) G_GNUC_CONST; + +gboolean thunar_menu_add_sections (ThunarMenu *menu, + ThunarMenuSections menu_sections); +GtkWidget* thunar_menu_get_launcher (ThunarMenu *menu); +void thunar_menu_hide_accel_labels (ThunarMenu *menu); + +G_END_DECLS; + +#endif /* !__THUNAR_CONTEXT_MENU_H__ */ diff --git a/thunar/thunar-renamer-dialog-ui.xml b/thunar/thunar-renamer-dialog-ui.xml deleted file mode 100644 index 8ecc8701..00000000 --- a/thunar/thunar-renamer-dialog-ui.xml +++ /dev/null @@ -1,47 +0,0 @@ -<ui> - - <!-- - Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - - Thunar bulk rename 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. - --> - - <toolbar name="toolbar"> - <toolitem action="add-files" /> - <toolitem action="remove-files" /> - <separator /> - <toolitem action="clear" /> - <separator expand="true" /> - <toolitem action="about" /> - </toolbar> - - <menubar name="main-menu"> - <menu action="file-menu"> - <placeholder name="placeholder-launcher" /> - <separator /> - <menu action="sendto-menu"> - <placeholder name="placeholder-sendto-actions" /> - </menu> - </menu> - </menubar> - - <popup action="file-context-menu"> - <placeholder name="placeholder-launcher" /> - <separator /> - <menu action="sendto-menu"> - <placeholder name="placeholder-sendto-actions" /> - </menu> - <separator /> - <placeholder name="placeholder-renamer-actions" /> - <separator /> - <menuitem action="add-files" /> - <menuitem action="remove-files" /> - <separator /> - <menuitem action="properties" /> - </popup> - -</ui> - -<!-- vi: set ts=2 sw=2 et ai nocindent syntax=xml: --> diff --git a/thunar/thunar-renamer-dialog.c b/thunar/thunar-renamer-dialog.c index 88ff90e8..0e4fb86c 100644 --- a/thunar/thunar-renamer-dialog.c +++ b/thunar/thunar-renamer-dialog.c @@ -37,11 +37,11 @@ #include <thunar/thunar-icon-factory.h> #include <thunar/thunar-icon-renderer.h> #include <thunar/thunar-launcher.h> -#include <thunar/thunar-menu-util.h> +#include <thunar/thunar-launcher.h> +#include <thunar/thunar-menu.h> #include <thunar/thunar-private.h> #include <thunar/thunar-properties-dialog.h> #include <thunar/thunar-renamer-dialog.h> -#include <thunar/thunar-renamer-dialog-ui.h> #include <thunar/thunar-renamer-model.h> #include <thunar/thunar-renamer-progress.h> @@ -63,6 +63,15 @@ enum TARGET_TEXT_URI_LIST, }; +typedef enum +{ + THUNAR_RENAMER_ACTION_ADD_FILES, + THUNAR_RENAMER_ACTION_REMOVE_FILES, + THUNAR_RENAMER_ACTION_CLEAR, + THUNAR_RENAMER_ACTION_ABOUT, + +} ThunarRenamerAction; + static void thunar_renamer_dialog_dispose (GObject *object); @@ -82,16 +91,10 @@ static void thunar_renamer_dialog_response (GtkDialog static void thunar_renamer_dialog_context_menu (ThunarRenamerDialog *renamer_dialog); static void thunar_renamer_dialog_help (ThunarRenamerDialog *renamer_dialog); static void thunar_renamer_dialog_save (ThunarRenamerDialog *renamer_dialog); -static void thunar_renamer_dialog_action_add_files (GtkAction *action, - ThunarRenamerDialog *renamer_dialog); -static void thunar_renamer_dialog_action_remove_files (GtkAction *action, - ThunarRenamerDialog *renamer_dialog); -static void thunar_renamer_dialog_action_clear (GtkAction *action, - ThunarRenamerDialog *renamer_dialog); -static void thunar_renamer_dialog_action_about (GtkAction *action, - ThunarRenamerDialog *renamer_dialog); -static void thunar_renamer_dialog_action_properties (GtkAction *action, - ThunarRenamerDialog *renamer_dialog); +static void thunar_renamer_dialog_action_add_files (ThunarRenamerDialog *renamer_dialog); +static void thunar_renamer_dialog_action_remove_files (ThunarRenamerDialog *renamer_dialog); +static void thunar_renamer_dialog_action_clear (ThunarRenamerDialog *renamer_dialog); +static void thunar_renamer_dialog_action_about (ThunarRenamerDialog *renamer_dialog); static void thunar_renamer_dialog_name_column_clicked (GtkTreeViewColumn *column, ThunarRenamerDialog *renamer_dialog); static gboolean thunar_renamer_dialog_button_press_event (GtkWidget *tree_view, @@ -139,6 +142,9 @@ static GList *thunar_renamer_dialog_get_selected_files (ThunarRenamerDia static gboolean thunar_renamer_dialog_get_standalone (ThunarRenamerDialog *renamer_dialog); static void thunar_renamer_dialog_set_standalone (ThunarRenamerDialog *renamer_dialog, gboolean fixed); +static GtkWidget *thunar_renamer_dialog_append_menu_item (ThunarRenamerDialog *renamer_dialog, + GtkMenuShell *menu, + ThunarRenamerAction action); @@ -158,9 +164,6 @@ struct _ThunarRenamerDialog ThunarLauncher *launcher; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - GtkWidget *cancel_button; GtkWidget *close_button; @@ -184,18 +187,16 @@ struct _ThunarRenamerDialog -static const GtkActionEntry action_entries[] = +static XfceGtkActionEntry thunar_renamer_action_entries[] = { - { "file-menu", NULL, N_ ("_File"), NULL, }, - { "sendto-menu", NULL, N_ ("_Send To"), NULL, }, - { "file-context-menu", NULL, N_ ("File Context Menu"), NULL, }, - { "add-files", "list-add", N_ ("_Add Files..."), NULL, N_ ("Include additional files in the list of files to be renamed"), G_CALLBACK (thunar_renamer_dialog_action_add_files), }, - { "remove-files", "list-remove", NULL, NULL, NULL, G_CALLBACK (thunar_renamer_dialog_action_remove_files), }, - { "clear", "edit-clear", N_ ("Clear"), NULL, N_ ("Clear the file list below"), G_CALLBACK (thunar_renamer_dialog_action_clear), }, - { "about", "help-about", N_ ("_About"), NULL, N_ ("Display information about Thunar Bulk Rename"), G_CALLBACK (thunar_renamer_dialog_action_about), }, - { "properties", "document-properties", N_ ("_Properties..."), "<alt>Return", N_ ("View the properties of the selected file"), G_CALLBACK (thunar_renamer_dialog_action_properties), }, + { THUNAR_RENAMER_ACTION_ADD_FILES, "<Actions>/ThunarRenamerDialog/add-files", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Add Files..."), N_ ("Include additional files in the list of files to be renamed"), "list-add", G_CALLBACK (thunar_renamer_dialog_action_add_files), }, + { THUNAR_RENAMER_ACTION_REMOVE_FILES, "<Actions>/ThunarRenamerDialog/remove-files", "", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, "list-remove", G_CALLBACK (thunar_renamer_dialog_action_remove_files),}, + { THUNAR_RENAMER_ACTION_CLEAR, "", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Clear"), N_ ("Clear the file list below"), "edit-clear", G_CALLBACK (thunar_renamer_dialog_action_clear), }, + { THUNAR_RENAMER_ACTION_ABOUT, "", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_About"), N_ ("Display information about Thunar Bulk Rename"), "help-about", G_CALLBACK (thunar_renamer_dialog_action_about), }, }; +#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_renamer_action_entries,G_N_ELEMENTS(thunar_renamer_action_entries),id) + /* Target types for dropping to the tree view */ static const GtkTargetEntry drop_targets[] = { @@ -303,13 +304,13 @@ thunar_renamer_dialog_init (ThunarRenamerDialog *renamer_dialog) GtkTreeViewColumn *column; GtkTreeSelection *selection; GtkCellRenderer *renderer; - GtkAccelGroup *accel_group; GtkSizeGroup *size_group; const gchar *active_str; GHashTable *settings; GEnumClass *klass; GtkWidget *notebook; GtkWidget *toolbar; + GtkToolItem *seperator; GtkWidget *button; GtkWidget *mcombo; GtkWidget *rcombo; @@ -332,6 +333,8 @@ thunar_renamer_dialog_init (ThunarRenamerDialog *renamer_dialog) /* allocate a new bulk rename model */ renamer_dialog->model = thunar_renamer_model_new (); + xfce_gtk_translate_action_entries (thunar_renamer_action_entries, G_N_ELEMENTS (thunar_renamer_action_entries)); + /* determine the list of available renamers (using the renamer providers) */ provider_factory = thunarx_provider_factory_get_default (); providers = thunarx_provider_factory_list_providers (provider_factory, THUNARX_TYPE_RENAMER_PROVIDER); @@ -361,34 +364,25 @@ thunar_renamer_dialog_init (ThunarRenamerDialog *renamer_dialog) gtk_dialog_set_default_response (GTK_DIALOG (renamer_dialog), GTK_RESPONSE_ACCEPT); gtk_widget_set_tooltip_text (button, _("Click here to actually rename the files listed above to their new names.")); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the action group for this dialog */ - renamer_dialog->action_group = gtk_action_group_new ("ThunarRenamerDialog"); - gtk_action_group_set_translation_domain (renamer_dialog->action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (renamer_dialog->action_group, action_entries, G_N_ELEMENTS (action_entries), GTK_WIDGET (renamer_dialog)); - - /* setup the UI manager for this dialog */ - renamer_dialog->ui_manager = gtk_ui_manager_new (); - gtk_ui_manager_insert_action_group (renamer_dialog->ui_manager, renamer_dialog->action_group, 0); - gtk_ui_manager_add_ui_from_string (renamer_dialog->ui_manager, thunar_renamer_dialog_ui, thunar_renamer_dialog_ui_length, NULL); - - /* connect the accelerators */ - accel_group = gtk_ui_manager_get_accel_group (renamer_dialog->ui_manager); - gtk_window_add_accel_group (GTK_WINDOW (renamer_dialog), accel_group); -G_GNUC_END_IGNORE_DEPRECATIONS - /* setup the launcher support for this dialog */ - renamer_dialog->launcher = thunar_launcher_new (); - thunar_launcher_set_widget (renamer_dialog->launcher, GTK_WIDGET (renamer_dialog)); - thunar_component_set_ui_manager (THUNAR_COMPONENT (renamer_dialog->launcher), renamer_dialog->ui_manager); + renamer_dialog->launcher = g_object_new (THUNAR_TYPE_LAUNCHER, "widget", GTK_WIDGET (renamer_dialog), NULL); exo_binding_new (G_OBJECT (renamer_dialog), "selected-files", G_OBJECT (renamer_dialog->launcher), "selected-files"); /* add the toolbar to the dialog */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - toolbar = gtk_ui_manager_get_widget (renamer_dialog->ui_manager, "/toolbar"); -G_GNUC_END_IGNORE_DEPRECATIONS + toolbar = gtk_toolbar_new (); + xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_RENAMER_ACTION_ADD_FILES), G_OBJECT (renamer_dialog), GTK_TOOLBAR (toolbar)); + xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_RENAMER_ACTION_REMOVE_FILES), G_OBJECT (renamer_dialog), GTK_TOOLBAR (toolbar)); + seperator = gtk_separator_tool_item_new (); + gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (seperator)); + gtk_widget_show (GTK_WIDGET (seperator)); + xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_RENAMER_ACTION_CLEAR), G_OBJECT (renamer_dialog), GTK_TOOLBAR (toolbar)); + seperator = gtk_separator_tool_item_new (); + gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (seperator)); + gtk_widget_show (GTK_WIDGET (seperator)); + xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_RENAMER_ACTION_ABOUT), G_OBJECT (renamer_dialog), GTK_TOOLBAR (toolbar)); exo_binding_new (G_OBJECT (renamer_dialog), "standalone", G_OBJECT (toolbar), "visible"); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (renamer_dialog))), toolbar, FALSE, FALSE, 0); + gtk_widget_show_all (GTK_WIDGET (toolbar)); /* create the main vbox */ mbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); @@ -633,9 +627,6 @@ thunar_renamer_dialog_dispose (GObject *object) /* reset the "current-directory" property */ thunar_renamer_dialog_set_current_directory (renamer_dialog, NULL); - /* reset the widget for the launcher support */ - thunar_launcher_set_widget (renamer_dialog->launcher, NULL); - (*G_OBJECT_CLASS (thunar_renamer_dialog_parent_class)->dispose) (object); } @@ -649,10 +640,6 @@ thunar_renamer_dialog_finalize (GObject *object) /* release the launcher support */ g_object_unref (G_OBJECT (renamer_dialog->launcher)); - /* release the action group and the ui manager */ - g_object_unref (G_OBJECT (renamer_dialog->action_group)); - g_object_unref (G_OBJECT (renamer_dialog->ui_manager)); - /* release our bulk rename model */ g_object_unref (G_OBJECT (renamer_dialog->model)); @@ -841,14 +828,54 @@ thunar_renamer_dialog_response (GtkDialog *dialog, +/** + * thunar_renamer_dialog_append_menu_item: + * @renamer_dialog : Instance of a #ThunarRenamerDialog + * @menu : #GtkMenuShell to which the item should be added + * @action : #ThunarRenamerAction to select which item should be added + * + * Adds the selected, widget specific #GtkMenuItem to the passed #GtkMenuShell + * + * Return value: (transfer none): The added #GtkMenuItem + **/ +static GtkWidget* +thunar_renamer_dialog_append_menu_item (ThunarRenamerDialog *renamer_dialog, + GtkMenuShell *menu, + ThunarRenamerAction action) +{ + gchar *label_text; + gchar *tooltip_text; + const XfceGtkActionEntry *action_entry = get_action_entry (action); + GtkWidget *item; + + _thunar_return_val_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog), NULL); + _thunar_return_val_if_fail (action_entry != NULL, NULL); + + switch (action) + { + case THUNAR_RENAMER_ACTION_REMOVE_FILES: + label_text = ngettext ("Remove File", "Remove Files", g_list_length (renamer_dialog->selected_files)); + tooltip_text = ngettext ("Remove the selected file from the list of files to be renamed", + "Remove the selected files from the list of files to be renamed", g_list_length (renamer_dialog->selected_files)); + item = xfce_gtk_image_menu_item_new_from_icon_name (label_text, tooltip_text, action_entry->accel_path, action_entry->callback, + G_OBJECT (renamer_dialog), action_entry->menu_item_icon_name, GTK_MENU_SHELL (menu) ); + gtk_widget_set_sensitive (item, renamer_dialog->selected_files != NULL); + return item; + default: + return xfce_gtk_menu_item_new_from_action_entry (action_entry, G_OBJECT (renamer_dialog), menu); + } + return NULL; +} + + + static void thunar_renamer_dialog_context_menu (ThunarRenamerDialog *renamer_dialog) { - GtkActionGroup *renamer_actions = NULL; ThunarxRenamer *renamer; - GtkWidget *menu; + ThunarMenu *menu; GList *items = NULL; - gint renamer_merge_id = 0; + GList *lp = NULL; _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); @@ -863,45 +890,32 @@ thunar_renamer_dialog_context_menu (ThunarRenamerDialog *renamer_dialog) items = thunarx_renamer_get_menu_items (renamer, GTK_WINDOW (renamer_dialog), renamer_dialog->selected_files); } -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* check if we have any renamer menu items */ - if (G_UNLIKELY (items != NULL)) + menu = g_object_new (THUNAR_TYPE_MENU, "menu-type", THUNAR_MENU_TYPE_CONTEXT, + "launcher", renamer_dialog->launcher, + "tab-support-disabled", TRUE, + "change_directory-support-disabled", TRUE, NULL); + thunar_menu_add_sections (menu, THUNAR_MENU_SECTION_OPEN | THUNAR_MENU_SECTION_SENDTO); + if (G_LIKELY (renamer != NULL)) { - /* allocate a new action group and the merge id for the custom items */ - renamer_actions = gtk_action_group_new ("thunar-renamer-dialog-renamer-actions"); - renamer_merge_id = gtk_ui_manager_new_merge_id (renamer_dialog->ui_manager); - gtk_ui_manager_insert_action_group (renamer_dialog->ui_manager, renamer_actions, -1); - - /* add the items to the UI manager */ - thunar_menu_util_add_items_to_ui_manager (renamer_dialog->ui_manager, renamer_actions, renamer_merge_id, - "/file-context-menu/placeholder-renamer-actions", items); - - /* be sure to update the UI manager to avoid flickering */ - gtk_ui_manager_ensure_update (renamer_dialog->ui_manager); - - /* cleanup */ - g_list_free (items); + /* determine the menu items provided by the active renamer */ + items = thunarx_renamer_get_menu_items (renamer, GTK_WINDOW (renamer_dialog), renamer_dialog->selected_files); + if (items != NULL) + { + for(lp = items; lp != NULL; lp = lp->next) + thunar_gtk_menu_thunarx_menu_item_new (lp->data, GTK_MENU_SHELL (menu)); + g_list_free (items); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + } } + thunar_renamer_dialog_append_menu_item (renamer_dialog, GTK_MENU_SHELL (menu), THUNAR_RENAMER_ACTION_ADD_FILES); + thunar_renamer_dialog_append_menu_item (renamer_dialog, GTK_MENU_SHELL (menu), THUNAR_RENAMER_ACTION_REMOVE_FILES); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + thunar_menu_add_sections (menu, THUNAR_MENU_SECTION_PROPERTIES); + thunar_menu_hide_accel_labels (menu); + gtk_widget_show_all (GTK_WIDGET (menu)); - /* run the menu (takes over the floating of menu) */ - menu = gtk_ui_manager_get_widget (renamer_dialog->ui_manager, "/file-context-menu"); thunar_gtk_menu_run (GTK_MENU (menu)); - /* remove the previously merge items from the UI manager */ - if (G_UNLIKELY (renamer_merge_id != 0)) - { - gtk_ui_manager_remove_ui (renamer_dialog->ui_manager, renamer_merge_id); - gtk_ui_manager_ensure_update (renamer_dialog->ui_manager); - } - - /* disconnect the previously created action group */ - if (G_UNLIKELY (renamer_actions != NULL)) - { - gtk_ui_manager_remove_action_group (renamer_dialog->ui_manager, renamer_actions); - g_object_unref (G_OBJECT (renamer_actions)); - } - -G_GNUC_END_IGNORE_DEPRECATIONS /* release the additional reference on the dialog */ g_object_unref (G_OBJECT (renamer_dialog)); } @@ -1031,8 +1045,7 @@ trd_video_filter_func (const GtkFileFilterInfo *info, static void -thunar_renamer_dialog_action_add_files (GtkAction *action, - ThunarRenamerDialog *renamer_dialog) +thunar_renamer_dialog_action_add_files (ThunarRenamerDialog *renamer_dialog) { GtkFileFilter *filter; ThunarFile *file; @@ -1041,9 +1054,6 @@ thunar_renamer_dialog_action_add_files (GtkAction *action, GSList *lp; gchar *uri; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); /* allocate the file chooser */ @@ -1139,8 +1149,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_renamer_dialog_action_remove_files (GtkAction *action, - ThunarRenamerDialog *renamer_dialog) +thunar_renamer_dialog_action_remove_files (ThunarRenamerDialog *renamer_dialog) { GtkTreeRowReference *row; GtkTreeSelection *selection; @@ -1149,9 +1158,6 @@ thunar_renamer_dialog_action_remove_files (GtkAction *action, GList *rows; GList *lp; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); /* determine the selected rows in the view */ @@ -1188,12 +1194,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_renamer_dialog_action_clear (GtkAction *action, - ThunarRenamerDialog *renamer_dialog) +thunar_renamer_dialog_action_clear (ThunarRenamerDialog *renamer_dialog) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); /* just clear the list of files in the model */ @@ -1203,12 +1205,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_renamer_dialog_action_about (GtkAction *action, - ThunarRenamerDialog *renamer_dialog) +thunar_renamer_dialog_action_about (ThunarRenamerDialog *renamer_dialog) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); /* just popup the about dialog */ @@ -1220,26 +1218,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_renamer_dialog_action_properties (GtkAction *action, - ThunarRenamerDialog *renamer_dialog) -{ - GtkWidget *dialog; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); - - /* popup the properties dialog */ - dialog = thunar_properties_dialog_new (GTK_WINDOW (renamer_dialog)); - gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); - thunar_properties_dialog_set_files (THUNAR_PROPERTIES_DIALOG (dialog), renamer_dialog->selected_files); - gtk_widget_show (dialog); -} - - - -static void thunar_renamer_dialog_name_column_clicked (GtkTreeViewColumn *column, ThunarRenamerDialog *renamer_dialog) { @@ -1635,17 +1613,9 @@ thunar_renamer_dialog_row_activated (GtkTreeView *tree_view, GtkTreeViewColumn *column, ThunarRenamerDialog *renamer_dialog) { - GtkAction *action; - - _thunar_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); - /* just activate the "open" action */ - action = thunar_gtk_ui_manager_get_action_by_name (renamer_dialog->ui_manager, "open"); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS + thunar_launcher_activate_selected_files (renamer_dialog->launcher, THUNAR_LAUNCHER_OPEN_AS_NEW_WINDOW, NULL); } @@ -1657,7 +1627,6 @@ thunar_renamer_dialog_selection_changed (GtkTreeSelection *selection, GtkTreeModel *model; GtkTreeIter iter; ThunarFile *file; - GtkAction *action; GList *rows; GList *lp; gint n_selected_files = 0; @@ -1687,22 +1656,6 @@ thunar_renamer_dialog_selection_changed (GtkTreeSelection *selection, } g_list_free (rows); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* the "Remove Files" action is only sensitive if we have one or more files in the selection */ - action = gtk_action_group_get_action (renamer_dialog->action_group, "remove-files"); - g_object_set (G_OBJECT (action), - "label", ngettext ("Remove File", "Remove Files", n_selected_files), - "sensitive", (n_selected_files > 0), - "tooltip", ngettext ("Remove the selected file from the list of files to be renamed", - "Remove the selected files from the list of files to be renamed", - n_selected_files), - NULL); - - /* the "Properties" action is only sensitive if we have exactly one selected file */ - action = gtk_action_group_get_action (renamer_dialog->action_group, "properties"); - gtk_action_set_sensitive (action, n_selected_files > 0); - G_GNUC_END_IGNORE_DEPRECATIONS - /* notify listeners */ g_object_notify (G_OBJECT (renamer_dialog), "selected-files"); } diff --git a/thunar/thunar-shortcuts-pane-ui.xml b/thunar/thunar-shortcuts-pane-ui.xml deleted file mode 100644 index 58f928d7..00000000 --- a/thunar/thunar-shortcuts-pane-ui.xml +++ /dev/null @@ -1,29 +0,0 @@ -<ui> - - <!-- - Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - - Thunar shortcuts pane 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="file-menu"> - <menu action="sendto-menu"> - <placeholder name="placeholder-sendto-sidepane"> - <menuitem action="sendto-shortcuts" /> - </placeholder> - </menu> - </menu> - </menubar> - - <popup action="file-context-menu"> - <menu action="sendto-menu"> - <placeholder name="placeholder-sendto-sidepane"> - <menuitem action="sendto-shortcuts" /> - </placeholder> - </menu> - </popup> - -</ui> diff --git a/thunar/thunar-shortcuts-pane.c b/thunar/thunar-shortcuts-pane.c index 2cc26a20..7e4f8fb1 100644 --- a/thunar/thunar-shortcuts-pane.c +++ b/thunar/thunar-shortcuts-pane.c @@ -25,7 +25,6 @@ #include <thunar/thunar-private.h> #include <thunar/thunar-shortcuts-model.h> #include <thunar/thunar-shortcuts-pane.h> -#include <thunar/thunar-shortcuts-pane-ui.h> #include <thunar/thunar-shortcuts-view.h> #include <thunar/thunar-side-pane.h> @@ -37,7 +36,6 @@ enum PROP_CURRENT_DIRECTORY, PROP_SELECTED_FILES, PROP_SHOW_HIDDEN, - PROP_UI_MANAGER, }; @@ -61,11 +59,6 @@ static void thunar_shortcuts_pane_set_current_directory (ThunarNavigato static GList *thunar_shortcuts_pane_get_selected_files (ThunarComponent *component); static void thunar_shortcuts_pane_set_selected_files (ThunarComponent *component, GList *selected_files); -static GtkUIManager *thunar_shortcuts_pane_get_ui_manager (ThunarComponent *component); -static void thunar_shortcuts_pane_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager); -static void thunar_shortcuts_pane_action_shortcuts_add (GtkAction *action, - ThunarShortcutsPane *shortcuts_pane); static void thunar_shortcuts_pane_show_shortcuts_view_padding (GtkWidget *widget); static void thunar_shortcuts_pane_hide_shortcuts_view_padding (GtkWidget *widget); @@ -83,10 +76,6 @@ struct _ThunarShortcutsPane ThunarFile *current_directory; GList *selected_files; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - guint ui_merge_id; - GtkWidget *view; guint idle_select_directory; @@ -94,13 +83,6 @@ struct _ThunarShortcutsPane -static const GtkActionEntry action_entries[] = -{ - { "sendto-shortcuts", "bookmark-new", "", NULL, NULL, G_CALLBACK (thunar_shortcuts_pane_action_shortcuts_add), }, -}; - - - G_DEFINE_TYPE_WITH_CODE (ThunarShortcutsPane, thunar_shortcuts_pane, GTK_TYPE_SCROLLED_WINDOW, G_IMPLEMENT_INTERFACE (THUNAR_TYPE_NAVIGATOR, thunar_shortcuts_pane_navigator_init) G_IMPLEMENT_INTERFACE (THUNAR_TYPE_COMPONENT, thunar_shortcuts_pane_component_init) @@ -124,7 +106,6 @@ thunar_shortcuts_pane_class_init (ThunarShortcutsPaneClass *klass) /* override ThunarComponent's properties */ g_object_class_override_property (gobject_class, PROP_SELECTED_FILES, "selected-files"); - g_object_class_override_property (gobject_class, PROP_UI_MANAGER, "ui-manager"); /* override ThunarSidePane's properties */ g_object_class_override_property (gobject_class, PROP_SHOW_HIDDEN, "show-hidden"); @@ -137,8 +118,6 @@ thunar_shortcuts_pane_component_init (ThunarComponentIface *iface) { iface->get_selected_files = thunar_shortcuts_pane_get_selected_files; iface->set_selected_files = thunar_shortcuts_pane_set_selected_files; - iface->get_ui_manager = thunar_shortcuts_pane_get_ui_manager; - iface->set_ui_manager = thunar_shortcuts_pane_set_ui_manager; } @@ -166,13 +145,6 @@ thunar_shortcuts_pane_init (ThunarShortcutsPane *shortcuts_pane) { GtkWidget *vscrollbar; - /* setup the action group for the shortcuts actions */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - shortcuts_pane->action_group = gtk_action_group_new ("ThunarShortcutsPane"); - gtk_action_group_set_translation_domain (shortcuts_pane->action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (shortcuts_pane->action_group, action_entries, G_N_ELEMENTS (action_entries), shortcuts_pane); -G_GNUC_END_IGNORE_DEPRECATIONS - /* configure the GtkScrolledWindow */ gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (shortcuts_pane), NULL); gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (shortcuts_pane), NULL); @@ -209,7 +181,6 @@ thunar_shortcuts_pane_dispose (GObject *object) thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (shortcuts_pane), NULL); thunar_component_set_selected_files (THUNAR_COMPONENT (shortcuts_pane), NULL); - thunar_component_set_ui_manager (THUNAR_COMPONENT (shortcuts_pane), NULL); (*G_OBJECT_CLASS (thunar_shortcuts_pane_parent_class)->dispose) (object); } @@ -219,11 +190,6 @@ thunar_shortcuts_pane_dispose (GObject *object) static void thunar_shortcuts_pane_finalize (GObject *object) { - ThunarShortcutsPane *shortcuts_pane = THUNAR_SHORTCUTS_PANE (object); - - /* release our action group */ - g_object_unref (G_OBJECT (shortcuts_pane->action_group)); - (*G_OBJECT_CLASS (thunar_shortcuts_pane_parent_class)->finalize) (object); } @@ -249,10 +215,6 @@ thunar_shortcuts_pane_get_property (GObject *object, g_value_set_boolean (value, thunar_side_pane_get_show_hidden (THUNAR_SIDE_PANE (object))); break; - case PROP_UI_MANAGER: - g_value_set_object (value, thunar_component_get_ui_manager (THUNAR_COMPONENT (object))); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -281,10 +243,6 @@ thunar_shortcuts_pane_set_property (GObject *object, thunar_side_pane_set_show_hidden (THUNAR_SIDE_PANE (object), g_value_get_boolean (value)); break; - case PROP_UI_MANAGER: - thunar_component_set_ui_manager (THUNAR_COMPONENT (object), g_value_get_object (value)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -372,11 +330,6 @@ thunar_shortcuts_pane_set_selected_files (ThunarComponent *component, GList *selected_files) { ThunarShortcutsPane *shortcuts_pane = THUNAR_SHORTCUTS_PANE (component); - GtkTreeModel *model; - GtkTreeModel *child_model; - GtkAction *action; - GList *lp; - gint n; /* disconnect from the previously selected files... */ thunar_g_file_list_free (shortcuts_pane->selected_files); @@ -384,140 +337,40 @@ thunar_shortcuts_pane_set_selected_files (ThunarComponent *component, /* ...and take a copy of the newly selected files */ shortcuts_pane->selected_files = thunar_g_file_list_copy (selected_files); - /* check if the selection contains only folders */ - for (lp = selected_files, n = 0; lp != NULL; lp = lp->next, ++n) - if (!thunar_file_is_directory (lp->data)) - break; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* change the visibility of the "shortcuts-add" action appropriately */ - action = gtk_action_group_get_action (shortcuts_pane->action_group, "sendto-shortcuts"); -G_GNUC_END_IGNORE_DEPRECATIONS - if (lp == NULL && selected_files != NULL) - { - /* check if atleast one of the selected folders is not already present in the model */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (shortcuts_pane->view)); - if (G_LIKELY (model != NULL)) - { - /* check all selected folders */ - child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); - for (lp = selected_files; lp != NULL; lp = lp->next) - if (!thunar_shortcuts_model_has_bookmark (THUNAR_SHORTCUTS_MODEL (child_model), thunar_file_get_file (lp->data))) - break; - } - - /* display the action and change the label appropriately */ - g_object_set (G_OBJECT (action), - "label", ngettext ("Side Pane (Create Shortcut)", "Side Pane (Create Shortcuts)", n), - "sensitive", (lp != NULL), - "tooltip", ngettext ("Add the selected folder to the shortcuts side pane", - "Add the selected folders to the shortcuts side pane", n), - "visible", TRUE, - NULL); - } - else - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* hide the action */ - gtk_action_set_visible (action, FALSE); -G_GNUC_END_IGNORE_DEPRECATIONS - } - /* notify listeners */ g_object_notify (G_OBJECT (shortcuts_pane), "selected-files"); } -static GtkUIManager* -thunar_shortcuts_pane_get_ui_manager (ThunarComponent *component) -{ - return THUNAR_SHORTCUTS_PANE (component)->ui_manager; -} - - - -static void -thunar_shortcuts_pane_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager) -{ - ThunarShortcutsPane *shortcuts_pane = THUNAR_SHORTCUTS_PANE (component); - GError *error = NULL; - - /* disconnect from the previous UI manager */ - if (G_UNLIKELY (shortcuts_pane->ui_manager != NULL)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* drop our action group from the previous UI manager */ - gtk_ui_manager_remove_action_group (shortcuts_pane->ui_manager, shortcuts_pane->action_group); - - /* unmerge our ui controls from the previous UI manager */ - gtk_ui_manager_remove_ui (shortcuts_pane->ui_manager, shortcuts_pane->ui_merge_id); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* drop our reference on the previous UI manager */ - g_object_unref (G_OBJECT (shortcuts_pane->ui_manager)); - } - - /* activate the new UI manager */ - shortcuts_pane->ui_manager = ui_manager; - - /* connect to the new UI manager */ - if (G_LIKELY (ui_manager != NULL)) - { - /* we keep a reference on the new manager */ - g_object_ref (G_OBJECT (ui_manager)); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* add our action group to the new manager */ - gtk_ui_manager_insert_action_group (ui_manager, shortcuts_pane->action_group, -1); - - /* merge our UI control items with the new manager */ - shortcuts_pane->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_shortcuts_pane_ui, thunar_shortcuts_pane_ui_length, &error); -G_GNUC_END_IGNORE_DEPRECATIONS - if (G_UNLIKELY (shortcuts_pane->ui_merge_id == 0)) - { - g_error ("Failed to merge ThunarShortcutsPane menus: %s", error->message); - g_error_free (error); - } - } - - /* notify listeners */ - g_object_notify (G_OBJECT (shortcuts_pane), "ui-manager"); -} - - - -static void -thunar_shortcuts_pane_action_shortcuts_add (GtkAction *action, - ThunarShortcutsPane *shortcuts_pane) +/** + * thunar_shortcuts_pane_add_shortcut: + * @shortcuts_pane : Instance of a #ThunarShortcutsPane + * @file : #ThunarFile for which a shortcut should be added + * + * Adds a shortcut for the passed #ThunarFile to the shortcuts_pane. + * Only folders will be considered. + **/ +void +thunar_shortcuts_pane_add_shortcut (ThunarShortcutsPane *shortcuts_pane, + ThunarFile *file) { GtkTreeModel *model; GtkTreeModel *child_model; - GList *lp; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_PANE (shortcuts_pane)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); /* determine the shortcuts model for the view */ model = gtk_tree_view_get_model (GTK_TREE_VIEW (shortcuts_pane->view)); if (G_LIKELY (model != NULL)) { - /* add all selected folders to the model */ child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (model)); - for (lp = shortcuts_pane->selected_files; lp != NULL; lp = lp->next) - if (G_LIKELY (thunar_file_is_directory (lp->data))) - { - /* append the folder to the shortcuts model */ - thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (child_model), NULL, lp->data); - } - - /* update the user interface to reflect the new action state */ - lp = thunar_g_file_list_copy (shortcuts_pane->selected_files); - thunar_component_set_selected_files (THUNAR_COMPONENT (shortcuts_pane), lp); - thunar_g_file_list_free (lp); + if (G_LIKELY (thunar_file_is_directory (file))) + { + /* append the folder to the shortcuts model */ + thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (child_model), NULL, file); + } } } diff --git a/thunar/thunar-shortcuts-pane.h b/thunar/thunar-shortcuts-pane.h index 3c2161a6..77d76425 100644 --- a/thunar/thunar-shortcuts-pane.h +++ b/thunar/thunar-shortcuts-pane.h @@ -34,7 +34,9 @@ typedef struct _ThunarShortcutsPane ThunarShortcutsPane; #define THUNAR_IS_SHORTCUTS_PANE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_SHORTCUTS_PANE)) #define THUNAR_SHORTCUTS_PANE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_SHORTCUTS_PANE, ThunarShortcutsPaneClass)) -GType thunar_shortcuts_pane_get_type (void) G_GNUC_CONST; +GType thunar_shortcuts_pane_get_type (void) G_GNUC_CONST; +void thunar_shortcuts_pane_add_shortcut (ThunarShortcutsPane *shortcuts_pane, + ThunarFile *file); G_END_DECLS; diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c index 503573f5..3b530c7c 100644 --- a/thunar/thunar-shortcuts-view.c +++ b/thunar/thunar-shortcuts-view.c @@ -40,7 +40,6 @@ #include <thunar/thunar-dnd.h> #include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gtk-extensions.h> -#include <thunar/thunar-menu-util.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-shortcuts-icon-renderer.h> @@ -1256,7 +1255,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS } /* add the menu items to the menu */ - thunar_menu_util_add_items_to_menu (menu, items); + for (lp = items; lp != NULL; lp = lp->next) + thunar_gtk_menu_thunarx_menu_item_new (lp->data, GTK_MENU_SHELL (menu)); /* cleanup */ g_list_free (items); diff --git a/thunar/thunar-standard-view-ui.xml b/thunar/thunar-standard-view-ui.xml deleted file mode 100644 index 6972427f..00000000 --- a/thunar/thunar-standard-view-ui.xml +++ /dev/null @@ -1,100 +0,0 @@ -<ui> - - <!-- - Copyright (c) 2005-2006 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. - --> - - <accelerator action="zoom-in-alt"/> - <accelerator action="open-location-alt"/> - - <menubar name="main-menu"> - <menu action="file-menu"> - <placeholder name="placeholder-create-actions"> - <menuitem action="create-folder" /> - <menuitem action="create-document" /> - </placeholder> - <placeholder name="placeholder-file-properties"> - <menuitem action="properties" /> - </placeholder> - </menu> - - <menu action="edit-menu"> - <placeholder name="placeholder-edit-clipboard-actions"> - <menuitem action="cut" /> - <menuitem action="copy" /> - <menuitem action="paste" /> - <separator /> - <menuitem action="move-to-trash" /> - <menuitem action="delete" /> - </placeholder> - <placeholder name="placeholder-edit-select-actions"> - <menuitem action="select-all-files" /> - <menuitem action="select-by-pattern" /> - <menuitem action="invert-selection" /> - </placeholder> - <placeholder name="placeholder-edit-alter-actions"> - <menuitem action="duplicate" /> - <menuitem action="make-link" /> - <menuitem action="rename" /> - <menuitem action="restore" /> - </placeholder> - </menu> - - <menu action="go-menu"> - <placeholder name="placeholder-go-history-actions"> - <menuitem action="back" /> - <menuitem action="forward" /> - </placeholder> - </menu> - </menubar> - - <popup action="file-context-menu"> - <placeholder name="placeholder-clipboard-actions"> - <menuitem action="cut" /> - <menuitem action="copy" /> - <menuitem action="paste-into-folder" /> - <separator /> - <menuitem action="move-to-trash" /> - <menuitem action="delete" /> - </placeholder> - <placeholder name="placeholder-edit-actions"> - <menuitem action="rename" /> - <menuitem action="restore" /> - </placeholder> - <placeholder name="placeholder-file-actions"> - <menuitem action="properties" /> - </placeholder> - </popup> - - <popup action="folder-context-menu"> - <menuitem action="create-folder" /> - <menuitem action="create-document" /> - <menuitem action="empty-trash" /> - <separator /> - <menuitem action="paste" /> - <separator /> - <placeholder name="placeholder-custom-actions" /> - <separator /> - <placeholder name="placeholder-view-items-actions" /> - <separator /> - <menuitem action="zoom-in" /> - <menuitem action="zoom-out" /> - <menuitem action="zoom-reset" /> - <separator /> - <menuitem action="properties" /> - </popup> - - <toolbar name="location-toolbar"> - <placeholder name="placeholder-history-actions"> - <toolitem action="back" /> - <toolitem action="forward" /> - </placeholder> - </toolbar> - -</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 c9f0e1b3..cf94c984 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -33,6 +33,7 @@ #include <gdk/gdkkeysyms.h> #include <thunar/thunar-application.h> +#include <thunar/thunar-menu.h> #include <thunar/thunar-create-dialog.h> #include <thunar/thunar-dialogs.h> #include <thunar/thunar-dnd.h> @@ -42,16 +43,14 @@ #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-history.h> #include <thunar/thunar-icon-renderer.h> +#include <thunar/thunar-launcher.h> #include <thunar/thunar-marshal.h> -#include <thunar/thunar-menu-util.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-private.h> #include <thunar/thunar-properties-dialog.h> #include <thunar/thunar-renamer-dialog.h> #include <thunar/thunar-simple-job.h> #include <thunar/thunar-standard-view.h> -#include <thunar/thunar-standard-view-ui.h> -#include <thunar/thunar-templates-action.h> #include <thunar/thunar-thumbnailer.h> #include <thunar/thunar-util.h> @@ -72,16 +71,15 @@ enum PROP_SELECTED_FILES, PROP_SHOW_HIDDEN, PROP_STATUSBAR_TEXT, - PROP_UI_MANAGER, PROP_ZOOM_LEVEL, PROP_THUMBNAIL_DRAW_FRAMES, + PROP_ACCEL_GROUP, N_PROPERTIES }; /* Signal identifiers */ enum { - DELETE_SELECTED_FILES, START_OPEN_LOCATION, LAST_SIGNAL, }; @@ -117,12 +115,9 @@ static void thunar_standard_view_unrealize (Gtk static void thunar_standard_view_grab_focus (GtkWidget *widget); static gboolean thunar_standard_view_draw (GtkWidget *widget, cairo_t *cr); -static GList *thunar_standard_view_get_selected_files (ThunarComponent *component); -static void thunar_standard_view_set_selected_files (ThunarComponent *component, - GList *selected_files); -static GtkUIManager *thunar_standard_view_get_ui_manager (ThunarComponent *component); -static void thunar_standard_view_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager); +static GList *thunar_standard_view_get_selected_files_component (ThunarComponent *component); +static void thunar_standard_view_set_selected_files_component (ThunarComponent *component, + GList *selected_files); static ThunarFile *thunar_standard_view_get_current_directory (ThunarNavigator *navigator); static void thunar_standard_view_set_current_directory (ThunarNavigator *navigator, ThunarFile *current_directory); @@ -148,7 +143,6 @@ static void thunar_standard_view_scroll_to_file (Thu gboolean use_align, gfloat row_align, gfloat col_align); -static gboolean thunar_standard_view_delete_selected_files (ThunarStandardView *standard_view); static GdkDragAction thunar_standard_view_get_dest_actions (ThunarStandardView *standard_view, GdkDragContext *context, gint x, @@ -159,47 +153,17 @@ static ThunarFile *thunar_standard_view_get_drop_file (Thu gint x, gint y, GtkTreePath **path_return); -static void thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view); static void thunar_standard_view_update_statusbar_text (ThunarStandardView *standard_view); static void thunar_standard_view_current_directory_destroy (ThunarFile *current_directory, ThunarStandardView *standard_view); static void thunar_standard_view_current_directory_changed (ThunarFile *current_directory, ThunarStandardView *standard_view); -static void thunar_standard_view_action_create_empty_file (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_create_folder (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_create_template (GtkAction *action, - const ThunarFile *file, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_properties (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_cut (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_copy (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_paste (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_move_to_trash (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_delete (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_paste_into_folder (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_select_all_files (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_select_by_pattern (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_selection_invert (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_duplicate (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_make_link (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_rename (GtkAction *action, - ThunarStandardView *standard_view); -static void thunar_standard_view_action_restore (GtkAction *action, - ThunarStandardView *standard_view); +static GList *thunar_standard_view_get_selected_files_view (ThunarView *view); +static void thunar_standard_view_set_selected_files_view (ThunarView *view, + GList *selected_files); +static void thunar_standard_view_select_all_files (ThunarView *view); +static void thunar_standard_view_select_by_pattern (ThunarView *view); +static void thunar_standard_view_selection_invert (ThunarView *view); static GClosure *thunar_standard_view_new_files_closure (ThunarStandardView *standard_view, GtkWidget *source_view); static void thunar_standard_view_new_files (ThunarStandardView *standard_view, @@ -216,9 +180,6 @@ static gboolean thunar_standard_view_key_press_event (Gtk static gboolean thunar_standard_view_scroll_event (GtkWidget *view, GdkEventScroll *event, ThunarStandardView *standard_view); -static gboolean thunar_standard_view_button_press_event (GtkWidget *view, - GdkEventButton *event, - ThunarStandardView *standard_view); static gboolean thunar_standard_view_drag_drop (GtkWidget *view, GdkDragContext *context, gint x, @@ -300,6 +261,7 @@ static void thunar_standard_view_scrolled (Gtk ThunarStandardView *standard_view); static void thunar_standard_view_size_allocate (ThunarStandardView *standard_view, GtkAllocation *allocation); +static void thunar_standard_view_connect_accelerators (ThunarStandardView *standard_view); @@ -308,26 +270,9 @@ struct _ThunarStandardViewPrivate /* current directory of the view */ ThunarFile *current_directory; - GtkAction *action_create_folder; - GtkAction *action_create_document; - GtkAction *action_properties; - GtkAction *action_cut; - GtkAction *action_copy; - GtkAction *action_paste; - GtkAction *action_move_to_trash; - GtkAction *action_delete; - GtkAction *action_paste_into_folder; - GtkAction *action_duplicate; - GtkAction *action_make_link; - GtkAction *action_rename; - GtkAction *action_restore; - /* history of the current view */ ThunarHistory *history; - /* support for file manager extensions */ - ThunarxProviderFactory *provider_factory; - /* zoom-level support */ ThunarZoomLevel zoom_level; @@ -338,10 +283,6 @@ struct _ThunarStandardViewPrivate gchar *statusbar_text; guint statusbar_text_idle_id; - /* custom menu actions support */ - GtkActionGroup *custom_actions; - gint custom_merge_id; - /* right-click drag/popup support */ GList *drag_g_file_list; guint drag_scroll_timer_id; @@ -394,29 +335,15 @@ struct _ThunarStandardViewPrivate GtkTreePath *selection_before_delete; }; - - -static const GtkActionEntry action_entries[] = +static XfceGtkActionEntry thunar_standard_view_action_entries[] = { - { "file-context-menu", NULL, N_ ("File Context Menu"), NULL, NULL, NULL, }, - { "folder-context-menu", NULL, N_ ("Folder Context Menu"), NULL, NULL, NULL, }, - { "create-folder", "folder-new", N_ ("Create _Folder..."), "<control><shift>N", N_ ("Create an empty folder within the current folder"), G_CALLBACK (thunar_standard_view_action_create_folder), }, - { "properties", "document-properties", N_ ("_Properties..."), "<alt>Return", N_ ("View the properties of the selected file"), G_CALLBACK (thunar_standard_view_action_properties), }, - { "cut", "edit-cut", N_ ("Cu_t"), "<control>X", NULL, G_CALLBACK (thunar_standard_view_action_cut), }, - { "copy", "edit-copy", N_ ("_Copy"), "<control>C", NULL, G_CALLBACK (thunar_standard_view_action_copy), }, - { "paste", "edit-paste", N_ ("_Paste"), "<control>V", N_ ("Move or copy files previously selected by a Cut or Copy command"), G_CALLBACK (thunar_standard_view_action_paste), }, - { "move-to-trash", "user-trash", N_ ("Mo_ve to Trash"), NULL, NULL, G_CALLBACK (thunar_standard_view_action_move_to_trash), }, - { "delete", "edit-delete", N_ ("_Delete"), NULL, NULL, G_CALLBACK (thunar_standard_view_action_delete), }, - { "paste-into-folder", "edit-paste", N_ ("Paste Into Folder"), NULL, N_ ("Move or copy files previously selected by a Cut or Copy command into the selected folder"), G_CALLBACK (thunar_standard_view_action_paste_into_folder), }, - { "select-all-files", NULL, N_ ("Select _all Files"), NULL, N_ ("Select all files in this window"), G_CALLBACK (thunar_standard_view_action_select_all_files), }, - { "select-by-pattern", NULL, N_ ("Select _by Pattern..."), "<control>S", N_ ("Select all files that match a certain pattern"), G_CALLBACK (thunar_standard_view_action_select_by_pattern), }, - { "invert-selection", NULL, N_ ("_Invert Selection"), NULL, N_ ("Select all files but not those currently selected"), G_CALLBACK (thunar_standard_view_action_selection_invert), }, - { "duplicate", NULL, N_ ("Du_plicate"), NULL, NULL, G_CALLBACK (thunar_standard_view_action_duplicate), }, - { "make-link", NULL, N_ ("Ma_ke Link"), NULL, NULL, G_CALLBACK (thunar_standard_view_action_make_link), }, - { "rename", NULL, N_ ("_Rename..."), "F2", NULL, G_CALLBACK (thunar_standard_view_action_rename), }, - { "restore", NULL, N_ ("_Restore"), NULL, NULL, G_CALLBACK (thunar_standard_view_action_restore), }, + { THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES, "<Actions>/ThunarStandardView/select-all-files", "<Primary>a", XFCE_GTK_MENU_ITEM, N_ ("Select _all Files"), N_ ("Select all files in this window"), NULL, G_CALLBACK (thunar_standard_view_select_all_files), }, + { THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN, "<Actions>/ThunarStandardView/select-by-pattern", "<Primary>s", XFCE_GTK_MENU_ITEM, N_ ("Select _by Pattern..."), N_ ("Select all files that match a certain pattern"), NULL, G_CALLBACK (thunar_standard_view_select_by_pattern), }, + { THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION, "<Actions>/ThunarStandardView/invert-selection", "", XFCE_GTK_MENU_ITEM, N_ ("_Invert Selection"), N_ ("Select all files but not those currently selected"), NULL, G_CALLBACK (thunar_standard_view_selection_invert), }, }; +#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_standard_view_action_entries,G_N_ELEMENTS(thunar_standard_view_action_entries),id) + /* Target types for dragging from the view */ static const GtkTargetEntry drag_targets[] = { @@ -450,7 +377,6 @@ static void thunar_standard_view_class_init (ThunarStandardViewClass *klass) { GtkWidgetClass *gtkwidget_class; - GtkBindingSet *binding_set; GObjectClass *gobject_class; gpointer g_iface; @@ -467,9 +393,7 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) gtkwidget_class->grab_focus = thunar_standard_view_grab_focus; gtkwidget_class->draw = thunar_standard_view_draw; - klass->delete_selected_files = thunar_standard_view_delete_selected_files; - klass->connect_ui_manager = (gpointer) exo_noop; - klass->disconnect_ui_manager = (gpointer) exo_noop; + xfce_gtk_translate_action_entries (thunar_standard_view_action_entries, G_N_ELEMENTS (thunar_standard_view_action_entries)); /** * ThunarStandardView:loading: @@ -532,10 +456,6 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) g_param_spec_override ("selected-files", g_object_interface_find_property (g_iface, "selected-files")); - standard_view_props[PROP_UI_MANAGER] = - g_param_spec_override ("ui-manager", - g_object_interface_find_property (g_iface, "ui-manager")); - /* override ThunarNavigator's properties */ g_iface = g_type_default_interface_peek (THUNAR_TYPE_NAVIGATOR); standard_view_props[PROP_CURRENT_DIRECTORY] = @@ -556,6 +476,14 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) g_param_spec_override ("zoom-level", g_object_interface_find_property (g_iface, "zoom-level")); + standard_view_props[PROP_ACCEL_GROUP] = + g_param_spec_object ("accel-group", + "accel-group", + "accel-group", + GTK_TYPE_ACCEL_GROUP, + G_PARAM_WRITABLE + | G_PARAM_CONSTRUCT_ONLY); + /* install all properties */ g_object_class_install_properties (gobject_class, N_PROPERTIES, standard_view_props); @@ -578,30 +506,6 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); - - /** - * ThunarStandardView::delete-selected-files: - * @standard_view : a #ThunarStandardView. - * - * Emitted whenever the user presses the Delete key. This - * is an internal signal used to bind the action to keys. - **/ - standard_view_signals[DELETE_SELECTED_FILES] = - g_signal_new (I_("delete-selected-files"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ThunarStandardViewClass, delete_selected_files), - g_signal_accumulator_true_handled, NULL, - _thunar_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); - - /* setup the key bindings for the standard views */ - binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_BackSpace, GDK_CONTROL_MASK, "delete-selected-files", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_Delete, 0, "delete-selected-files", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_Delete, GDK_SHIFT_MASK, "delete-selected-files", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Delete, 0, "delete-selected-files", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Delete, GDK_SHIFT_MASK, "delete-selected-files", 0); } @@ -609,10 +513,8 @@ thunar_standard_view_class_init (ThunarStandardViewClass *klass) static void thunar_standard_view_component_init (ThunarComponentIface *iface) { - iface->get_selected_files = thunar_standard_view_get_selected_files; - iface->set_selected_files = thunar_standard_view_set_selected_files; - iface->get_ui_manager = thunar_standard_view_get_ui_manager; - iface->set_ui_manager = thunar_standard_view_set_ui_manager; + iface->get_selected_files = thunar_standard_view_get_selected_files_component; + iface->set_selected_files = thunar_standard_view_set_selected_files_component; } @@ -639,6 +541,8 @@ thunar_standard_view_view_init (ThunarViewIface *iface) iface->reload = thunar_standard_view_reload; iface->get_visible_range = thunar_standard_view_get_visible_range; iface->scroll_to_file = thunar_standard_view_scroll_to_file; + iface->get_selected_files = thunar_standard_view_get_selected_files_view; + iface->set_selected_files = thunar_standard_view_set_selected_files_view; } @@ -654,9 +558,6 @@ thunar_standard_view_init (ThunarStandardView *standard_view) /* grab a reference on the preferences */ standard_view->preferences = thunar_preferences_get (); - /* grab a reference on the provider factory */ - standard_view->priv->provider_factory = thunarx_provider_factory_get_default (); - /* create a thumbnailer */ standard_view->priv->thumbnailer = thunar_thumbnailer_get (); g_signal_connect (G_OBJECT (standard_view->priv->thumbnailer), "request-finished", G_CALLBACK (thunar_standard_view_finished_thumbnailing), standard_view); @@ -670,42 +571,8 @@ thunar_standard_view_init (ThunarStandardView *standard_view) gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (standard_view), NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (standard_view), GTK_SHADOW_IN); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the action group for this view */ - standard_view->action_group = gtk_action_group_new ("ThunarStandardView"); - gtk_action_group_set_translation_domain (standard_view->action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (standard_view->action_group, action_entries, - G_N_ELEMENTS (action_entries), - GTK_WIDGET (standard_view)); - - /* lookup all actions to speed up access later */ - standard_view->priv->action_create_folder = gtk_action_group_get_action (standard_view->action_group, "create-folder"); - standard_view->priv->action_properties = gtk_action_group_get_action (standard_view->action_group, "properties"); - standard_view->priv->action_cut = gtk_action_group_get_action (standard_view->action_group, "cut"); - standard_view->priv->action_copy = gtk_action_group_get_action (standard_view->action_group, "copy"); - standard_view->priv->action_paste = gtk_action_group_get_action (standard_view->action_group, "paste"); - standard_view->priv->action_move_to_trash = gtk_action_group_get_action (standard_view->action_group, "move-to-trash"); - standard_view->priv->action_delete = gtk_action_group_get_action (standard_view->action_group, "delete"); - standard_view->priv->action_paste_into_folder = gtk_action_group_get_action (standard_view->action_group, "paste-into-folder"); - standard_view->priv->action_duplicate = gtk_action_group_get_action (standard_view->action_group, "duplicate"); - standard_view->priv->action_make_link = gtk_action_group_get_action (standard_view->action_group, "make-link"); - standard_view->priv->action_rename = gtk_action_group_get_action (standard_view->action_group, "rename"); - standard_view->priv->action_restore = gtk_action_group_get_action (standard_view->action_group, "restore"); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* add the "Create Document" sub menu action */ - standard_view->priv->action_create_document = thunar_templates_action_new ("create-document", _("Create _Document")); - g_signal_connect (G_OBJECT (standard_view->priv->action_create_document), "create-empty-file", - G_CALLBACK (thunar_standard_view_action_create_empty_file), standard_view); - g_signal_connect (G_OBJECT (standard_view->priv->action_create_document), "create-template", - G_CALLBACK (thunar_standard_view_action_create_template), standard_view); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_action_group_add_action (standard_view->action_group, standard_view->priv->action_create_document); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_unref (G_OBJECT (standard_view->priv->action_create_document)); - /* setup the history support */ - standard_view->priv->history = g_object_new (THUNAR_TYPE_HISTORY, "action-group", standard_view->action_group, NULL); + standard_view->priv->history = g_object_new (THUNAR_TYPE_HISTORY, NULL); g_signal_connect_swapped (G_OBJECT (standard_view->priv->history), "change-directory", G_CALLBACK (thunar_navigator_change_directory), standard_view); /* setup the list model */ @@ -810,7 +677,6 @@ thunar_standard_view_constructor (GType type, /* setup support to navigate using a horizontal mouse wheel and the back and forward buttons */ g_signal_connect (G_OBJECT (view), "scroll-event", G_CALLBACK (thunar_standard_view_scroll_event), object); - g_signal_connect (G_OBJECT (view), "button-press-event", G_CALLBACK (thunar_standard_view_button_press_event), object); /* need to catch certain keys for the internal view widget */ g_signal_connect (G_OBJECT (view), "key-press-event", G_CALLBACK (thunar_standard_view_key_press_event), object); @@ -870,9 +736,6 @@ thunar_standard_view_dispose (GObject *object) standard_view->priv->drag_timer_event = NULL; } - /* reset the UI manager property */ - thunar_component_set_ui_manager (THUNAR_COMPONENT (standard_view), NULL); - /* disconnect from file */ if (standard_view->priv->current_directory != NULL) { @@ -895,8 +758,14 @@ thunar_standard_view_finalize (GObject *object) /* some safety checks */ _thunar_assert (standard_view->loading_binding == NULL); _thunar_assert (standard_view->icon_factory == NULL); - _thunar_assert (standard_view->ui_manager == NULL); - _thunar_assert (standard_view->clipboard == NULL); + + /* Dont listen to the accel keys defined by the action entries any more */ + xfce_gtk_accel_group_disconnect_action_entries (standard_view->accel_group, + thunar_standard_view_action_entries, + G_N_ELEMENTS (thunar_standard_view_action_entries)); + + /* as well disconnect accelerators of derived widgets */ + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->disconnect_accelerators) (standard_view, standard_view->accel_group); /* release the thumbnailer */ g_signal_handlers_disconnect_by_func (standard_view->priv->thumbnailer, thunar_standard_view_finished_thumbnailing, standard_view); @@ -909,9 +778,6 @@ thunar_standard_view_finalize (GObject *object) /* release the selected_files list (if any) */ thunar_g_file_list_free (standard_view->priv->selected_files); - /* release our reference on the provider factory */ - g_object_unref (G_OBJECT (standard_view->priv->provider_factory)); - /* release the drag path list (just in case the drag-end wasn't fired before) */ thunar_g_file_list_free (standard_view->priv->drag_g_file_list); @@ -927,9 +793,6 @@ thunar_standard_view_finalize (GObject *object) /* release the reference on the icon renderer */ g_object_unref (G_OBJECT (standard_view->icon_renderer)); - /* release the reference on the action group */ - g_object_unref (G_OBJECT (standard_view->action_group)); - /* drop any existing "new-files" closure */ if (G_UNLIKELY (standard_view->priv->new_files_closure != NULL)) { @@ -1008,10 +871,6 @@ 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_component_get_ui_manager (THUNAR_COMPONENT (object))); - break; - case PROP_ZOOM_LEVEL: g_value_set_enum (value, thunar_view_get_zoom_level (THUNAR_VIEW (object))); break; @@ -1055,10 +914,6 @@ thunar_standard_view_set_property (GObject *object, thunar_view_set_show_hidden (THUNAR_VIEW (object), g_value_get_boolean (value)); break; - case PROP_UI_MANAGER: - thunar_component_set_ui_manager (THUNAR_COMPONENT (object), g_value_get_object (value)); - break; - case PROP_ZOOM_LEVEL: thunar_view_set_zoom_level (THUNAR_VIEW (object), g_value_get_enum (value)); break; @@ -1068,6 +923,12 @@ thunar_standard_view_set_property (GObject *object, thunar_standard_view_reload(THUNAR_VIEW (object), TRUE); break; + case PROP_ACCEL_GROUP: + standard_view->accel_group = g_value_dup_object (value); + g_object_ref (standard_view->accel_group); + thunar_standard_view_connect_accelerators (standard_view); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1081,19 +942,10 @@ thunar_standard_view_realize (GtkWidget *widget) { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (widget); GtkIconTheme *icon_theme; - GdkDisplay *display; /* let the GtkWidget do its work */ GTK_WIDGET_CLASS (thunar_standard_view_parent_class)->realize (widget); - /* query the clipboard manager for the display */ - display = gtk_widget_get_display (widget); - standard_view->clipboard = thunar_clipboard_manager_get_for_display (display); - - /* we need update the selection state based on the clipboard content */ - g_signal_connect_swapped (G_OBJECT (standard_view->clipboard), "changed", - G_CALLBACK (thunar_standard_view_selection_changed), standard_view); - /* determine the icon factory for the screen on which we are realized */ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)); standard_view->icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); @@ -1117,18 +969,11 @@ thunar_standard_view_unrealize (GtkWidget *widget) { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (widget); - /* disconnect the clipboard changed handler */ - g_signal_handlers_disconnect_by_func (G_OBJECT (standard_view->clipboard), thunar_standard_view_selection_changed, standard_view); - /* drop the reference on the icon factory */ g_signal_handlers_disconnect_by_func (G_OBJECT (standard_view->icon_factory), gtk_widget_queue_draw, standard_view); g_object_unref (G_OBJECT (standard_view->icon_factory)); standard_view->icon_factory = NULL; - /* drop the reference on the clipboard manager */ - g_object_unref (G_OBJECT (standard_view->clipboard)); - standard_view->clipboard = NULL; - /* let the GtkWidget do its work */ GTK_WIDGET_CLASS (thunar_standard_view_parent_class)->unrealize (widget); } @@ -1176,16 +1021,24 @@ thunar_standard_view_draw (GtkWidget *widget, static GList* -thunar_standard_view_get_selected_files (ThunarComponent *component) +thunar_standard_view_get_selected_files_component (ThunarComponent *component) { return THUNAR_STANDARD_VIEW (component)->priv->selected_files; } +static GList* +thunar_standard_view_get_selected_files_view (ThunarView *view) +{ + return THUNAR_STANDARD_VIEW (view)->priv->selected_files; +} + + + static void -thunar_standard_view_set_selected_files (ThunarComponent *component, - GList *selected_files) +thunar_standard_view_set_selected_files_component (ThunarComponent *component, + GList *selected_files) { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (component); GtkTreePath *first_path = NULL; @@ -1247,91 +1100,11 @@ thunar_standard_view_set_selected_files (ThunarComponent *component, -static GtkUIManager* -thunar_standard_view_get_ui_manager (ThunarComponent *component) -{ - return THUNAR_STANDARD_VIEW (component)->ui_manager; -} - - - static void -thunar_standard_view_set_ui_manager (ThunarComponent *component, - GtkUIManager *ui_manager) +thunar_standard_view_set_selected_files_view (ThunarView *view, + GList *selected_files) { - ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (component); - GError *error = NULL; - - /* leave if nothing changed */ - if (standard_view->ui_manager == ui_manager) - return; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* disconnect from the previous UI manager */ - if (G_LIKELY (standard_view->ui_manager != NULL)) - { - /* remove any registered custom menu actions */ - if (G_LIKELY (standard_view->priv->custom_merge_id != 0)) - { - gtk_ui_manager_remove_ui (standard_view->ui_manager, standard_view->priv->custom_merge_id); - standard_view->priv->custom_merge_id = 0; - } - - /* drop the previous custom action group */ - if (G_LIKELY (standard_view->priv->custom_actions != NULL)) - { - gtk_ui_manager_remove_action_group (standard_view->ui_manager, standard_view->priv->custom_actions); - g_object_unref (G_OBJECT (standard_view->priv->custom_actions)); - standard_view->priv->custom_actions = 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 the ui controls from derived classes */ - (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->disconnect_ui_manager) (standard_view, standard_view->ui_manager); - - /* unmerge our ui controls from the previous UI manager */ - gtk_ui_manager_remove_ui (standard_view->ui_manager, standard_view->ui_merge_id); - - /* force update to remove all actions and proxies */ - gtk_ui_manager_ensure_update (standard_view->ui_manager); - - /* 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, &error); - if (G_UNLIKELY (standard_view->ui_merge_id == 0)) - { - g_error ("Failed to merge ThunarStandardView menus: %s", error->message); - g_error_free (error); - } - - /* merge the ui controls from derived classes */ - (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->connect_ui_manager) (standard_view, ui_manager); - - /* force update to avoid flickering */ - gtk_ui_manager_ensure_update (standard_view->ui_manager); - } - -G_GNUC_END_IGNORE_DEPRECATIONS - /* let others know that we have a new manager */ - g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_UI_MANAGER]); + thunar_standard_view_set_selected_files_component (THUNAR_COMPONENT (view), selected_files); } @@ -1441,7 +1214,6 @@ thunar_standard_view_set_current_directory (ThunarNavigator *navigator, { ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (navigator); ThunarFolder *folder; - gboolean trashed; _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); _thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory)); @@ -1524,21 +1296,6 @@ thunar_standard_view_set_current_directory (ThunarNavigator *navigator, /* reconnect our model to the view */ g_object_set (G_OBJECT (gtk_bin_get_child (GTK_BIN (standard_view))), "model", standard_view->model, NULL); - /* check if the new directory is in the trash */ - trashed = thunar_file_is_trashed (current_directory); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the "Create Folder"/"Create Document" actions */ - gtk_action_set_visible (standard_view->priv->action_create_folder, !trashed); - gtk_action_set_visible (standard_view->priv->action_create_document, !trashed); - - /* update the "Rename" action */ - gtk_action_set_visible (standard_view->priv->action_rename, !trashed); - - /* update the "Restore" action */ - gtk_action_set_visible (standard_view->priv->action_restore, trashed); -G_GNUC_END_IGNORE_DEPRECATIONS - /* schedule a thumbnail timeout */ /* NOTE: quickly after this we always trigger a size allocate wich will handle this */ @@ -1897,54 +1654,6 @@ thunar_standard_view_scroll_to_file (ThunarView *view, -static gboolean -thunar_standard_view_delete_selected_files (ThunarStandardView *standard_view) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - GtkAction *action = GTK_ACTION (standard_view->priv->action_move_to_trash); -G_GNUC_END_IGNORE_DEPRECATIONS - const gchar *accel_path; - GtkAccelKey key; - - _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), FALSE); - - if (thunar_g_vfs_is_uri_scheme_supported ("trash")) - { - /* Check if there is a user defined accelerator for the delete action, - * if there is, skip events from the hard-coded keys which are set in - * the class of the standard view. See bug #4173. - * - * The trick here is that if a custom accelerator is set by the user, - * this function is never called. If a hardcoded key combination is - * pressed and a custom accelerator is set, accel_key || accel_mods - * are no 0. */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - accel_path = gtk_action_get_accel_path (action); -G_GNUC_END_IGNORE_DEPRECATIONS - if (accel_path != NULL - && gtk_accel_map_lookup_entry (accel_path, &key) - && (key.accel_key != 0 || key.accel_mods != 0)) - return FALSE; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* just emit the "activate" signal on the "move-trash" action */ - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS - } - else - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* do a permanent delete */ - gtk_action_activate (GTK_ACTION (standard_view->priv->action_delete)); -G_GNUC_END_IGNORE_DEPRECATIONS - } - - /* ...and we're done */ - return TRUE; -} - - - static GdkDragAction thunar_standard_view_get_dest_actions (ThunarStandardView *standard_view, GdkDragContext *context, @@ -2058,128 +1767,6 @@ thunar_standard_view_get_drop_file (ThunarStandardView *standard_view, -static void -thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view) -{ - GtkTreeIter iter; - ThunarFile *file = NULL; - GtkWidget *window; - GList *providers; - GList *items = NULL; - GList *files = NULL; - GList *tmp; - GList *lp; - GList *selected_items; - gchar *path; - - /* we cannot add anything if we aren't connected to any UI manager */ - if (G_UNLIKELY (standard_view->ui_manager == NULL)) - return; - - /* determine the toplevel window we belong to */ - window = gtk_widget_get_toplevel (GTK_WIDGET (standard_view)); - - /* get the selected items */ - selected_items = (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items) (standard_view); - - /* load the menu providers from the provider factory */ - providers = thunarx_provider_factory_list_providers (standard_view->priv->provider_factory, THUNARX_TYPE_MENU_PROVIDER); - if (G_LIKELY (providers != NULL)) - { - /* determine the list of selected files or the current folder */ - if (G_LIKELY (selected_items != NULL)) - { - for (lp = selected_items; lp != NULL; lp = lp->next) - { - gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, lp->data); - file = thunar_list_model_get_file (standard_view->model, &iter); - files = g_list_prepend (files, file); - } - files = g_list_reverse (files); - } - else - { - /* grab a reference to the current directory of the view */ - file = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - } - - /* load the menu items offered by the menu providers */ - for (lp = providers; lp != NULL; lp = lp->next) - { - if (G_LIKELY (files != NULL)) - tmp = thunarx_menu_provider_get_file_menu_items (lp->data, window, files); - else if (G_LIKELY (file != NULL)) - tmp = thunarx_menu_provider_get_folder_menu_items (lp->data, window, THUNARX_FILE_INFO (file)); - else - tmp = NULL; - items = g_list_concat (items, tmp); - g_object_unref (G_OBJECT (lp->data)); - } - g_list_free (providers); - - /* cleanup the selected files list (if any) */ - if (G_LIKELY (files != NULL)) - thunar_g_file_list_free (files); - } - - /* remove the previously determined menu actions from the UI manager */ - if (G_LIKELY (standard_view->priv->custom_merge_id != 0)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (standard_view->ui_manager, standard_view->priv->custom_merge_id); - gtk_ui_manager_ensure_update (standard_view->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS - standard_view->priv->custom_merge_id = 0; - } - - /* drop any previous custom action group */ - if (G_LIKELY (standard_view->priv->custom_actions != NULL)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_action_group (standard_view->ui_manager, standard_view->priv->custom_actions); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_unref (G_OBJECT (standard_view->priv->custom_actions)); - standard_view->priv->custom_actions = NULL; - } - - /* add the actions specified by the menu providers */ - if (G_LIKELY (items != NULL)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* allocate the action group and the merge id for the custom actions */ - standard_view->priv->custom_actions = gtk_action_group_new ("thunar-standard-view-custom-actions"); - standard_view->priv->custom_merge_id = gtk_ui_manager_new_merge_id (standard_view->ui_manager); - gtk_ui_manager_insert_action_group (standard_view->ui_manager, standard_view->priv->custom_actions, -1); -G_GNUC_END_IGNORE_DEPRECATIONS - - if (G_LIKELY (selected_items != NULL)) - { - /* add to the file context menu */ - path = "/file-context-menu/placeholder-custom-actions"; - } - else - { - /* add to the folder context menu */ - path = "/folder-context-menu/placeholder-custom-actions"; - } - - thunar_menu_util_add_items_to_ui_manager (standard_view->ui_manager, - standard_view->priv->custom_actions, - standard_view->priv->custom_merge_id, - path, items); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* be sure to update the UI manager to avoid flickering */ - gtk_ui_manager_ensure_update (standard_view->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* cleanup */ - g_list_free (items); - } -} - - - static gboolean thunar_standard_view_update_statusbar_text_idle (gpointer data) { @@ -2341,338 +1928,10 @@ thunar_standard_view_current_directory_changed (ThunarFile *current_dire static void -thunar_standard_view_action_create_empty_file (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarApplication *application; - ThunarFile *current_directory; - GList path_list; - gchar *name; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* ask the user to enter a name for the new empty file */ - name = thunar_show_create_dialog (GTK_WIDGET (standard_view), - "text/plain", - _("New Empty File"), - _("New Empty File...")); - if (G_LIKELY (name != NULL)) - { - /* determine the ThunarFile for the current directory */ - current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - if (G_LIKELY (current_directory != NULL)) - { - /* fake the path list */ - path_list.data = g_file_resolve_relative_path (thunar_file_get_file (current_directory), name); - path_list.next = path_list.prev = NULL; - - /* launch the operation */ - application = thunar_application_get (); - thunar_application_creat (application, GTK_WIDGET (standard_view), &path_list, NULL, - thunar_standard_view_new_files_closure (standard_view, NULL)); - g_object_unref (application); - - /* release the path */ - g_object_unref (path_list.data); - } - - /* release the file name in the local encoding */ - g_free (name); - } -} - - - -static void -thunar_standard_view_action_create_folder (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarApplication *application; - ThunarFile *current_directory; - GList path_list; - gchar *name; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* ask the user to enter a name for the new folder */ - name = thunar_show_create_dialog (GTK_WIDGET (standard_view), - "inode/directory", - _("New Folder"), - _("Create New Folder")); - if (G_LIKELY (name != NULL)) - { - /* determine the ThunarFile for the current directory */ - current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - if (G_LIKELY (current_directory != NULL)) - { - /* fake the path list */ - path_list.data = g_file_resolve_relative_path (thunar_file_get_file (current_directory), name); - path_list.next = path_list.prev = NULL; - - /* launch the operation */ - application = thunar_application_get (); - thunar_application_mkdir (application, GTK_WIDGET (standard_view), &path_list, - thunar_standard_view_new_files_closure (standard_view, NULL)); - g_object_unref (G_OBJECT (application)); - - /* release the path */ - g_object_unref (path_list.data); - } - - /* release the file name */ - g_free (name); - } -} - - - -static void -thunar_standard_view_action_create_template (GtkAction *action, - const ThunarFile *file, - ThunarStandardView *standard_view) -{ - ThunarApplication *application; - ThunarFile *current_directory; - GList target_path_list; - gchar *name; - gchar *title; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_FILE (file)); - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* generate a title for the create dialog */ - title = g_strdup_printf (_("Create Document from template \"%s\""), - thunar_file_get_display_name (file)); - - /* ask the user to enter a name for the new document */ - name = thunar_show_create_dialog (GTK_WIDGET (standard_view), - thunar_file_get_content_type (THUNAR_FILE (file)), - thunar_file_get_display_name (file), - title); - if (G_LIKELY (name != NULL)) - { - /* determine the ThunarFile for the current directory */ - current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - if (G_LIKELY (current_directory != NULL)) - { - /* fake the target path list */ - target_path_list.data = g_file_get_child (thunar_file_get_file (current_directory), name); - target_path_list.next = NULL; - target_path_list.prev = NULL; - - /* launch the operation */ - application = thunar_application_get (); - thunar_application_creat (application, GTK_WIDGET (standard_view), &target_path_list, - thunar_file_get_file (file), - thunar_standard_view_new_files_closure (standard_view, NULL)); - g_object_unref (G_OBJECT (application)); - - /* release the target path */ - g_object_unref (target_path_list.data); - } - - /* release the file name */ - g_free (name); - } - - /* cleanup */ - g_free (title); -} - - - -static void -thunar_standard_view_action_properties (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarFile *directory; - GtkWidget *toplevel; - GtkWidget *dialog; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* popup the files dialog */ - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (standard_view)); - if (G_LIKELY (toplevel != NULL)) - { - dialog = thunar_properties_dialog_new (GTK_WINDOW (toplevel)); - - /* check if no files are currently selected */ - if (standard_view->priv->selected_files == NULL) - { - /* if we don't have any files selected, we just popup - * the properties dialog for the current folder. - */ - directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - thunar_properties_dialog_set_file (THUNAR_PROPERTIES_DIALOG (dialog), directory); - } - else - { - /* popup the properties dialog for all file(s) */ - thunar_properties_dialog_set_files (THUNAR_PROPERTIES_DIALOG (dialog), - standard_view->priv->selected_files); - } - - gtk_widget_show (dialog); - } -} - - - -static void -thunar_standard_view_action_cut (GtkAction *action, - ThunarStandardView *standard_view) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - _thunar_return_if_fail (THUNAR_IS_CLIPBOARD_MANAGER (standard_view->clipboard)); - - thunar_clipboard_manager_cut_files (standard_view->clipboard, standard_view->priv->selected_files); -} - - - -static void -thunar_standard_view_action_copy (GtkAction *action, - ThunarStandardView *standard_view) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - _thunar_return_if_fail (THUNAR_IS_CLIPBOARD_MANAGER (standard_view->clipboard)); - - thunar_clipboard_manager_copy_files (standard_view->clipboard, standard_view->priv->selected_files); -} - - - -static void -thunar_standard_view_action_paste (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarFile *current_directory; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - if (G_LIKELY (current_directory != NULL)) - { - thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_file (current_directory), - GTK_WIDGET (standard_view), thunar_standard_view_new_files_closure (standard_view, NULL)); - } -} - - - -static void -thunar_standard_view_unlink_selection (ThunarStandardView *standard_view, - gboolean permanently) +thunar_standard_view_select_all_files (ThunarView *view) { - ThunarApplication *application; - - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* delete the selected files */ - application = thunar_application_get (); - thunar_application_unlink_files (application, GTK_WIDGET (standard_view), - standard_view->priv->selected_files, - permanently); - g_object_unref (G_OBJECT (application)); - - /* do not select new files */ - thunar_component_set_selected_files (THUNAR_COMPONENT (standard_view), NULL); -} - - - -static void -thunar_standard_view_action_move_to_trash (GtkAction *action, - ThunarStandardView *standard_view) -{ - gboolean permanently; - GdkModifierType state; - const gchar *accel_path; - GtkAccelKey key; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* check if we should permanently delete the files (user holds shift) */ - permanently = (gtk_get_current_event_state (&state) && (state & GDK_SHIFT_MASK) != 0); - if (permanently) - { - /* look if the user has set a custom accelerator (accel_key != 0) - * that contains a shift modifier */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - accel_path = gtk_action_get_accel_path (action); -G_GNUC_END_IGNORE_DEPRECATIONS - if (accel_path != NULL - && gtk_accel_map_lookup_entry (accel_path, &key) - && key.accel_key != 0 - && (key.accel_mods & GDK_SHIFT_MASK) != 0) - permanently = FALSE; - } - - thunar_standard_view_unlink_selection (standard_view, permanently); -} - - - -static void -thunar_standard_view_action_delete (GtkAction *action, - ThunarStandardView *standard_view) -{ - thunar_standard_view_unlink_selection (standard_view, TRUE); -} - - - -static void -thunar_standard_view_action_paste_into_folder (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarFile *file; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* determine the first selected file and verify that it's a folder */ - file = g_list_nth_data (standard_view->priv->selected_files, 0); - if (G_LIKELY (file != NULL && thunar_file_is_directory (file))) - thunar_clipboard_manager_paste_files (standard_view->clipboard, thunar_file_get_file (file), GTK_WIDGET (standard_view), NULL); -} - - + ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); -static void -thunar_standard_view_action_select_all_files (GtkAction *action, - ThunarStandardView *standard_view) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); /* grab the focus to the view */ @@ -2685,25 +1944,22 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_standard_view_action_select_by_pattern (GtkAction *action, - ThunarStandardView *standard_view) +thunar_standard_view_select_by_pattern (ThunarView *view) { - GtkWidget *window; - GtkWidget *dialog; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *entry; - GList *paths; - GList *lp; - gint response; - gchar *example_pattern; - const gchar *pattern; - gchar *pattern_extended = NULL; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS + ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); + GtkWidget *window; + GtkWidget *dialog; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *entry; + GList *paths; + GList *lp; + gint response; + gchar *example_pattern; + const gchar *pattern; + gchar *pattern_extended = NULL; + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); window = gtk_widget_get_toplevel (GTK_WIDGET (standard_view)); @@ -2785,12 +2041,10 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_standard_view_action_selection_invert (GtkAction *action, - ThunarStandardView *standard_view) +thunar_standard_view_selection_invert (ThunarView *view) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS + ThunarStandardView *standard_view = THUNAR_STANDARD_VIEW (view); + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); /* grab the focus to the view */ @@ -2802,221 +2056,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS -static void -thunar_standard_view_action_duplicate (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarApplication *application; - ThunarFile *current_directory; - GClosure *new_files_closure; - GList *selected_files; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* determine the file for the current directory */ - current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - if (G_LIKELY (current_directory != NULL)) - { - /* determine the selected files for the view */ - selected_files = thunar_file_list_to_thunar_g_file_list (standard_view->priv->selected_files); - if (G_LIKELY (selected_files != NULL)) - { - /* copy the selected files into the current directory, which effectively - * creates duplicates of the files. - */ - application = thunar_application_get (); - new_files_closure = thunar_standard_view_new_files_closure (standard_view, NULL); - thunar_application_copy_into (application, GTK_WIDGET (standard_view), selected_files, - thunar_file_get_file (current_directory), new_files_closure); - g_object_unref (G_OBJECT (application)); - - /* clean up */ - thunar_g_file_list_free (selected_files); - } - } -} - - - -static void -thunar_standard_view_action_make_link (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarApplication *application; - ThunarFile *current_directory; - GClosure *new_files_closure; - GList *selected_files; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* determine the file for the current directory */ - current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - if (G_LIKELY (current_directory != NULL)) - { - /* determine the selected paths for the view */ - selected_files = thunar_file_list_to_thunar_g_file_list (standard_view->priv->selected_files); - if (G_LIKELY (selected_files != NULL)) - { - /* link the selected files into the current directory, which effectively - * creates new unique links for the files. - */ - application = thunar_application_get (); - new_files_closure = thunar_standard_view_new_files_closure (standard_view, NULL); - thunar_application_link_into (application, GTK_WIDGET (standard_view), selected_files, - thunar_file_get_file (current_directory), new_files_closure); - g_object_unref (G_OBJECT (application)); - - /* clean up */ - thunar_g_file_list_free (selected_files); - } - } -} - - - -static void -thunar_standard_view_rename_error (ExoJob *job, - GError *error, - ThunarStandardView *standard_view) -{ - GArray *param_values; - ThunarFile *file; - - _thunar_return_if_fail (EXO_IS_JOB (job)); - _thunar_return_if_fail (error != NULL); - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - param_values = thunar_simple_job_get_param_values (THUNAR_SIMPLE_JOB (job)); - file = g_value_get_object (&g_array_index (param_values, GValue, 0)); - - /* display an error message */ - thunar_dialogs_show_error (GTK_WIDGET (standard_view), error, - _("Failed to rename \"%s\""), - thunar_file_get_display_name (file)); -} - - - -static void -thunar_standard_view_rename_finished (ExoJob *job, - ThunarStandardView *standard_view) -{ - GArray *param_values; - ThunarFile *file; - - _thunar_return_if_fail (EXO_IS_JOB (job)); - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - param_values = thunar_simple_job_get_param_values (THUNAR_SIMPLE_JOB (job)); - file = g_value_get_object (&g_array_index (param_values, GValue, 0)); - - /* make sure the file is still visible */ - thunar_view_scroll_to_file (THUNAR_VIEW (standard_view), file, TRUE, FALSE, 0.0f, 0.0f); - - /* update the selection, so we get updated actions, statusbar, - * etc. with the new file name and probably new mime type. - */ - thunar_standard_view_selection_changed (standard_view); - - /* destroy the job */ - g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, standard_view); - g_object_unref (job); -} - - - -static void -thunar_standard_view_action_rename (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarFile *file; - GtkWidget *window; - ThunarJob *job; - GdkModifierType state; - gboolean force_bulk_renamer; - const gchar *accel_path; - GtkAccelKey key; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* leave if no files are selected */ - if (G_UNLIKELY (standard_view->priv->selected_files == NULL)) - return; - - /* open the bulk renamer also with one file selected and shift */ - force_bulk_renamer = (gtk_get_current_event_state (&state) && (state & GDK_SHIFT_MASK) != 0); - if (G_UNLIKELY (force_bulk_renamer)) - { - /* Check if the user defined a custom accelerator that includes the - * shift button. If he or she has, we won't force the bulk renamer. */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - accel_path = gtk_action_get_accel_path (action); -G_GNUC_END_IGNORE_DEPRECATIONS - if (accel_path != NULL - && gtk_accel_map_lookup_entry (accel_path, &key) - && (key.accel_mods & GDK_SHIFT_MASK) != 0) - force_bulk_renamer = FALSE; - } - - /* start renaming if we have exactly one selected file */ - if (!force_bulk_renamer - && standard_view->priv->selected_files->next == NULL) - { - /* get the window */ - window = gtk_widget_get_toplevel (GTK_WIDGET (standard_view)); - - /* get the file */ - file = THUNAR_FILE (standard_view->priv->selected_files->data); - - /* run the rename dialog */ - job = thunar_dialogs_show_rename_file (GTK_WINDOW (window), file); - if (G_LIKELY (job != NULL)) - { - g_signal_connect (job, "error", G_CALLBACK (thunar_standard_view_rename_error), standard_view); - g_signal_connect (job, "finished", G_CALLBACK (thunar_standard_view_rename_finished), standard_view); - } - } - else - { - /* determine the current directory of the view */ - file = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - - /* display the bulk rename dialog */ - thunar_show_renamer_dialog (GTK_WIDGET (standard_view), file, standard_view->priv->selected_files, FALSE, NULL); - } -} - - - -static void -thunar_standard_view_action_restore (GtkAction *action, - ThunarStandardView *standard_view) -{ - ThunarApplication *application; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); - - /* restore the selected files */ - application = thunar_application_get (); - thunar_application_restore_files (application, GTK_WIDGET (standard_view), standard_view->priv->selected_files, - thunar_standard_view_new_files_closure (standard_view, NULL)); - g_object_unref (G_OBJECT (application)); -} - - - static GClosure* thunar_standard_view_new_files_closure (ThunarStandardView *standard_view, GtkWidget *source_view) @@ -3175,7 +2214,6 @@ thunar_standard_view_scroll_event (GtkWidget *view, GdkEventScroll *event, ThunarStandardView *standard_view) { - GdkEventButton fake_event; GdkScrollDirection scrolling_direction; gboolean misc_horizontal_wheel_navigates; @@ -3203,12 +2241,10 @@ thunar_standard_view_scroll_event (GtkWidget *view, g_object_get (G_OBJECT (standard_view->preferences), "misc-horizontal-wheel-navigates", &misc_horizontal_wheel_navigates, NULL); if (G_UNLIKELY (misc_horizontal_wheel_navigates)) { - /* create a fake event (8 == back, 9 forward) */ - fake_event.type = GDK_BUTTON_PRESS; - fake_event.button = scrolling_direction == GDK_SCROLL_LEFT ? 8 : 9; - - /* trigger a fake button press event */ - return thunar_standard_view_button_press_event (view, &fake_event, standard_view); + if (scrolling_direction == GDK_SCROLL_LEFT) + thunar_history_action_back (standard_view->priv->history); + else + thunar_history_action_forward (standard_view->priv->history); } } @@ -3229,36 +2265,6 @@ thunar_standard_view_scroll_event (GtkWidget *view, static gboolean -thunar_standard_view_button_press_event (GtkWidget *view, - GdkEventButton *event, - ThunarStandardView *standard_view) -{ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - GtkAction *action = NULL; - - if (G_LIKELY (event->type == GDK_BUTTON_PRESS)) - { - /* determine the appropriate action ("back" for button 8, "forward" for button 9) */ - if (G_UNLIKELY (event->button == 8)) - action = gtk_ui_manager_get_action (standard_view->ui_manager, "/main-menu/go-menu/placeholder-go-history-actions/back"); - else if (G_UNLIKELY (event->button == 9)) - action = gtk_ui_manager_get_action (standard_view->ui_manager, "/main-menu/go-menu/placeholder-go-history-actions/forward"); - - /* perform the action (if any) */ - if (G_UNLIKELY (action != NULL)) - { - gtk_action_activate (action); - return TRUE; - } - } -G_GNUC_END_IGNORE_DEPRECATIONS - /* next please... */ - return FALSE; -} - - - -static gboolean thunar_standard_view_key_press_event (GtkWidget *view, GdkEventKey *event, ThunarStandardView *standard_view) @@ -4411,28 +3417,58 @@ thunar_standard_view_size_allocate (ThunarStandardView *standard_view, void thunar_standard_view_context_menu (ThunarStandardView *standard_view) { - GtkWidget *menu; - GList *selected_items; + GtkWidget *window; + ThunarMenu *context_menu; + GList *selected_items; _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); /* grab an additional reference on the view */ g_object_ref (G_OBJECT (standard_view)); - /* run the menu (figuring out whether to use the file or the folder context menu) */ selected_items = (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items) (standard_view); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - menu = gtk_ui_manager_get_widget (standard_view->ui_manager, (selected_items != NULL) ? "/file-context-menu" : "/folder-context-menu"); -G_GNUC_END_IGNORE_DEPRECATIONS + + window = gtk_widget_get_toplevel (GTK_WIDGET (standard_view)); + + context_menu = g_object_new (THUNAR_TYPE_MENU, "menu-type", THUNAR_MENU_TYPE_CONTEXT, + "launcher", thunar_window_get_launcher (THUNAR_WINDOW (window)), NULL); + if (selected_items != NULL) + { + thunar_menu_add_sections (context_menu, THUNAR_MENU_SECTION_OPEN + | THUNAR_MENU_SECTION_SENDTO + | THUNAR_MENU_SECTION_CUT + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_TRASH_DELETE + | THUNAR_MENU_SECTION_EMPTY_TRASH + | THUNAR_MENU_SECTION_RESTORE + | THUNAR_MENU_SECTION_RENAME + | THUNAR_MENU_SECTION_CUSTOM_ACTIONS + | THUNAR_MENU_SECTION_PROPERTIES); + } + else /* right click on some empty space */ + { + thunar_menu_add_sections (context_menu, THUNAR_MENU_SECTION_CREATE_NEW_FILES + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_EMPTY_TRASH + | THUNAR_MENU_SECTION_CUSTOM_ACTIONS); + thunar_standard_view_append_menu_items (standard_view, GTK_MENU (context_menu), NULL); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (context_menu)); + thunar_menu_add_sections (context_menu, THUNAR_MENU_SECTION_ZOOM + | THUNAR_MENU_SECTION_PROPERTIES); + } + thunar_menu_hide_accel_labels (context_menu); + gtk_widget_show_all (GTK_WIDGET (context_menu)); + thunar_window_redirect_menu_tooltips_to_statusbar (THUNAR_WINDOW (window), GTK_MENU (context_menu)); + /* if there is a drag_timer_event (long press), we use it */ if (standard_view->priv->drag_timer_event != NULL) { - thunar_gtk_menu_run_at_event (GTK_MENU (menu), standard_view->priv->drag_timer_event); + thunar_gtk_menu_run_at_event (GTK_MENU (context_menu), standard_view->priv->drag_timer_event); gdk_event_free (standard_view->priv->drag_timer_event); standard_view->priv->drag_timer_event = NULL; } else - thunar_gtk_menu_run (GTK_MENU (menu)); + thunar_gtk_menu_run (GTK_MENU (context_menu)); g_list_free_full (selected_items, (GDestroyNotify) gtk_tree_path_free); @@ -4512,17 +3548,7 @@ void thunar_standard_view_selection_changed (ThunarStandardView *standard_view) { GtkTreeIter iter; - ThunarFile *current_directory; - gboolean can_paste_into_folder; - gboolean restorable; - gboolean trashable; - gboolean pastable; - gboolean writable; - gboolean trashed; - gboolean hide_trash_action; - gboolean show_delete_action; GList *lp, *selected_files; - gint n_selected_files = 0; _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); @@ -4539,9 +3565,7 @@ thunar_standard_view_selection_changed (ThunarStandardView *standard_view) /* determine the new list of selected files (replacing GtkTreePath's with ThunarFile's) */ selected_files = (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->get_selected_items) (standard_view); - restorable = (selected_files != NULL); - trashable = (selected_files != NULL); - for (lp = selected_files; lp != NULL; lp = lp->next, ++n_selected_files) + for (lp = selected_files; lp != NULL; lp = lp->next) { /* determine the iterator for the path */ gtk_tree_model_get_iter (GTK_TREE_MODEL (standard_view->model), &iter, lp->data); @@ -4551,139 +3575,27 @@ thunar_standard_view_selection_changed (ThunarStandardView *standard_view) /* ...and replace it with the file */ lp->data = thunar_list_model_get_file (standard_view->model, &iter); - - /* enable "Restore" if we have only trashed files (atleast one file) */ - if (!thunar_file_is_trashed (lp->data)) - restorable = FALSE; - - /* enable "Move to Trash" if files can be trashed */ - if (!thunar_file_can_be_trashed (lp->data)) - trashable = FALSE; } /* and setup the new selected files list */ standard_view->priv->selected_files = selected_files; - /* check whether the folder displayed by the view is writable/in the trash */ - current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view)); - writable = (current_directory != NULL && thunar_file_is_writable (current_directory)); - trashed = (current_directory != NULL && thunar_file_is_trashed (current_directory)); - - /* if moving to trash is not applicable, replace it with the delete action - * but only if the directory is writable -- keep "move to trash" otherwise */ - hide_trash_action = writable && (trashed || !trashable || !thunar_g_vfs_is_uri_scheme_supported ("trash")); - - g_object_get (G_OBJECT (standard_view->preferences), "misc-show-delete-action", &show_delete_action, NULL); - - /* check whether the clipboard contains data that can be pasted here */ - pastable = (standard_view->clipboard != NULL && thunar_clipboard_manager_get_can_paste (standard_view->clipboard)); - - /* check whether the only selected file is - * folder to which we can paste to */ - can_paste_into_folder = (n_selected_files == 1) - && thunar_file_is_directory (selected_files->data) - && thunar_file_is_writable (selected_files->data); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the "Create Folder"/"Create Document" actions */ - gtk_action_set_sensitive (standard_view->priv->action_create_folder, !trashed && writable); - gtk_action_set_sensitive (standard_view->priv->action_create_document, !trashed && writable); - - /* update the "Properties" action */ - gtk_action_set_sensitive (standard_view->priv->action_properties, - current_directory != NULL || n_selected_files > 0); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* update the "Cut" action */ - g_object_set (G_OBJECT (standard_view->priv->action_cut), - "sensitive", (n_selected_files > 0) && writable, - "tooltip", ngettext ("Prepare the selected file to be moved with a Paste command", - "Prepare the selected files to be moved with a Paste command", - n_selected_files), - NULL); - - /* update the "Copy" action */ - g_object_set (G_OBJECT (standard_view->priv->action_copy), - "sensitive", (n_selected_files > 0), - "tooltip", ngettext ("Prepare the selected file to be copied with a Paste command", - "Prepare the selected files to be copied with a Paste command", - n_selected_files), - NULL); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the "Paste" action */ - gtk_action_set_sensitive (standard_view->priv->action_paste, writable && pastable); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* update the "Move to Trash" action */ - g_object_set (G_OBJECT (standard_view->priv->action_move_to_trash), - "sensitive", (n_selected_files > 0) && writable, - "visible", !hide_trash_action, - "tooltip", ngettext ("Move the selected file to the Trash", - "Move the selected files to the Trash", - n_selected_files), - NULL); - - /* update the "Delete" action */ - g_object_set (G_OBJECT (standard_view->priv->action_delete), - "sensitive", (n_selected_files > 0) && writable, - "visible", hide_trash_action || show_delete_action, - "tooltip", ngettext ("Permanently delete the selected file", - "Permanently delete the selected files", - n_selected_files), - NULL); - - /* update the "Paste Into Folder" action */ - g_object_set (G_OBJECT (standard_view->priv->action_paste_into_folder), - "sensitive", pastable, - "visible", can_paste_into_folder, - NULL); - - /* update the "Duplicate File(s)" action */ - g_object_set (G_OBJECT (standard_view->priv->action_duplicate), - "sensitive", (n_selected_files > 0) && !restorable && writable, - "tooltip", ngettext ("Duplicate the selected file", - "Duplicate each selected file", - n_selected_files), - NULL); - - /* update the "Make Link(s)" action */ - g_object_set (G_OBJECT (standard_view->priv->action_make_link), - "label", ngettext ("Ma_ke Link", "Ma_ke Links", n_selected_files), - "sensitive", (n_selected_files > 0) && !restorable && writable, - "tooltip", ngettext ("Create a symbolic link for the selected file", - "Create a symbolic link for each selected file", - n_selected_files), - NULL); - - /* update the "Rename" action */ - g_object_set (G_OBJECT (standard_view->priv->action_rename), - "sensitive", (n_selected_files > 0 && !restorable && writable), - "tooltip", ngettext ("Rename the selected file", - "Rename the selected files", - n_selected_files), - NULL); - - /* update the "Restore" action */ - g_object_set (G_OBJECT (standard_view->priv->action_restore), - "sensitive", (n_selected_files > 0 && restorable), - "tooltip", ngettext ("Restore the selected file", - "Restore the selected files", - n_selected_files), - NULL); - /* update the statusbar text */ thunar_standard_view_update_statusbar_text (standard_view); - /* merge the custom actions */ - thunar_standard_view_merge_custom_actions (standard_view); - /* emit notification for "selected-files" */ g_object_notify_by_pspec (G_OBJECT (standard_view), standard_view_props[PROP_SELECTED_FILES]); } +/** + * thunar_standard_view_set_history: + * @standard_view : a #ThunarStandardView instance. + * @history : the #ThunarHistory to set. + * + * replaces the history of this #ThunarStandardView with the passed history + **/ void thunar_standard_view_set_history (ThunarStandardView *standard_view, ThunarHistory *history) @@ -4697,17 +3609,106 @@ thunar_standard_view_set_history (ThunarStandardView *standard_view, /* connect callback */ g_signal_connect_swapped (G_OBJECT (history), "change-directory", G_CALLBACK (thunar_navigator_change_directory), standard_view); +} - /* make the history use the action group of this view */ - g_object_set (G_OBJECT (history), "action-group", standard_view->action_group, NULL); + + +/** + * thunar_standard_view_get_history: + * @standard_view : a #ThunarStandardView instance. + * + * returns the #ThunarHistory of this #ThunarStandardView + * + * Return value: (transfer none): The #ThunarHistory of this #ThunarStandardView + **/ +ThunarHistory* +thunar_standard_view_get_history (ThunarStandardView *standard_view) +{ + return standard_view->priv->history; } +/** + * thunar_standard_view_copy_history: + * @standard_view : a #ThunarStandardView instance. + * + * returns a copy of the #ThunarHistory of this #ThunarStandardView + * The caller has to release the passed history with g_object_unref() after use. + * + * Return value: (transfer full): A copy of the #ThunarHistory of this #ThunarStandardView + **/ ThunarHistory * thunar_standard_view_copy_history (ThunarStandardView *standard_view) { _thunar_return_val_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view), NULL); - return thunar_history_copy (standard_view->priv->history, NULL); + return thunar_history_copy (standard_view->priv->history); +} + + + +/** + * thunar_standard_view_append_menu_items: + * @standard_view : a #ThunarStandardView. + * @menu : the #GtkMenu to add the menu items. + * @accel_group : a #GtkAccelGroup to be used used for new menu items + * + * Appends widget-specific menu items to a #GtkMenu and connects them to the passed #GtkAccelGroup + * The concrete implementation depends on the concrete widget which is implementing this view + **/ +void +thunar_standard_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group) +{ + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->append_menu_items) (standard_view, menu, accel_group); +} + + + +/** + * thunar_standard_view_append_menu_item: + * @standard_view : Instance of a #ThunarStandardView + * @menu : #GtkMenuShell to which the item should be added + * @action : #ThunarStandardViewAction to select which item should be added + * + * Adds the selected, widget specific #GtkMenuItem to the passed #GtkMenuShell + * + * Return value: (transfer none): The added #GtkMenuItem + **/ +void +thunar_standard_view_append_menu_item (ThunarStandardView *standard_view, + GtkMenu *menu, + ThunarStandardViewAction action) +{ + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (action), G_OBJECT (standard_view), GTK_MENU_SHELL (menu)); +} + + + +/** + * thunar_standard_view_connect_accelerators: + * @standard_view : a #ThunarStandardView. + * + * Connects all accelerators and corresponding default keys of this widget to the global accelerator list + * The concrete implementation depends on the concrete widget which is implementing this view + **/ +static void +thunar_standard_view_connect_accelerators (ThunarStandardView *standard_view) +{ + _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); + + xfce_gtk_accel_map_add_entries (thunar_standard_view_action_entries, G_N_ELEMENTS (thunar_standard_view_action_entries)); + xfce_gtk_accel_group_connect_action_entries (standard_view->accel_group, + thunar_standard_view_action_entries, + G_N_ELEMENTS (thunar_standard_view_action_entries), + standard_view); + + /* as well append accelerators of derived widgets */ + (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->connect_accelerators) (standard_view, standard_view->accel_group); } diff --git a/thunar/thunar-standard-view.h b/thunar/thunar-standard-view.h index f8513685..31cb4450 100644 --- a/thunar/thunar-standard-view.h +++ b/thunar/thunar-standard-view.h @@ -40,18 +40,19 @@ typedef struct _ThunarStandardView ThunarStandardView; #define THUNAR_IS_STANDARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_STANDARD_VIEW)) #define THUNAR_STANDARD_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_STANDARD_VIEW, ThunarStandardViewClass)) +/* #XfceGtkActionEntrys provided by this widget */ +typedef enum +{ + THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES, + THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN, + THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION, + +} ThunarStandardViewAction; + struct _ThunarStandardViewClass { GtkScrolledWindowClass __parent__; - /* Called by the ThunarStandardView class to let derived classes - * connect to and disconnect from the UI manager. - */ - void (*connect_ui_manager) (ThunarStandardView *standard_view, - GtkUIManager *ui_manager); - void (*disconnect_ui_manager) (ThunarStandardView *standard_view, - GtkUIManager *ui_manager); - /* Returns the list of currently selected GtkTreePath's, where * both the list and the items are owned by the caller. */ GList *(*get_selected_items) (ThunarStandardView *standard_view); @@ -109,6 +110,15 @@ struct _ThunarStandardViewClass void (*start_open_location) (ThunarStandardView *standard_view, const gchar *initial_text); + /* Appends view-specific menu items to the given menu */ + void (*append_menu_items) (ThunarStandardView *standard_view, GtkMenu *menu, GtkAccelGroup *accel_group); + + /* Connects view-specific accelerators to the given accelGroup */ + void (*connect_accelerators) (ThunarStandardView *standard_view, GtkAccelGroup *accel_group); + + /* Disconnects view-specific accelerators to the given accelGroup */ + void (*disconnect_accelerators) (ThunarStandardView *standard_view, GtkAccelGroup *accel_group); + /* Internal action signals */ gboolean (*delete_selected_files) (ThunarStandardView *standard_view); @@ -125,37 +135,35 @@ struct _ThunarStandardView ThunarPreferences *preferences; - ThunarClipboardManager *clipboard; ThunarListModel *model; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - guint ui_merge_id; - ThunarIconFactory *icon_factory; GtkCellRenderer *icon_renderer; GtkCellRenderer *name_renderer; ExoBinding *loading_binding; gboolean loading; + GtkAccelGroup *accel_group; ThunarStandardViewPrivate *priv; }; -GType thunar_standard_view_get_type (void) G_GNUC_CONST; - -void thunar_standard_view_context_menu (ThunarStandardView *standard_view); - -void thunar_standard_view_queue_popup (ThunarStandardView *standard_view, - GdkEventButton *event); - -void thunar_standard_view_selection_changed (ThunarStandardView *standard_view); - - -void thunar_standard_view_set_history (ThunarStandardView *standard_view, - ThunarHistory *history); - -ThunarHistory *thunar_standard_view_copy_history (ThunarStandardView *standard_view); +GType thunar_standard_view_get_type (void) G_GNUC_CONST; + +void thunar_standard_view_context_menu (ThunarStandardView *standard_view); +void thunar_standard_view_queue_popup (ThunarStandardView *standard_view, + GdkEventButton *event); +void thunar_standard_view_selection_changed (ThunarStandardView *standard_view); +void thunar_standard_view_set_history (ThunarStandardView *standard_view, + ThunarHistory *history); +ThunarHistory *thunar_standard_view_get_history (ThunarStandardView *standard_view); +ThunarHistory *thunar_standard_view_copy_history (ThunarStandardView *standard_view); +void thunar_standard_view_append_menu_items (ThunarStandardView *standard_view, + GtkMenu *menu, + GtkAccelGroup *accel_group); +void thunar_standard_view_append_menu_item (ThunarStandardView *standard_view, + GtkMenu *menu, + ThunarStandardViewAction action); G_END_DECLS; diff --git a/thunar/thunar-templates-action.c b/thunar/thunar-templates-action.c deleted file mode 100644 index c60956c8..00000000 --- a/thunar/thunar-templates-action.c +++ /dev/null @@ -1,578 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, 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 <gio/gio.h> - -#include <thunar/thunar-icon-factory.h> -#include <thunar/thunar-io-scan-directory.h> -#include <thunar/thunar-private.h> -#include <thunar/thunar-templates-action.h> -#include <thunar/thunar-util.h> - - -/* Signal identifiers */ -enum -{ - CREATE_EMPTY_FILE, - CREATE_TEMPLATE, - LAST_SIGNAL, -}; - - - -static void thunar_templates_action_finalize (GObject *object); -static GtkWidget *thunar_templates_action_create_menu_item (GtkAction *action); -static void thunar_templates_action_load (GtkWidget *menu, - ThunarTemplatesAction *templates_action); - - - -struct _ThunarTemplatesActionClass -{ - GtkActionClass __parent__; - - void (*create_empty_file) (ThunarTemplatesAction *templates_action); - void (*create_template) (ThunarTemplatesAction *templates_action, - const ThunarFile *file); -}; - -struct _ThunarTemplatesAction -{ - GtkAction __parent__; - - ThunarJob *job; -}; - - - -static guint templates_action_signals[LAST_SIGNAL]; - - - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS -G_DEFINE_TYPE (ThunarTemplatesAction, thunar_templates_action, GTK_TYPE_ACTION) -G_GNUC_END_IGNORE_DEPRECATIONS - - - -static void -thunar_templates_action_class_init (ThunarTemplatesActionClass *klass) -{ - GtkActionClass *gtkaction_class; - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_templates_action_finalize; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtkaction_class = GTK_ACTION_CLASS (klass); - gtkaction_class->create_menu_item = thunar_templates_action_create_menu_item; -G_GNUC_END_IGNORE_DEPRECATIONS - - /** - * ThunarTemplatesAction::create-empty-file: - * @templates_action : a #ThunarTemplatesAction. - * - * Emitted by @templates_action whenever the user requests to - * create a new empty file. - **/ - templates_action_signals[CREATE_EMPTY_FILE] = - g_signal_new (I_("create-empty-file"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarTemplatesActionClass, create_empty_file), - NULL, NULL, g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /** - * ThunarTemplatesAction::create-template: - * @templates_action : a #ThunarTemplatesAction. - * @file : the #ThunarFile of the template file. - * - * Emitted by @templates_action whenever the user requests to - * create a new file based on the template referred to by - * @file. - **/ - templates_action_signals[CREATE_TEMPLATE] = - g_signal_new (I_("create-template"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarTemplatesActionClass, create_template), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, THUNAR_TYPE_FILE); -} - - - -static void -thunar_templates_action_init (ThunarTemplatesAction *templates_action) -{ - templates_action->job = NULL; -} - - - -static void -thunar_templates_action_finalize (GObject *object) -{ - ThunarTemplatesAction *templates_action = THUNAR_TEMPLATES_ACTION (object); - - if (templates_action->job != NULL) - { - g_signal_handlers_disconnect_matched (templates_action->job, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, - templates_action); - g_object_unref (templates_action->job); - } - - (*G_OBJECT_CLASS (thunar_templates_action_parent_class)->finalize) (object); -} - - - -static GtkWidget* -thunar_templates_action_create_menu_item (GtkAction *action) -{ - GtkWidget *item; - GtkWidget *menu; - - _thunar_return_val_if_fail (THUNAR_IS_TEMPLATES_ACTION (action), NULL); - - /* let GtkAction allocate the menu item */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - item = (*GTK_ACTION_CLASS (thunar_templates_action_parent_class)->create_menu_item) (action); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* associate an empty submenu with the item (will be filled when shown) */ - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu); - - thunar_templates_action_load (menu, THUNAR_TEMPLATES_ACTION (action)); - - return item; -} - - - -static void -item_activated (GtkWidget *item, - ThunarTemplatesAction *templates_action) -{ - const ThunarFile *file; - - _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); - _thunar_return_if_fail (GTK_IS_WIDGET (item)); - - /* check if a file is set for the item (else it's the "Empty File" item) */ - file = g_object_get_data (G_OBJECT (item), I_("thunar-file")); - if (G_UNLIKELY (file != NULL)) - { - g_signal_emit (G_OBJECT (templates_action), - templates_action_signals[CREATE_TEMPLATE], 0, file); - } - else - { - g_signal_emit (G_OBJECT (templates_action), - templates_action_signals[CREATE_EMPTY_FILE], 0); - } -} - - - -static GtkWidget * -find_parent_menu (ThunarFile *file, - GList *dirs, - GList *items) -{ - GtkWidget *parent_menu = NULL; - GFile *parent; - GList *lp; - GList *ip; - - /* determine the parent of the file */ - parent = g_file_get_parent (thunar_file_get_file (file)); - - /* check if the file has a parent at all */ - if (parent == NULL) - return NULL; - - /* iterate over all dirs and menu items */ - for (lp = g_list_first (dirs), ip = g_list_first (items); - parent_menu == NULL && lp != NULL && ip != NULL; - lp = lp->next, ip = ip->next) - { - /* check if the current dir/item is the parent of our file */ - if (g_file_equal (parent, thunar_file_get_file (lp->data))) - { - /* we want to insert an item for the file in this menu */ - parent_menu = gtk_menu_item_get_submenu (ip->data); - } - } - - /* destroy the parent GFile */ - g_object_unref (parent); - - return parent_menu; -} - - - -static gint -compare_files (ThunarFile *a, - ThunarFile *b) -{ - GFile *file_a; - GFile *file_b; - GFile *parent_a; - GFile *parent_b; - - file_a = thunar_file_get_file (a); - file_b = thunar_file_get_file (b); - - /* check whether the files are equal */ - if (g_file_equal (file_a, file_b)) - return 0; - - /* directories always come first */ - if (thunar_file_get_kind (a) == G_FILE_TYPE_DIRECTORY - && thunar_file_get_kind (b) != G_FILE_TYPE_DIRECTORY) - { - return -1; - } - else if (thunar_file_get_kind (a) != G_FILE_TYPE_DIRECTORY - && thunar_file_get_kind (b) == G_FILE_TYPE_DIRECTORY) - { - return 1; - } - - /* ancestors come first */ - if (g_file_has_prefix (file_b, file_a)) - return -1; - else if (g_file_has_prefix (file_a, file_b)) - return 1; - - parent_a = g_file_get_parent (file_a); - parent_b = g_file_get_parent (file_b); - - if (g_file_equal (parent_a, parent_b)) - { - g_object_unref (parent_a); - g_object_unref (parent_b); - - /* compare siblings by their display name */ - return g_utf8_collate (thunar_file_get_display_name (a), - thunar_file_get_display_name (b)); - } - - /* again, ancestors come first */ - if (g_file_has_prefix (file_b, parent_a)) - { - g_object_unref (parent_a); - g_object_unref (parent_b); - - return -1; - } - else if (g_file_has_prefix (file_a, parent_b)) - { - g_object_unref (parent_a); - g_object_unref (parent_b); - - return 1; - } - - g_object_unref (parent_a); - g_object_unref (parent_b); - - return 0; -} - - - -static gboolean -thunar_templates_action_set_files (GtkWidget *menu, - GList *files, - ThunarTemplatesAction *templates_action) -{ - ThunarIconFactory *icon_factory; - ThunarFile *file; - GdkPixbuf *icon; - GtkWidget *parent_menu; - GtkWidget *submenu; - GtkWidget *image; - GtkWidget *item; - GList *lp; - GList *dirs = NULL; - GList *items = NULL; - GList *parent_menus = NULL; - GList *pp; - GList *menu_children = NULL; - gchar *label; - gchar *dot; - - /* do nothing if there is no menu */ - if (menu == NULL) - return FALSE; - - /* get the icon factory */ - icon_factory = thunar_icon_factory_get_default (); - - /* sort items so that directories come before files and ancestors come - * before descendants */ - files = g_list_sort (files, (GCompareFunc) (void (*)(void)) compare_files); - - for (lp = g_list_first (files); lp != NULL; lp = lp->next) - { - file = lp->data; - - /* determine the parent menu for this file/directory */ - parent_menu = find_parent_menu (file, dirs, items); - parent_menu = parent_menu == NULL ? menu : parent_menu; - - if (thunar_file_get_kind (file) == G_FILE_TYPE_DIRECTORY) - { - /* allocate a new submenu for the directory */ - submenu = gtk_menu_new (); - g_object_ref_sink (G_OBJECT (submenu)); - gtk_menu_set_screen (GTK_MENU (submenu), gtk_widget_get_screen (menu)); - - /* allocate a new menu item for the directory */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - item = gtk_image_menu_item_new_with_label (thunar_file_get_display_name (file)); -G_GNUC_END_IGNORE_DEPRECATIONS - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - - /* prepend the directory, its item and the parent menu it should - * later be added to to the respective lists */ - dirs = g_list_prepend (dirs, file); - items = g_list_prepend (items, item); - parent_menus = g_list_prepend (parent_menus, parent_menu); - } - else - { - /* generate a label by stripping off the extension */ - label = g_strdup (thunar_file_get_display_name (file)); - dot = thunar_util_str_get_extension (label); - if (dot) - *dot = '\0'; - - /* allocate a new menu item */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - item = gtk_image_menu_item_new_with_label (label); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_set_data_full (G_OBJECT (item), I_("thunar-file"), - g_object_ref (file), g_object_unref); - g_signal_connect (item, "activate", G_CALLBACK (item_activated), - templates_action); - gtk_menu_shell_append (GTK_MENU_SHELL (parent_menu), item); - gtk_widget_show (item); - - g_free(label); - } - - /* determine the icon for this file/directory */ - icon = thunar_icon_factory_load_file_icon (icon_factory, file, - THUNAR_FILE_ICON_STATE_DEFAULT, - 16); - - /* allocate an image based on the icon */ - image = gtk_image_new_from_pixbuf (icon); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* release the icon reference */ - g_object_unref (icon); - } - - /* add all non-empty directory items to their parent menu */ - for (lp = items, pp = parent_menus; - lp != NULL && pp != NULL; - lp = lp->next, pp = pp->next) - { - /* determine the submenu for this directory item */ - submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (lp->data)); - menu_children = gtk_container_get_children (GTK_CONTAINER (submenu)); - - if (menu_children == NULL) - { - /* the directory submenu is empty, destroy it */ - gtk_widget_destroy (lp->data); - } - else - { - /* the directory has template files, so add it to its parent menu */ - gtk_menu_shell_prepend (GTK_MENU_SHELL (pp->data), lp->data); - gtk_widget_show (lp->data); - } - } - - /* destroy lists */ - g_list_free (dirs); - g_list_free (items); - g_list_free (parent_menus); - g_list_free (menu_children); - - /* release the icon factory */ - g_object_unref (icon_factory); - - /* let the job destroy the file list */ - return FALSE; -} - - - -static void -thunar_templates_action_set_error (GtkWidget *menu, - const gchar *error_message, - ThunarTemplatesAction *templates_action) -{ - GtkWidget *item; - GList *menu_children = NULL; - - _thunar_return_if_fail (error_message != NULL); - _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); - - /* check if any items were added to the menu */ - if (G_LIKELY (menu != NULL && (menu_children = gtk_container_get_children( GTK_CONTAINER (menu))) == NULL)) - { - /* tell the user that no templates were found */ - item = gtk_menu_item_new_with_label (error_message); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_set_sensitive (item, FALSE); - gtk_widget_show (item); - } - - g_list_free (menu_children); -} - - - -static void -thunar_templates_action_load_finished (GtkWidget *menu, - ThunarTemplatesAction *templates_action) -{ - GtkWidget *image; - GtkWidget *item; - - _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); - - if (G_LIKELY (menu != NULL)) - { - /* append a menu separator */ - item = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* add the "Empty File" item */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - item = gtk_image_menu_item_new_with_mnemonic (_("_Empty File")); -G_GNUC_END_IGNORE_DEPRECATIONS - g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated), - templates_action); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* add the icon for the emtpy file item */ - image = gtk_image_new_from_icon_name ("text-x-generic", GTK_ICON_SIZE_MENU); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); -G_GNUC_END_IGNORE_DEPRECATIONS - } -} - - - -static void -thunar_templates_action_load (GtkWidget *menu, - ThunarTemplatesAction *templates_action) -{ - GList *files = NULL; - GFile *home_dir; - GFile *templates_dir; - const gchar *path; - - _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action)); - _thunar_return_if_fail (GTK_IS_MENU_SHELL (menu)); - - home_dir = thunar_g_file_new_for_home (); - path = g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES); - - if (G_LIKELY (path != NULL)) - templates_dir = g_file_new_for_path (path); - else - templates_dir = g_file_resolve_relative_path (home_dir, "Templates"); - - if (G_LIKELY (!g_file_equal (templates_dir, home_dir))) - { - /* load the ThunarFiles */ - files = thunar_io_scan_directory (NULL, templates_dir, - G_FILE_QUERY_INFO_NONE, - TRUE, FALSE, TRUE, NULL); - } - - g_object_unref (templates_dir); - g_object_unref (home_dir); - - if (files == NULL) - { - thunar_templates_action_set_error (menu, _("No templates installed"), - templates_action); - } - else - { - thunar_templates_action_set_files (menu, files, templates_action); - thunar_g_file_list_free (files); - } - - thunar_templates_action_load_finished (menu, templates_action); -} - - - -/** - * thunar_templates_action_new: - * @name : the internal name of the action. - * @label : the label for the action. - * - * Allocates a new #ThunarTemplatesAction with the given - * @name and @label. - * - * Return value: the newly allocated #ThunarTemplatesAction. - **/ -GtkAction* -thunar_templates_action_new (const gchar *name, - const gchar *label) -{ - _thunar_return_val_if_fail (name != NULL, NULL); - _thunar_return_val_if_fail (label != NULL, NULL); - - return g_object_new (THUNAR_TYPE_TEMPLATES_ACTION, - "hide-if-empty", FALSE, - "label", label, - "name", name, - "icon-name", "document-new", - NULL); -} - - diff --git a/thunar/thunar-templates-action.h b/thunar/thunar-templates-action.h deleted file mode 100644 index fe2a6e91..00000000 --- a/thunar/thunar-templates-action.h +++ /dev/null @@ -1,44 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __THUNAR_TEMPLATES_ACTION_H__ -#define __THUNAR_TEMPLATES_ACTION_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarTemplatesActionClass ThunarTemplatesActionClass; -typedef struct _ThunarTemplatesAction ThunarTemplatesAction; - -#define THUNAR_TYPE_TEMPLATES_ACTION (thunar_templates_action_get_type ()) -#define THUNAR_TEMPLATES_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_TEMPLATES_ACTION, ThunarTemplatesAction)) -#define THUNAR_TEMPLATES_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_TEMPLATES_ACTION, ThunarTemplatesActionClass)) -#define THUNAR_IS_TEMPLATES_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_TEMPLATES_ACTION)) -#define THUNAR_IS_TEMPLATES_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_TEMPLATES_ACTION)) -#define THUNAR_TEMPLATES_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_TEMPLATES_ACTION, ThunarTemplatesActionClass)) - -GType thunar_templates_action_get_type (void) G_GNUC_CONST; - -GtkAction *thunar_templates_action_new (const gchar *name, - const gchar *label) G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_TEMPLATES_ACTION_H__ */ diff --git a/thunar/thunar-trash-action.c b/thunar/thunar-trash-action.c deleted file mode 100644 index 2e79f8f6..00000000 --- a/thunar/thunar-trash-action.c +++ /dev/null @@ -1,173 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, 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-file.h> -#include <thunar/thunar-private.h> -#include <thunar/thunar-trash-action.h> -#include <thunar/thunar-icon-factory.h> - - - -static void thunar_trash_action_constructed (GObject *object); -static void thunar_trash_action_finalize (GObject *object); -static void thunar_trash_action_changed (ThunarTrashAction *trash_action, - ThunarFile *trash_bin); - - -struct _ThunarTrashActionClass -{ - GtkActionClass __parent__; -}; - -struct _ThunarTrashAction -{ - GtkAction __parent__; - ThunarFile *trash_bin; -}; - - - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS -G_DEFINE_TYPE (ThunarTrashAction, thunar_trash_action, GTK_TYPE_ACTION) -G_GNUC_END_IGNORE_DEPRECATIONS - - - -static void -thunar_trash_action_class_init (ThunarTrashActionClass *klass) -{ - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->constructed = thunar_trash_action_constructed; - gobject_class->finalize = thunar_trash_action_finalize; -} - - - -static void -thunar_trash_action_init (ThunarTrashAction *trash_action) -{ - GFile *trash_bin; - - /* try to connect to the trash bin */ - trash_bin = thunar_g_file_new_for_trash (); - trash_action->trash_bin = thunar_file_get (trash_bin, NULL); - g_object_unref (trash_bin); - - /* safety check for trash bin... */ - if (G_LIKELY (trash_action->trash_bin != NULL)) - { - /* watch the trash bin for changes */ - thunar_file_watch (trash_action->trash_bin); - - /* stay informed about changes to the trash bin */ - g_signal_connect_swapped (G_OBJECT (trash_action->trash_bin), "changed", - G_CALLBACK (thunar_trash_action_changed), - trash_action); - - /* initially update the stock icon */ - thunar_trash_action_changed (trash_action, trash_action->trash_bin); - - /* schedule a reload in idle (fix for bug #9513) */ - thunar_file_reload_idle (trash_action->trash_bin); - } -} - - - -static void -thunar_trash_action_constructed (GObject *object) -{ - ThunarTrashAction *trash_action = THUNAR_TRASH_ACTION (object); - const gchar *label; - - if (trash_action->trash_bin != NULL) - label = thunar_file_get_display_name (trash_action->trash_bin); - else - label = _("T_rash"); - - g_object_set (trash_action, "label", label, NULL); -} - - - -static void -thunar_trash_action_finalize (GObject *object) -{ - ThunarTrashAction *trash_action = THUNAR_TRASH_ACTION (object); - - /* check if we are connected to the trash bin */ - if (G_LIKELY (trash_action->trash_bin != NULL)) - { - /* unwatch the trash bin */ - thunar_file_unwatch (trash_action->trash_bin); - - /* release the trash bin */ - g_signal_handlers_disconnect_by_func (G_OBJECT (trash_action->trash_bin), thunar_trash_action_changed, trash_action); - g_object_unref (G_OBJECT (trash_action->trash_bin)); - } - - (*G_OBJECT_CLASS (thunar_trash_action_parent_class)->finalize) (object); -} - - - -static void -thunar_trash_action_changed (ThunarTrashAction *trash_action, - ThunarFile *trash_bin) -{ - _thunar_return_if_fail (THUNAR_IS_TRASH_ACTION (trash_action)); - _thunar_return_if_fail (trash_action->trash_bin == trash_bin); - _thunar_return_if_fail (THUNAR_IS_FILE (trash_bin)); - - /* unset the pixmap cache on the file */ - thunar_icon_factory_clear_pixmap_cache (trash_bin); - - /* adjust the stock icon appropriately */ - if (thunar_file_get_item_count (trash_bin) > 0) - g_object_set (G_OBJECT (trash_action), "icon-name", "user-trash-full", NULL); - else - g_object_set (G_OBJECT (trash_action), "icon-name", "user-trash", NULL); -} - - - -/** - * thunar_trash_action_new: - * - * Allocates a new #ThunarTrashAction, whose associated widgets update their icons according to the - * current trash state. - * - * Return value: the newly allocated #ThunarTrashAction. - **/ -GtkAction* -thunar_trash_action_new (void) -{ - return g_object_new (THUNAR_TYPE_TRASH_ACTION, - "name", "open-trash", - "tooltip", _("Display the contents of the trash can"), - "icon-name", "user-trash-full", - NULL); -} diff --git a/thunar/thunar-trash-action.h b/thunar/thunar-trash-action.h deleted file mode 100644 index c9c97fca..00000000 --- a/thunar/thunar-trash-action.h +++ /dev/null @@ -1,43 +0,0 @@ -/* vi:set et ai sw=2 sts=2 ts=2: */ -/*- - * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __THUNAR_TRASH_ACTION_H__ -#define __THUNAR_TRASH_ACTION_H__ - -#include <exo/exo.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarTrashActionClass ThunarTrashActionClass; -typedef struct _ThunarTrashAction ThunarTrashAction; - -#define THUNAR_TYPE_TRASH_ACTION (thunar_trash_action_get_type ()) -#define THUNAR_TRASH_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_TRASH_ACTION, ThunarTrashAction)) -#define THUNAR_TRASH_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_TRASH_ACTION, ThunarTrashActionClass)) -#define THUNAR_IS_TRASH_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_TRASH_ACTION)) -#define THUNAR_IS_TRASH_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_TRASH_ACTION)) -#define THUNAR_TRASH_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_TRASH_ACTION, ThunarTrashActionClass)) - -GType thunar_trash_action_get_type (void) G_GNUC_CONST; - -GtkAction *thunar_trash_action_new (void) G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_TRASH_ACTION_H__ */ diff --git a/thunar/thunar-tree-pane.c b/thunar/thunar-tree-pane.c index c1a9086b..109336b6 100644 --- a/thunar/thunar-tree-pane.c +++ b/thunar/thunar-tree-pane.c @@ -33,7 +33,6 @@ enum PROP_CURRENT_DIRECTORY, PROP_SELECTED_FILES, PROP_SHOW_HIDDEN, - PROP_UI_MANAGER, }; @@ -97,7 +96,6 @@ thunar_tree_pane_class_init (ThunarTreePaneClass *klass) /* override ThunarComponent's properties */ g_object_class_override_property (gobject_class, PROP_SELECTED_FILES, "selected-files"); - g_object_class_override_property (gobject_class, PROP_UI_MANAGER, "ui-manager"); /* override ThunarSidePane's properties */ g_object_class_override_property (gobject_class, PROP_SHOW_HIDDEN, "show-hidden"); @@ -110,8 +108,6 @@ thunar_tree_pane_component_init (ThunarComponentIface *iface) { iface->get_selected_files = (gpointer) exo_noop_null; iface->set_selected_files = (gpointer) exo_noop; - iface->get_ui_manager = (gpointer) exo_noop_null; - iface->set_ui_manager = (gpointer) exo_noop; } @@ -162,7 +158,6 @@ thunar_tree_pane_dispose (GObject *object) thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (tree_pane), NULL); thunar_component_set_selected_files (THUNAR_COMPONENT (tree_pane), NULL); - thunar_component_set_ui_manager (THUNAR_COMPONENT (tree_pane), NULL); (*G_OBJECT_CLASS (thunar_tree_pane_parent_class)->dispose) (object); } @@ -189,10 +184,6 @@ thunar_tree_pane_get_property (GObject *object, g_value_set_boolean (value, thunar_side_pane_get_show_hidden (THUNAR_SIDE_PANE (object))); break; - case PROP_UI_MANAGER: - g_value_set_object (value, thunar_component_get_ui_manager (THUNAR_COMPONENT (object))); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -221,10 +212,6 @@ thunar_tree_pane_set_property (GObject *object, thunar_side_pane_set_show_hidden (THUNAR_SIDE_PANE (object), g_value_get_boolean (value)); break; - case PROP_UI_MANAGER: - thunar_component_set_ui_manager (THUNAR_COMPONENT (object), g_value_get_object (value)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/thunar/thunar-tree-view.c b/thunar/thunar-tree-view.c index 33777590..2edf5aa0 100644 --- a/thunar/thunar-tree-view.c +++ b/thunar/thunar-tree-view.c @@ -35,7 +35,6 @@ #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-job.h> #include <thunar/thunar-marshal.h> -#include <thunar/thunar-menu-util.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-properties-dialog.h> @@ -1559,7 +1558,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS g_list_free (providers); /* add the menu items to the menu */ - thunar_menu_util_add_items_to_menu (menu, items); + for (lp = items; lp != NULL; lp = lp->next) + thunar_gtk_menu_thunarx_menu_item_new (lp->data, GTK_MENU_SHELL (menu)); /* add a separator to the end of the menu */ if (G_LIKELY (lp != items)) diff --git a/thunar/thunar-view.c b/thunar/thunar-view.c index d2a15616..6f7e604e 100644 --- a/thunar/thunar-view.c +++ b/thunar/thunar-view.c @@ -324,3 +324,20 @@ thunar_view_scroll_to_file (ThunarView *view, } + +GList* +thunar_view_get_selected_files (ThunarView *view) +{ + _thunar_return_val_if_fail (THUNAR_IS_VIEW (view), NULL); + return (*THUNAR_VIEW_GET_IFACE (view)->get_selected_files) (view); +} + + + +void +thunar_view_set_selected_files (ThunarView *view, + GList *path_list) +{ + _thunar_return_if_fail (THUNAR_IS_VIEW (view)); + (*THUNAR_VIEW_GET_IFACE (view)->set_selected_files) (view, path_list); +} diff --git a/thunar/thunar-view.h b/thunar/thunar-view.h index 9aa62f3d..3a6f6a04 100644 --- a/thunar/thunar-view.h +++ b/thunar/thunar-view.h @@ -64,6 +64,9 @@ struct _ThunarViewIface gboolean use_align, gfloat row_align, gfloat col_align); + GList* (*get_selected_files) (ThunarView *view); + void (*set_selected_files) (ThunarView *view, + GList *path_list); }; GType thunar_view_get_type (void) G_GNUC_CONST; @@ -93,6 +96,9 @@ void thunar_view_scroll_to_file (ThunarView *view, gboolean use_align, gfloat row_align, gfloat col_align); +GList* thunar_view_get_selected_files (ThunarView *view); +void thunar_view_set_selected_files (ThunarView *view, + GList *path_list); G_END_DECLS; diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 31e0c395..5a48ad2b 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -31,7 +31,6 @@ #endif #include <gdk/gdkkeysyms.h> -#include <libxfce4ui/libxfce4ui.h> #include <thunar/thunar-application.h> #include <thunar/thunar-browser.h> @@ -49,17 +48,15 @@ #include <thunar/thunar-location-buttons.h> #include <thunar/thunar-location-entry.h> #include <thunar/thunar-marshal.h> -#include <thunar/thunar-menu-util.h> +#include <thunar/thunar-menu.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-preferences-dialog.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-util.h> #include <thunar/thunar-statusbar.h> -#include <thunar/thunar-trash-action.h> #include <thunar/thunar-tree-pane.h> #include <thunar/thunar-window.h> -#include <thunar/thunar-window-ui.h> #include <thunar/thunar-device-monitor.h> #include <glib.h> @@ -71,8 +68,6 @@ enum { PROP_0, PROP_CURRENT_DIRECTORY, - PROP_SHOW_HIDDEN, - PROP_UI_MANAGER, PROP_ZOOM_LEVEL, }; @@ -92,173 +87,171 @@ enum -static void thunar_window_dispose (GObject *object); -static void thunar_window_finalize (GObject *object); -static gboolean thunar_window_delete (GtkWidget *widget, - GdkEvent *event, - gpointer data); -static void thunar_window_get_property (GObject *object, +static void thunar_window_dispose (GObject *object); +static void thunar_window_finalize (GObject *object); +static gboolean thunar_window_delete (GtkWidget *widget, + GdkEvent *event, + gpointer data); +static void thunar_window_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); -static void thunar_window_set_property (GObject *object, +static void thunar_window_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static gboolean thunar_window_back (ThunarWindow *window); -static gboolean thunar_window_reload (ThunarWindow *window, +static gboolean thunar_window_reload (ThunarWindow *window, gboolean reload_info); -static gboolean thunar_window_toggle_sidepane (ThunarWindow *window); -static gboolean thunar_window_toggle_menubar (ThunarWindow *window); -static void thunar_window_toggle_menubar_deactivate (GtkWidget *menubar, - ThunarWindow *window); -static gboolean thunar_window_zoom_in (ThunarWindow *window); -static gboolean thunar_window_zoom_out (ThunarWindow *window); -static gboolean thunar_window_zoom_reset (ThunarWindow *window); -static gboolean thunar_window_tab_change (ThunarWindow *window, +static gboolean thunar_window_toggle_sidepane (ThunarWindow *window); +static gboolean thunar_window_zoom_in (ThunarWindow *window); +static gboolean thunar_window_zoom_out (ThunarWindow *window); +static gboolean thunar_window_zoom_reset (ThunarWindow *window); +static gboolean thunar_window_tab_change (ThunarWindow *window, gint nth); -static void thunar_window_realize (GtkWidget *widget); -static void thunar_window_unrealize (GtkWidget *widget); -static gboolean thunar_window_configure_event (GtkWidget *widget, +static void thunar_window_realize (GtkWidget *widget); +static void thunar_window_unrealize (GtkWidget *widget); +static gboolean thunar_window_configure_event (GtkWidget *widget, GdkEventConfigure *event); -static void thunar_window_notebook_switch_page (GtkWidget *notebook, +static void thunar_window_notebook_switch_page (GtkWidget *notebook, GtkWidget *page, guint page_num, ThunarWindow *window); -static void thunar_window_notebook_page_added (GtkWidget *notebook, +static void thunar_window_notebook_page_added (GtkWidget *notebook, GtkWidget *page, guint page_num, ThunarWindow *window); -static void thunar_window_notebook_page_removed (GtkWidget *notebook, +static void thunar_window_notebook_page_removed (GtkWidget *notebook, GtkWidget *page, guint page_num, ThunarWindow *window); -static gboolean thunar_window_notebook_button_press_event (GtkWidget *notebook, +static gboolean thunar_window_notebook_button_press_event(GtkWidget *notebook, GdkEventButton *event, ThunarWindow *window); -static gboolean thunar_window_notebook_popup_menu (GtkWidget *notebook, +static gboolean thunar_window_notebook_popup_menu (GtkWidget *notebook, ThunarWindow *window); -static gpointer thunar_window_notebook_create_window (GtkWidget *notebook, +static gpointer thunar_window_notebook_create_window (GtkWidget *notebook, GtkWidget *page, gint x, gint y, ThunarWindow *window); -static void thunar_window_merge_custom_preferences (ThunarWindow *window); -static gboolean thunar_window_bookmark_merge (gpointer user_data); -static void thunar_window_merge_go_actions (ThunarWindow *window); -static void thunar_window_update_location_bar_visible (ThunarWindow *window); -static void thunar_window_handle_reload_request (ThunarWindow *window); -static void thunar_window_install_sidepane (ThunarWindow *window, +static void thunar_window_bookmark_add_menu_item (GFile *g_file, + const gchar *name, + gint line_num, + gpointer user_data); +static void thunar_window_update_location_bar_visible(ThunarWindow *window); +static void thunar_window_handle_reload_request (ThunarWindow *window); +static void thunar_window_install_sidepane (ThunarWindow *window, GType type); -static void thunar_window_start_open_location (ThunarWindow *window, +static void thunar_window_start_open_location (ThunarWindow *window, const gchar *initial_text); -static void thunar_window_action_open_new_tab (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_new_window (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_empty_trash (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_detach_tab (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_close_all_windows (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_close_tab (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_close_window (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_preferences (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_reload (GtkAction *action, - ThunarWindow *window); -static void switch_next_tab (GtkAction *action, - ThunarWindow *window); -static void switch_previous_tab (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_pathbar_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_toolbar_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_shortcuts_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_tree_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_statusbar_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_menubar_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_zoom_in (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_zoom_out (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_zoom_reset (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_view_changed (GtkRadioAction *action, - GtkRadioAction *current, - ThunarWindow *window); -static void thunar_window_action_go_up (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_home (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_desktop (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_computer (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_templates (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_file_system (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_trash (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_network (GtkAction *action, +static void thunar_window_action_open_new_tab (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_open_new_window (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_detach_tab (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_close_all_windows (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_close_tab (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_close_window (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_reload (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_switch_next_tab (ThunarWindow *window); +static void thunar_window_action_switch_previous_tab (ThunarWindow *window); +static void thunar_window_action_pathbar_changed (ThunarWindow *window); +static void thunar_window_action_toolbar_changed (ThunarWindow *window); +static void thunar_window_action_shortcuts_changed (ThunarWindow *window); +static void thunar_window_action_tree_changed (ThunarWindow *window); +static void thunar_window_action_statusbar_changed (ThunarWindow *window); +static void thunar_window_action_menubar_changed (ThunarWindow *window); +static void thunar_window_action_detailed_view (ThunarWindow *window); +static void thunar_window_action_icon_view (ThunarWindow *window); +static void thunar_window_action_compact_view (ThunarWindow *window); +static void thunar_window_action_view_changed (ThunarWindow *window, + GType view_type); +static void thunar_window_action_go_up (ThunarWindow *window); +static void thunar_window_action_back (ThunarWindow *window); +static void thunar_window_action_forward (ThunarWindow *window); +static void thunar_window_action_open_home (ThunarWindow *window); +static void thunar_window_action_open_desktop (ThunarWindow *window); +static void thunar_window_action_open_computer (ThunarWindow *window); +static void thunar_window_action_open_templates (ThunarWindow *window); +static void thunar_window_action_open_file_system (ThunarWindow *window); +static void thunar_window_action_open_trash (ThunarWindow *window); +static void thunar_window_action_open_network (ThunarWindow *window); +static void thunar_window_action_open_bookmark (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_open_location (ThunarWindow *window); +static void thunar_window_action_contents (ThunarWindow *window); +static void thunar_window_action_about (ThunarWindow *window); +static void thunar_window_action_show_hidden (ThunarWindow *window); +static void thunar_window_action_open_file_menu (ThunarWindow *window); +static void thunar_window_current_directory_changed (ThunarFile *current_directory, ThunarWindow *window); -static void thunar_window_action_open_bookmark (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_location (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_contents (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_about (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_show_hidden (GtkToggleAction *action, - ThunarWindow *window); -static gboolean thunar_window_propagate_key_event (GtkWindow *window, - GdkEvent *key_event, - gpointer user_data); -static void thunar_window_current_directory_changed (ThunarFile *current_directory, - ThunarWindow *window); -static void thunar_window_connect_proxy (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy, - ThunarWindow *window); -static void thunar_window_disconnect_proxy (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy, - ThunarWindow *window); -static void thunar_window_menu_item_selected (GtkWidget *menu_item, - ThunarWindow *window); -static void thunar_window_menu_item_deselected (GtkWidget *menu_item, - ThunarWindow *window); -static void thunar_window_update_custom_actions (ThunarView *view, +static void thunar_window_menu_item_selected (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_menu_item_deselected (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_notify_loading (ThunarView *view, GParamSpec *pspec, ThunarWindow *window); -static void thunar_window_notify_loading (ThunarView *view, - GParamSpec *pspec, - ThunarWindow *window); -static void thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor, +static void thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor, ThunarDevice *device, GFile *root_file, ThunarWindow *window); -static void thunar_window_device_changed (ThunarDeviceMonitor *device_monitor, +static void thunar_window_device_changed (ThunarDeviceMonitor *device_monitor, ThunarDevice *device, ThunarWindow *window); -static gboolean thunar_window_merge_idle (gpointer user_data); -static void thunar_window_merge_idle_destroy (gpointer user_data); -static gboolean thunar_window_save_paned (ThunarWindow *window); -static gboolean thunar_window_save_geometry_timer (gpointer user_data); -static void thunar_window_save_geometry_timer_destroy (gpointer user_data); -static void thunar_window_set_zoom_level (ThunarWindow *window, +static gboolean thunar_window_save_paned (ThunarWindow *window); +static gboolean thunar_window_save_geometry_timer (gpointer user_data); +static void thunar_window_save_geometry_timer_destroy(gpointer user_data); +static void thunar_window_set_zoom_level (ThunarWindow *window, ThunarZoomLevel zoom_level); -static void thunar_window_update_window_icon (ThunarWindow *window); +static void thunar_window_update_window_icon (ThunarWindow *window); +static gboolean thunar_window_create_file_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_edit_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_view_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_go_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_help_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static void thunar_window_select_files (ThunarWindow *window, + GList *path_list); +static void thunar_window_binding_create (ThunarWindow *window, + gpointer src_object, + const gchar *src_prop, + gpointer dst_object, + const gchar *dst_prop, + GBindingFlags flags); +static gboolean thunar_window_history_clicked (GtkWidget *button, + GdkEventButton *event, + GtkWidget *window); +static void thunar_window_history_changed (ThunarWindow *window); +static void thunar_window_menu_add_bookmarks (ThunarWindow *window, + GtkMenuShell *view_menu); +static gboolean thunar_window_menu_item_hovered (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_check_uca_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data); +static gboolean thunar_window_check_bookmark_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data); +static void thunar_window_set_current_directory_gfile (ThunarWindow *window, + GFile *current_directory); @@ -267,11 +260,8 @@ struct _ThunarWindowClass GtkWindowClass __parent__; /* internal action signals */ - gboolean (*back) (ThunarWindow *window); gboolean (*reload) (ThunarWindow *window, gboolean reload_info); - gboolean (*toggle_sidepane) (ThunarWindow *window); - gboolean (*toggle_menubar) (ThunarWindow *window); gboolean (*zoom_in) (ThunarWindow *window); gboolean (*zoom_out) (ThunarWindow *window); gboolean (*zoom_reset) (ThunarWindow *window); @@ -285,17 +275,12 @@ struct _ThunarWindow /* support for custom preferences actions */ ThunarxProviderFactory *provider_factory; - guint custom_preferences_merge_id; - - /* UI manager merge ID for go menu actions */ - guint go_items_actions_merge_id; + GList *thunarx_preferences_providers; - /* UI manager merge ID for the bookmark actions */ - guint bookmark_items_actions_merge_id; - GtkActionGroup *bookmark_action_group; GFile *bookmark_file; GFileMonitor *bookmark_monitor; - guint bookmark_reload_idle_id; + GtkMenuShell *view_menu; + GdkEventKey *latest_key_event; ThunarClipboardManager *clipboard; @@ -303,20 +288,9 @@ struct _ThunarWindow ThunarIconFactory *icon_factory; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - /* to be able to change folder on "device-pre-unmount" if required */ ThunarDeviceMonitor *device_monitor; - /* closures for the menu_item_selected()/menu_item_deselected() callbacks */ - GClosure *menu_item_selected_closure; - GClosure *menu_item_deselected_closure; - - /* custom menu actions for the file menu */ - GtkActionGroup *custom_actions; - guint custom_merge_id; - GtkWidget *grid; GtkWidget *menubar; GtkWidget *spinner; @@ -334,15 +308,22 @@ struct _ThunarWindow GtkWidget *location_bar; GtkWidget *location_toolbar; + /* we need to maintain pointers to be able to toggle sensitivity */ + GtkWidget *location_toolbar_item_back; + GtkWidget *location_toolbar_item_forward; + GtkWidget *location_toolbar_item_parent; + ThunarLauncher *launcher; + gulong signal_handler_id_history_changed; + ThunarFile *current_directory; + GtkAccelGroup *accel_group; /* zoom-level support */ ThunarZoomLevel zoom_level; - /* menu merge idle source */ - guint merge_idle_id; + gboolean show_hidden; /* support to remember window geometry */ guint save_geometry_timer_id; @@ -351,58 +332,71 @@ struct _ThunarWindow * see the toggle_sidepane() function. */ GType toggle_sidepane_type; + + /* Takes care to select a file after e.g. rename/create */ + GClosure *select_files_closure; }; -static GtkActionEntry action_entries[] = -{ - { "file-menu", NULL, N_ ("_File"), NULL, }, - { "new-tab", "tab-new", N_ ("New _Tab"), "<control>T", N_ ("Open a new tab for the displayed location"), G_CALLBACK (thunar_window_action_open_new_tab), }, - { "new-window", "window-new", N_ ("New _Window"), "<control>N", N_ ("Open a new Thunar window for the displayed location"), G_CALLBACK (thunar_window_action_open_new_window), }, - { "sendto-menu", NULL, N_ ("_Send To"), NULL, }, - { "empty-trash", NULL, N_ ("_Empty Trash"), NULL, N_ ("Delete all files and folders in the Trash"), G_CALLBACK (thunar_window_action_empty_trash), }, - { "detach-tab", NULL, N_ ("Detac_h Tab"), NULL, N_ ("Open current folder in a new window"), G_CALLBACK (thunar_window_action_detach_tab), }, - { "switch-previous-tab", "go-previous", N_ ("_Previous Tab"), "<control>Page_Up", N_ ("Switch to Previous Tab"), G_CALLBACK (switch_previous_tab), }, - { "switch-next-tab", "go-next", N_ ("_Next Tab"), "<control>Page_Down", N_ ("Switch to Next Tab"), G_CALLBACK (switch_next_tab), }, - { "close-all-windows", NULL, N_ ("Close _All Windows"), "<control><shift>W", N_ ("Close all Thunar windows"), G_CALLBACK (thunar_window_action_close_all_windows), }, - { "close-tab", "window-close", N_ ("C_lose Tab"), "<control>W", N_ ("Close this folder"), G_CALLBACK (thunar_window_action_close_tab), }, - { "close-window", "application-exit", N_ ("_Close Window"), "<control>Q", N_ ("Close this window"), G_CALLBACK (thunar_window_action_close_window), }, - { "edit-menu", NULL, N_ ("_Edit"), NULL, }, - { "preferences", "preferences-system", N_ ("Pr_eferences..."), NULL, N_ ("Edit Thunars Preferences"), G_CALLBACK (thunar_window_action_preferences), }, - { "view-menu", NULL, N_ ("_View"), NULL, }, - { "reload", "view-refresh-symbolic", N_ ("_Reload"), "<control>R", N_ ("Reload the current folder"), G_CALLBACK (thunar_window_action_reload), }, - { "view-location-selector-menu", NULL, N_ ("_Location Selector"), NULL, }, - { "view-side-pane-menu", NULL, N_ ("_Side Pane"), NULL, }, - { "zoom-in", "zoom-in-symbolic", N_ ("Zoom I_n"), "<control>plus", N_ ("Show the contents in more detail"), G_CALLBACK (thunar_window_action_zoom_in), }, - { "zoom-in-alt", NULL, "zoom-in-alt", "<control>equal", NULL, G_CALLBACK (thunar_window_action_zoom_in), }, - { "zoom-out", "zoom-out-symbolic", N_ ("Zoom _Out"), "<control>minus", N_ ("Show the contents in less detail"), G_CALLBACK (thunar_window_action_zoom_out), }, - { "zoom-reset", "zoom-original-symbolic", N_ ("Normal Si_ze"), "<control>0", N_ ("Show the contents at the normal size"), G_CALLBACK (thunar_window_action_zoom_reset), }, - { "go-menu", NULL, N_ ("_Go"), NULL, }, - { "open-parent", "go-up-symbolic", N_ ("Open _Parent"), "<alt>Up", N_ ("Open the parent folder"), G_CALLBACK (thunar_window_action_go_up), }, - { "open-home", "go-home-symbolic", N_ ("_Home"), "<alt>Home", N_ ("Go to the home folder"), G_CALLBACK (thunar_window_action_open_home), }, - { "open-desktop", "user-desktop", N_ ("Desktop"), NULL, N_ ("Go to the desktop folder"), G_CALLBACK (thunar_window_action_open_desktop), }, - { "open-computer", "computer", N_ ("Computer"), NULL, N_ ("Browse all local and remote disks and folders accessible from this computer"), G_CALLBACK (thunar_window_action_open_computer), }, - { "open-file-system", "drive-harddisk", N_ ("File System"), NULL, N_ ("Browse the file system"), G_CALLBACK (thunar_window_action_open_file_system), }, - { "open-network", "network-workgroup", N_("B_rowse Network"), NULL, N_ ("Browse local network connections"), G_CALLBACK (thunar_window_action_open_network), }, - { "open-templates", "text-x-generic-template", N_("T_emplates"), NULL, N_ ("Go to the templates folder"), G_CALLBACK (thunar_window_action_open_templates), }, - { "open-location", NULL, N_ ("_Open Location..."), "<control>L", N_ ("Specify a location to open"), G_CALLBACK (thunar_window_action_open_location), }, - { "open-location-alt", NULL, "open-location-alt", "<alt>D", NULL, G_CALLBACK (thunar_window_action_open_location), }, - { "help-menu", NULL, N_ ("_Help"), NULL, }, - { "contents", "help-browser", N_ ("_Contents"), "F1", N_ ("Display Thunar user manual"), G_CALLBACK (thunar_window_action_contents), }, - { "about", "help-about", N_ ("_About"), NULL, N_ ("Display information about Thunar"), G_CALLBACK (thunar_window_action_about), }, +static XfceGtkActionEntry thunar_window_action_entries[] = +{ + { THUNAR_WINDOW_ACTION_FILE_MENU, "<Actions>/ThunarWindow/file-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_File"), NULL, NULL, NULL,}, + { THUNAR_WINDOW_ACTION_NEW_TAB, "<Actions>/ThunarWindow/new-tab", "<Primary>t", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("New _Tab"), N_ ("Open a new tab for the displayed location"), "tab-new", G_CALLBACK (thunar_window_action_open_new_tab), }, + { THUNAR_WINDOW_ACTION_NEW_WINDOW, "<Actions>/ThunarWindow/new-window", "<Primary>n", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("New _Window"), N_ ("Open a new Thunar window for the displayed location"), "window-new", G_CALLBACK (thunar_window_action_open_new_window), }, + { THUNAR_WINDOW_ACTION_DETACH_TAB, "<Actions>/ThunarWindow/detach-tab", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Detac_h Tab"), N_ ("Open current folder in a new window"), NULL, G_CALLBACK (thunar_window_action_detach_tab), }, + { THUNAR_WINDOW_ACTION_CLOSE_TAB, "<Actions>/ThunarWindow/close-tab", "<Primary>w", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("C_lose Tab"), N_ ("Close this folder"), "window-close", G_CALLBACK (thunar_window_action_close_tab), }, + { THUNAR_WINDOW_ACTION_CLOSE_WINDOW, "<Actions>/ThunarWindow/close-window", "<Primary>q", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Close Window"), N_ ("Close this window"), "application-exit", G_CALLBACK (thunar_window_action_close_window), }, + { THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS, "<Actions>/ThunarWindow/close-all-windows", "<Primary><Shift>w", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Close _All Windows"), N_ ("Close all Thunar windows"), NULL, G_CALLBACK (thunar_window_action_close_all_windows), }, + + { THUNAR_WINDOW_ACTION_EDIT_MENU, "<Actions>/ThunarWindow/edit-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Edit"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_PREFERENCES, "<Actions>/ThunarWindow/preferences", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Pr_eferences..."), N_ ("Edit Thunars Preferences"), "preferences-system", G_CALLBACK (thunar_window_action_preferences), }, + + { THUNAR_WINDOW_ACTION_VIEW_MENU, "<Actions>/ThunarWindow/view-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_View"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_RELOAD, "<Actions>/ThunarWindow/reload", "<Primary>r", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Reload"), N_ ("Reload the current folder"), "view-refresh-symbolic", G_CALLBACK (thunar_window_action_reload), }, + { THUNAR_WINDOW_ACTION_RELOAD_ALT, "<Actions>/ThunarWindow/reload-alt", "F5", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_window_action_reload), }, + { THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_MENU, "<Actions>/ThunarWindow/view-location-selector-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Location Selector"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_PATHBAR, "<Actions>/ThunarWindow/view-location-selector-pathbar", "", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Pathbar Style"), N_ ("Modern approach with buttons that correspond to folders"), NULL, G_CALLBACK (thunar_window_action_pathbar_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_TOOLBAR, "<Actions>/ThunarWindow/view-location-selector-toolbar", "", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Toolbar Style"), N_ ("Traditional approach with location bar and navigation buttons"), NULL, G_CALLBACK (thunar_window_action_toolbar_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_MENU, "<Actions>/ThunarWindow/view-side-pane-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Side Pane"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_SHORTCUTS, "<Actions>/ThunarWindow/view-side-pane-shortcuts", "<Primary>b", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Shortcuts"), N_ ("Toggles the visibility of the shortcuts pane"), NULL, G_CALLBACK (thunar_window_action_shortcuts_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_TREE, "<Actions>/ThunarWindow/view-side-pane-tree", "<Primary>e", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Tree"), N_ ("Toggles the visibility of the tree pane"), NULL, G_CALLBACK (thunar_window_action_tree_changed), }, + { THUNAR_WINDOW_ACTION_TOGGLE_SIDE_PANE, "<Actions>/ThunarWindow/toggle-side-pane", "F9", XFCE_GTK_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_window_toggle_sidepane), }, + { THUNAR_WINDOW_ACTION_VIEW_STATUSBAR, "<Actions>/ThunarWindow/view-statusbar", "", XFCE_GTK_CHECK_MENU_ITEM, N_ ("St_atusbar"), N_ ("Change the visibility of this window's statusbar"), NULL, G_CALLBACK (thunar_window_action_statusbar_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_MENUBAR, "<Actions>/ThunarWindow/view-menubar", "<Primary>m", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Menubar"), N_ ("Change the visibility of this window's menubar"), NULL, G_CALLBACK (thunar_window_action_menubar_changed), }, + { THUNAR_WINDOW_ACTION_SHOW_HIDDEN, "<Actions>/ThunarWindow/show-hidden", "<Primary>h", XFCE_GTK_CHECK_MENU_ITEM, N_ ("Show _Hidden Files"), N_ ("Toggles the display of hidden files in the current window"), NULL, G_CALLBACK (thunar_window_action_show_hidden), }, + { THUNAR_WINDOW_ACTION_ZOOM_IN, "<Actions>/ThunarWindow/zoom-in", "<Primary>KP_Add", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Zoom I_n"), N_ ("Show the contents in more detail"), "zoom-in-symbolic", G_CALLBACK (thunar_window_zoom_in), }, + { THUNAR_WINDOW_ACTION_ZOOM_OUT, "<Actions>/ThunarWindow/zoom-out", "<Primary>KP_Subtract", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Zoom _Out"), N_ ("Show the contents in less detail"), "zoom-out-symbolic", G_CALLBACK (thunar_window_zoom_out), }, + { THUNAR_WINDOW_ACTION_ZOOM_RESET, "<Actions>/ThunarWindow/zoom-reset", "<Primary>KP_0", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Normal Si_ze"), N_ ("Show the contents at the normal size"), "zoom-original-symbolic", G_CALLBACK (thunar_window_zoom_reset), }, + { THUNAR_WINDOW_ACTION_VIEW_AS_ICONS, "<Actions>/ThunarWindow/view-as-icons", "<Primary>1", XFCE_GTK_RADIO_MENU_ITEM, N_ ("View as _Icons"), N_("Display folder content in an icon view"), NULL, G_CALLBACK (thunar_window_action_icon_view), }, + { THUNAR_WINDOW_ACTION_VIEW_AS_DETAILED_LIST, "<Actions>/ThunarWindow/view-as-detailed-list", "<Primary>2", XFCE_GTK_RADIO_MENU_ITEM, N_ ("View as _Detailed List"), N_("Display folder content in a detailed list view"), NULL, G_CALLBACK (thunar_window_action_detailed_view), }, + { THUNAR_WINDOW_ACTION_VIEW_AS_COMPACT_LIST, "<Actions>/ThunarWindow/view-as-compact-list", "<Primary>3", XFCE_GTK_RADIO_MENU_ITEM, N_ ("View as _Compact List"), N_("Display folder content in a compact list view"), NULL, G_CALLBACK (thunar_window_action_compact_view), }, + + { THUNAR_WINDOW_ACTION_GO_MENU, "<Actions>/ThunarWindow/go-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Go"), NULL, NULL, NULL }, + { THUNAR_WINDOW_ACTION_OPEN_FILE_SYSTEM, "<Actions>/ThunarWindow/open-file-system", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("File System"), N_ ("Browse the file system"), "drive-harddisk", G_CALLBACK (thunar_window_action_open_file_system), }, + { THUNAR_WINDOW_ACTION_OPEN_COMPUTER, "<Actions>/ThunarWindow/open-computer", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Computer"), N_ ("Go to the computer folder"), "computer", G_CALLBACK (thunar_window_action_open_computer), }, + { THUNAR_WINDOW_ACTION_OPEN_HOME, "<Actions>/ThunarWindow/open-home", "<Alt>Home", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Home"), N_ ("Go to the home folder"), "go-home-symbolic", G_CALLBACK (thunar_window_action_open_home), }, + { THUNAR_WINDOW_ACTION_OPEN_DESKTOP, "<Actions>/ThunarWindow/open-desktop", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Desktop"), N_ ("Go to the desktop folder"), "user-desktop", G_CALLBACK (thunar_window_action_open_desktop), }, + { THUNAR_WINDOW_ACTION_OPEN_COMPUTER, "<Actions>/ThunarWindow/open-computer", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Computer"), N_ ("Browse all local and remote disks and folders accessible from this computer"), "computer", G_CALLBACK (thunar_window_action_open_computer), }, + { THUNAR_WINDOW_ACTION_OPEN_TRASH, "<Actions>/ThunarWindow/open-trash", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("T_rash"), N_ ("Display the contents of the trash can"), NULL, G_CALLBACK (thunar_window_action_open_trash), }, + { THUNAR_WINDOW_ACTION_OPEN_PARENT, "<Actions>/ThunarWindow/open-parent", "<Alt>Up", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Open _Parent"), N_ ("Open the parent folder"), "go-up-symbolic", G_CALLBACK (thunar_window_action_go_up), }, + { THUNAR_WINDOW_ACTION_OPEN_LOCATION, "<Actions>/ThunarWindow/open-location", "<Primary>l", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Open Location..."), N_ ("Specify a location to open"), NULL, G_CALLBACK (thunar_window_action_open_location), }, + { THUNAR_WINDOW_ACTION_OPEN_LOCATION_ALT, "<Actions>/ThunarWindow/open-location-alt", "<Alt>d", XFCE_GTK_MENU_ITEM, "open-location-alt", NULL, NULL, G_CALLBACK (thunar_window_action_open_location), }, + { THUNAR_WINDOW_ACTION_OPEN_TEMPLATES, "<Actions>/ThunarWindow/open-templates", "", XFCE_GTK_IMAGE_MENU_ITEM, N_("T_emplates"), N_ ("Go to the templates folder"), "text-x-generic-template", G_CALLBACK (thunar_window_action_open_templates), }, + { THUNAR_WINDOW_ACTION_OPEN_NETWORK, "<Actions>/ThunarWindow/open-network", "", XFCE_GTK_IMAGE_MENU_ITEM, N_("B_rowse Network"), N_ ("Browse local network connections"), "network-workgroup", G_CALLBACK (thunar_window_action_open_network), }, + + { THUNAR_WINDOW_ACTION_HELP_MENU, "<Actions>/ThunarWindow/contents/help-menu", "", XFCE_GTK_MENU_ITEM , N_ ("_Help"), NULL, NULL, NULL}, + { THUNAR_WINDOW_ACTION_CONTENTS, "<Actions>/ThunarWindow/contents", "F1", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Contents"), N_ ("Display Thunar user manual"), "help-browser", G_CALLBACK (thunar_window_action_contents), }, + { THUNAR_WINDOW_ACTION_ABOUT, "<Actions>/ThunarWindow/about", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_About"), N_ ("Display information about Thunar"), "help-about", G_CALLBACK (thunar_window_action_about), }, + { THUNAR_WINDOW_ACTION_BACK, "<Actions>/ThunarStandardView/back", "<Alt>Left", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Back"), N_ ("Go to the previous visited folder"), "go-previous-symbolic", G_CALLBACK (thunar_window_action_back), }, + { THUNAR_WINDOW_ACTION_BACK_ALT, "<Actions>/ThunarStandardView/back-alt", "BackSpace", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_window_action_back), }, + { THUNAR_WINDOW_ACTION_FORWARD, "<Actions>/ThunarStandardView/forward", "<Alt>Right", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Forward"), N_ ("Go to the next visited folder"), "go-next-symbolic", G_CALLBACK (thunar_window_action_forward), }, + { THUNAR_WINDOW_ACTION_SWITCH_PREV_TAB, "<Actions>/ThunarWindow/switch-previous-tab", "<Primary>Page_Up", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Previous Tab"), N_ ("Switch to Previous Tab"), "go-previous", G_CALLBACK (thunar_window_action_switch_previous_tab), }, + { THUNAR_WINDOW_ACTION_SWITCH_NEXT_TAB, "<Actions>/ThunarWindow/switch-next-tab", "<Primary>Page_Down", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Next Tab"), N_ ("Switch to Next Tab"), "go-next", G_CALLBACK (thunar_window_action_switch_next_tab), }, + { 0, "<Actions>/ThunarWindow/open-file-menu", "F10", 0, NULL, NULL, NULL, G_CALLBACK (thunar_window_action_open_file_menu), }, }; -static const GtkToggleActionEntry toggle_action_entries[] = -{ - { "show-hidden", NULL, N_ ("Show _Hidden Files"), "<control>H", N_ ("Toggles the display of hidden files in the current window"), G_CALLBACK (thunar_window_action_show_hidden), FALSE, }, - { "view-location-selector-pathbar", NULL, N_ ("_Pathbar Style"), NULL, N_ ("Modern approach with buttons that correspond to folders"), G_CALLBACK (thunar_window_action_pathbar_changed), FALSE, }, - { "view-location-selector-toolbar", NULL, N_ ("_Toolbar Style"), NULL, N_ ("Traditional approach with location bar and navigation buttons"), G_CALLBACK (thunar_window_action_toolbar_changed), FALSE, }, - { "view-side-pane-shortcuts", NULL, N_ ("_Shortcuts"), "<control>B", N_ ("Toggles the visibility of the shortcuts pane"), G_CALLBACK (thunar_window_action_shortcuts_changed), FALSE, }, - { "view-side-pane-tree", NULL, N_ ("_Tree"), "<control>E", N_ ("Toggles the visibility of the tree pane"), G_CALLBACK (thunar_window_action_tree_changed), FALSE, }, - { "view-statusbar", NULL, N_ ("St_atusbar"), NULL, N_ ("Change the visibility of this window's statusbar"), G_CALLBACK (thunar_window_action_statusbar_changed), FALSE, }, - { "view-menubar", NULL, N_ ("_Menubar"), "<control>M", N_ ("Change the visibility of this window's menubar"), G_CALLBACK (thunar_window_action_menubar_changed), TRUE, }, -}; +#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_window_action_entries,G_N_ELEMENTS(thunar_window_action_entries),id) @@ -434,15 +428,14 @@ thunar_window_class_init (ThunarWindowClass *klass) gtkwidget_class->unrealize = thunar_window_unrealize; gtkwidget_class->configure_event = thunar_window_configure_event; - klass->back = thunar_window_back; klass->reload = thunar_window_reload; - klass->toggle_sidepane = thunar_window_toggle_sidepane; - klass->toggle_menubar = thunar_window_toggle_menubar; klass->zoom_in = thunar_window_zoom_in; klass->zoom_out = thunar_window_zoom_out; klass->zoom_reset = thunar_window_zoom_reset; klass->tab_change = thunar_window_tab_change; + xfce_gtk_translate_action_entries (thunar_window_action_entries, G_N_ELEMENTS (thunar_window_action_entries)); + /** * ThunarWindow:current-directory: * @@ -458,36 +451,6 @@ thunar_window_class_init (ThunarWindowClass *klass) EXO_PARAM_READWRITE)); /** - * ThunarWindow:show-hidden: - * - * Whether to show hidden files in the current window. - **/ - g_object_class_install_property (gobject_class, - PROP_SHOW_HIDDEN, - g_param_spec_boolean ("show-hidden", - "show-hidden", - "show-hidden", - FALSE, - EXO_PARAM_READABLE)); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /** - * ThunarWindow:ui-manager: - * - * The #GtkUIManager used for this #ThunarWindow. This property - * can only be read and is garantied to always contain a valid - * #GtkUIManager instance (thus it's never %NULL). - **/ - g_object_class_install_property (gobject_class, - PROP_UI_MANAGER, - g_param_spec_object ("ui-manager", - "ui-manager", - "ui-manager", - GTK_TYPE_UI_MANAGER, - EXO_PARAM_READABLE)); -G_GNUC_END_IGNORE_DEPRECATIONS - - /** * ThunarWindow:zoom-level: * * The #ThunarZoomLevel applied to the #ThunarView currently @@ -503,29 +466,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS EXO_PARAM_READWRITE)); /** - * ThunarWindow::back: - * @window : a #ThunarWindow instance. - * - * Emitted whenever the user requests to go to the - * previous visited folder. This is an internal - * signal used to bind the action to keys. - **/ - window_signals[BACK] = - g_signal_new (I_("back"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ThunarWindowClass, back), - g_signal_accumulator_true_handled, NULL, - _thunar_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); - - /** * ThunarWindow::reload: * @window : a #ThunarWindow instance. * * Emitted whenever the user requests to reload the contents - * of the currently displayed folder. This is an internal - * signal used to bind the action to keys. + * of the currently displayed folder. **/ window_signals[RELOAD] = g_signal_new (I_("reload"), @@ -538,40 +483,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS G_TYPE_BOOLEAN); /** - * ThunarWindow::toggle-sidepane: - * @window : a #ThunarWindow instance. - * - * Emitted whenever the user toggles the visibility of the - * sidepane. This is an internal signal used to bind the - * action to keys. - **/ - window_signals[TOGGLE_SIDEPANE] = - g_signal_new (I_("toggle-sidepane"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ThunarWindowClass, toggle_sidepane), - g_signal_accumulator_true_handled, NULL, - _thunar_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); - - /** - * ThunarWindow::toggle-menubar: - * @window : a #ThunarWindow instance. - * - * Emitted whenever the user toggles the visibility of the - * menubar. This is an internal signal used to bind the - * action to keys. - **/ - window_signals[TOGGLE_MENUBAR] = - g_signal_new (I_("toggle-menubar"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ThunarWindowClass, toggle_menubar), - g_signal_accumulator_true_handled, NULL, - _thunar_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); - - /** * ThunarWindow::zoom-in: * @window : a #ThunarWindow instance. * @@ -639,14 +550,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* setup the key bindings for the windows */ binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_BackSpace, 0, "back", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_F5, 0, "reload", 1, G_TYPE_BOOLEAN, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_F9, 0, "toggle-sidepane", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, 0, "toggle-menubar", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Add, GDK_CONTROL_MASK, "zoom-in", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Subtract, GDK_CONTROL_MASK, "zoom-out", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_0, GDK_CONTROL_MASK, "zoom-reset", 0); - gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Insert, GDK_CONTROL_MASK, "zoom-reset", 0); /* setup the key bindings for Alt+N */ for (i = 0; i < 10; i++) @@ -658,52 +561,79 @@ G_GNUC_END_IGNORE_DEPRECATIONS -static inline gint -view_type2index (GType type) +static gboolean +thunar_window_check_uca_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data) { - /* this necessary for platforms where sizeof(GType) != sizeof(gint), - * see https://bugzilla.xfce.org/show_bug.cgi?id=2726 for details. - */ - if (sizeof (GType) == sizeof (gint)) - { - /* no need to map anything */ - return (gint) type; - } - else - { - /* map from types to unique indices */ - if (G_LIKELY (type == THUNAR_TYPE_COMPACT_VIEW)) - return 0; - else if (type == THUNAR_TYPE_DETAILS_VIEW) - return 1; - else - return 2; - } + if (thunar_launcher_check_uca_key_activation (window->launcher, key_event)) + return GDK_EVENT_STOP; + return GDK_EVENT_PROPAGATE; } -static inline GType -view_index2type (gint idx) +static gchar* +thunar_window_bookmark_get_accel_path (GFile *bookmark_file) { - /* this necessary for platforms where sizeof(GType) != sizeof(gint), - * see https://bugzilla.xfce.org/show_bug.cgi?id=2726 for details. - */ - if (sizeof (GType) == sizeof (gint)) - { - /* no need to map anything */ - return (GType) idx; - } - else + GChecksum *checksum; + gchar *uri; + gchar *accel_path; + const gchar *unique_name; + + _thunar_return_val_if_fail (G_IS_FILE (bookmark_file), NULL); + + /* create unique id based on the uri */ + uri = g_file_get_uri (bookmark_file); + checksum = g_checksum_new (G_CHECKSUM_MD5); + g_checksum_update (checksum, (const guchar *) uri, strlen (uri)); + unique_name = g_checksum_get_string (checksum); + accel_path = g_strconcat("<Actions>/ThunarBookmarks/", unique_name, NULL); + + g_free (uri); + g_checksum_free (checksum); + return accel_path; +} + + + +static void +thunar_window_bookmark_check_key (GFile *g_file, + const gchar *name, + gint line_num, + gpointer user_data) +{ + ThunarWindow *window = THUNAR_WINDOW (user_data); + gchar *accel_path; + GtkAccelKey key; + + accel_path = thunar_window_bookmark_get_accel_path (g_file); + if (gtk_accel_map_lookup_entry (accel_path, &key) == TRUE) { - /* map from indices to unique types */ - switch (idx) + if (window->latest_key_event->keyval == key.accel_key) { - case 0: return THUNAR_TYPE_COMPACT_VIEW; - case 1: return THUNAR_TYPE_DETAILS_VIEW; - default: return THUNAR_TYPE_ICON_VIEW; + if ((window->latest_key_event->state & gtk_accelerator_get_default_mod_mask ()) == key.accel_mods) + thunar_window_set_current_directory_gfile (window, g_file); } } + g_free (accel_path); +} + + + +static gboolean +thunar_window_check_bookmark_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data) +{ + /* in order to access it inside the clalback */ + window->latest_key_event = key_event; + + /* load bookmark menu items from bookmark file */ + thunar_util_load_bookmarks (window->bookmark_file, + thunar_window_bookmark_check_key, + window); + return GDK_EVENT_PROPAGATE; } @@ -711,15 +641,10 @@ view_index2type (gint idx) static void thunar_window_init (ThunarWindow *window) { - GtkRadioAction *radio_action; - GtkAccelGroup *accel_group; GtkWidget *label; GtkWidget *infobar; GtkWidget *item; - GtkAction *action; - gboolean last_show_hidden; gboolean last_menubar_visible; - GSList *group; gchar *last_location_bar; gchar *last_side_pane; GType type; @@ -735,15 +660,25 @@ thunar_window_init (ThunarWindow *window) /* unset the view type */ window->view_type = G_TYPE_NONE; - /* grab a reference on the provider factory */ + /* grab a reference on the provider factory and load the providers*/ window->provider_factory = thunarx_provider_factory_get_default (); + window->thunarx_preferences_providers = thunarx_provider_factory_list_providers (window->provider_factory, THUNARX_TYPE_PREFERENCES_PROVIDER); /* grab a reference on the preferences */ window->preferences = thunar_preferences_get (); + window->accel_group = gtk_accel_group_new (); + xfce_gtk_accel_map_add_entries (thunar_window_action_entries, G_N_ELEMENTS (thunar_window_action_entries)); + xfce_gtk_accel_group_connect_action_entries (window->accel_group, + thunar_window_action_entries, + G_N_ELEMENTS (thunar_window_action_entries), + window); + + gtk_window_add_accel_group (GTK_WINDOW (window), window->accel_group); + /* get all properties for init */ g_object_get (G_OBJECT (window->preferences), - "last-show-hidden", &last_show_hidden, + "last-show-hidden", &window->show_hidden, "last-window-width", &last_window_width, "last-window-height", &last_window_height, "last-window-maximized", &last_window_maximized, @@ -764,73 +699,18 @@ thunar_window_init (ThunarWindow *window) g_signal_connect (window->device_monitor, "device-removed", G_CALLBACK (thunar_window_device_changed), window); g_signal_connect (window->device_monitor, "device-changed", G_CALLBACK (thunar_window_device_changed), window); - /* allocate a closure for the menu_item_selected() callback */ - window->menu_item_selected_closure = g_cclosure_new_object (G_CALLBACK (thunar_window_menu_item_selected), G_OBJECT (window)); - g_closure_ref (window->menu_item_selected_closure); - g_closure_sink (window->menu_item_selected_closure); - - /* allocate a closure for the menu_item_deselected() callback */ - window->menu_item_deselected_closure = g_cclosure_new_object (G_CALLBACK (thunar_window_menu_item_deselected), G_OBJECT (window)); - g_closure_ref (window->menu_item_deselected_closure); - g_closure_sink (window->menu_item_deselected_closure); window->icon_factory = thunar_icon_factory_get_default (); - /* Catch key events before accelerators get processed */ - g_signal_connect (window, "key-press-event", G_CALLBACK (thunar_window_propagate_key_event), NULL); - g_signal_connect (window, "key-release-event", G_CALLBACK (thunar_window_propagate_key_event), NULL); + window->select_files_closure = g_cclosure_new_swap (G_CALLBACK (thunar_window_select_files), window, NULL); + g_closure_ref (window->select_files_closure); + g_closure_sink (window->select_files_closure); + window->launcher = g_object_new (THUNAR_TYPE_LAUNCHER, "widget", GTK_WIDGET (window), + "select-files-closure", window->select_files_closure, NULL); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup the action group for this window */ - window->action_group = gtk_action_group_new ("ThunarWindow"); - gtk_action_group_set_translation_domain (window->action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions (window->action_group, action_entries, G_N_ELEMENTS (action_entries), GTK_WIDGET (window)); - gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries, G_N_ELEMENTS (toggle_action_entries), GTK_WIDGET (window)); - - /* initialize the "show-hidden" action using the last value from the preferences */ - action = gtk_action_group_get_action (window->action_group, "show-hidden"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), last_show_hidden); - - /* - * add view options - */ - radio_action = gtk_radio_action_new ("view-as-icons", _("View as _Icons"), _("Display folder content in an icon view"), - NULL, view_type2index (THUNAR_TYPE_ICON_VIEW)); - gtk_action_group_add_action_with_accel (window->action_group, GTK_ACTION (radio_action), "<control>1"); - gtk_radio_action_set_group (radio_action, NULL); - group = gtk_radio_action_get_group (radio_action); - g_object_unref (G_OBJECT (radio_action)); - - radio_action = gtk_radio_action_new ("view-as-detailed-list", _("View as _Detailed List"), _("Display folder content in a detailed list view"), - NULL, view_type2index (THUNAR_TYPE_DETAILS_VIEW)); - gtk_action_group_add_action_with_accel (window->action_group, GTK_ACTION (radio_action), "<control>2"); - gtk_radio_action_set_group (radio_action, group); - group = gtk_radio_action_get_group (radio_action); - g_object_unref (G_OBJECT (radio_action)); - - radio_action = gtk_radio_action_new ("view-as-compact-list", _("View as _Compact List"), _("Display folder content in a compact list view"), - NULL, view_type2index (THUNAR_TYPE_COMPACT_VIEW)); - gtk_action_group_add_action_with_accel (window->action_group, GTK_ACTION (radio_action), "<control>3"); - gtk_radio_action_set_group (radio_action, group); - group = gtk_radio_action_get_group (radio_action); - g_object_unref (G_OBJECT (radio_action)); - - window->ui_manager = gtk_ui_manager_new (); - g_signal_connect (G_OBJECT (window->ui_manager), "connect-proxy", G_CALLBACK (thunar_window_connect_proxy), window); - g_signal_connect (G_OBJECT (window->ui_manager), "disconnect-proxy", G_CALLBACK (thunar_window_disconnect_proxy), window); - gtk_ui_manager_insert_action_group (window->ui_manager, window->action_group, 0); - gtk_ui_manager_add_ui_from_string (window->ui_manager, thunar_window_ui, thunar_window_ui_length, NULL); - - accel_group = gtk_ui_manager_get_accel_group (window->ui_manager); - gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* setup the launcher support */ - window->launcher = thunar_launcher_new (); - thunar_launcher_set_widget (window->launcher, GTK_WIDGET (window)); - thunar_component_set_ui_manager (THUNAR_COMPONENT (window->launcher), window->ui_manager); exo_binding_new (G_OBJECT (window), "current-directory", G_OBJECT (window->launcher), "current-directory"); g_signal_connect_swapped (G_OBJECT (window->launcher), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); g_signal_connect_swapped (G_OBJECT (window->launcher), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window); + thunar_launcher_append_accelerators (window->launcher, window->accel_group); /* determine the default window size from the preferences */ gtk_window_set_default_size (GTK_WINDOW (window), last_window_width, last_window_height); @@ -847,19 +727,30 @@ G_GNUC_END_IGNORE_DEPRECATIONS gtk_container_add (GTK_CONTAINER (window), window->grid); gtk_widget_show (window->grid); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - window->menubar = gtk_ui_manager_get_widget (window->ui_manager, "/main-menu"); -G_GNUC_END_IGNORE_DEPRECATIONS + /* build the menubar */ + window->menubar = gtk_menu_bar_new (); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_FILE_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_file_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_EDIT_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_edit_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_view_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_GO_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_go_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_HELP_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_help_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + gtk_widget_show_all (window->menubar); + + if (last_menubar_visible == FALSE) + gtk_widget_hide (window->menubar); gtk_widget_set_hexpand (window->menubar, TRUE); gtk_grid_attach (GTK_GRID (window->grid), window->menubar, 0, 0, 1, 1); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update menubar visibiliy */ - action = gtk_action_group_get_action (window->action_group, "view-menubar"); - g_signal_connect (G_OBJECT (window->menubar), "deactivate", G_CALLBACK (thunar_window_toggle_menubar_deactivate), window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), last_menubar_visible); -G_GNUC_END_IGNORE_DEPRECATIONS - /* append the menu item for the spinner */ item = gtk_menu_item_new (); gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE); @@ -932,37 +823,38 @@ G_GNUC_END_IGNORE_DEPRECATIONS g_signal_connect_swapped (G_OBJECT (window->location_bar), "reload-requested", G_CALLBACK (thunar_window_handle_reload_request), window); g_signal_connect_swapped (G_OBJECT (window->location_bar), "entry-done", G_CALLBACK (thunar_window_update_location_bar_visible), window); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS /* setup the toolbar for the location bar */ - window->location_toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/location-toolbar"); -G_GNUC_END_IGNORE_DEPRECATIONS - + window->location_toolbar = gtk_toolbar_new (); gtk_toolbar_set_style (GTK_TOOLBAR (window->location_toolbar), GTK_TOOLBAR_ICONS); gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->location_toolbar), small_icons ? GTK_ICON_SIZE_SMALL_TOOLBAR : GTK_ICON_SIZE_LARGE_TOOLBAR); gtk_widget_set_hexpand (window->location_toolbar, TRUE); gtk_grid_attach (GTK_GRID (window->grid), window->location_toolbar, 0, 1, 1, 1); - /* add the location bar tool item */ + window->location_toolbar_item_back = xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_BACK), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + window->location_toolbar_item_forward = xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_FORWARD), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + window->location_toolbar_item_parent = xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_PARENT), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_HOME), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + + g_signal_connect (G_OBJECT (window->location_toolbar_item_back), "button-press-event", G_CALLBACK (thunar_window_history_clicked), G_OBJECT (window)); + g_signal_connect (G_OBJECT (window->location_toolbar_item_forward), "button-press-event", G_CALLBACK (thunar_window_history_clicked), G_OBJECT (window)); + window->signal_handler_id_history_changed = 0; + + /* The UCA shortcuts and the bookmarks need to be checked 'by hand', since we dont want to permanently keep menu items for them */ + g_signal_connect (window, "key-press-event", G_CALLBACK (thunar_window_check_uca_key_activation), NULL); + g_signal_connect (window, "key-press-event", G_CALLBACK (thunar_window_check_bookmark_key_activation), NULL); + + /* add the location bar to the toolbar */ tool_item = gtk_tool_item_new (); gtk_tool_item_set_expand (tool_item, TRUE); gtk_toolbar_insert (GTK_TOOLBAR (window->location_toolbar), tool_item, -1); gtk_toolbar_set_show_arrow (GTK_TOOLBAR (window->location_toolbar), FALSE); - gtk_widget_show (GTK_WIDGET (tool_item)); /* add the location bar itself */ gtk_container_add (GTK_CONTAINER (tool_item), window->location_bar); - /* display the new location bar widget */ - gtk_widget_show (window->location_bar); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* activate the selected location selector */ - action = gtk_action_group_get_action (window->action_group, "view-location-selector-pathbar"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !strcmp(last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_BUTTONS))); - action = gtk_action_group_get_action (window->action_group, "view-location-selector-toolbar"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !strcmp(last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_ENTRY))); -G_GNUC_END_IGNORE_DEPRECATIONS + /* display the toolbar */ + gtk_widget_show_all (window->location_toolbar); g_free (last_location_bar); @@ -973,82 +865,393 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* update window icon whenever preferences change */ g_signal_connect_object (G_OBJECT (window->preferences), "notify::misc-change-window-icon", G_CALLBACK (thunar_window_update_window_icon), window, G_CONNECT_SWAPPED); - /* determine the selected side pane (FIXME: Should probably be last-shortcuts-visible and last-tree-visible preferences) */ + /* determine the selected side pane */ if (exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_SHORTCUTS_PANE))) type = THUNAR_TYPE_SHORTCUTS_PANE; else if (exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_TREE_PANE))) type = THUNAR_TYPE_TREE_PANE; else type = G_TYPE_NONE; + thunar_window_install_sidepane (window, type); g_free (last_side_pane); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* activate the selected side pane */ - action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (type == THUNAR_TYPE_SHORTCUTS_PANE)); - action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (type == THUNAR_TYPE_TREE_PANE)); - - /* check if we should display the statusbar by default */ - action = gtk_action_group_get_action (window->action_group, "view-statusbar"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), last_statusbar_visible); - - /* connect signal */ - action = gtk_action_group_get_action (window->action_group, "view-as-icons"); -G_GNUC_END_IGNORE_DEPRECATIONS - g_signal_connect (G_OBJECT (action), "changed", G_CALLBACK (thunar_window_action_view_changed), window); + /* setup a new statusbar */ + window->statusbar = thunar_statusbar_new (); + gtk_widget_set_hexpand (window->statusbar, TRUE); + gtk_grid_attach (GTK_GRID (window->view_box), window->statusbar, 0, 2, 1, 1); + if (last_statusbar_visible) + gtk_widget_show (window->statusbar); + + if (G_LIKELY (window->view != NULL)) + thunar_window_binding_create (window, window->view, "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); - /* schedule asynchronous menu action merging */ - window->merge_idle_id = g_idle_add_full (G_PRIORITY_LOW + 20, thunar_window_merge_idle, window, thunar_window_merge_idle_destroy); + + /* setup a new statusbar */ + window->statusbar = thunar_statusbar_new (); + gtk_widget_set_hexpand (window->statusbar, TRUE); + gtk_grid_attach (GTK_GRID (window->view_box), window->statusbar, 0, 2, 1, 1); + if (last_statusbar_visible) + gtk_widget_show (window->statusbar); + + if (G_LIKELY (window->view != NULL)) + thunar_window_binding_create (window, window->view, "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); + + /* ensure that all the view types are registered */ + g_type_ensure (THUNAR_TYPE_ICON_VIEW); + g_type_ensure (THUNAR_TYPE_DETAILS_VIEW); + g_type_ensure (THUNAR_TYPE_COMPACT_VIEW); + + /* load the bookmarks file and monitor */ + window->bookmark_file = thunar_g_file_new_for_bookmarks (); + window->bookmark_monitor = g_file_monitor_file (window->bookmark_file, G_FILE_MONITOR_NONE, NULL, NULL); + + /* same is done for view in thunar_window_action_view_changed */ + thunar_side_pane_set_show_hidden (THUNAR_SIDE_PANE (window->sidepane), window->show_hidden); } +/** + * thunar_window_select_files: + * @window : a #ThunarWindow instance. + * @files_to_selected : a list of #GFile<!---->s + * + * Visually selects the files, given by the list + **/ static void -thunar_window_dispose (GObject *object) +thunar_window_select_files (ThunarWindow *window, + GList *files_to_selected) { - ThunarWindow *window = THUNAR_WINDOW (object); + GList *thunarFiles = NULL; - /* destroy the save geometry timer source */ - if (G_UNLIKELY (window->save_geometry_timer_id != 0)) - g_source_remove (window->save_geometry_timer_id); + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + for (GList *lp = files_to_selected; lp != NULL; lp = lp->next) + thunarFiles = g_list_append (thunarFiles, thunar_file_get (G_FILE (files_to_selected->data), NULL)); + thunar_view_set_selected_files (THUNAR_VIEW (window->view), thunarFiles); + g_list_free_full (thunarFiles, g_object_unref); +} + + + +static gboolean +thunar_window_menu_is_open (ThunarWindow *window) +{ + GList *lp; + GtkWidget *submenu; - /* destroy the merge idle source */ - if (G_UNLIKELY (window->merge_idle_id != 0)) - g_source_remove (window->merge_idle_id); + g_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); - /* un-merge the custom preferences */ - if (G_LIKELY (window->custom_preferences_merge_id != 0)) + for(lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (window->ui_manager, window->custom_preferences_merge_id); -G_GNUC_END_IGNORE_DEPRECATIONS - window->custom_preferences_merge_id = 0; + submenu = gtk_menu_item_get_submenu(lp->data); + if (submenu != NULL && gtk_widget_get_visible (submenu)) + return TRUE; } + return FALSE; +} + + + +static gboolean +thunar_window_menu_item_hovered (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + gboolean ret; + + g_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + if (thunar_window_menu_is_open(window)) + g_signal_emit_by_name (menu, "button-press-event", NULL, &ret); + return FALSE; +} + + + +static gboolean +thunar_window_create_file_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + GtkWidget *item; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + submenu = g_object_new (THUNAR_TYPE_MENU, "menu-type", THUNAR_MENU_TYPE_WINDOW, + "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_NEW_TAB), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_NEW_WINDOW), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_OPEN + | THUNAR_MENU_SECTION_SENDTO + | THUNAR_MENU_SECTION_CREATE_NEW_FILES + | THUNAR_MENU_SECTION_EMPTY_TRASH + | THUNAR_MENU_SECTION_CUSTOM_ACTIONS + | THUNAR_MENU_SECTION_PROPERTIES); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_DETACH_TAB), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_widget_set_sensitive (item, gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) > 1); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_TAB), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_WINDOW), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static gboolean +thunar_window_create_edit_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + GtkWidget *gtk_menu_item; + GList *thunarx_menu_items; + GList *pp, *lp; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); - /* un-merge the go menu actions */ - if (G_LIKELY (window->go_items_actions_merge_id != 0)) + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_CUT + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_TRASH_DELETE); + if (window->view != NULL) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (window->ui_manager, window->go_items_actions_merge_id); -G_GNUC_END_IGNORE_DEPRECATIONS - window->go_items_actions_merge_id = 0; + thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), + GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES); + thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), + GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN); + thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), + GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION); } + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_DUPLICATE + | THUNAR_MENU_SECTION_MAKELINK + | THUNAR_MENU_SECTION_RENAME + | THUNAR_MENU_SECTION_RESTORE); - /* un-merge the bookmark actions */ - if (G_LIKELY (window->bookmark_items_actions_merge_id != 0)) + /* determine the available preferences providers */ + if (G_LIKELY (window->thunarx_preferences_providers != NULL)) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (window->ui_manager, window->bookmark_items_actions_merge_id); -G_GNUC_END_IGNORE_DEPRECATIONS - window->bookmark_items_actions_merge_id = 0; + /* add menu items from all providers */ + for (pp = window->thunarx_preferences_providers; pp != NULL; pp = pp->next) + { + /* determine the available menu items for the provider */ + thunarx_menu_items = thunarx_preferences_provider_get_menu_items (THUNARX_PREFERENCES_PROVIDER (pp->data), GTK_WIDGET (window)); + for (lp = thunarx_menu_items; lp != NULL; lp = lp->next) + { + gtk_menu_item = thunar_gtk_menu_thunarx_menu_item_new (lp->data, GTK_MENU_SHELL (submenu)); + + /* Each thunarx_menu_item will be destroyed together with its related gtk_menu_item */ + g_signal_connect_swapped (G_OBJECT (gtk_menu_item), "destroy", G_CALLBACK (g_object_unref), lp->data); + } + + /* release the list */ + g_list_free (thunarx_menu_items); + } } + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_PREFERENCES), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + - if (window->bookmark_reload_idle_id != 0) +static gboolean +thunar_window_create_view_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + GtkWidget *item; + GtkWidget *sub_items; + gchar *last_location_bar; + gchar *last_side_pane; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_RELOAD), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_MENU), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + sub_items = gtk_menu_new(); + gtk_menu_set_accel_group (GTK_MENU (sub_items), window->accel_group); + g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_PATHBAR), G_OBJECT (window), + exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_ENTRY)), GTK_MENU_SHELL (sub_items)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_TOOLBAR), G_OBJECT (window), + exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_BUTTONS)), GTK_MENU_SHELL (sub_items)); + g_free (last_location_bar); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), GTK_WIDGET (sub_items)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_MENU), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + sub_items = gtk_menu_new(); + gtk_menu_set_accel_group (GTK_MENU (sub_items), window->accel_group); + g_object_get (window->preferences, "last-side-pane", &last_side_pane, NULL); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_SHORTCUTS), G_OBJECT (window), + exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_SHORTCUTS_PANE)), GTK_MENU_SHELL (sub_items)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_TREE), G_OBJECT (window), + exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_TREE_PANE)), GTK_MENU_SHELL (sub_items)); + g_free (last_side_pane); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), GTK_WIDGET (sub_items)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_STATUSBAR), G_OBJECT (window), + gtk_widget_get_visible (window->statusbar), GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_MENUBAR), G_OBJECT (window), + gtk_widget_get_visible (window->menubar), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SHOW_HIDDEN), G_OBJECT (window), + window->show_hidden, GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + if (window->view != NULL) + thunar_standard_view_append_menu_items (THUNAR_STANDARD_VIEW (window->view), GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_window_append_menu_item (window, GTK_MENU_SHELL (submenu), THUNAR_WINDOW_ACTION_ZOOM_IN); + thunar_window_append_menu_item (window, GTK_MENU_SHELL (submenu), THUNAR_WINDOW_ACTION_ZOOM_OUT); + thunar_window_append_menu_item (window, GTK_MENU_SHELL (submenu), THUNAR_WINDOW_ACTION_ZOOM_RESET); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_ICONS), + G_OBJECT (window), window->view_type == THUNAR_TYPE_ICON_VIEW, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_DETAILED_LIST), + G_OBJECT (window), window->view_type == THUNAR_TYPE_DETAILS_VIEW, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_COMPACT_LIST), + G_OBJECT (window), window->view_type == THUNAR_TYPE_COMPACT_VIEW, GTK_MENU_SHELL (submenu)); + + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static gboolean +thunar_window_create_go_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + gchar *icon_name; + const XfceGtkActionEntry *action_entry; + ThunarHistory *history = NULL; + GtkWidget *item; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + if (window->view != NULL) + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_PARENT), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_widget_set_sensitive (item, !thunar_g_file_is_root (thunar_file_get_file (window->current_directory))); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_BACK), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + if (history != NULL) + gtk_widget_set_sensitive (item, thunar_history_has_back (history)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_FORWARD), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + if (history != NULL) + gtk_widget_set_sensitive (item, thunar_history_has_forward (history)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_COMPUTER), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_HOME), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_DESKTOP), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + if (thunar_g_vfs_is_uri_scheme_supported ("trash")) { - g_source_remove (window->bookmark_reload_idle_id); - window->bookmark_reload_idle_id = 0; + GFile *gfile; + ThunarFile *trash_folder; + + /* try to connect to the trash bin */ + gfile = thunar_g_file_new_for_trash (); + if (gfile != NULL) + { + trash_folder = thunar_file_get (gfile, NULL); + if (trash_folder != NULL) + { + action_entry = get_action_entry (THUNAR_WINDOW_ACTION_OPEN_TRASH); + if (action_entry != NULL) + { + if (thunar_file_get_item_count (trash_folder) > 0) + icon_name = "user-trash-full"; + else + icon_name = "user-trash"; + xfce_gtk_image_menu_item_new_from_icon_name (action_entry->menu_item_label_text, action_entry->menu_item_tooltip_text, + action_entry->accel_path, action_entry->callback, G_OBJECT (window), icon_name, GTK_MENU_SHELL (submenu)); + g_object_unref (trash_folder); + } + } + g_object_unref (gfile); + } } + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_TEMPLATES), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_window_menu_add_bookmarks (window, GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_FILE_SYSTEM), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_NETWORK), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_LOCATION), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static gboolean +thunar_window_create_help_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CONTENTS), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_ABOUT), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static void +thunar_window_dispose (GObject *object) +{ + ThunarWindow *window = THUNAR_WINDOW (object); + + /* indicate that history items are out of use */ + window->location_toolbar_item_back = NULL; + window->location_toolbar_item_forward = NULL; + + /* destroy the save geometry timer source */ + if (G_UNLIKELY (window->save_geometry_timer_id != 0)) + g_source_remove (window->save_geometry_timer_id); /* disconnect from the current-directory */ thunar_window_set_current_directory (window, NULL); @@ -1063,29 +1266,13 @@ thunar_window_finalize (GObject *object) { ThunarWindow *window = THUNAR_WINDOW (object); - /* drop our references on the menu_item_selected()/menu_item_deselected() closures */ - g_closure_unref (window->menu_item_deselected_closure); - g_closure_unref (window->menu_item_selected_closure); - /* disconnect from the volume monitor */ g_signal_handlers_disconnect_matched (window->device_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); g_object_unref (window->device_monitor); - /* disconnect from the ui manager */ - g_signal_handlers_disconnect_matched (window->ui_manager, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); - g_object_unref (window->ui_manager); - - /* release the custom actions */ - if (window->custom_actions != NULL) - g_object_unref (window->custom_actions); - - g_object_unref (window->action_group); g_object_unref (window->icon_factory); g_object_unref (window->launcher); - if (window->bookmark_action_group != NULL) - g_object_unref (window->bookmark_action_group); - if (window->bookmark_file != NULL) g_object_unref (window->bookmark_file); @@ -1101,6 +1288,9 @@ thunar_window_finalize (GObject *object) /* release the preferences reference */ g_object_unref (window->preferences); + g_closure_invalidate (window->select_files_closure); + g_closure_unref (window->select_files_closure); + (*G_OBJECT_CLASS (thunar_window_parent_class)->finalize) (object); } @@ -1154,7 +1344,6 @@ thunar_window_get_property (GObject *object, GParamSpec *pspec) { ThunarWindow *window = THUNAR_WINDOW (object); - GtkAction *action; switch (prop_id) { @@ -1162,17 +1351,6 @@ thunar_window_get_property (GObject *object, g_value_set_object (value, thunar_window_get_current_directory (window)); break; - case PROP_SHOW_HIDDEN: -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - action = gtk_action_group_get_action (window->action_group, "show-hidden"); - g_value_set_boolean (value, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); -G_GNUC_END_IGNORE_DEPRECATIONS - break; - - case PROP_UI_MANAGER: - g_value_set_object (value, window->ui_manager); - break; - case PROP_ZOOM_LEVEL: g_value_set_enum (value, window->zoom_level); break; @@ -1212,75 +1390,61 @@ thunar_window_set_property (GObject *object, static gboolean -thunar_window_back (ThunarWindow *window) +thunar_window_reload (ThunarWindow *window, + gboolean reload_info) { - GtkAction *action; - GdkEvent *event; - const gchar *accel_path; - GtkAccelKey key; - _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); - /* check source event */ - event = gtk_get_current_event (); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (event != NULL - && event->type == GDK_KEY_PRESS) - { - action = thunar_gtk_ui_manager_get_action_by_name (window->ui_manager, "open-parent"); - if (G_LIKELY (action != NULL)) - { - /* check if the current event (back) is different then the open-parent - * accelerator. this way a user can override the default backspace action - * of back in open-parent, without backspace resulting in a back action - * if open-parent is insensitive in the menu */ - accel_path = gtk_action_get_accel_path (action); - if (accel_path != NULL - && gtk_accel_map_lookup_entry (accel_path, &key) - && key.accel_key == ((GdkEventKey *) event)->keyval - && key.accel_mods == 0) - return FALSE; - } - } - - /* activate the "back" action */ - action = thunar_gtk_ui_manager_get_action_by_name (window->ui_manager, "back"); - if (G_LIKELY (action != NULL)) + /* force the view to reload */ + if (G_LIKELY (window->view != NULL)) { - gtk_action_activate (action); + thunar_view_reload (THUNAR_VIEW (window->view), reload_info); return TRUE; } -G_GNUC_END_IGNORE_DEPRECATIONS return FALSE; } -static gboolean -thunar_window_reload (ThunarWindow *window, - gboolean reload_info) +/** + * thunar_window_has_shortcut_sidepane: + * @window : a #ThunarWindow instance. + * + * Return value: True, if this window is running a shortcut sidepane + **/ +gboolean +thunar_window_has_shortcut_sidepane (ThunarWindow *window) { _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); - /* force the view to reload */ - if (G_LIKELY (window->view != NULL)) + /* check if a side pane is currently active */ + if (G_LIKELY (window->sidepane != NULL)) { - thunar_view_reload (THUNAR_VIEW (window->view), reload_info); - return TRUE; + return G_OBJECT_TYPE (window->sidepane) == THUNAR_TYPE_SHORTCUTS_PANE; } - return FALSE; } +/** + * thunar_window_get_sidepane: + * @window : a #ThunarWindow instance. + * + * Return value: (transfer none): The #ThunarSidePane of this window, or NULL if not available + **/ +GtkWidget* thunar_window_get_sidepane (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + return GTK_WIDGET (window->sidepane); +} + + + static gboolean thunar_window_toggle_sidepane (ThunarWindow *window) { - GtkAction *action; - gchar *type_name; - _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); /* check if a side pane is currently active */ @@ -1288,36 +1452,13 @@ thunar_window_toggle_sidepane (ThunarWindow *window) { /* determine the currently active side pane type */ window->toggle_sidepane_type = G_OBJECT_TYPE (window->sidepane); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* just reset both side pane actions */ - action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE); - action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE); -G_GNUC_END_IGNORE_DEPRECATIONS + thunar_window_install_sidepane (window, G_TYPE_NONE); } else { /* check if we have a previously remembered toggle type */ - if (G_UNLIKELY (window->toggle_sidepane_type == G_TYPE_INVALID)) - { - /* guess type based on the last-side-pane preference, default to shortcuts */ - g_object_get (G_OBJECT (window->preferences), "last-side-pane", &type_name, NULL); - if (exo_str_is_equal (type_name, g_type_name (THUNAR_TYPE_TREE_PANE))) - window->toggle_sidepane_type = THUNAR_TYPE_TREE_PANE; - else - window->toggle_sidepane_type = THUNAR_TYPE_SHORTCUTS_PANE; - g_free (type_name); - } - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* activate the given side pane */ - action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (window->toggle_sidepane_type == THUNAR_TYPE_SHORTCUTS_PANE)); - action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (window->toggle_sidepane_type == THUNAR_TYPE_TREE_PANE)); -G_GNUC_END_IGNORE_DEPRECATIONS + if (window->toggle_sidepane_type == THUNAR_TYPE_TREE_PANE || window->toggle_sidepane_type == THUNAR_TYPE_SHORTCUTS_PANE) + thunar_window_install_sidepane (window, window->toggle_sidepane_type); } return TRUE; @@ -1326,42 +1467,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS static gboolean -thunar_window_toggle_menubar (ThunarWindow *window) -{ - _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); - - if (!gtk_widget_get_visible (window->menubar)) - { - /* temporarily show menu bar */ - gtk_widget_show (window->menubar); - return TRUE; - } - - return FALSE; -} - - - -static void -thunar_window_toggle_menubar_deactivate (GtkWidget *menubar, - ThunarWindow *window) -{ - GtkAction *action; - - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - _thunar_return_if_fail (window->menubar == menubar); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* this was a temporarily show, hide the bar */ - action = gtk_action_group_get_action (window->action_group, "view-menubar"); - if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) - gtk_widget_hide (menubar); -G_GNUC_END_IGNORE_DEPRECATIONS -} - - - -static gboolean thunar_window_zoom_in (ThunarWindow *window) { _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); @@ -1428,8 +1533,7 @@ thunar_window_tab_change (ThunarWindow *window, static void -switch_next_tab (GtkAction *action, - ThunarWindow *window) +thunar_window_action_switch_next_tab (ThunarWindow *window) { gint current_page; gint new_page; @@ -1447,8 +1551,7 @@ switch_next_tab (GtkAction *action, static void -switch_previous_tab (GtkAction *action, - ThunarWindow *window) +thunar_window_action_switch_previous_tab (ThunarWindow *window) { gint current_page; gint new_page; @@ -1573,9 +1676,9 @@ thunar_window_notebook_switch_page (GtkWidget *notebook, guint page_num, ThunarWindow *window) { - GtkAction *action; - GSList *view_bindings; - ThunarFile *current_directory; + GSList *view_bindings; + ThunarFile *current_directory; + ThunarHistory *history; _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); _thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook)); @@ -1588,8 +1691,13 @@ thunar_window_notebook_switch_page (GtkWidget *notebook, if (G_LIKELY (window->view != NULL)) { - /* unregisters the actions from the ui */ - thunar_component_set_ui_manager (THUNAR_COMPONENT (window->view), NULL); + /* disconnect from previous history */ + if (window->signal_handler_id_history_changed != 0) + { + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + g_signal_handler_disconnect (history, window->signal_handler_id_history_changed); + window->signal_handler_id_history_changed = 0; + } /* unset view during switch */ window->view = NULL; @@ -1604,18 +1712,8 @@ thunar_window_notebook_switch_page (GtkWidget *notebook, current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (page)); thunar_window_set_current_directory (window, current_directory); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* activate the selected view */ - action = gtk_action_group_get_action (window->action_group, "view-as-icons"); - g_signal_handlers_block_by_func (action, thunar_window_action_view_changed, window); - gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), view_type2index (G_OBJECT_TYPE (page))); -G_GNUC_END_IGNORE_DEPRECATIONS - g_signal_handlers_unblock_by_func (action, thunar_window_action_view_changed, window); - - /* add stock bindings */ thunar_window_binding_create (window, window, "current-directory", page, "current-directory", G_BINDING_DEFAULT); - thunar_window_binding_create (window, window, "show-hidden", page, "show-hidden", G_BINDING_SYNC_CREATE); thunar_window_binding_create (window, page, "loading", window->spinner, "active", G_BINDING_SYNC_CREATE); thunar_window_binding_create (window, page, "selected-files", window->launcher, "selected-files", G_BINDING_SYNC_CREATE); thunar_window_binding_create (window, page, "zoom-level", window, "zoom-level", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); @@ -1638,11 +1736,20 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* activate new view */ window->view = page; + window->view_type = G_TYPE_FROM_INSTANCE (page); - /* integrate the standard view action in the ui */ - thunar_component_set_ui_manager (THUNAR_COMPONENT (page), window->ui_manager); + if (window->view_type != G_TYPE_NONE) + g_object_set (G_OBJECT (window->preferences), "last-view", g_type_name (window->view_type), NULL); - /* update the actions */ + /* connect to the new history */ + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + if (history != NULL) + { + window->signal_handler_id_history_changed = g_signal_connect_swapped (G_OBJECT (history), "history-changed", G_CALLBACK (thunar_window_history_changed), window); + thunar_window_history_changed (window); + } + + /* update the selection */ thunar_standard_view_selection_changed (THUNAR_STANDARD_VIEW (page)); gtk_widget_grab_focus (page); @@ -1655,7 +1762,6 @@ thunar_window_notebook_show_tabs (ThunarWindow *window) { gint n_pages; gboolean show_tabs = TRUE; - GtkAction *action; /* check if tabs should be visible */ n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); @@ -1667,12 +1773,29 @@ thunar_window_notebook_show_tabs (ThunarWindow *window) /* update visibility */ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), show_tabs); +} -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* visibility of the detach action */ - action = gtk_action_group_get_action (window->action_group, "detach-tab"); - gtk_action_set_visible (action, n_pages > 1); -G_GNUC_END_IGNORE_DEPRECATIONS + + +static void +thunar_window_history_changed (ThunarWindow *window) +{ + ThunarHistory *history; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + if (window->view == NULL) + return; + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + if (history == NULL) + return; + + if (window->location_toolbar_item_back != NULL) + gtk_widget_set_sensitive (window->location_toolbar_item_back, thunar_history_has_back (history)); + + if (window->location_toolbar_item_forward != NULL) + gtk_widget_set_sensitive (window->location_toolbar_item_forward, thunar_history_has_forward (history)); } @@ -1690,7 +1813,6 @@ thunar_window_notebook_page_added (GtkWidget *notebook, /* connect signals */ g_signal_connect (G_OBJECT (page), "notify::loading", G_CALLBACK (thunar_window_notify_loading), window); - g_signal_connect (G_OBJECT (page), "notify::selected-files", G_CALLBACK (thunar_window_update_custom_actions), window); g_signal_connect_swapped (G_OBJECT (page), "start-open-location", G_CALLBACK (thunar_window_start_open_location), window); g_signal_connect_swapped (G_OBJECT (page), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); g_signal_connect_swapped (G_OBJECT (page), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window); @@ -1721,9 +1843,6 @@ thunar_window_notebook_page_removed (GtkWidget *notebook, /* drop connected signals */ g_signal_handlers_disconnect_matched (page, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); - /* remove from the ui */ - thunar_component_set_ui_manager (THUNAR_COMPONENT (page), NULL); - n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); if (n_pages == 0) { @@ -1739,20 +1858,6 @@ thunar_window_notebook_page_removed (GtkWidget *notebook, -static void -thunar_window_notebook_popup_menu_real (ThunarWindow *window) -{ - GtkWidget *menu; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* run the menu (figuring out whether to use the file or the folder context menu) */ - menu = gtk_ui_manager_get_widget (window->ui_manager, "/tab-context-menu"); -G_GNUC_END_IGNORE_DEPRECATIONS - thunar_gtk_menu_run (GTK_MENU (menu)); -} - - - static gboolean thunar_window_notebook_button_press_event (GtkWidget *notebook, GdkEventButton *event, @@ -1803,7 +1908,7 @@ thunar_window_notebook_button_press_event (GtkWidget *notebook, gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page_num); /* show the tab menu */ - thunar_window_notebook_popup_menu_real (window); + thunar_window_notebook_popup_menu (notebook, window); } return TRUE; @@ -1818,7 +1923,19 @@ static gboolean thunar_window_notebook_popup_menu (GtkWidget *notebook, ThunarWindow *window) { - thunar_window_notebook_popup_menu_real (window); + GtkWidget *menu; + + menu = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (menu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_NEW_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_DETACH_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SWITCH_PREV_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SWITCH_NEXT_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + gtk_widget_show_all (menu); + thunar_gtk_menu_run (GTK_MENU (menu)); return TRUE; } @@ -1898,17 +2015,18 @@ thunar_window_notebook_insert (ThunarWindow *window, if (directory == NULL) return; - /* save the history of the origin view */ - if (THUNAR_IS_STANDARD_VIEW (window->view)) - history = thunar_standard_view_copy_history (THUNAR_STANDARD_VIEW (window->view)); - /* allocate and setup a new view */ - view = g_object_new (window->view_type, "current-directory", directory, NULL); + view = g_object_new (window->view_type, "current-directory", directory, "accel-group", window->accel_group, NULL); + thunar_view_set_show_hidden (THUNAR_VIEW (view), window->show_hidden); gtk_widget_show (view); - /* use the history of the origin view if available */ - if (history != NULL) - thunar_standard_view_set_history (THUNAR_STANDARD_VIEW (view), history); + /* save the history of the origin view */ + if (THUNAR_IS_STANDARD_VIEW (window->view)) + { + history = thunar_standard_view_copy_history (THUNAR_STANDARD_VIEW (window->view)); + if (history != NULL) + thunar_standard_view_set_history (THUNAR_STANDARD_VIEW (view), history); + } label_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); @@ -2010,10 +2128,10 @@ thunar_window_update_location_bar_visible (ThunarWindow *window) g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); - if (strcmp (last_location_bar, g_type_name (G_TYPE_NONE))) - gtk_widget_show (window->location_toolbar); - else + if (exo_str_is_equal (last_location_bar, g_type_name (G_TYPE_NONE))) gtk_widget_hide (window->location_toolbar); + else + gtk_widget_show (window->location_toolbar); g_free (last_location_bar); } @@ -2075,8 +2193,6 @@ thunar_window_install_sidepane (ThunarWindow *window, /* allocate the new side pane widget */ window->sidepane = g_object_new (type, NULL); gtk_widget_set_size_request (window->sidepane, 0, -1); - thunar_component_set_ui_manager (THUNAR_COMPONENT (window->sidepane), window->ui_manager); - exo_binding_new (G_OBJECT (window), "show-hidden", G_OBJECT (window->sidepane), "show-hidden"); exo_binding_new (G_OBJECT (window), "current-directory", G_OBJECT (window->sidepane), "current-directory"); g_signal_connect_swapped (G_OBJECT (window->sidepane), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); g_signal_connect_swapped (G_OBJECT (window->sidepane), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window); @@ -2098,303 +2214,85 @@ thunar_window_install_sidepane (ThunarWindow *window, static void -thunar_window_merge_custom_preferences (ThunarWindow *window) -{ - GList *providers; - GList *items; - GList *pp; - - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - _thunar_return_if_fail (window->custom_preferences_merge_id == 0); - - /* determine the available preferences providers */ - providers = thunarx_provider_factory_list_providers (window->provider_factory, THUNARX_TYPE_PREFERENCES_PROVIDER); - if (G_LIKELY (providers != NULL)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* allocate a new merge id from the UI manager */ - window->custom_preferences_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* add menu items from all providers */ - for (pp = providers; pp != NULL; pp = pp->next) - { - /* determine the available menu items for the provider */ - items = thunarx_preferences_provider_get_menu_items (THUNARX_PREFERENCES_PROVIDER (pp->data), GTK_WIDGET (window)); - - thunar_menu_util_add_items_to_ui_manager (window->ui_manager, - window->action_group, - window->custom_preferences_merge_id, - "/main-menu/edit-menu/placeholder-custom-preferences", - items); - - /* release the reference on the provider */ - g_object_unref (G_OBJECT (pp->data)); - - /* release the action list */ - g_list_free (items); - } - - /* release the provider list */ - g_list_free (providers); - } -} - - - -static void -thunar_window_bookmark_changed (ThunarWindow *window) +thunar_window_menu_add_bookmarks (ThunarWindow *window, + GtkMenuShell *view_menu) { _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - if (window->bookmark_reload_idle_id == 0) - window->bookmark_reload_idle_id = g_idle_add (thunar_window_bookmark_merge, window); -} - - - -static void -thunar_window_bookmark_release_file (gpointer data) -{ - ThunarFile *file = THUNAR_FILE (data); + /* in order to pass the view_menu into the callback */ + window->view_menu = view_menu; - /* stop watching */ - thunar_file_unwatch (file); - - /* disconnect changed and destroy signals */ - g_signal_handlers_disconnect_matched (file, - G_SIGNAL_MATCH_FUNC, 0, - 0, NULL, - G_CALLBACK (thunar_window_bookmark_changed), - NULL); - - g_object_unref (file); + /* load bookmark menu items from bookmark file */ + thunar_util_load_bookmarks (window->bookmark_file, + thunar_window_bookmark_add_menu_item, + window); + window->view_menu = NULL; } static void -thunar_window_bookmark_merge_line (GFile *file_path, - const gchar *name, - gint line_num, - gpointer user_data) +thunar_window_bookmark_add_menu_item (GFile *g_file, + const gchar *name, + gint line_num, + gpointer user_data) { ThunarWindow *window = THUNAR_WINDOW (user_data); - GtkAction *action = NULL; - GChecksum *checksum; - gchar *uri; - ThunarFile *file; + ThunarFile *thunar_file; gchar *parse_name; + gchar *accel_path; gchar *tooltip; gchar *remote_name = NULL; - const gchar *unique_name; - const gchar *path; GtkIconTheme *icon_theme; const gchar *icon_name; + GtkWidget *menu_item; - _thunar_return_if_fail (G_IS_FILE (file_path)); + _thunar_return_if_fail (G_IS_FILE (g_file)); _thunar_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* create unique id based on the uri */ - uri = g_file_get_uri (file_path); - checksum = g_checksum_new (G_CHECKSUM_MD5); - g_checksum_update (checksum, (const guchar *) uri, strlen (uri)); - unique_name = g_checksum_get_string (checksum); - g_free (uri); - - parse_name = g_file_get_parse_name (file_path); + accel_path = thunar_window_bookmark_get_accel_path (g_file); + parse_name = g_file_get_parse_name (g_file); tooltip = g_strdup_printf (_("Open the location \"%s\""), parse_name); g_free (parse_name); icon_theme = gtk_icon_theme_get_for_screen (gtk_window_get_screen (GTK_WINDOW (window))); - if (g_file_has_uri_scheme (file_path, "file")) + if (g_file_has_uri_scheme (g_file, "file")) { /* try to open the file corresponding to the uri */ - file = thunar_file_get (file_path, NULL); - if (G_UNLIKELY (file == NULL)) - return; - - /* make sure the file refers to a directory */ - if (G_UNLIKELY (thunar_file_is_directory (file))) + thunar_file = thunar_file_get (g_file, NULL); + if (G_LIKELY (thunar_file != NULL)) { - if (name == NULL) - name = thunar_file_get_display_name (file); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - action = gtk_action_new (unique_name, name, tooltip, NULL); - icon_name = thunar_file_get_icon_name (file, THUNAR_FILE_ICON_STATE_DEFAULT, icon_theme); - gtk_action_set_icon_name (action, icon_name); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_set_data_full (G_OBJECT (action), I_("thunar-file"), file, - thunar_window_bookmark_release_file); - - /* watch the file */ - thunar_file_watch (file); - - g_signal_connect_swapped (G_OBJECT (file), "destroy", - G_CALLBACK (thunar_window_bookmark_changed), window); - g_signal_connect_swapped (G_OBJECT (file), "changed", - G_CALLBACK (thunar_window_bookmark_changed), window); - } - else - { - g_object_unref (file); - } + /* make sure the file refers to a directory */ + if (G_UNLIKELY (thunar_file_is_directory (thunar_file))) + { + if (name == NULL) + name = thunar_file_get_display_name (thunar_file); - /* add to the local bookmarks */ - path = "/main-menu/go-menu/placeholder-go-local-actions"; + icon_name = thunar_file_get_icon_name (thunar_file, THUNAR_FILE_ICON_STATE_DEFAULT, icon_theme); + menu_item = xfce_gtk_image_menu_item_new_from_icon_name (name, tooltip, accel_path, NULL, NULL, icon_name, window->view_menu); + g_signal_connect_swapped (G_OBJECT (menu_item), "activate", G_CALLBACK (thunar_window_action_open_bookmark), G_OBJECT (window)); + g_object_set_data_full (G_OBJECT (menu_item), I_("g-file"), g_object_ref(g_file), g_object_unref); + } + g_object_unref (thunar_file); + } } else { if (name == NULL) { - remote_name = thunar_g_file_get_display_name_remote (file_path); + remote_name = thunar_g_file_get_display_name_remote (g_file); name = remote_name; } - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - action = gtk_action_new (unique_name, name, tooltip, NULL); - gtk_action_set_icon_name (action, "folder-remote"); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_set_data_full (G_OBJECT (action), I_("location-file"), - g_object_ref (file_path), g_object_unref); - + menu_item = xfce_gtk_image_menu_item_new_from_icon_name (name, tooltip, accel_path, NULL, NULL, "folder-remote", window->view_menu); + g_signal_connect_swapped (G_OBJECT (menu_item), "activate", G_CALLBACK (thunar_window_action_open_bookmark), G_OBJECT (window)); + g_object_set_data_full (G_OBJECT (menu_item), I_("g-file"), g_object_ref (g_file), g_object_unref); g_free (remote_name); - - /* add to the remote bookmarks */ - path = "/main-menu/go-menu/placeholder-go-remote-actions"; } -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - if (G_LIKELY (action != NULL)) - { - if (gtk_action_group_get_action (window->bookmark_action_group, unique_name) == NULL) - { - /* connect action */ - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_window_action_open_bookmark), window); - - /* insert the bookmark in the group */ - gtk_action_group_add_action_with_accel (window->bookmark_action_group, action, NULL); - - /* add the action to the UI manager */ - gtk_ui_manager_add_ui (window->ui_manager, - window->bookmark_items_actions_merge_id, - path, - unique_name, unique_name, - GTK_UI_MANAGER_MENUITEM, FALSE); - } - - g_object_unref (action); - } -G_GNUC_END_IGNORE_DEPRECATIONS - - g_checksum_free (checksum); g_free (tooltip); -} - - - -static gboolean -thunar_window_bookmark_merge (gpointer user_data) -{ - ThunarWindow *window = THUNAR_WINDOW (user_data); - - _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); - -THUNAR_THREADS_ENTER - - /* remove old actions */ - if (window->bookmark_items_actions_merge_id != 0) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_ui (window->ui_manager, window->bookmark_items_actions_merge_id); - gtk_ui_manager_ensure_update (window->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS - } - - /* drop old bookmarks action group */ - if (window->bookmark_action_group != NULL) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - gtk_ui_manager_remove_action_group (window->ui_manager, window->bookmark_action_group); -G_GNUC_END_IGNORE_DEPRECATIONS - g_object_unref (window->bookmark_action_group); - } - - /* lazy initialize the bookmarks */ - if (window->bookmark_file == NULL) - { - window->bookmark_file = thunar_g_file_new_for_bookmarks (); - window->bookmark_monitor = g_file_monitor_file (window->bookmark_file, G_FILE_MONITOR_NONE, NULL, NULL); - if (G_LIKELY (window->bookmark_monitor != NULL)) - { - g_signal_connect_swapped (window->bookmark_monitor, "changed", - G_CALLBACK (thunar_window_bookmark_changed), window); - } - } - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* generate a new merge id */ - window->bookmark_items_actions_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager); - - /* create a new action group */ - window->bookmark_action_group = gtk_action_group_new ("ThunarBookmarks"); - gtk_ui_manager_insert_action_group (window->ui_manager, window->bookmark_action_group, -1); -G_GNUC_END_IGNORE_DEPRECATIONS - - /* collect bookmarks */ - thunar_util_load_bookmarks (window->bookmark_file, - thunar_window_bookmark_merge_line, - window); - - window->bookmark_reload_idle_id = 0; - -THUNAR_THREADS_LEAVE - - return FALSE; -} - - - -static void -thunar_window_merge_go_actions (ThunarWindow *window) -{ - GtkAction *action; - - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - _thunar_return_if_fail (window->go_items_actions_merge_id == 0); - - /* setup the "open-trash" action */ - if (thunar_g_vfs_is_uri_scheme_supported ("trash")) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* allocate a new merge id from the UI manager */ - window->go_items_actions_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager); - - /* add the trash action to the action group */ - action = thunar_trash_action_new (); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_window_action_open_trash), window); - gtk_action_group_add_action_with_accel (window->action_group, action, NULL); - - /* add the action to the UI manager */ - gtk_ui_manager_add_ui (window->ui_manager, - window->go_items_actions_merge_id, - "/main-menu/go-menu/placeholder-go-items-actions", - gtk_action_get_name (GTK_ACTION (action)), - gtk_action_get_name (GTK_ACTION (action)), - GTK_UI_MANAGER_MENUITEM, FALSE); -G_GNUC_END_IGNORE_DEPRECATIONS - - g_object_unref (action); - } - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* setup visibility of the "open-network" action */ - action = gtk_action_group_get_action (window->action_group, "open-network"); - gtk_action_set_visible (action, thunar_g_vfs_is_uri_scheme_supported ("network")); -G_GNUC_END_IGNORE_DEPRECATIONS + g_free (accel_path); } @@ -2465,8 +2363,8 @@ thunar_window_start_open_location (ThunarWindow *window, static void -thunar_window_action_open_new_tab (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_new_tab (ThunarWindow *window, + GtkWidget *menu_item) { /* insert new tab with current directory as default */ thunar_window_notebook_insert (window, thunar_window_get_current_directory (window)); @@ -2475,8 +2373,8 @@ thunar_window_action_open_new_tab (GtkAction *action, static void -thunar_window_action_open_new_window (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_new_window (ThunarWindow *window, + GtkWidget *menu_item) { ThunarApplication *application; ThunarHistory *history; @@ -2496,7 +2394,13 @@ thunar_window_action_open_new_window (GtkAction *action, /* let the view of the new window inherit the history of the origin view */ history = thunar_standard_view_copy_history (THUNAR_STANDARD_VIEW (window->view)); if (history != NULL) - thunar_standard_view_set_history (THUNAR_STANDARD_VIEW (new_window->view), history); + { + thunar_standard_view_set_history (THUNAR_STANDARD_VIEW (new_window->view), history); + thunar_window_history_changed (new_window); + + /* connect to the new history */ + window->signal_handler_id_history_changed = g_signal_connect_swapped (G_OBJECT (history), "history-changed", G_CALLBACK (thunar_window_history_changed), new_window); + } /* determine the first visible file in the current window */ if (thunar_view_get_visible_range (THUNAR_VIEW (window->view), &start_file, NULL)) @@ -2512,22 +2416,8 @@ thunar_window_action_open_new_window (GtkAction *action, static void -thunar_window_action_empty_trash (GtkAction *action, - ThunarWindow *window) -{ - ThunarApplication *application; - - /* launch the operation */ - application = thunar_application_get (); - thunar_application_empty_trash (application, GTK_WIDGET (window), NULL); - g_object_unref (G_OBJECT (application)); -} - - - -static void -thunar_window_action_detach_tab (GtkAction *action, - ThunarWindow *window) +thunar_window_action_detach_tab (ThunarWindow *window, + GtkWidget *menu_item) { GtkWidget *notebook; GtkWidget *label; @@ -2568,8 +2458,8 @@ thunar_window_action_detach_tab (GtkAction *action, static void -thunar_window_action_close_all_windows (GtkAction *action, - ThunarWindow *window) +thunar_window_action_close_all_windows (ThunarWindow *window, + GtkWidget *menu_item) { ThunarApplication *application; GList *windows; @@ -2586,8 +2476,8 @@ thunar_window_action_close_all_windows (GtkAction *action, static void -thunar_window_action_close_tab (GtkAction *action, - ThunarWindow *window) +thunar_window_action_close_tab (ThunarWindow *window, + GtkWidget *menu_item) { if (window->view != NULL) gtk_widget_destroy (window->view); @@ -2596,8 +2486,8 @@ thunar_window_action_close_tab (GtkAction *action, static void -thunar_window_action_close_window (GtkAction *action, - ThunarWindow *window) +thunar_window_action_close_window (ThunarWindow *window, + GtkWidget *menu_item) { gtk_widget_destroy (GTK_WIDGET (window)); } @@ -2605,15 +2495,12 @@ thunar_window_action_close_window (GtkAction *action, static void -thunar_window_action_preferences (GtkAction *action, - ThunarWindow *window) +thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item) { GtkWidget *dialog; ThunarApplication *application; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* allocate and display a preferences dialog */; @@ -2629,14 +2516,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_window_action_reload (GtkAction *action, - ThunarWindow *window) +thunar_window_action_reload (ThunarWindow *window, + GtkWidget *menu_item) { gboolean result; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* force the view to reload */ @@ -2650,255 +2534,168 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_window_action_pathbar_changed (GtkToggleAction *action, - ThunarWindow *window) +thunar_window_action_pathbar_changed (ThunarWindow *window) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - GtkAction *other_action; - GType type; + gchar *last_location_bar; + gboolean pathbar_checked; - _thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* determine the new type of location bar */ - type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_LOCATION_BUTTONS : G_TYPE_NONE; - - /* update the preferences */ - g_object_set (window->preferences, "last-location-bar", g_type_name (type), NULL); + g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); + pathbar_checked = exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_ENTRY)); + g_free (last_location_bar); - /* check if we actually installed anything */ - if (G_LIKELY (type != G_TYPE_NONE)) - { - /* reset the state of the toolbar action (without firing the handler) */ - other_action = gtk_action_group_get_action (window->action_group, "view-location-selector-toolbar"); - g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_toolbar_changed, window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE); - g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_toolbar_changed, window); - } -G_GNUC_END_IGNORE_DEPRECATIONS + if (pathbar_checked) + g_object_set (window->preferences, "last-location-bar", g_type_name (G_TYPE_NONE), NULL); + else + g_object_set (window->preferences, "last-location-bar", g_type_name (THUNAR_TYPE_LOCATION_ENTRY), NULL); } static void -thunar_window_action_toolbar_changed (GtkToggleAction *action, - ThunarWindow *window) +thunar_window_action_toolbar_changed (ThunarWindow *window) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - GtkAction *other_action; - GType type; + gchar *last_location_bar; + gboolean toolbar_checked; - _thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* determine the new type of location bar */ - type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_LOCATION_ENTRY : G_TYPE_NONE; - - /* update the preferences */ - g_object_set (window->preferences, "last-location-bar", g_type_name (type), NULL); + g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); + toolbar_checked = exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_BUTTONS)); + g_free (last_location_bar); - /* check if we actually installed anything */ - if (G_LIKELY (type != G_TYPE_NONE)) - { - /* reset the state of the pathbar action (without firing the handler) */ - other_action = gtk_action_group_get_action (window->action_group, "view-location-selector-pathbar"); - g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_pathbar_changed, window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE); - g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_pathbar_changed, window); - } -G_GNUC_END_IGNORE_DEPRECATIONS + if (toolbar_checked) + g_object_set (window->preferences, "last-location-bar", g_type_name (G_TYPE_NONE), NULL); + else + g_object_set (window->preferences, "last-location-bar", g_type_name (THUNAR_TYPE_LOCATION_BUTTONS), NULL); } static void -thunar_window_action_shortcuts_changed (GtkToggleAction *action, - ThunarWindow *window) +thunar_window_action_shortcuts_changed (ThunarWindow *window) { - GtkAction *other_action; - GType type; + gchar *last_side_pane; + gboolean shortcuts_checked; + GType type = G_TYPE_NONE; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* determine the new type of side pane */ - type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_SHORTCUTS_PANE : G_TYPE_NONE; -G_GNUC_END_IGNORE_DEPRECATIONS + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* install the new sidepane */ - thunar_window_install_sidepane (window, type); + g_object_get (window->preferences, "last-side-pane", &last_side_pane, NULL); + shortcuts_checked = exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_SHORTCUTS_PANE)); + g_free (last_side_pane); - /* check if we actually installed anything */ - if (G_LIKELY (type != G_TYPE_NONE)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* reset the state of the tree pane action (without firing the handler) */ - other_action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree"); - g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_tree_changed, window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE); - g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_tree_changed, window); -G_GNUC_END_IGNORE_DEPRECATIONS - } + if (shortcuts_checked) + type = G_TYPE_NONE; + else + type = THUNAR_TYPE_SHORTCUTS_PANE; + + thunar_window_install_sidepane (window, type); } static void -thunar_window_action_tree_changed (GtkToggleAction *action, - ThunarWindow *window) +thunar_window_action_tree_changed (ThunarWindow *window) { - GtkAction *other_action; - GType type; + gchar *last_side_pane; + gboolean tree_view_checked; + GType type = G_TYPE_NONE; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* determine the new type of side pane */ - type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_TREE_PANE : G_TYPE_NONE; -G_GNUC_END_IGNORE_DEPRECATIONS + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* install the new sidepane */ - thunar_window_install_sidepane (window, type); + g_object_get (window->preferences, "last-side-pane", &last_side_pane, NULL); + tree_view_checked = exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_TREE_PANE)); + g_free (last_side_pane); - /* check if we actually installed anything */ - if (G_LIKELY (type != G_TYPE_NONE)) - { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* reset the state of the shortcuts pane action (without firing the handler) */ - other_action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts"); - g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_shortcuts_changed, window); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE); - g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_shortcuts_changed, window); -G_GNUC_END_IGNORE_DEPRECATIONS - } + if (tree_view_checked) + type = G_TYPE_NONE; + else + type = THUNAR_TYPE_TREE_PANE; + + thunar_window_install_sidepane (window, type); } static void -thunar_window_action_statusbar_changed (GtkToggleAction *action, - ThunarWindow *window) +thunar_window_action_statusbar_changed (ThunarWindow *window) { - gboolean active; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + gboolean last_statusbar_visible; - /* determine the new state of the action */ - active = gtk_toggle_action_get_active (action); -G_GNUC_END_IGNORE_DEPRECATIONS + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* check if we should drop the statusbar */ - if (!active && window->statusbar != NULL) - { - /* just get rid of the statusbar */ - gtk_widget_destroy (window->statusbar); - window->statusbar = NULL; - } - else if (active && window->statusbar == NULL) - { - /* setup a new statusbar */ - window->statusbar = thunar_statusbar_new (); - gtk_widget_set_hexpand (window->statusbar, TRUE); - gtk_grid_attach (GTK_GRID (window->view_box), window->statusbar, 0, 2, 1, 1); - gtk_widget_show (window->statusbar); + g_object_get (window->preferences, "last-statusbar-visible", &last_statusbar_visible, NULL); - /* connect to the view (if any) */ - if (G_LIKELY (window->view != NULL)) - thunar_window_binding_create (window, window->view, "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); - } + gtk_widget_set_visible (window->statusbar, !last_statusbar_visible); - /* remember the setting */ - if (gtk_widget_get_visible (GTK_WIDGET (window))) - g_object_set (G_OBJECT (window->preferences), "last-statusbar-visible", active, NULL); + g_object_set (G_OBJECT (window->preferences), "last-statusbar-visible", !last_statusbar_visible, NULL); } static void -thunar_window_action_menubar_changed (GtkToggleAction *action, - ThunarWindow *window) +thunar_window_action_menubar_changed (ThunarWindow *window) { - gboolean active; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); + gboolean last_menubar_visible; + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* determine the new state of the action */ - active = gtk_toggle_action_get_active (action); -G_GNUC_END_IGNORE_DEPRECATIONS + g_object_get (window->preferences, "last-menubar-visible", &last_menubar_visible, NULL); - /* show or hide the bar */ - gtk_widget_set_visible (window->menubar, active); + gtk_widget_set_visible (window->menubar, !last_menubar_visible); - /* remember the setting */ - if (gtk_widget_get_visible (GTK_WIDGET (window))) - g_object_set (G_OBJECT (window->preferences), "last-menubar-visible", active, NULL); + g_object_set (G_OBJECT (window->preferences), "last-menubar-visible", !last_menubar_visible, NULL); } static void -thunar_window_action_zoom_in (GtkAction *action, - ThunarWindow *window) +thunar_window_action_detailed_view (ThunarWindow *window) { - gboolean result; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - - /* increase the zoom level */ - g_signal_emit (G_OBJECT (window), window_signals[ZOOM_IN], 0, &result); + thunar_window_action_view_changed (window, THUNAR_TYPE_DETAILS_VIEW); } static void -thunar_window_action_zoom_out (GtkAction *action, - ThunarWindow *window) +thunar_window_action_icon_view (ThunarWindow *window) { - gboolean result; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - - /* decrease the zoom level */ - g_signal_emit (G_OBJECT (window), window_signals[ZOOM_OUT], 0, &result); + thunar_window_action_view_changed (window, THUNAR_TYPE_ICON_VIEW); } static void -thunar_window_action_zoom_reset (GtkAction *action, - ThunarWindow *window) +thunar_window_action_compact_view (ThunarWindow *window) { - gboolean result; - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - - /* reset zoom level */ - g_signal_emit (G_OBJECT (window), window_signals[ZOOM_RESET], 0, &result); + thunar_window_action_view_changed (window, THUNAR_TYPE_COMPACT_VIEW); } static void -thunar_window_action_view_changed (GtkRadioAction *action, - GtkRadioAction *current, - ThunarWindow *window) +thunar_window_action_view_changed (ThunarWindow *window, + GType view_type) { ThunarFile *file = NULL; ThunarFile *current_directory = NULL; GtkWidget *old_view; + ThunarHistory *history; GList *selected_files = NULL; /* drop the previous view (if any) */ old_view = window->view; if (G_LIKELY (window->view != NULL)) { + if (window->signal_handler_id_history_changed != 0) + { + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + g_signal_handler_disconnect (history, window->signal_handler_id_history_changed); + window->signal_handler_id_history_changed = 0; + } + /* get first visible file in the previous view */ if (!thunar_view_get_visible_range (THUNAR_VIEW (window->view), &file, NULL)) file = NULL; @@ -2910,17 +2707,8 @@ thunar_window_action_view_changed (GtkRadioAction *action, /* remember the file selection */ selected_files = thunar_g_file_list_copy (thunar_component_get_selected_files (THUNAR_COMPONENT (old_view))); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the UI (else GtkUIManager will crash on merging) */ - gtk_ui_manager_ensure_update (window->ui_manager); -G_GNUC_END_IGNORE_DEPRECATIONS } - - /* determine the new type of view */ -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - window->view_type = view_index2type (gtk_radio_action_get_current_value (action)); -G_GNUC_END_IGNORE_DEPRECATIONS + window->view_type = view_type; /* always open a new directory */ if (current_directory == NULL && window->current_directory != NULL) @@ -2952,7 +2740,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS thunar_g_file_list_free (selected_files); /* remember the setting */ - if (gtk_widget_get_visible (GTK_WIDGET (window))) + if (gtk_widget_get_visible (GTK_WIDGET (window)) && window->view_type != G_TYPE_NONE) g_object_set (G_OBJECT (window->preferences), "last-view", g_type_name (window->view_type), NULL); /* release the file references */ @@ -2960,13 +2748,15 @@ G_GNUC_END_IGNORE_DEPRECATIONS g_object_unref (G_OBJECT (file)); if (G_UNLIKELY (current_directory != NULL)) g_object_unref (G_OBJECT (current_directory)); + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + window->signal_handler_id_history_changed = g_signal_connect_swapped (G_OBJECT (history), "history-changed", G_CALLBACK (thunar_window_history_changed), window); } static void -thunar_window_action_go_up (GtkAction *action, - ThunarWindow *window) +thunar_window_action_go_up (ThunarWindow *window) { ThunarFile *parent; GError *error = NULL; @@ -2987,8 +2777,33 @@ thunar_window_action_go_up (GtkAction *action, static void -thunar_window_action_open_home (GtkAction *action, - ThunarWindow *window) +thunar_window_action_back (ThunarWindow *window) +{ + ThunarHistory *history; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + thunar_history_action_back (history); +} + + + +static void +thunar_window_action_forward (ThunarWindow *window) +{ + ThunarHistory *history; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + thunar_history_action_forward (history); +} + + + +static void +thunar_window_action_open_home (ThunarWindow *window) { GFile *home; ThunarFile *home_file; @@ -3021,8 +2836,7 @@ thunar_window_action_open_home (GtkAction *action, static gboolean -thunar_window_open_user_folder (GtkAction *action, - ThunarWindow *window, +thunar_window_open_user_folder (ThunarWindow *window, GUserDirectory thunar_user_dir, const gchar *default_name) { @@ -3115,24 +2929,17 @@ thunar_window_open_user_folder (GtkAction *action, static void -thunar_window_action_open_desktop (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_desktop (ThunarWindow *window) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - thunar_window_open_user_folder (action, window, - G_USER_DIRECTORY_DESKTOP, - "Desktop"); + thunar_window_open_user_folder (window, G_USER_DIRECTORY_DESKTOP, "Desktop"); } static void -thunar_window_action_open_computer (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_computer (ThunarWindow *window) { GFile *computer; ThunarFile *computer_file; @@ -3165,8 +2972,7 @@ thunar_window_action_open_computer (GtkAction *action, static void -thunar_window_action_open_templates (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_templates (ThunarWindow *window) { GtkWidget *dialog; GtkWidget *button; @@ -3177,14 +2983,9 @@ thunar_window_action_open_templates (GtkAction *action, gboolean show_about_templates; gboolean success; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - success = thunar_window_open_user_folder (action,window, - G_USER_DIRECTORY_TEMPLATES, - "Templates"); + success = thunar_window_open_user_folder (window, G_USER_DIRECTORY_TEMPLATES, "Templates"); /* check whether we should display the "About Templates" dialog */ g_object_get (G_OBJECT (window->preferences), @@ -3250,8 +3051,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_window_action_open_file_system (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_file_system (ThunarWindow *window) { GFile *root; ThunarFile *root_file; @@ -3284,16 +3084,12 @@ thunar_window_action_open_file_system (GtkAction *action, static void -thunar_window_action_open_trash (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_trash (ThunarWindow *window) { GFile *trash_bin; ThunarFile *trash_bin_file; GError *error = NULL; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* determine the path to the trash bin */ @@ -3321,16 +3117,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_window_action_open_network (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_network (ThunarWindow *window) { ThunarFile *network_file; GError *error = NULL; GFile *network; -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_ACTION (action)); -G_GNUC_END_IGNORE_DEPRECATIONS _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* determine the network root location */ @@ -3357,31 +3149,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS -static gboolean -thunar_window_propagate_key_event (GtkWindow* window, - GdkEvent *key_event, - gpointer user_data) -{ - GtkWidget* focused_widget; - - _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), GDK_EVENT_PROPAGATE); - - focused_widget = gtk_window_get_focus (window); - - /* Turn the accelerator priority around globally, - * so that the focused widget always gets the accels first. - * Implementing this cleanly while maintaining some wanted accels - * (like Ctrl+N and exo accels) is a lot of work. So we resort to - * only priorize GtkEditable, because that is the easiest way to - * fix the right-ahead problem. */ - if (focused_widget != NULL && GTK_IS_EDITABLE (focused_widget)) - return gtk_window_propagate_key_event (window, (GdkEventKey *) key_event); - - return GDK_EVENT_PROPAGATE; -} - - - static void thunar_window_poke_location_finish (ThunarBrowser *browser, GFile *location, @@ -3399,34 +3166,19 @@ thunar_window_poke_location_finish (ThunarBrowser *browser, static void -thunar_window_action_open_bookmark (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_bookmark (ThunarWindow *window, + GtkWidget *menu_item) { - ThunarFile *local_file; - GFile *remote_file; + GFile *bookmark_location; - /* try to open the local file */ - local_file = g_object_get_data (G_OBJECT (action), I_("thunar-file")); - if (local_file != NULL) - { - thunar_window_set_current_directory (window, local_file); - return; - } - - /* try to the remote file */ - remote_file = g_object_get_data (G_OBJECT (action), I_("location-file")); - if (remote_file != NULL) - { - thunar_browser_poke_location (THUNAR_BROWSER (window), remote_file, window, - thunar_window_poke_location_finish, NULL); - } + bookmark_location = g_object_get_data (G_OBJECT (menu_item), I_("g-file")); + thunar_window_set_current_directory_gfile (THUNAR_WINDOW (window), bookmark_location); } static void -thunar_window_action_open_location (GtkAction *action, - ThunarWindow *window) +thunar_window_action_open_location (ThunarWindow *window) { /* just use the "start-open-location" callback */ thunar_window_start_open_location (window, NULL); @@ -3435,8 +3187,7 @@ thunar_window_action_open_location (GtkAction *action, static void -thunar_window_action_contents (GtkAction *action, - ThunarWindow *window) +thunar_window_action_contents (ThunarWindow *window) { /* display the documentation index */ xfce_dialog_show_help (GTK_WINDOW (window), "thunar", NULL, NULL); @@ -3445,8 +3196,7 @@ thunar_window_action_contents (GtkAction *action, static void -thunar_window_action_about (GtkAction *action, - ThunarWindow *window) +thunar_window_action_about (ThunarWindow *window) { /* just popup the about dialog */ thunar_dialogs_show_about (GTK_WINDOW (window), PACKAGE_NAME, @@ -3457,22 +3207,31 @@ thunar_window_action_about (GtkAction *action, static void -thunar_window_action_show_hidden (GtkToggleAction *action, - ThunarWindow *window) +thunar_window_action_show_hidden (ThunarWindow *window) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - _thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - /* just emit the "notify" signal for the "show-hidden" - * signal and the view will automatically sync its state. - */ - g_object_notify (G_OBJECT (window), "show-hidden"); + window->show_hidden = !window->show_hidden; + gtk_container_foreach (GTK_CONTAINER (window->notebook), (GtkCallback) (void (*)(void)) thunar_view_set_show_hidden, GINT_TO_POINTER (window->show_hidden)); + thunar_side_pane_set_show_hidden (THUNAR_SIDE_PANE (window->sidepane), window->show_hidden); - if (gtk_widget_get_visible (GTK_WIDGET (window))) - g_object_set (G_OBJECT (window->preferences), "last-show-hidden", - gtk_toggle_action_get_active (action), NULL); -G_GNUC_END_IGNORE_DEPRECATIONS + g_object_set (G_OBJECT (window->preferences), "last-show-hidden", window->show_hidden, NULL); + +} + + + +static void +thunar_window_action_open_file_menu (ThunarWindow *window) +{ + GtkWidget *file_menu; + gboolean ret; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + file_menu = gtk_container_get_children (GTK_CONTAINER (window->menubar))->data; + g_signal_emit_by_name (file_menu, "button-press-event", NULL, &ret); + gtk_menu_shell_select_first (GTK_MENU_SHELL (window->menubar), TRUE); } @@ -3481,22 +3240,15 @@ static void thunar_window_current_directory_changed (ThunarFile *current_directory, ThunarWindow *window) { - GtkAction *action; gboolean show_full_path; gchar *parse_name = NULL; const gchar *name; + gboolean ret; _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); _thunar_return_if_fail (THUNAR_IS_FILE (current_directory)); _thunar_return_if_fail (window->current_directory == current_directory); -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* update the "Empty Trash" action */ - action = gtk_action_group_get_action (window->action_group, "empty-trash"); - gtk_action_set_sensitive (action, (thunar_file_get_item_count (current_directory) > 0)); - gtk_action_set_visible (action, (thunar_file_is_root (current_directory) && thunar_file_is_trashed (current_directory))); -G_GNUC_END_IGNORE_DEPRECATIONS - /* get name of directory or full path */ g_object_get (G_OBJECT (window->preferences), "misc-full-path-in-title", &show_full_path, NULL); if (G_UNLIKELY (show_full_path)) @@ -3510,78 +3262,34 @@ G_GNUC_END_IGNORE_DEPRECATIONS /* set window icon */ thunar_window_update_window_icon (window); -} - - -static void -thunar_window_connect_proxy (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy, - ThunarWindow *window) -{ - /* we want to get informed when the user hovers a menu item */ - if (GTK_IS_MENU_ITEM (proxy)) - { - g_signal_connect_closure (G_OBJECT (proxy), "select", window->menu_item_selected_closure, FALSE); - g_signal_connect_closure (G_OBJECT (proxy), "deselect", window->menu_item_deselected_closure, FALSE); - } + /* update the window menu. E.g. relevant for functional shortcuts after startup, + * and for keyboard navigation in the window menu */ + for (GList *lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) + g_signal_emit_by_name (lp->data, "button-press-event", NULL, &ret); } static void -thunar_window_disconnect_proxy (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy, - ThunarWindow *window) +thunar_window_menu_item_selected (ThunarWindow *window, + GtkWidget *menu_item) { - /* undo what we did in connect_proxy() */ - if (GTK_IS_MENU_ITEM (proxy)) - { - g_signal_handlers_disconnect_matched (G_OBJECT (proxy), G_SIGNAL_MATCH_CLOSURE, 0, 0, window->menu_item_selected_closure, NULL, NULL); - g_signal_handlers_disconnect_matched (G_OBJECT (proxy), G_SIGNAL_MATCH_CLOSURE, 0, 0, window->menu_item_deselected_closure, NULL, NULL); - } -} - + gchar *tooltip; + gint id; - -static void -thunar_window_menu_item_selected (GtkWidget *menu_item, - ThunarWindow *window) -{ - GtkAction *action; - const gchar *tooltip; - gint id; - gchar *short_tip = NULL; - gchar *p; + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); /* we can only display tooltips if we have a statusbar */ if (G_LIKELY (window->statusbar != NULL)) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* determine the action for the menu item */ - action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (menu_item)); - if (G_UNLIKELY (action == NULL)) - return; - - /* determine the tooltip from the action */ - tooltip = gtk_action_get_tooltip (action); -G_GNUC_END_IGNORE_DEPRECATIONS + tooltip = gtk_widget_get_tooltip_text (menu_item); if (G_LIKELY (tooltip != NULL)) { - /* check if there is a new line in the tooltip */ - p = strchr (tooltip, '\n'); - if (p != NULL) - { - short_tip = g_strndup (tooltip, p - tooltip); - tooltip = short_tip; - } - /* push to the statusbar */ id = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->statusbar), "Menu tooltip"); gtk_statusbar_push (GTK_STATUSBAR (window->statusbar), id, tooltip); - g_free (short_tip); + g_free (tooltip); } } } @@ -3589,11 +3297,13 @@ G_GNUC_END_IGNORE_DEPRECATIONS static void -thunar_window_menu_item_deselected (GtkWidget *menu_item, - ThunarWindow *window) +thunar_window_menu_item_deselected (ThunarWindow *window, + GtkWidget *menu_item) { gint id; + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + /* we can only undisplay tooltips if we have a statusbar */ if (G_LIKELY (window->statusbar != NULL)) { @@ -3606,111 +3316,6 @@ thunar_window_menu_item_deselected (GtkWidget *menu_item, static void -thunar_window_update_custom_actions (ThunarView *view, - GParamSpec *pspec, - ThunarWindow *window) -{ - ThunarFile *folder; - GList *selected_files; - GList *items = NULL; - GList *lp; - GList *providers; - GList *tmp; - - _thunar_return_if_fail (THUNAR_IS_VIEW (view)); - _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); - - /* leave if the signal is emitted from a non-active tab */ - if (!gtk_widget_get_realized (GTK_WIDGET (window)) - || window->view != GTK_WIDGET (view)) - return; - - /* grab a reference to the current directory of the window */ - folder = thunar_window_get_current_directory (window); - - /* leave if current directory is invalid */ - if (folder != NULL && - !thunarx_file_info_is_directory (THUNARX_FILE_INFO (folder))) - return; - - /* load the menu provides from the provider factory */ - providers = thunarx_provider_factory_list_providers (window->provider_factory, - THUNARX_TYPE_MENU_PROVIDER); - if (G_LIKELY (providers != NULL)) - { - /* get a list of selected files */ - selected_files = thunar_component_get_selected_files (THUNAR_COMPONENT (view)); - - /* load the actions offered by the menu providers */ - for (lp = providers; lp != NULL; lp = lp->next) - { - if (G_LIKELY (selected_files != NULL)) - { - tmp = thunarx_menu_provider_get_file_menu_items (lp->data, - GTK_WIDGET (window), - selected_files); - } - else if (G_LIKELY (folder != NULL)) - { - tmp = thunarx_menu_provider_get_folder_menu_items (lp->data, - GTK_WIDGET (window), - THUNARX_FILE_INFO (folder)); - } - else - { - tmp = NULL; - } - - items = g_list_concat (items, tmp); - g_object_unref (G_OBJECT (lp->data)); - } - g_list_free (providers); - } - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* remove previously inserted menu actions from the UI manager */ - if (window->custom_merge_id != 0) - { - gtk_ui_manager_remove_ui (window->ui_manager, window->custom_merge_id); - gtk_ui_manager_ensure_update (window->ui_manager); - window->custom_merge_id = 0; - } - - /* drop any previous custom action group */ - if (window->custom_actions != NULL) - { - gtk_ui_manager_remove_action_group (window->ui_manager, window->custom_actions); - g_object_unref (window->custom_actions); - window->custom_actions = NULL; - } - - /* add the actions specified by the menu providers */ - if (G_LIKELY (items != NULL)) - { - /* allocate the action group and the merge id for the custom actions */ - window->custom_actions = gtk_action_group_new ("ThunarActions"); - window->custom_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager); - - /* insert the new action group and make sure the UI manager gets updated */ - gtk_ui_manager_insert_action_group (window->ui_manager, window->custom_actions, 0); - gtk_ui_manager_ensure_update (window->ui_manager); - - /* add the menu items to the UI manager */ - thunar_menu_util_add_items_to_ui_manager (window->ui_manager, - window->custom_actions, - window->custom_merge_id, - "/main-menu/file-menu/placeholder-custom-actions", - items); - - /* cleanup */ - g_list_free (items); - } -G_GNUC_END_IGNORE_DEPRECATIONS -} - - - -static void thunar_window_notify_loading (ThunarView *view, GParamSpec *pspec, ThunarWindow *window) @@ -3745,8 +3350,6 @@ thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor, GFile *root_file, ThunarWindow *window) { - GtkAction *action; - _thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (device_monitor)); _thunar_return_if_fail (window->device_monitor == device_monitor); _thunar_return_if_fail (THUNAR_IS_DEVICE (device)); @@ -3761,12 +3364,8 @@ thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor, if (g_file_equal (thunar_file_get_file (window->current_directory), root_file) || thunar_file_is_gfile_ancestor (window->current_directory, root_file)) { -G_GNUC_BEGIN_IGNORE_DEPRECATIONS /* change to the home folder */ - action = gtk_action_group_get_action (window->action_group, "open-home"); - if (G_LIKELY (action != NULL)) - gtk_action_activate (action); -G_GNUC_END_IGNORE_DEPRECATIONS + thunar_window_action_open_home (window); } } @@ -3798,32 +3397,6 @@ thunar_window_device_changed (ThunarDeviceMonitor *device_monitor, static gboolean -thunar_window_merge_idle (gpointer user_data) -{ - ThunarWindow *window = THUNAR_WINDOW (user_data); - - /* merge custom preferences from the providers */ -THUNAR_THREADS_ENTER - thunar_window_merge_custom_preferences (window); - thunar_window_merge_go_actions (window); -THUNAR_THREADS_LEAVE - - thunar_window_bookmark_merge (window); - - return FALSE; -} - - - -static void -thunar_window_merge_idle_destroy (gpointer user_data) -{ - THUNAR_WINDOW (user_data)->merge_idle_id = 0; -} - - - -static gboolean thunar_window_save_paned (ThunarWindow *window) { _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); @@ -3914,10 +3487,6 @@ thunar_window_set_zoom_level (ThunarWindow *window, /* notify listeners */ g_object_notify (G_OBJECT (window), "zoom-level"); } - - /* update the "Zoom In" and "Zoom Out" actions */ - thunar_gtk_action_group_set_action_sensitive (window->action_group, "zoom-in", (zoom_level < THUNAR_ZOOM_N_LEVELS - 1)); - thunar_gtk_action_group_set_action_sensitive (window->action_group, "zoom-out", (zoom_level > 0)); } @@ -3950,9 +3519,8 @@ void thunar_window_set_current_directory (ThunarWindow *window, ThunarFile *current_directory) { - GType type; - GtkAction *action; - gchar *type_name; + GType type; + gchar *type_name; _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); _thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory)); @@ -3985,39 +3553,35 @@ thunar_window_set_current_directory (ThunarWindow *window, /* determine the default view */ g_object_get (G_OBJECT (window->preferences), "default-view", &type_name, NULL); type = g_type_from_name (type_name); + g_free (type_name); /* determine the last selected view if the last selected view preference is not selected */ - if (g_type_is_a (type, G_TYPE_NONE)) + if (g_type_is_a (type, G_TYPE_NONE) || g_type_is_a (type, G_TYPE_INVALID)) { g_object_get (G_OBJECT (window->preferences), "last-view", &type_name, NULL); type = g_type_from_name (type_name); + g_free (type_name); } -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* activate the selected view */ - action = gtk_action_group_get_action (window->action_group, "view-as-icons"); - g_signal_handlers_block_by_func (action, thunar_window_action_view_changed, window); - gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), view_type2index (g_type_is_a (type, THUNAR_TYPE_VIEW) ? type : THUNAR_TYPE_ICON_VIEW)); - thunar_window_action_view_changed (GTK_RADIO_ACTION (action), GTK_RADIO_ACTION (action), window); -G_GNUC_END_IGNORE_DEPRECATIONS - g_signal_handlers_unblock_by_func (action, thunar_window_action_view_changed, window); + /* fallback, in case nothing was set */ + if (g_type_is_a (type, G_TYPE_NONE) || g_type_is_a (type, G_TYPE_INVALID)) + type = THUNAR_TYPE_ICON_VIEW; + + thunar_window_action_view_changed (window, type); } /* update window icon and title */ thunar_window_current_directory_changed (current_directory, window); - /* grab the focus to the main view */ if (G_LIKELY (window->view != NULL)) - gtk_widget_grab_focus (window->view); - } - - /* enable the 'Open new window' action if we have a valid directory */ - thunar_gtk_action_group_set_action_sensitive (window->action_group, "new-window", (current_directory != NULL)); - thunar_gtk_action_group_set_action_sensitive (window->action_group, "new-tab", (current_directory != NULL)); + { + /* grab the focus to the main view */ + gtk_widget_grab_focus (window->view); + } - /* enable the 'Up' action if possible for the new directory */ - thunar_gtk_action_group_set_action_sensitive (window->action_group, "open-parent", (current_directory != NULL - && thunar_file_has_parent (current_directory))); + thunar_window_history_changed (window); + gtk_widget_set_sensitive (window->location_toolbar_item_parent, !thunar_g_file_is_root (thunar_file_get_file (current_directory))); + } /* tell everybody that we have a new "current-directory", * we do this first so other widgets display the new @@ -4028,6 +3592,28 @@ G_GNUC_END_IGNORE_DEPRECATIONS +static void +thunar_window_set_current_directory_gfile (ThunarWindow *window, + GFile *current_directory) +{ + ThunarFile *thunar_file; + + /* remote files possibly need to be poked first */ + if (g_file_has_uri_scheme (current_directory, "file")) + { + thunar_file = thunar_file_get (current_directory, NULL); + thunar_window_set_current_directory (THUNAR_WINDOW (window), thunar_file); + g_object_unref (thunar_file); + } + else + { + thunar_browser_poke_location (THUNAR_BROWSER (window), current_directory, THUNAR_WINDOW (window), + thunar_window_poke_location_finish, NULL); + } +} + + + /** * thunar_window_scroll_to_file: * @window : a #ThunarWindow instance. @@ -4139,3 +3725,137 @@ thunar_window_set_directories (ThunarWindow *window, /* we succeeded if new pages have been opened */ return gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) > 0; } + + + +/** + * thunar_window_get_action_entry: + * @window : Instance of a #ThunarWindow + * @action : #ThunarWindowAction for which the #XfceGtkActionEntry is requested + * + * returns a reference to the requested #XfceGtkActionEntry + * + * Return value: (transfer none): The reference to the #XfceGtkActionEntry + **/ +const XfceGtkActionEntry* +thunar_window_get_action_entry (ThunarWindow *window, + ThunarWindowAction action) +{ + return get_action_entry (action); +} + + + +/** + * thunar_window_append_menu_item: + * @window : Instance of a #ThunarWindow + * @menu : #GtkMenuShell to which the item should be added + * @action : #ThunarWindowAction to select which item should be added + * + * Adds the selected, widget specific #GtkMenuItem to the passed #GtkMenuShell + * + * Return value: (transfer none): The added #GtkMenuItem + **/ +void +thunar_window_append_menu_item (ThunarWindow *window, + GtkMenuShell *menu, + ThunarWindowAction action) +{ + GtkWidget *item; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (action), G_OBJECT (window), menu); + + if (action == THUNAR_WINDOW_ACTION_ZOOM_IN) + gtk_widget_set_sensitive (item, G_LIKELY (window->zoom_level < THUNAR_ZOOM_N_LEVELS - 1)); + if (action == THUNAR_WINDOW_ACTION_ZOOM_OUT) + gtk_widget_set_sensitive (item, G_LIKELY (window->zoom_level > 0)); +} + + + +/** + * thunar_window_get_launcher: + * @window : a #ThunarWindow instance. + * + * Return value: (transfer none): The single #ThunarLauncher of this #ThunarWindow + **/ +ThunarLauncher* +thunar_window_get_launcher (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL); + + return window->launcher; +} + + + +static void +thunar_window_redirect_menu_tooltips_to_statusbar_recursive (GtkWidget *menu_item, + ThunarWindow *window) +{ + GtkWidget *submenu; + + if (GTK_IS_MENU_ITEM (menu_item)) + { + submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item)); + if (submenu != NULL) + gtk_container_foreach (GTK_CONTAINER (submenu), (GtkCallback) (void (*)(void)) thunar_window_redirect_menu_tooltips_to_statusbar_recursive, window); + + /* this disables to show the tooltip on hover */ + gtk_widget_set_has_tooltip (menu_item, FALSE); + + /* These method will put the tooltip on the statusbar */ + g_signal_connect_swapped (G_OBJECT (menu_item), "select", G_CALLBACK (thunar_window_menu_item_selected), window); + g_signal_connect_swapped (G_OBJECT (menu_item), "deselect", G_CALLBACK (thunar_window_menu_item_deselected), window); + } +} + + + +/** + * thunar_window_redirect_menu_tooltips_to_statusbar: + * @window : a #ThunarWindow instance. + * @menu : #GtkMenu for which all tooltips should be shown in the statusbar + * + * All tooltips of the provided #GtkMenu and any submenu will not be shown directly any more. + * Instead they will be shown in the status bar of the passed #ThunarWindow + **/ +void +thunar_window_redirect_menu_tooltips_to_statusbar (ThunarWindow *window, GtkMenu *menu) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (GTK_IS_MENU (menu)); + + gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) (void (*)(void)) thunar_window_redirect_menu_tooltips_to_statusbar_recursive, window); +} + + + +static gboolean +thunar_window_history_clicked (GtkWidget *button, + GdkEventButton *event, + GtkWidget *data) +{ + ThunarHistory *history; + ThunarWindow *window; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (data), FALSE); + + window = THUNAR_WINDOW (data); + + if (event->button == 3) + { + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + + if (button == window->location_toolbar_item_back) + thunar_history_show_menu (history, THUNAR_HISTORY_MENU_BACK, button); + else if (button == window->location_toolbar_item_forward) + thunar_history_show_menu (history, THUNAR_HISTORY_MENU_FORWARD, button); + else + g_warning ("This button is not able to spawn a history menu"); + } + + return FALSE; +} diff --git a/thunar/thunar-window.c.orig b/thunar/thunar-window.c.orig new file mode 100644 index 00000000..bc2f0c82 --- /dev/null +++ b/thunar/thunar-window.c.orig @@ -0,0 +1,3987 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org> + * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_LOCALE_H +#include <locale.h> +#endif + +#include <gdk/gdkkeysyms.h> + +#include <thunar/thunar-application.h> +#include <thunar/thunar-browser.h> +#include <thunar/thunar-clipboard-manager.h> +#include <thunar/thunar-compact-view.h> +#include <thunar/thunar-details-view.h> +#include <thunar/thunar-dialogs.h> +#include <thunar/thunar-shortcuts-pane.h> +#include <thunar/thunar-gio-extensions.h> +#include <thunar/thunar-gobject-extensions.h> +#include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-history.h> +#include <thunar/thunar-icon-view.h> +#include <thunar/thunar-launcher.h> +#include <thunar/thunar-location-buttons.h> +#include <thunar/thunar-location-entry.h> +#include <thunar/thunar-marshal.h> +#include <thunar/thunar-menu.h> +#include <thunar/thunar-pango-extensions.h> +#include <thunar/thunar-preferences-dialog.h> +#include <thunar/thunar-preferences.h> +#include <thunar/thunar-private.h> +#include <thunar/thunar-util.h> +#include <thunar/thunar-statusbar.h> +#include <thunar/thunar-tree-pane.h> +#include <thunar/thunar-window.h> +#include <thunar/thunar-device-monitor.h> + +#include <glib.h> + + + +/* Property identifiers */ +enum +{ + PROP_0, + PROP_CURRENT_DIRECTORY, + PROP_ZOOM_LEVEL, +}; + +/* Signal identifiers */ +enum +{ + BACK, + RELOAD, + TOGGLE_SIDEPANE, + TOGGLE_MENUBAR, + ZOOM_IN, + ZOOM_OUT, + ZOOM_RESET, + TAB_CHANGE, + LAST_SIGNAL, +}; + + + +static void thunar_window_dispose (GObject *object); +static void thunar_window_finalize (GObject *object); +static gboolean thunar_window_delete (GtkWidget *widget, + GdkEvent *event, + gpointer data); +static void thunar_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gboolean thunar_window_reload (ThunarWindow *window, + gboolean reload_info); +static gboolean thunar_window_toggle_sidepane (ThunarWindow *window); +static gboolean thunar_window_zoom_in (ThunarWindow *window); +static gboolean thunar_window_zoom_out (ThunarWindow *window); +static gboolean thunar_window_zoom_reset (ThunarWindow *window); +static gboolean thunar_window_tab_change (ThunarWindow *window, + gint nth); +static void thunar_window_realize (GtkWidget *widget); +static void thunar_window_unrealize (GtkWidget *widget); +static gboolean thunar_window_configure_event (GtkWidget *widget, + GdkEventConfigure *event); +static void thunar_window_notebook_switch_page (GtkWidget *notebook, + GtkWidget *page, + guint page_num, + ThunarWindow *window); +static void thunar_window_notebook_page_added (GtkWidget *notebook, + GtkWidget *page, + guint page_num, + ThunarWindow *window); +static void thunar_window_notebook_page_removed (GtkWidget *notebook, + GtkWidget *page, + guint page_num, + ThunarWindow *window); +static gboolean thunar_window_notebook_button_press_event(GtkWidget *notebook, + GdkEventButton *event, + ThunarWindow *window); +static gboolean thunar_window_notebook_popup_menu (GtkWidget *notebook, + ThunarWindow *window); +static gpointer thunar_window_notebook_create_window (GtkWidget *notebook, + GtkWidget *page, + gint x, + gint y, + ThunarWindow *window); +static void thunar_window_bookmark_add_menu_item (GFile *g_file, + const gchar *name, + gint line_num, + gpointer user_data); +static void thunar_window_update_location_bar_visible(ThunarWindow *window); +static void thunar_window_handle_reload_request (ThunarWindow *window); +static void thunar_window_install_sidepane (ThunarWindow *window, + GType type); +static void thunar_window_start_open_location (ThunarWindow *window, + const gchar *initial_text); +static void thunar_window_action_open_new_tab (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_open_new_window (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_detach_tab (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_close_all_windows (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_close_tab (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_close_window (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_reload (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_switch_next_tab (ThunarWindow *window); +static void thunar_window_action_switch_previous_tab (ThunarWindow *window); +static void thunar_window_action_pathbar_changed (ThunarWindow *window); +static void thunar_window_action_toolbar_changed (ThunarWindow *window); +static void thunar_window_action_shortcuts_changed (ThunarWindow *window); +static void thunar_window_action_tree_changed (ThunarWindow *window); +static void thunar_window_action_statusbar_changed (ThunarWindow *window); +static void thunar_window_action_menubar_changed (ThunarWindow *window); +static void thunar_window_action_detailed_view (ThunarWindow *window); +static void thunar_window_action_icon_view (ThunarWindow *window); +static void thunar_window_action_compact_view (ThunarWindow *window); +static void thunar_window_action_view_changed (ThunarWindow *window, + GType view_type); +static void thunar_window_action_go_up (ThunarWindow *window); +static void thunar_window_action_back (ThunarWindow *window); +static void thunar_window_action_forward (ThunarWindow *window); +static void thunar_window_action_open_home (ThunarWindow *window); +static void thunar_window_action_open_desktop (ThunarWindow *window); +static void thunar_window_action_open_computer (ThunarWindow *window); +static void thunar_window_action_open_templates (ThunarWindow *window); +static void thunar_window_action_open_file_system (ThunarWindow *window); +static void thunar_window_action_open_trash (ThunarWindow *window); +static void thunar_window_action_open_network (ThunarWindow *window); +static void thunar_window_action_open_bookmark (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_action_open_location (ThunarWindow *window); +static void thunar_window_action_contents (ThunarWindow *window); +static void thunar_window_action_about (ThunarWindow *window); +static void thunar_window_action_show_hidden (ThunarWindow *window); +static void thunar_window_action_open_file_menu (ThunarWindow *window); +static void thunar_window_current_directory_changed (ThunarFile *current_directory, + ThunarWindow *window); +<<<<<<< Upstream, based on origin/master +static void thunar_window_action_open_new_window (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_empty_trash (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_detach_tab (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_close_all_windows (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_close_tab (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_close_window (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_preferences (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_reload (GtkAction *action, + ThunarWindow *window); +static void switch_next_tab (GtkAction *action, + ThunarWindow *window); +static void switch_previous_tab (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_pathbar_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_toolbar_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_shortcuts_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_tree_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_statusbar_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_menubar_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_zoom_in (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_zoom_out (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_zoom_reset (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_view_changed (GtkRadioAction *action, + GtkRadioAction *current, + ThunarWindow *window); +static void thunar_window_action_go_up (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_home (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_desktop (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_computer (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_templates (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_file_system (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_trash (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_network (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_bookmark (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_location (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_contents (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_about (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_show_hidden (GtkToggleAction *action, + ThunarWindow *window); +static gboolean thunar_window_propagate_key_event (GtkWindow *window, + GdkEvent *key_event, + gpointer user_data); +static void thunar_window_current_directory_changed (ThunarFile *current_directory, + ThunarWindow *window); +static void thunar_window_connect_proxy (GtkUIManager *manager, + GtkAction *action, + GtkWidget *proxy, + ThunarWindow *window); +static void thunar_window_disconnect_proxy (GtkUIManager *manager, + GtkAction *action, + GtkWidget *proxy, + ThunarWindow *window); +static void thunar_window_menu_item_selected (GtkWidget *menu_item, + ThunarWindow *window); +static void thunar_window_menu_item_deselected (GtkWidget *menu_item, + ThunarWindow *window); +static void thunar_window_update_custom_actions (ThunarView *view, +======= +static void thunar_window_menu_item_selected (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_menu_item_deselected (ThunarWindow *window, + GtkWidget *menu_item); +static void thunar_window_notify_loading (ThunarView *view, +>>>>>>> d01bcd1 giant commit + GParamSpec *pspec, + ThunarWindow *window); +static void thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor, + ThunarDevice *device, + GFile *root_file, + ThunarWindow *window); +static void thunar_window_device_changed (ThunarDeviceMonitor *device_monitor, + ThunarDevice *device, + ThunarWindow *window); +static gboolean thunar_window_save_paned (ThunarWindow *window); +static gboolean thunar_window_save_geometry_timer (gpointer user_data); +static void thunar_window_save_geometry_timer_destroy(gpointer user_data); +static void thunar_window_set_zoom_level (ThunarWindow *window, + ThunarZoomLevel zoom_level); +static void thunar_window_update_window_icon (ThunarWindow *window); +static gboolean thunar_window_create_file_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_edit_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_view_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_go_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_create_help_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static void thunar_window_select_files (ThunarWindow *window, + GList *path_list); +static void thunar_window_binding_create (ThunarWindow *window, + gpointer src_object, + const gchar *src_prop, + gpointer dst_object, + const gchar *dst_prop, + GBindingFlags flags); +static gboolean thunar_window_history_clicked (GtkWidget *button, + GdkEventButton *event, + GtkWidget *window); +static void thunar_window_history_changed (ThunarWindow *window); +static void thunar_window_menu_add_bookmarks (ThunarWindow *window, + GtkMenuShell *view_menu); +static gboolean thunar_window_menu_item_hovered (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu); +static gboolean thunar_window_check_uca_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data); +static gboolean thunar_window_check_bookmark_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data); +static void thunar_window_set_current_directory_gfile (ThunarWindow *window, + GFile *current_directory); + + + +struct _ThunarWindowClass +{ + GtkWindowClass __parent__; + + /* internal action signals */ + gboolean (*reload) (ThunarWindow *window, + gboolean reload_info); + gboolean (*zoom_in) (ThunarWindow *window); + gboolean (*zoom_out) (ThunarWindow *window); + gboolean (*zoom_reset) (ThunarWindow *window); + gboolean (*tab_change) (ThunarWindow *window, + gint idx); +}; + +struct _ThunarWindow +{ + GtkWindow __parent__; + + /* support for custom preferences actions */ + ThunarxProviderFactory *provider_factory; + GList *thunarx_preferences_providers; + + GFile *bookmark_file; + GFileMonitor *bookmark_monitor; + GtkMenuShell *view_menu; + GdkEventKey *latest_key_event; + + ThunarClipboardManager *clipboard; + + ThunarPreferences *preferences; + + ThunarIconFactory *icon_factory; + + /* to be able to change folder on "device-pre-unmount" if required */ + ThunarDeviceMonitor *device_monitor; + + GtkWidget *grid; + GtkWidget *menubar; + GtkWidget *spinner; + GtkWidget *paned; + GtkWidget *sidepane; + GtkWidget *view_box; + GtkWidget *notebook; + GtkWidget *view; + GtkWidget *statusbar; + + GType view_type; + GSList *view_bindings; + + /* support for two different styles of location bars */ + GtkWidget *location_bar; + GtkWidget *location_toolbar; + + /* we need to maintain pointers to be able to toggle sensitivity */ + GtkWidget *location_toolbar_item_back; + GtkWidget *location_toolbar_item_forward; + GtkWidget *location_toolbar_item_parent; + + ThunarLauncher *launcher; + + gulong signal_handler_id_history_changed; + + ThunarFile *current_directory; + GtkAccelGroup *accel_group; + + /* zoom-level support */ + ThunarZoomLevel zoom_level; + + gboolean show_hidden; + + /* support to remember window geometry */ + guint save_geometry_timer_id; + + /* support to toggle side pane using F9, + * see the toggle_sidepane() function. + */ + GType toggle_sidepane_type; + + /* Takes care to select a file after e.g. rename/create */ + GClosure *select_files_closure; +}; + + + +static XfceGtkActionEntry thunar_window_action_entries[] = +{ + { THUNAR_WINDOW_ACTION_FILE_MENU, "<Actions>/ThunarWindow/file-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_File"), NULL, NULL, NULL,}, + { THUNAR_WINDOW_ACTION_NEW_TAB, "<Actions>/ThunarWindow/new-tab", "<Primary>t", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("New _Tab"), N_ ("Open a new tab for the displayed location"), "tab-new", G_CALLBACK (thunar_window_action_open_new_tab), }, + { THUNAR_WINDOW_ACTION_NEW_WINDOW, "<Actions>/ThunarWindow/new-window", "<Primary>n", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("New _Window"), N_ ("Open a new Thunar window for the displayed location"), "window-new", G_CALLBACK (thunar_window_action_open_new_window), }, + { THUNAR_WINDOW_ACTION_DETACH_TAB, "<Actions>/ThunarWindow/detach-tab", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Detac_h Tab"), N_ ("Open current folder in a new window"), NULL, G_CALLBACK (thunar_window_action_detach_tab), }, + { THUNAR_WINDOW_ACTION_CLOSE_TAB, "<Actions>/ThunarWindow/close-tab", "<Primary>w", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("C_lose Tab"), N_ ("Close this folder"), "window-close", G_CALLBACK (thunar_window_action_close_tab), }, + { THUNAR_WINDOW_ACTION_CLOSE_WINDOW, "<Actions>/ThunarWindow/close-window", "<Primary>q", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Close Window"), N_ ("Close this window"), "application-exit", G_CALLBACK (thunar_window_action_close_window), }, + { THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS, "<Actions>/ThunarWindow/close-all-windows", "<Primary><Shift>w", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Close _All Windows"), N_ ("Close all Thunar windows"), NULL, G_CALLBACK (thunar_window_action_close_all_windows), }, + + { THUNAR_WINDOW_ACTION_EDIT_MENU, "<Actions>/ThunarWindow/edit-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Edit"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_PREFERENCES, "<Actions>/ThunarWindow/preferences", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Pr_eferences..."), N_ ("Edit Thunars Preferences"), "preferences-system", G_CALLBACK (thunar_window_action_preferences), }, + + { THUNAR_WINDOW_ACTION_VIEW_MENU, "<Actions>/ThunarWindow/view-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_View"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_RELOAD, "<Actions>/ThunarWindow/reload", "<Primary>r", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Reload"), N_ ("Reload the current folder"), "view-refresh-symbolic", G_CALLBACK (thunar_window_action_reload), }, + { THUNAR_WINDOW_ACTION_RELOAD_ALT, "<Actions>/ThunarWindow/reload-alt", "F5", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_window_action_reload), }, + { THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_MENU, "<Actions>/ThunarWindow/view-location-selector-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Location Selector"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_PATHBAR, "<Actions>/ThunarWindow/view-location-selector-pathbar", "", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Pathbar Style"), N_ ("Modern approach with buttons that correspond to folders"), NULL, G_CALLBACK (thunar_window_action_pathbar_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_TOOLBAR, "<Actions>/ThunarWindow/view-location-selector-toolbar", "", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Toolbar Style"), N_ ("Traditional approach with location bar and navigation buttons"), NULL, G_CALLBACK (thunar_window_action_toolbar_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_MENU, "<Actions>/ThunarWindow/view-side-pane-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Side Pane"), NULL, NULL, NULL, }, + { THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_SHORTCUTS, "<Actions>/ThunarWindow/view-side-pane-shortcuts", "<Primary>b", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Shortcuts"), N_ ("Toggles the visibility of the shortcuts pane"), NULL, G_CALLBACK (thunar_window_action_shortcuts_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_TREE, "<Actions>/ThunarWindow/view-side-pane-tree", "<Primary>e", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Tree"), N_ ("Toggles the visibility of the tree pane"), NULL, G_CALLBACK (thunar_window_action_tree_changed), }, + { THUNAR_WINDOW_ACTION_TOGGLE_SIDE_PANE, "<Actions>/ThunarWindow/toggle-side-pane", "F9", XFCE_GTK_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_window_toggle_sidepane), }, + { THUNAR_WINDOW_ACTION_VIEW_STATUSBAR, "<Actions>/ThunarWindow/view-statusbar", "", XFCE_GTK_CHECK_MENU_ITEM, N_ ("St_atusbar"), N_ ("Change the visibility of this window's statusbar"), NULL, G_CALLBACK (thunar_window_action_statusbar_changed), }, + { THUNAR_WINDOW_ACTION_VIEW_MENUBAR, "<Actions>/ThunarWindow/view-menubar", "<Primary>m", XFCE_GTK_CHECK_MENU_ITEM, N_ ("_Menubar"), N_ ("Change the visibility of this window's menubar"), NULL, G_CALLBACK (thunar_window_action_menubar_changed), }, + { THUNAR_WINDOW_ACTION_SHOW_HIDDEN, "<Actions>/ThunarWindow/show-hidden", "<Primary>h", XFCE_GTK_CHECK_MENU_ITEM, N_ ("Show _Hidden Files"), N_ ("Toggles the display of hidden files in the current window"), NULL, G_CALLBACK (thunar_window_action_show_hidden), }, + { THUNAR_WINDOW_ACTION_ZOOM_IN, "<Actions>/ThunarWindow/zoom-in", "<Primary>KP_Add", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Zoom I_n"), N_ ("Show the contents in more detail"), "zoom-in-symbolic", G_CALLBACK (thunar_window_zoom_in), }, + { THUNAR_WINDOW_ACTION_ZOOM_OUT, "<Actions>/ThunarWindow/zoom-out", "<Primary>KP_Subtract", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Zoom _Out"), N_ ("Show the contents in less detail"), "zoom-out-symbolic", G_CALLBACK (thunar_window_zoom_out), }, + { THUNAR_WINDOW_ACTION_ZOOM_RESET, "<Actions>/ThunarWindow/zoom-reset", "<Primary>KP_0", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Normal Si_ze"), N_ ("Show the contents at the normal size"), "zoom-original-symbolic", G_CALLBACK (thunar_window_zoom_reset), }, + { THUNAR_WINDOW_ACTION_VIEW_AS_ICONS, "<Actions>/ThunarWindow/view-as-icons", "<Primary>1", XFCE_GTK_RADIO_MENU_ITEM, N_ ("View as _Icons"), N_("Display folder content in an icon view"), NULL, G_CALLBACK (thunar_window_action_icon_view), }, + { THUNAR_WINDOW_ACTION_VIEW_AS_DETAILED_LIST, "<Actions>/ThunarWindow/view-as-detailed-list", "<Primary>2", XFCE_GTK_RADIO_MENU_ITEM, N_ ("View as _Detailed List"), N_("Display folder content in a detailed list view"), NULL, G_CALLBACK (thunar_window_action_detailed_view), }, + { THUNAR_WINDOW_ACTION_VIEW_AS_COMPACT_LIST, "<Actions>/ThunarWindow/view-as-compact-list", "<Primary>3", XFCE_GTK_RADIO_MENU_ITEM, N_ ("View as _Compact List"), N_("Display folder content in a compact list view"), NULL, G_CALLBACK (thunar_window_action_compact_view), }, + + { THUNAR_WINDOW_ACTION_GO_MENU, "<Actions>/ThunarWindow/go-menu", "", XFCE_GTK_MENU_ITEM, N_ ("_Go"), NULL, NULL, NULL }, + { THUNAR_WINDOW_ACTION_OPEN_FILE_SYSTEM, "<Actions>/ThunarWindow/open-file-system", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("File System"), N_ ("Browse the file system"), "drive-harddisk", G_CALLBACK (thunar_window_action_open_file_system), }, + { THUNAR_WINDOW_ACTION_OPEN_COMPUTER, "<Actions>/ThunarWindow/open-computer", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Computer"), N_ ("Go to the computer folder"), "computer", G_CALLBACK (thunar_window_action_open_computer), }, + { THUNAR_WINDOW_ACTION_OPEN_HOME, "<Actions>/ThunarWindow/open-home", "<Alt>Home", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Home"), N_ ("Go to the home folder"), "go-home-symbolic", G_CALLBACK (thunar_window_action_open_home), }, + { THUNAR_WINDOW_ACTION_OPEN_DESKTOP, "<Actions>/ThunarWindow/open-desktop", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Desktop"), N_ ("Go to the desktop folder"), "user-desktop", G_CALLBACK (thunar_window_action_open_desktop), }, + { THUNAR_WINDOW_ACTION_OPEN_COMPUTER, "<Actions>/ThunarWindow/open-computer", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Computer"), N_ ("Browse all local and remote disks and folders accessible from this computer"), "computer", G_CALLBACK (thunar_window_action_open_computer), }, + { THUNAR_WINDOW_ACTION_OPEN_TRASH, "<Actions>/ThunarWindow/open-trash", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("T_rash"), N_ ("Display the contents of the trash can"), NULL, G_CALLBACK (thunar_window_action_open_trash), }, + { THUNAR_WINDOW_ACTION_OPEN_PARENT, "<Actions>/ThunarWindow/open-parent", "<Alt>Up", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Open _Parent"), N_ ("Open the parent folder"), "go-up-symbolic", G_CALLBACK (thunar_window_action_go_up), }, + { THUNAR_WINDOW_ACTION_OPEN_LOCATION, "<Actions>/ThunarWindow/open-location", "<Primary>l", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Open Location..."), N_ ("Specify a location to open"), NULL, G_CALLBACK (thunar_window_action_open_location), }, + { THUNAR_WINDOW_ACTION_OPEN_LOCATION_ALT, "<Actions>/ThunarWindow/open-location-alt", "<Alt>d", XFCE_GTK_MENU_ITEM, "open-location-alt", NULL, NULL, G_CALLBACK (thunar_window_action_open_location), }, + { THUNAR_WINDOW_ACTION_OPEN_TEMPLATES, "<Actions>/ThunarWindow/open-templates", "", XFCE_GTK_IMAGE_MENU_ITEM, N_("T_emplates"), N_ ("Go to the templates folder"), "text-x-generic-template", G_CALLBACK (thunar_window_action_open_templates), }, + { THUNAR_WINDOW_ACTION_OPEN_NETWORK, "<Actions>/ThunarWindow/open-network", "", XFCE_GTK_IMAGE_MENU_ITEM, N_("B_rowse Network"), N_ ("Browse local network connections"), "network-workgroup", G_CALLBACK (thunar_window_action_open_network), }, + + { THUNAR_WINDOW_ACTION_HELP_MENU, "<Actions>/ThunarWindow/contents/help-menu", "", XFCE_GTK_MENU_ITEM , N_ ("_Help"), NULL, NULL, NULL}, + { THUNAR_WINDOW_ACTION_CONTENTS, "<Actions>/ThunarWindow/contents", "F1", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Contents"), N_ ("Display Thunar user manual"), "help-browser", G_CALLBACK (thunar_window_action_contents), }, + { THUNAR_WINDOW_ACTION_ABOUT, "<Actions>/ThunarWindow/about", "", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_About"), N_ ("Display information about Thunar"), "help-about", G_CALLBACK (thunar_window_action_about), }, + { THUNAR_WINDOW_ACTION_BACK, "<Actions>/ThunarStandardView/back", "<Alt>Left", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Back"), N_ ("Go to the previous visited folder"), "go-previous-symbolic", G_CALLBACK (thunar_window_action_back), }, + { THUNAR_WINDOW_ACTION_BACK_ALT, "<Actions>/ThunarStandardView/back-alt", "BackSpace", XFCE_GTK_IMAGE_MENU_ITEM, NULL, NULL, NULL, G_CALLBACK (thunar_window_action_back), }, + { THUNAR_WINDOW_ACTION_FORWARD, "<Actions>/ThunarStandardView/forward", "<Alt>Right", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("Forward"), N_ ("Go to the next visited folder"), "go-next-symbolic", G_CALLBACK (thunar_window_action_forward), }, + { THUNAR_WINDOW_ACTION_SWITCH_PREV_TAB, "<Actions>/ThunarWindow/switch-previous-tab", "<Primary>Page_Up", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Previous Tab"), N_ ("Switch to Previous Tab"), "go-previous", G_CALLBACK (thunar_window_action_switch_previous_tab), }, + { THUNAR_WINDOW_ACTION_SWITCH_NEXT_TAB, "<Actions>/ThunarWindow/switch-next-tab", "<Primary>Page_Down", XFCE_GTK_IMAGE_MENU_ITEM, N_ ("_Next Tab"), N_ ("Switch to Next Tab"), "go-next", G_CALLBACK (thunar_window_action_switch_next_tab), }, + { 0, "<Actions>/ThunarWindow/open-file-menu", "F10", 0, NULL, NULL, NULL, G_CALLBACK (thunar_window_action_open_file_menu), }, +}; + +#define get_action_entry(id) xfce_gtk_get_action_entry_by_id(thunar_window_action_entries,G_N_ELEMENTS(thunar_window_action_entries),id) + + + +static guint window_signals[LAST_SIGNAL]; + + + +G_DEFINE_TYPE_WITH_CODE (ThunarWindow, thunar_window, GTK_TYPE_WINDOW, + G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL)) + + + +static void +thunar_window_class_init (ThunarWindowClass *klass) +{ + GtkWidgetClass *gtkwidget_class; + GtkBindingSet *binding_set; + GObjectClass *gobject_class; + guint i; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->dispose = thunar_window_dispose; + gobject_class->finalize = thunar_window_finalize; + gobject_class->get_property = thunar_window_get_property; + gobject_class->set_property = thunar_window_set_property; + + gtkwidget_class = GTK_WIDGET_CLASS (klass); + gtkwidget_class->realize = thunar_window_realize; + gtkwidget_class->unrealize = thunar_window_unrealize; + gtkwidget_class->configure_event = thunar_window_configure_event; + + klass->reload = thunar_window_reload; + klass->zoom_in = thunar_window_zoom_in; + klass->zoom_out = thunar_window_zoom_out; + klass->zoom_reset = thunar_window_zoom_reset; + klass->tab_change = thunar_window_tab_change; + + xfce_gtk_translate_action_entries (thunar_window_action_entries, G_N_ELEMENTS (thunar_window_action_entries)); + + /** + * ThunarWindow:current-directory: + * + * The directory currently displayed within this #ThunarWindow + * or %NULL. + **/ + g_object_class_install_property (gobject_class, + PROP_CURRENT_DIRECTORY, + g_param_spec_object ("current-directory", + "current-directory", + "current-directory", + THUNAR_TYPE_FILE, + EXO_PARAM_READWRITE)); + + /** + * ThunarWindow:zoom-level: + * + * The #ThunarZoomLevel applied to the #ThunarView currently + * shown within this window. + **/ + g_object_class_install_property (gobject_class, + PROP_ZOOM_LEVEL, + g_param_spec_enum ("zoom-level", + "zoom-level", + "zoom-level", + THUNAR_TYPE_ZOOM_LEVEL, + THUNAR_ZOOM_LEVEL_100_PERCENT, + EXO_PARAM_READWRITE)); + + /** + * ThunarWindow::reload: + * @window : a #ThunarWindow instance. + * + * Emitted whenever the user requests to reload the contents + * of the currently displayed folder. + **/ + window_signals[RELOAD] = + g_signal_new (I_("reload"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ThunarWindowClass, reload), + g_signal_accumulator_true_handled, NULL, + _thunar_marshal_BOOLEAN__BOOLEAN, + G_TYPE_BOOLEAN, 1, + G_TYPE_BOOLEAN); + + /** + * ThunarWindow::zoom-in: + * @window : a #ThunarWindow instance. + * + * Emitted whenever the user requests to zoom in. This + * is an internal signal used to bind the action to keys. + **/ + window_signals[ZOOM_IN] = + g_signal_new (I_("zoom-in"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ThunarWindowClass, zoom_in), + g_signal_accumulator_true_handled, NULL, + _thunar_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); + + /** + * ThunarWindow::zoom-out: + * @window : a #ThunarWindow instance. + * + * Emitted whenever the user requests to zoom out. This + * is an internal signal used to bind the action to keys. + **/ + window_signals[ZOOM_OUT] = + g_signal_new (I_("zoom-out"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ThunarWindowClass, zoom_out), + g_signal_accumulator_true_handled, NULL, + _thunar_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); + + /** + * ThunarWindow::zoom-reset: + * @window : a #ThunarWindow instance. + * + * Emitted whenever the user requests reset the zoom level. + * This is an internal signal used to bind the action to keys. + **/ + window_signals[ZOOM_RESET] = + g_signal_new (I_("zoom-reset"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ThunarWindowClass, zoom_reset), + g_signal_accumulator_true_handled, NULL, + _thunar_marshal_BOOLEAN__VOID, + G_TYPE_BOOLEAN, 0); + + /** + * ThunarWindow::tab-change: + * @window : a #ThunarWindow instance. + * @idx : tab index, + * + * Emitted whenever the user uses a Alt+N combination to + * switch tabs. + **/ + window_signals[TAB_CHANGE] = + g_signal_new (I_("tab-change"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ThunarWindowClass, tab_change), + g_signal_accumulator_true_handled, NULL, + _thunar_marshal_BOOLEAN__INT, + G_TYPE_BOOLEAN, 1, + G_TYPE_INT); + + /* setup the key bindings for the windows */ + binding_set = gtk_binding_set_by_class (klass); + + /* setup the key bindings for Alt+N */ + for (i = 0; i < 10; i++) + { + gtk_binding_entry_add_signal (binding_set, GDK_KEY_0 + i, GDK_MOD1_MASK, + "tab-change", 1, G_TYPE_UINT, i - 1); + } +} + + + +static gboolean +thunar_window_check_uca_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data) +{ + if (thunar_launcher_check_uca_key_activation (window->launcher, key_event)) + return GDK_EVENT_STOP; + return GDK_EVENT_PROPAGATE; +} + + + +static gchar* +thunar_window_bookmark_get_accel_path (GFile *bookmark_file) +{ + GChecksum *checksum; + gchar *uri; + gchar *accel_path; + const gchar *unique_name; + + _thunar_return_val_if_fail (G_IS_FILE (bookmark_file), NULL); + + /* create unique id based on the uri */ + uri = g_file_get_uri (bookmark_file); + checksum = g_checksum_new (G_CHECKSUM_MD5); + g_checksum_update (checksum, (const guchar *) uri, strlen (uri)); + unique_name = g_checksum_get_string (checksum); + accel_path = g_strconcat("<Actions>/ThunarBookmarks/", unique_name, NULL); + + g_free (uri); + g_checksum_free (checksum); + return accel_path; +} + + + +static void +thunar_window_bookmark_check_key (GFile *g_file, + const gchar *name, + gint line_num, + gpointer user_data) +{ + ThunarWindow *window = THUNAR_WINDOW (user_data); + gchar *accel_path; + GtkAccelKey key; + + accel_path = thunar_window_bookmark_get_accel_path (g_file); + if (gtk_accel_map_lookup_entry (accel_path, &key) == TRUE) + { + if (window->latest_key_event->keyval == key.accel_key) + { + if ((window->latest_key_event->state & gtk_accelerator_get_default_mod_mask ()) == key.accel_mods) + thunar_window_set_current_directory_gfile (window, g_file); + } + } + g_free (accel_path); +} + + + +static gboolean +thunar_window_check_bookmark_key_activation (ThunarWindow *window, + GdkEventKey *key_event, + gpointer user_data) +{ + /* in order to access it inside the clalback */ + window->latest_key_event = key_event; + + /* load bookmark menu items from bookmark file */ + thunar_util_load_bookmarks (window->bookmark_file, + thunar_window_bookmark_check_key, + window); + return GDK_EVENT_PROPAGATE; +} + + + +static void +thunar_window_init (ThunarWindow *window) +{ + GtkWidget *label; + GtkWidget *infobar; + GtkWidget *item; + gboolean last_menubar_visible; + gchar *last_location_bar; + gchar *last_side_pane; + GType type; + gint last_separator_position; + gint last_window_width; + gint last_window_height; + gboolean last_window_maximized; + gboolean last_statusbar_visible; + GtkToolItem *tool_item; + gboolean small_icons; + GtkStyleContext *context; + + /* unset the view type */ + window->view_type = G_TYPE_NONE; + + /* grab a reference on the provider factory and load the providers*/ + window->provider_factory = thunarx_provider_factory_get_default (); + window->thunarx_preferences_providers = thunarx_provider_factory_list_providers (window->provider_factory, THUNARX_TYPE_PREFERENCES_PROVIDER); + + /* grab a reference on the preferences */ + window->preferences = thunar_preferences_get (); + + window->accel_group = gtk_accel_group_new (); + xfce_gtk_accel_map_add_entries (thunar_window_action_entries, G_N_ELEMENTS (thunar_window_action_entries)); + xfce_gtk_accel_group_connect_action_entries (window->accel_group, + thunar_window_action_entries, + G_N_ELEMENTS (thunar_window_action_entries), + window); + + gtk_window_add_accel_group (GTK_WINDOW (window), window->accel_group); + + /* get all properties for init */ + g_object_get (G_OBJECT (window->preferences), + "last-show-hidden", &window->show_hidden, + "last-window-width", &last_window_width, + "last-window-height", &last_window_height, + "last-window-maximized", &last_window_maximized, + "last-menubar-visible", &last_menubar_visible, + "last-separator-position", &last_separator_position, + "last-location-bar", &last_location_bar, + "last-side-pane", &last_side_pane, + "last-statusbar-visible", &last_statusbar_visible, + "misc-small-toolbar-icons", &small_icons, + NULL); + + /* set up a handler to confirm exit when there are multiple tabs open */ + g_signal_connect (window, "delete-event", G_CALLBACK (thunar_window_delete), NULL); + + /* connect to the volume monitor */ + window->device_monitor = thunar_device_monitor_get (); + g_signal_connect (window->device_monitor, "device-pre-unmount", G_CALLBACK (thunar_window_device_pre_unmount), window); + g_signal_connect (window->device_monitor, "device-removed", G_CALLBACK (thunar_window_device_changed), window); + g_signal_connect (window->device_monitor, "device-changed", G_CALLBACK (thunar_window_device_changed), window); + + window->icon_factory = thunar_icon_factory_get_default (); + +<<<<<<< Upstream, based on origin/master + /* Catch key events before accelerators get processed */ + g_signal_connect (window, "key-press-event", G_CALLBACK (thunar_window_propagate_key_event), NULL); + g_signal_connect (window, "key-release-event", G_CALLBACK (thunar_window_propagate_key_event), NULL); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + /* setup the action group for this window */ + window->action_group = gtk_action_group_new ("ThunarWindow"); + gtk_action_group_set_translation_domain (window->action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions (window->action_group, action_entries, G_N_ELEMENTS (action_entries), GTK_WIDGET (window)); + gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries, G_N_ELEMENTS (toggle_action_entries), GTK_WIDGET (window)); +======= + window->select_files_closure = g_cclosure_new_swap (G_CALLBACK (thunar_window_select_files), window, NULL); + g_closure_ref (window->select_files_closure); + g_closure_sink (window->select_files_closure); + window->launcher = g_object_new (THUNAR_TYPE_LAUNCHER, "widget", GTK_WIDGET (window), + "select-files-closure", window->select_files_closure, NULL); +>>>>>>> d01bcd1 giant commit + + exo_binding_new (G_OBJECT (window), "current-directory", G_OBJECT (window->launcher), "current-directory"); + g_signal_connect_swapped (G_OBJECT (window->launcher), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); + g_signal_connect_swapped (G_OBJECT (window->launcher), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window); + thunar_launcher_append_accelerators (window->launcher, window->accel_group); + + /* determine the default window size from the preferences */ + gtk_window_set_default_size (GTK_WINDOW (window), last_window_width, last_window_height); + + /* restore the maxized state of the window */ + if (G_UNLIKELY (last_window_maximized)) + gtk_window_maximize (GTK_WINDOW (window)); + + /* add thunar style class for easier theming */ + context = gtk_widget_get_style_context (GTK_WIDGET (window)); + gtk_style_context_add_class (context, "thunar"); + + window->grid = gtk_grid_new (); + gtk_container_add (GTK_CONTAINER (window), window->grid); + gtk_widget_show (window->grid); + + /* build the menubar */ + window->menubar = gtk_menu_bar_new (); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_FILE_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_file_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_EDIT_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_edit_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_view_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_GO_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_go_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_HELP_MENU), G_OBJECT (window), GTK_MENU_SHELL (window->menubar)); + g_signal_connect_swapped (G_OBJECT (item), "button-press-event", G_CALLBACK (thunar_window_create_help_menu), window); + g_signal_connect_swapped (G_OBJECT (item), "enter-notify-event", G_CALLBACK (thunar_window_menu_item_hovered), window); + gtk_widget_show_all (window->menubar); + + if (last_menubar_visible == FALSE) + gtk_widget_hide (window->menubar); + gtk_widget_set_hexpand (window->menubar, TRUE); + gtk_grid_attach (GTK_GRID (window->grid), window->menubar, 0, 0, 1, 1); + + /* append the menu item for the spinner */ + item = gtk_menu_item_new (); + gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE); +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + gtk_menu_item_set_right_justified (GTK_MENU_ITEM (item), TRUE); +G_GNUC_END_IGNORE_DEPRECATIONS + gtk_menu_shell_append (GTK_MENU_SHELL (window->menubar), item); + gtk_widget_show (item); + + /* place the spinner into the menu item */ + window->spinner = gtk_spinner_new (); + gtk_container_add (GTK_CONTAINER (item), window->spinner); + exo_binding_new (G_OBJECT (window->spinner), "active", + G_OBJECT (window->spinner), "visible"); + + /* check if we need to add the root warning */ + if (G_UNLIKELY (geteuid () == 0)) + { + /* add the bar for the root warning */ + infobar = gtk_info_bar_new (); + gtk_info_bar_set_message_type (GTK_INFO_BAR (infobar), GTK_MESSAGE_WARNING); + gtk_widget_set_hexpand (infobar, TRUE); + gtk_grid_attach (GTK_GRID (window->grid), infobar, 0, 2, 1, 1); + gtk_widget_show (infobar); + + /* add the label with the root warning */ + label = gtk_label_new (_("Warning: you are using the root account. You may harm your system.")); + gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (infobar))), label); + gtk_widget_show (label); + } + + window->paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); + gtk_container_set_border_width (GTK_CONTAINER (window->paned), 0); + gtk_widget_set_hexpand (window->paned, TRUE); + gtk_widget_set_vexpand (window->paned, TRUE); + gtk_grid_attach (GTK_GRID (window->grid), window->paned, 0, 4, 1, 1); + gtk_widget_show (window->paned); + + /* determine the last separator position and apply it to the paned view */ + gtk_paned_set_position (GTK_PANED (window->paned), last_separator_position); + g_signal_connect_swapped (window->paned, "accept-position", G_CALLBACK (thunar_window_save_paned), window); + g_signal_connect_swapped (window->paned, "button-release-event", G_CALLBACK (thunar_window_save_paned), window); + + window->view_box = gtk_grid_new (); + gtk_paned_pack2 (GTK_PANED (window->paned), window->view_box, TRUE, FALSE); + gtk_widget_show (window->view_box); + + /* tabs */ + window->notebook = gtk_notebook_new (); + gtk_widget_set_hexpand (window->notebook, TRUE); + gtk_widget_set_vexpand (window->notebook, TRUE); + gtk_grid_attach (GTK_GRID (window->view_box), window->notebook, 0, 1, 1, 1); + g_signal_connect (G_OBJECT (window->notebook), "switch-page", G_CALLBACK (thunar_window_notebook_switch_page), window); + g_signal_connect (G_OBJECT (window->notebook), "page-added", G_CALLBACK (thunar_window_notebook_page_added), window); + g_signal_connect (G_OBJECT (window->notebook), "page-removed", G_CALLBACK (thunar_window_notebook_page_removed), window); + g_signal_connect_after (G_OBJECT (window->notebook), "button-press-event", G_CALLBACK (thunar_window_notebook_button_press_event), window); + g_signal_connect (G_OBJECT (window->notebook), "popup-menu", G_CALLBACK (thunar_window_notebook_popup_menu), window); + g_signal_connect (G_OBJECT (window->notebook), "create-window", G_CALLBACK (thunar_window_notebook_create_window), window); + gtk_notebook_set_show_border (GTK_NOTEBOOK (window->notebook), FALSE); + gtk_notebook_set_scrollable (GTK_NOTEBOOK (window->notebook), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (window->notebook), 0); + gtk_notebook_set_group_name (GTK_NOTEBOOK (window->notebook), "thunar-tabs"); + gtk_widget_show (window->notebook); + + /* allocate the new location bar widget */ + window->location_bar = thunar_location_bar_new (); + g_object_bind_property (G_OBJECT (window), "current-directory", G_OBJECT (window->location_bar), "current-directory", G_BINDING_SYNC_CREATE); + g_signal_connect_swapped (G_OBJECT (window->location_bar), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); + g_signal_connect_swapped (G_OBJECT (window->location_bar), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window); + g_signal_connect_swapped (G_OBJECT (window->location_bar), "reload-requested", G_CALLBACK (thunar_window_handle_reload_request), window); + g_signal_connect_swapped (G_OBJECT (window->location_bar), "entry-done", G_CALLBACK (thunar_window_update_location_bar_visible), window); + + /* setup the toolbar for the location bar */ + window->location_toolbar = gtk_toolbar_new (); + gtk_toolbar_set_style (GTK_TOOLBAR (window->location_toolbar), GTK_TOOLBAR_ICONS); + gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->location_toolbar), + small_icons ? GTK_ICON_SIZE_SMALL_TOOLBAR : GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_widget_set_hexpand (window->location_toolbar, TRUE); + gtk_grid_attach (GTK_GRID (window->grid), window->location_toolbar, 0, 1, 1, 1); + + window->location_toolbar_item_back = xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_BACK), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + window->location_toolbar_item_forward = xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_FORWARD), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + window->location_toolbar_item_parent = xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_PARENT), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + xfce_gtk_tool_button_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_HOME), G_OBJECT (window), GTK_TOOLBAR (window->location_toolbar)); + + g_signal_connect (G_OBJECT (window->location_toolbar_item_back), "button-press-event", G_CALLBACK (thunar_window_history_clicked), G_OBJECT (window)); + g_signal_connect (G_OBJECT (window->location_toolbar_item_forward), "button-press-event", G_CALLBACK (thunar_window_history_clicked), G_OBJECT (window)); + window->signal_handler_id_history_changed = 0; + + /* The UCA shortcuts and the bookmarks need to be checked 'by hand', since we dont want to permanently keep menu items for them */ + g_signal_connect (window, "key-press-event", G_CALLBACK (thunar_window_check_uca_key_activation), NULL); + g_signal_connect (window, "key-press-event", G_CALLBACK (thunar_window_check_bookmark_key_activation), NULL); + + /* add the location bar to the toolbar */ + tool_item = gtk_tool_item_new (); + gtk_tool_item_set_expand (tool_item, TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (window->location_toolbar), tool_item, -1); + gtk_toolbar_set_show_arrow (GTK_TOOLBAR (window->location_toolbar), FALSE); + + /* add the location bar itself */ + gtk_container_add (GTK_CONTAINER (tool_item), window->location_bar); + + /* display the toolbar */ + gtk_widget_show_all (window->location_toolbar); + + g_free (last_location_bar); + + /* setup setting the location bar visibility on-demand */ + g_signal_connect_object (G_OBJECT (window->preferences), "notify::last-location-bar", G_CALLBACK (thunar_window_update_location_bar_visible), window, G_CONNECT_SWAPPED); + thunar_window_update_location_bar_visible (window); + + /* update window icon whenever preferences change */ + g_signal_connect_object (G_OBJECT (window->preferences), "notify::misc-change-window-icon", G_CALLBACK (thunar_window_update_window_icon), window, G_CONNECT_SWAPPED); + + /* determine the selected side pane */ + if (exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_SHORTCUTS_PANE))) + type = THUNAR_TYPE_SHORTCUTS_PANE; + else if (exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_TREE_PANE))) + type = THUNAR_TYPE_TREE_PANE; + else + type = G_TYPE_NONE; + thunar_window_install_sidepane (window, type); + g_free (last_side_pane); + + /* setup a new statusbar */ + window->statusbar = thunar_statusbar_new (); + gtk_widget_set_hexpand (window->statusbar, TRUE); + gtk_grid_attach (GTK_GRID (window->view_box), window->statusbar, 0, 2, 1, 1); + if (last_statusbar_visible) + gtk_widget_show (window->statusbar); + + if (G_LIKELY (window->view != NULL)) + thunar_window_binding_create (window, window->view, "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); + + + /* setup a new statusbar */ + window->statusbar = thunar_statusbar_new (); + gtk_widget_set_hexpand (window->statusbar, TRUE); + gtk_grid_attach (GTK_GRID (window->view_box), window->statusbar, 0, 2, 1, 1); + if (last_statusbar_visible) + gtk_widget_show (window->statusbar); + + if (G_LIKELY (window->view != NULL)) + thunar_window_binding_create (window, window->view, "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE); + + /* ensure that all the view types are registered */ + g_type_ensure (THUNAR_TYPE_ICON_VIEW); + g_type_ensure (THUNAR_TYPE_DETAILS_VIEW); + g_type_ensure (THUNAR_TYPE_COMPACT_VIEW); + + /* load the bookmarks file and monitor */ + window->bookmark_file = thunar_g_file_new_for_bookmarks (); + window->bookmark_monitor = g_file_monitor_file (window->bookmark_file, G_FILE_MONITOR_NONE, NULL, NULL); + + /* same is done for view in thunar_window_action_view_changed */ + thunar_side_pane_set_show_hidden (THUNAR_SIDE_PANE (window->sidepane), window->show_hidden); +} + + + +/** + * thunar_window_select_files: + * @window : a #ThunarWindow instance. + * @files_to_selected : a list of #GFile<!---->s + * + * Visually selects the files, given by the list + **/ +static void +thunar_window_select_files (ThunarWindow *window, + GList *files_to_selected) +{ + GList *thunarFiles = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + for (GList *lp = files_to_selected; lp != NULL; lp = lp->next) + thunarFiles = g_list_append (thunarFiles, thunar_file_get (G_FILE (files_to_selected->data), NULL)); + thunar_view_set_selected_files (THUNAR_VIEW (window->view), thunarFiles); + g_list_free_full (thunarFiles, g_object_unref); +} + + + +static gboolean +thunar_window_menu_is_open (ThunarWindow *window) +{ + GList *lp; + GtkWidget *submenu; + + g_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + for(lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) + { + submenu = gtk_menu_item_get_submenu(lp->data); + if (submenu != NULL && gtk_widget_get_visible (submenu)) + return TRUE; + } + return FALSE; +} + + + +static gboolean +thunar_window_menu_item_hovered (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + gboolean ret; + + g_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + if (thunar_window_menu_is_open(window)) + g_signal_emit_by_name (menu, "button-press-event", NULL, &ret); + return FALSE; +} + + + +static gboolean +thunar_window_create_file_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + GtkWidget *item; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + submenu = g_object_new (THUNAR_TYPE_MENU, "menu-type", THUNAR_MENU_TYPE_WINDOW, + "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_NEW_TAB), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_NEW_WINDOW), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_OPEN + | THUNAR_MENU_SECTION_SENDTO + | THUNAR_MENU_SECTION_CREATE_NEW_FILES + | THUNAR_MENU_SECTION_EMPTY_TRASH + | THUNAR_MENU_SECTION_CUSTOM_ACTIONS + | THUNAR_MENU_SECTION_PROPERTIES); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_DETACH_TAB), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_widget_set_sensitive (item, gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) > 1); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_TAB), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_WINDOW), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static gboolean +thunar_window_create_edit_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + GtkWidget *gtk_menu_item; + GList *thunarx_menu_items; + GList *pp, *lp; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_CUT + | THUNAR_MENU_SECTION_COPY_PASTE + | THUNAR_MENU_SECTION_TRASH_DELETE); + if (window->view != NULL) + { + thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), + GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_ALL_FILES); + thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), + GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_SELECT_BY_PATTERN); + thunar_standard_view_append_menu_item (THUNAR_STANDARD_VIEW (window->view), + GTK_MENU (submenu), THUNAR_STANDARD_VIEW_ACTION_INVERT_SELECTION); + } + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_menu_add_sections (submenu, THUNAR_MENU_SECTION_DUPLICATE + | THUNAR_MENU_SECTION_MAKELINK + | THUNAR_MENU_SECTION_RENAME + | THUNAR_MENU_SECTION_RESTORE); + + /* determine the available preferences providers */ + if (G_LIKELY (window->thunarx_preferences_providers != NULL)) + { + /* add menu items from all providers */ + for (pp = window->thunarx_preferences_providers; pp != NULL; pp = pp->next) + { + /* determine the available menu items for the provider */ + thunarx_menu_items = thunarx_preferences_provider_get_menu_items (THUNARX_PREFERENCES_PROVIDER (pp->data), GTK_WIDGET (window)); + for (lp = thunarx_menu_items; lp != NULL; lp = lp->next) + { + gtk_menu_item = thunar_gtk_menu_thunarx_menu_item_new (lp->data, GTK_MENU_SHELL (submenu)); + + /* Each thunarx_menu_item will be destroyed together with its related gtk_menu_item */ + g_signal_connect_swapped (G_OBJECT (gtk_menu_item), "destroy", G_CALLBACK (g_object_unref), lp->data); + } + + /* release the list */ + g_list_free (thunarx_menu_items); + } + } + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_PREFERENCES), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static gboolean +thunar_window_create_view_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + GtkWidget *item; + GtkWidget *sub_items; + gchar *last_location_bar; + gchar *last_side_pane; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_RELOAD), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_MENU), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + sub_items = gtk_menu_new(); + gtk_menu_set_accel_group (GTK_MENU (sub_items), window->accel_group); + g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_PATHBAR), G_OBJECT (window), + exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_ENTRY)), GTK_MENU_SHELL (sub_items)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_TOOLBAR), G_OBJECT (window), + exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_BUTTONS)), GTK_MENU_SHELL (sub_items)); + g_free (last_location_bar); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), GTK_WIDGET (sub_items)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_MENU), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + sub_items = gtk_menu_new(); + gtk_menu_set_accel_group (GTK_MENU (sub_items), window->accel_group); + g_object_get (window->preferences, "last-side-pane", &last_side_pane, NULL); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_SHORTCUTS), G_OBJECT (window), + exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_SHORTCUTS_PANE)), GTK_MENU_SHELL (sub_items)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_TREE), G_OBJECT (window), + exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_TREE_PANE)), GTK_MENU_SHELL (sub_items)); + g_free (last_side_pane); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), GTK_WIDGET (sub_items)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_STATUSBAR), G_OBJECT (window), + gtk_widget_get_visible (window->statusbar), GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_MENUBAR), G_OBJECT (window), + gtk_widget_get_visible (window->menubar), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SHOW_HIDDEN), G_OBJECT (window), + window->show_hidden, GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + if (window->view != NULL) + thunar_standard_view_append_menu_items (THUNAR_STANDARD_VIEW (window->view), GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_window_append_menu_item (window, GTK_MENU_SHELL (submenu), THUNAR_WINDOW_ACTION_ZOOM_IN); + thunar_window_append_menu_item (window, GTK_MENU_SHELL (submenu), THUNAR_WINDOW_ACTION_ZOOM_OUT); + thunar_window_append_menu_item (window, GTK_MENU_SHELL (submenu), THUNAR_WINDOW_ACTION_ZOOM_RESET); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_ICONS), + G_OBJECT (window), window->view_type == THUNAR_TYPE_ICON_VIEW, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_DETAILED_LIST), + G_OBJECT (window), window->view_type == THUNAR_TYPE_DETAILS_VIEW, GTK_MENU_SHELL (submenu)); + xfce_gtk_toggle_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_VIEW_AS_COMPACT_LIST), + G_OBJECT (window), window->view_type == THUNAR_TYPE_COMPACT_VIEW, GTK_MENU_SHELL (submenu)); + + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static gboolean +thunar_window_create_go_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + gchar *icon_name; + const XfceGtkActionEntry *action_entry; + ThunarHistory *history = NULL; + GtkWidget *item; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + if (window->view != NULL) + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_PARENT), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_widget_set_sensitive (item, !thunar_g_file_is_root (thunar_file_get_file (window->current_directory))); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_BACK), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + if (history != NULL) + gtk_widget_set_sensitive (item, thunar_history_has_back (history)); + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_FORWARD), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + if (history != NULL) + gtk_widget_set_sensitive (item, thunar_history_has_forward (history)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_COMPUTER), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_HOME), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_DESKTOP), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + if (thunar_g_vfs_is_uri_scheme_supported ("trash")) + { + GFile *gfile; + ThunarFile *trash_folder; + + /* try to connect to the trash bin */ + gfile = thunar_g_file_new_for_trash (); + if (gfile != NULL) + { + trash_folder = thunar_file_get (gfile, NULL); + if (trash_folder != NULL) + { + action_entry = get_action_entry (THUNAR_WINDOW_ACTION_OPEN_TRASH); + if (action_entry != NULL) + { + if (thunar_file_get_item_count (trash_folder) > 0) + icon_name = "user-trash-full"; + else + icon_name = "user-trash"; + xfce_gtk_image_menu_item_new_from_icon_name (action_entry->menu_item_label_text, action_entry->menu_item_tooltip_text, + action_entry->accel_path, action_entry->callback, G_OBJECT (window), icon_name, GTK_MENU_SHELL (submenu)); + g_object_unref (trash_folder); + } + } + g_object_unref (gfile); + } + } + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_TEMPLATES), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + thunar_window_menu_add_bookmarks (window, GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_FILE_SYSTEM), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_NETWORK), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_OPEN_LOCATION), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static gboolean +thunar_window_create_help_menu (ThunarWindow *window, + GdkEventCrossing *event, + GtkWidget *menu) +{ + ThunarMenu *submenu; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (GTK_IS_MENU_ITEM (menu), FALSE); + + submenu = g_object_new (THUNAR_TYPE_MENU, "launcher", window->launcher, NULL); + gtk_menu_set_accel_group (GTK_MENU (submenu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CONTENTS), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_ABOUT), G_OBJECT (window), GTK_MENU_SHELL (submenu)); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), GTK_WIDGET (submenu)); + gtk_widget_show_all (GTK_WIDGET (submenu)); + + thunar_window_redirect_menu_tooltips_to_statusbar (window, GTK_MENU (submenu)); + return FALSE; +} + + + +static void +thunar_window_dispose (GObject *object) +{ + ThunarWindow *window = THUNAR_WINDOW (object); + + /* indicate that history items are out of use */ + window->location_toolbar_item_back = NULL; + window->location_toolbar_item_forward = NULL; + + /* destroy the save geometry timer source */ + if (G_UNLIKELY (window->save_geometry_timer_id != 0)) + g_source_remove (window->save_geometry_timer_id); + + /* disconnect from the current-directory */ + thunar_window_set_current_directory (window, NULL); + + (*G_OBJECT_CLASS (thunar_window_parent_class)->dispose) (object); +} + + + +static void +thunar_window_finalize (GObject *object) +{ + ThunarWindow *window = THUNAR_WINDOW (object); + + /* disconnect from the volume monitor */ + g_signal_handlers_disconnect_matched (window->device_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); + g_object_unref (window->device_monitor); + + g_object_unref (window->icon_factory); + g_object_unref (window->launcher); + + if (window->bookmark_file != NULL) + g_object_unref (window->bookmark_file); + + if (window->bookmark_monitor != NULL) + { + g_file_monitor_cancel (window->bookmark_monitor); + g_object_unref (window->bookmark_monitor); + } + + /* release our reference on the provider factory */ + g_object_unref (window->provider_factory); + + /* release the preferences reference */ + g_object_unref (window->preferences); + + g_closure_invalidate (window->select_files_closure); + g_closure_unref (window->select_files_closure); + + (*G_OBJECT_CLASS (thunar_window_parent_class)->finalize) (object); +} + + + +static gboolean thunar_window_delete (GtkWidget *widget, + GdkEvent *event, + gpointer data ) +{ + GtkNotebook *notebook; + gboolean confirm_close_multiple_tabs, do_not_ask_again; + gint response, n_tabs; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (widget),FALSE); + + /* if we don't have muliple tabs then just exit */ + notebook = GTK_NOTEBOOK (THUNAR_WINDOW (widget)->notebook); + n_tabs = gtk_notebook_get_n_pages (GTK_NOTEBOOK (THUNAR_WINDOW (widget)->notebook)); + if (n_tabs < 2) + return FALSE; + + /* check if the user has disabled confirmation of closing multiple tabs, and just exit if so */ + g_object_get (G_OBJECT (THUNAR_WINDOW (widget)->preferences), + "misc-confirm-close-multiple-tabs", &confirm_close_multiple_tabs, + NULL); + if(!confirm_close_multiple_tabs) + return FALSE; + + /* ask the user for confirmation */ + do_not_ask_again = FALSE; + response = xfce_dialog_confirm_close_tabs (GTK_WINDOW (widget), n_tabs, TRUE, &do_not_ask_again); + + /* if the user requested not to be asked again, store this preference */ + if (response != GTK_RESPONSE_CANCEL && do_not_ask_again) + g_object_set (G_OBJECT (THUNAR_WINDOW (widget)->preferences), + "misc-confirm-close-multiple-tabs", FALSE, NULL); + + if(response == GTK_RESPONSE_YES) + return FALSE; + if(response == GTK_RESPONSE_CLOSE) + gtk_notebook_remove_page (notebook, gtk_notebook_get_current_page(notebook)); + return TRUE; +} + + + +static void +thunar_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ThunarWindow *window = THUNAR_WINDOW (object); + + switch (prop_id) + { + case PROP_CURRENT_DIRECTORY: + g_value_set_object (value, thunar_window_get_current_directory (window)); + break; + + case PROP_ZOOM_LEVEL: + g_value_set_enum (value, window->zoom_level); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ThunarWindow *window = THUNAR_WINDOW (object); + + switch (prop_id) + { + case PROP_CURRENT_DIRECTORY: + thunar_window_set_current_directory (window, g_value_get_object (value)); + break; + + case PROP_ZOOM_LEVEL: + thunar_window_set_zoom_level (window, g_value_get_enum (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static gboolean +thunar_window_reload (ThunarWindow *window, + gboolean reload_info) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + /* force the view to reload */ + if (G_LIKELY (window->view != NULL)) + { + thunar_view_reload (THUNAR_VIEW (window->view), reload_info); + return TRUE; + } + + return FALSE; +} + + + +/** + * thunar_window_has_shortcut_sidepane: + * @window : a #ThunarWindow instance. + * + * Return value: True, if this window is running a shortcut sidepane + **/ +gboolean +thunar_window_has_shortcut_sidepane (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + /* check if a side pane is currently active */ + if (G_LIKELY (window->sidepane != NULL)) + { + return G_OBJECT_TYPE (window->sidepane) == THUNAR_TYPE_SHORTCUTS_PANE; + } + return FALSE; +} + + + +/** + * thunar_window_get_sidepane: + * @window : a #ThunarWindow instance. + * + * Return value: (transfer none): The #ThunarSidePane of this window, or NULL if not available + **/ +GtkWidget* thunar_window_get_sidepane (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + return GTK_WIDGET (window->sidepane); +} + + + +static gboolean +thunar_window_toggle_sidepane (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + /* check if a side pane is currently active */ + if (G_LIKELY (window->sidepane != NULL)) + { + /* determine the currently active side pane type */ + window->toggle_sidepane_type = G_OBJECT_TYPE (window->sidepane); + thunar_window_install_sidepane (window, G_TYPE_NONE); + } + else + { + /* check if we have a previously remembered toggle type */ + if (window->toggle_sidepane_type == THUNAR_TYPE_TREE_PANE || window->toggle_sidepane_type == THUNAR_TYPE_SHORTCUTS_PANE) + thunar_window_install_sidepane (window, window->toggle_sidepane_type); + } + + return TRUE; +} + + + +static gboolean +thunar_window_zoom_in (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + /* check if we can still zoom in */ + if (G_LIKELY (window->zoom_level < THUNAR_ZOOM_N_LEVELS - 1)) + { + thunar_window_set_zoom_level (window, window->zoom_level + 1); + return TRUE; + } + + return FALSE; +} + + + +static gboolean +thunar_window_zoom_out (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + /* check if we can still zoom out */ + if (G_LIKELY (window->zoom_level > 0)) + { + thunar_window_set_zoom_level (window, window->zoom_level - 1); + return TRUE; + } + + return FALSE; +} + + + +static gboolean +thunar_window_zoom_reset (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + /* tell the view to reset it's zoom level */ + if (G_LIKELY (window->view != NULL)) + { + thunar_view_reset_zoom_level (THUNAR_VIEW (window->view)); + return TRUE; + } + + return FALSE; +} + + + +static gboolean +thunar_window_tab_change (ThunarWindow *window, + gint nth) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + /* Alt+0 is 10th tab */ + gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), + nth == -1 ? 9 : nth); + + return TRUE; +} + + + +static void +thunar_window_action_switch_next_tab (ThunarWindow *window) +{ + gint current_page; + gint new_page; + gint pages; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)); + pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + new_page = (current_page + 1) % pages; + + gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), new_page); +} + + + +static void +thunar_window_action_switch_previous_tab (ThunarWindow *window) +{ + gint current_page; + gint new_page; + gint pages; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)); + pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + new_page = (current_page - 1) % pages; + + gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), new_page); +} + + + +static void +thunar_window_realize (GtkWidget *widget) +{ + ThunarWindow *window = THUNAR_WINDOW (widget); + + /* let the GtkWidget class perform the realize operation */ + (*GTK_WIDGET_CLASS (thunar_window_parent_class)->realize) (widget); + + /* connect to the clipboard manager of the new display and be sure to redraw the window + * whenever the clipboard contents change to make sure we always display up2date state. + */ + window->clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (widget)); + g_signal_connect_swapped (G_OBJECT (window->clipboard), "changed", + G_CALLBACK (gtk_widget_queue_draw), widget); +} + + + +static void +thunar_window_unrealize (GtkWidget *widget) +{ + ThunarWindow *window = THUNAR_WINDOW (widget); + + /* disconnect from the clipboard manager */ + g_signal_handlers_disconnect_by_func (G_OBJECT (window->clipboard), gtk_widget_queue_draw, widget); + + /* let the GtkWidget class unrealize the window */ + (*GTK_WIDGET_CLASS (thunar_window_parent_class)->unrealize) (widget); + + /* drop the reference on the clipboard manager, we do this after letting the GtkWidget class + * unrealise the window to prevent the clipboard being disposed during the unrealize */ + g_object_unref (G_OBJECT (window->clipboard)); +} + + + +static gboolean +thunar_window_configure_event (GtkWidget *widget, + GdkEventConfigure *event) +{ + ThunarWindow *window = THUNAR_WINDOW (widget); + GtkAllocation widget_allocation; + + gtk_widget_get_allocation (widget, &widget_allocation); + + /* check if we have a new dimension here */ + if (widget_allocation.width != event->width || widget_allocation.height != event->height) + { + /* drop any previous timer source */ + if (window->save_geometry_timer_id != 0) + g_source_remove (window->save_geometry_timer_id); + + /* check if we should schedule another save timer */ + if (gtk_widget_get_visible (widget)) + { + /* save the geometry one second after the last configure event */ + window->save_geometry_timer_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, 1, thunar_window_save_geometry_timer, + window, thunar_window_save_geometry_timer_destroy); + } + } + + /* let Gtk+ handle the configure event */ + return (*GTK_WIDGET_CLASS (thunar_window_parent_class)->configure_event) (widget, event); +} + + + +static void +thunar_window_binding_destroyed (gpointer data, + GObject *binding) +{ + ThunarWindow *window = THUNAR_WINDOW (data); + + if (window->view_bindings != NULL) + window->view_bindings = g_slist_remove (window->view_bindings, binding); +} + + + +static void +thunar_window_binding_create (ThunarWindow *window, + gpointer src_object, + const gchar *src_prop, + gpointer dst_object, + const gchar *dst_prop, + GBindingFlags flags) +{ + GBinding *binding; + + _thunar_return_if_fail (G_IS_OBJECT (src_object)); + _thunar_return_if_fail (G_IS_OBJECT (dst_object)); + + binding = g_object_bind_property (G_OBJECT (src_object), src_prop, + G_OBJECT (dst_object), dst_prop, + flags); + + g_object_weak_ref (G_OBJECT (binding), thunar_window_binding_destroyed, window); + window->view_bindings = g_slist_prepend (window->view_bindings, binding); +} + + + +static void +thunar_window_notebook_switch_page (GtkWidget *notebook, + GtkWidget *page, + guint page_num, + ThunarWindow *window) +{ + GSList *view_bindings; + ThunarFile *current_directory; + ThunarHistory *history; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + _thunar_return_if_fail (THUNAR_IS_VIEW (page)); + _thunar_return_if_fail (window->notebook == notebook); + + /* leave if nothing changed */ + if (window->view == page) + return; + + if (G_LIKELY (window->view != NULL)) + { + /* disconnect from previous history */ + if (window->signal_handler_id_history_changed != 0) + { + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + g_signal_handler_disconnect (history, window->signal_handler_id_history_changed); + window->signal_handler_id_history_changed = 0; + } + + /* unset view during switch */ + window->view = NULL; + } + + /* disconnect existing bindings */ + view_bindings = window->view_bindings; + window->view_bindings = NULL; + g_slist_free_full (view_bindings, g_object_unref); + + /* update the directory of the current window */ + current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (page)); + thunar_window_set_current_directory (window, current_directory); + + /* add stock bindings */ + thunar_window_binding_create (window, window, "current-directory", page, "current-directory", G_BINDING_DEFAULT); + thunar_window_binding_create (window, page, "loading", window->spinner, "active", G_BINDING_SYNC_CREATE); + thunar_window_binding_create (window, page, "selected-files", window->launcher, "selected-files", G_BINDING_SYNC_CREATE); + thunar_window_binding_create (window, page, "zoom-level", window, "zoom-level", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + + /* connect to the sidepane (if any) */ + if (G_LIKELY (window->sidepane != NULL)) + { + thunar_window_binding_create (window, page, "selected-files", + window->sidepane, "selected-files", + G_BINDING_SYNC_CREATE); + } + + /* connect to the statusbar (if any) */ + if (G_LIKELY (window->statusbar != NULL)) + { + thunar_window_binding_create (window, page, "statusbar-text", + window->statusbar, "text", + G_BINDING_SYNC_CREATE); + } + + /* activate new view */ + window->view = page; + window->view_type = G_TYPE_FROM_INSTANCE (page); + + if (window->view_type != G_TYPE_NONE) + g_object_set (G_OBJECT (window->preferences), "last-view", g_type_name (window->view_type), NULL); + + /* connect to the new history */ + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + if (history != NULL) + { + window->signal_handler_id_history_changed = g_signal_connect_swapped (G_OBJECT (history), "history-changed", G_CALLBACK (thunar_window_history_changed), window); + thunar_window_history_changed (window); + } + + /* update the selection */ + thunar_standard_view_selection_changed (THUNAR_STANDARD_VIEW (page)); + + gtk_widget_grab_focus (page); +} + + + +static void +thunar_window_notebook_show_tabs (ThunarWindow *window) +{ + gint n_pages; + gboolean show_tabs = TRUE; + + /* check if tabs should be visible */ + n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + if (n_pages < 2) + { + g_object_get (G_OBJECT (window->preferences), + "misc-always-show-tabs", &show_tabs, NULL); + } + + /* update visibility */ + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), show_tabs); +} + + + +static void +thunar_window_history_changed (ThunarWindow *window) +{ + ThunarHistory *history; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + if (window->view == NULL) + return; + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + if (history == NULL) + return; + + if (window->location_toolbar_item_back != NULL) + gtk_widget_set_sensitive (window->location_toolbar_item_back, thunar_history_has_back (history)); + + if (window->location_toolbar_item_forward != NULL) + gtk_widget_set_sensitive (window->location_toolbar_item_forward, thunar_history_has_forward (history)); +} + + + +static void +thunar_window_notebook_page_added (GtkWidget *notebook, + GtkWidget *page, + guint page_num, + ThunarWindow *window) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + _thunar_return_if_fail (THUNAR_IS_VIEW (page)); + _thunar_return_if_fail (window->notebook == notebook); + + /* connect signals */ + g_signal_connect (G_OBJECT (page), "notify::loading", G_CALLBACK (thunar_window_notify_loading), window); + g_signal_connect_swapped (G_OBJECT (page), "start-open-location", G_CALLBACK (thunar_window_start_open_location), window); + g_signal_connect_swapped (G_OBJECT (page), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); + g_signal_connect_swapped (G_OBJECT (page), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window); + + /* update tab visibility */ + thunar_window_notebook_show_tabs (window); + + /* set default type if not set yet */ + if (window->view_type == G_TYPE_NONE) + window->view_type = G_OBJECT_TYPE (page); +} + + + +static void +thunar_window_notebook_page_removed (GtkWidget *notebook, + GtkWidget *page, + guint page_num, + ThunarWindow *window) +{ + gint n_pages; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + _thunar_return_if_fail (THUNAR_IS_VIEW (page)); + _thunar_return_if_fail (window->notebook == notebook); + + /* drop connected signals */ + g_signal_handlers_disconnect_matched (page, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); + + n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); + if (n_pages == 0) + { + /* destroy the window */ + gtk_widget_destroy (GTK_WIDGET (window)); + } + else + { + /* update tab visibility */ + thunar_window_notebook_show_tabs (window); + } +} + + + +static gboolean +thunar_window_notebook_button_press_event (GtkWidget *notebook, + GdkEventButton *event, + ThunarWindow *window) +{ + gint page_num = 0; + GtkWidget *page; + GtkWidget *label_box; + GtkAllocation alloc; + gint x, y; + gboolean close_tab; + + if ((event->button == 2 || event->button == 3) + && event->type == GDK_BUTTON_PRESS) + { + /* get real window coordinates */ + gdk_window_get_position (event->window, &x, &y); + x += event->x; + y += event->y; + + /* lookup the clicked tab */ + while ((page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page_num)) != NULL) + { + label_box = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), page); + gtk_widget_get_allocation (label_box, &alloc); + + if (x >= alloc.x && x < alloc.x + alloc.width + && y >= alloc.y && y < alloc.y + alloc.height) + break; + + page_num++; + } + + /* leave if no tab could be found */ + if (page == NULL) + return FALSE; + + if (event->button == 2) + { + /* check if we should close the tab */ + g_object_get (window->preferences, "misc-tab-close-middle-click", &close_tab, NULL); + if (close_tab) + gtk_widget_destroy (page); + } + else if (event->button == 3) + { + /* update the current tab before we show the menu */ + gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page_num); + + /* show the tab menu */ + thunar_window_notebook_popup_menu (notebook, window); + } + + return TRUE; + } + + return FALSE; +} + + + +static gboolean +thunar_window_notebook_popup_menu (GtkWidget *notebook, + ThunarWindow *window) +{ + GtkWidget *menu; + + menu = gtk_menu_new (); + gtk_menu_set_accel_group (GTK_MENU (menu), window->accel_group); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_NEW_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_DETACH_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SWITCH_PREV_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_SWITCH_NEXT_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + xfce_gtk_menu_append_seperator (GTK_MENU_SHELL (menu)); + xfce_gtk_menu_item_new_from_action_entry (get_action_entry (THUNAR_WINDOW_ACTION_CLOSE_TAB), G_OBJECT (window), GTK_MENU_SHELL (menu)); + gtk_widget_show_all (menu); + thunar_gtk_menu_run (GTK_MENU (menu)); + return TRUE; +} + + + +static gpointer +thunar_window_notebook_create_window (GtkWidget *notebook, + GtkWidget *page, + gint x, + gint y, + ThunarWindow *window) +{ + GtkWidget *new_window; + ThunarApplication *application; + gint width, height; + GdkMonitor *monitor; + GdkScreen *screen; + GdkRectangle geo; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL); + _thunar_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + _thunar_return_val_if_fail (window->notebook == notebook, NULL); + _thunar_return_val_if_fail (THUNAR_IS_VIEW (page), NULL); + + /* do nothing if this window has only 1 tab */ + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) < 2) + return NULL; + + /* create new window */ + application = thunar_application_get (); + screen = gtk_window_get_screen (GTK_WINDOW (window)); + new_window = thunar_application_open_window (application, NULL, screen, NULL, TRUE); + g_object_unref (application); + + /* make sure the new window has the same size */ + gtk_window_get_size (GTK_WINDOW (window), &width, &height); + gtk_window_resize (GTK_WINDOW (new_window), width, height); + + /* move the window to the drop position */ + if (x >= 0 && y >= 0) + { + /* get the monitor geometry */ + monitor = gdk_display_get_monitor_at_point (gdk_display_get_default (), x, y); + gdk_monitor_get_geometry (monitor, &geo); + + /* calculate window position, but keep it on the current monitor */ + x = CLAMP (x - width / 2, geo.x, geo.x + geo.width - width); + y = CLAMP (y - height / 2, geo.y, geo.y + geo.height - height); + + /* move the window */ + gtk_window_move (GTK_WINDOW (new_window), MAX (0, x), MAX (0, y)); + } + + /* insert page in new notebook */ + return THUNAR_WINDOW (new_window)->notebook; +} + + + +void +thunar_window_notebook_insert (ThunarWindow *window, + ThunarFile *directory) +{ + ThunarHistory *history = NULL; + GtkWidget *view; + gint page_num; + GtkWidget *label; + GtkWidget *label_box; + GtkWidget *button; + GtkWidget *icon; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (THUNAR_IS_FILE (directory)); + _thunar_return_if_fail (window->view_type != G_TYPE_NONE); + + /* leave if no directory is set */ + if (directory == NULL) + return; + + /* allocate and setup a new view */ + view = g_object_new (window->view_type, "current-directory", directory, "accel-group", window->accel_group, NULL); + thunar_view_set_show_hidden (THUNAR_VIEW (view), window->show_hidden); + gtk_widget_show (view); + + /* save the history of the origin view */ + if (THUNAR_IS_STANDARD_VIEW (window->view)) + { + history = thunar_standard_view_copy_history (THUNAR_STANDARD_VIEW (window->view)); + if (history != NULL) + thunar_standard_view_set_history (THUNAR_STANDARD_VIEW (view), history); + } + + label_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + + label = gtk_label_new (NULL); + exo_binding_new (G_OBJECT (view), "display-name", G_OBJECT (label), "label"); + exo_binding_new (G_OBJECT (view), "tooltip-text", G_OBJECT (label), "tooltip-text"); + gtk_widget_set_has_tooltip (label, TRUE); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_widget_set_margin_start (GTK_WIDGET(label), 3); + gtk_widget_set_margin_end (GTK_WIDGET(label), 3); + gtk_widget_set_margin_top (GTK_WIDGET(label), 3); + gtk_widget_set_margin_bottom (GTK_WIDGET(label), 3); + gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); + gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (label_box), label, TRUE, TRUE, 0); + gtk_widget_show (label); + + button = gtk_button_new (); + gtk_box_pack_start (GTK_BOX (label_box), button, FALSE, FALSE, 0); + gtk_widget_set_can_default (button, FALSE); + gtk_widget_set_focus_on_click (button, FALSE); + gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + gtk_widget_set_tooltip_text (button, _("Close tab")); + g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), view); + gtk_widget_show (button); + + icon = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_MENU); + gtk_container_add (GTK_CONTAINER (button), icon); + gtk_widget_show (icon); + + /* insert the new page */ + page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)); + page_num = gtk_notebook_insert_page (GTK_NOTEBOOK (window->notebook), view, label_box, page_num + 1); + + /* switch to the new tab*/ + gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), page_num); + + /* set tab child properties */ + gtk_container_child_set (GTK_CONTAINER (window->notebook), view, "tab-expand", TRUE, NULL); + gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook), view, TRUE); + gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (window->notebook), view, TRUE); + + /* take focus on the view */ + gtk_widget_grab_focus (view); +} + + + +void +thunar_window_update_directories (ThunarWindow *window, + ThunarFile *old_directory, + ThunarFile *new_directory) +{ + GtkWidget *view; + ThunarFile *directory; + gint n; + gint n_pages; + gint active_page; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (THUNAR_IS_FILE (old_directory)); + _thunar_return_if_fail (THUNAR_IS_FILE (new_directory)); + + n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + if (G_UNLIKELY (n_pages == 0)) + return; + + active_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)); + + for (n = 0; n < n_pages; n++) + { + /* get the view */ + view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), n); + if (! THUNAR_IS_NAVIGATOR (view)) + continue; + + /* get the directory of the view */ + directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (view)); + if (! THUNAR_IS_FILE (directory)) + continue; + + /* if it matches the old directory, change to the new one */ + if (directory == old_directory) + { + if (n == active_page) + thunar_navigator_change_directory (THUNAR_NAVIGATOR (view), new_directory); + else + thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (view), new_directory); + } + } +} + + + +static void +thunar_window_update_location_bar_visible (ThunarWindow *window) +{ + gchar *last_location_bar = NULL; + + g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); + + if (exo_str_is_equal (last_location_bar, g_type_name (G_TYPE_NONE))) + gtk_widget_hide (window->location_toolbar); + else + gtk_widget_show (window->location_toolbar); + + g_free (last_location_bar); +} + + + +static void +thunar_window_update_window_icon (ThunarWindow *window) +{ + gboolean change_window_icon; + GtkIconTheme *icon_theme; + const gchar *icon_name = "folder"; + + g_object_get (window->preferences, "misc-change-window-icon", &change_window_icon, NULL); + + if (change_window_icon) + { + icon_theme = gtk_icon_theme_get_for_screen (gtk_window_get_screen (GTK_WINDOW (window))); + icon_name = thunar_file_get_icon_name (window->current_directory, + THUNAR_FILE_ICON_STATE_DEFAULT, + icon_theme); + } + + gtk_window_set_icon_name (GTK_WINDOW (window), icon_name); +} + + + +static void +thunar_window_handle_reload_request (ThunarWindow *window) +{ + gboolean result; + + /* force the view to reload */ + g_signal_emit (G_OBJECT (window), window_signals[RELOAD], 0, TRUE, &result); +} + + + +static void +thunar_window_install_sidepane (ThunarWindow *window, + GType type) +{ + GtkStyleContext *context; + + _thunar_return_if_fail (type == G_TYPE_NONE || g_type_is_a (type, THUNAR_TYPE_SIDE_PANE)); + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* drop the previous side pane (if any) */ + if (G_UNLIKELY (window->sidepane != NULL)) + { + gtk_widget_destroy (window->sidepane); + window->sidepane = NULL; + } + + /* check if we have a new sidepane widget */ + if (G_LIKELY (type != G_TYPE_NONE)) + { + /* allocate the new side pane widget */ + window->sidepane = g_object_new (type, NULL); + gtk_widget_set_size_request (window->sidepane, 0, -1); + exo_binding_new (G_OBJECT (window), "current-directory", G_OBJECT (window->sidepane), "current-directory"); + g_signal_connect_swapped (G_OBJECT (window->sidepane), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window); + g_signal_connect_swapped (G_OBJECT (window->sidepane), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window); + context = gtk_widget_get_style_context (window->sidepane); + gtk_style_context_add_class (context, "sidebar"); + gtk_paned_pack1 (GTK_PANED (window->paned), window->sidepane, FALSE, FALSE); + gtk_widget_show (window->sidepane); + + /* connect the side pane widget to the view (if any) */ + if (G_LIKELY (window->view != NULL)) + thunar_window_binding_create (window, window->view, "selected-files", window->sidepane, "selected-files", G_BINDING_SYNC_CREATE); + } + + /* remember the setting */ + if (gtk_widget_get_visible (GTK_WIDGET (window))) + g_object_set (G_OBJECT (window->preferences), "last-side-pane", g_type_name (type), NULL); +} + + + +static void +thunar_window_menu_add_bookmarks (ThunarWindow *window, + GtkMenuShell *view_menu) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* in order to pass the view_menu into the callback */ + window->view_menu = view_menu; + + /* load bookmark menu items from bookmark file */ + thunar_util_load_bookmarks (window->bookmark_file, + thunar_window_bookmark_add_menu_item, + window); + window->view_menu = NULL; +} + + + +static void +thunar_window_bookmark_add_menu_item (GFile *g_file, + const gchar *name, + gint line_num, + gpointer user_data) +{ + ThunarWindow *window = THUNAR_WINDOW (user_data); + ThunarFile *thunar_file; + gchar *parse_name; + gchar *accel_path; + gchar *tooltip; + gchar *remote_name = NULL; + GtkIconTheme *icon_theme; + const gchar *icon_name; + GtkWidget *menu_item; + + _thunar_return_if_fail (G_IS_FILE (g_file)); + _thunar_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL)); + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + accel_path = thunar_window_bookmark_get_accel_path (g_file); + parse_name = g_file_get_parse_name (g_file); + tooltip = g_strdup_printf (_("Open the location \"%s\""), parse_name); + g_free (parse_name); + + icon_theme = gtk_icon_theme_get_for_screen (gtk_window_get_screen (GTK_WINDOW (window))); + + if (g_file_has_uri_scheme (g_file, "file")) + { + /* try to open the file corresponding to the uri */ + thunar_file = thunar_file_get (g_file, NULL); + if (G_LIKELY (thunar_file != NULL)) + { + /* make sure the file refers to a directory */ + if (G_UNLIKELY (thunar_file_is_directory (thunar_file))) + { + if (name == NULL) + name = thunar_file_get_display_name (thunar_file); + + icon_name = thunar_file_get_icon_name (thunar_file, THUNAR_FILE_ICON_STATE_DEFAULT, icon_theme); + menu_item = xfce_gtk_image_menu_item_new_from_icon_name (name, tooltip, accel_path, NULL, NULL, icon_name, window->view_menu); + g_signal_connect_swapped (G_OBJECT (menu_item), "activate", G_CALLBACK (thunar_window_action_open_bookmark), G_OBJECT (window)); + g_object_set_data_full (G_OBJECT (menu_item), I_("g-file"), g_object_ref(g_file), g_object_unref); + } + g_object_unref (thunar_file); + } + } + else + { + if (name == NULL) + { + remote_name = thunar_g_file_get_display_name_remote (g_file); + name = remote_name; + } + menu_item = xfce_gtk_image_menu_item_new_from_icon_name (name, tooltip, accel_path, NULL, NULL, "folder-remote", window->view_menu); + g_signal_connect_swapped (G_OBJECT (menu_item), "activate", G_CALLBACK (thunar_window_action_open_bookmark), G_OBJECT (window)); + g_object_set_data_full (G_OBJECT (menu_item), I_("g-file"), g_object_ref (g_file), g_object_unref); + g_free (remote_name); + } + + g_free (tooltip); + g_free (accel_path); +} + + + +static void +thunar_window_open_or_launch (ThunarWindow *window, + ThunarFile *file) +{ + GError *error = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + if (thunar_file_is_directory (file)) + { + /* open the new directory */ + thunar_window_set_current_directory (window, file); + } + else + { + /* try to launch the selected file */ + if (!thunar_file_launch (file, window, NULL, &error)) + { + thunar_dialogs_show_error (window, error, _("Failed to launch \"%s\""), + thunar_file_get_display_name (file)); + g_error_free (error); + } + } +} + + + +static void +thunar_window_poke_file_finish (ThunarBrowser *browser, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer ignored) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + if (error == NULL) + { + thunar_window_open_or_launch (THUNAR_WINDOW (browser), target_file); + } + else + { + thunar_dialogs_show_error (GTK_WIDGET (browser), error, + _("Failed to open \"%s\""), + thunar_file_get_display_name (file)); + } +} + + + +static void +thunar_window_start_open_location (ThunarWindow *window, + const gchar *initial_text) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* temporary show the location toolbar, even if it is normally hidden */ + gtk_widget_show (window->location_toolbar); + thunar_location_bar_request_entry (THUNAR_LOCATION_BAR (window->location_bar), initial_text); +} + + + +static void +thunar_window_action_open_new_tab (ThunarWindow *window, + GtkWidget *menu_item) +{ + /* insert new tab with current directory as default */ + thunar_window_notebook_insert (window, thunar_window_get_current_directory (window)); +} + + + +static void +thunar_window_action_open_new_window (ThunarWindow *window, + GtkWidget *menu_item) +{ + ThunarApplication *application; + ThunarHistory *history; + ThunarWindow *new_window; + ThunarFile *start_file; + + /* popup a new window */ + application = thunar_application_get (); + new_window = THUNAR_WINDOW (thunar_application_open_window (application, window->current_directory, + gtk_widget_get_screen (GTK_WIDGET (window)), NULL, TRUE)); + g_object_unref (G_OBJECT (application)); + + /* if we have no origin view we are done */ + if (window->view == NULL) + return; + + /* let the view of the new window inherit the history of the origin view */ + history = thunar_standard_view_copy_history (THUNAR_STANDARD_VIEW (window->view)); + if (history != NULL) + { + thunar_standard_view_set_history (THUNAR_STANDARD_VIEW (new_window->view), history); + thunar_window_history_changed (new_window); + + /* connect to the new history */ + window->signal_handler_id_history_changed = g_signal_connect_swapped (G_OBJECT (history), "history-changed", G_CALLBACK (thunar_window_history_changed), new_window); + } + + /* determine the first visible file in the current window */ + if (thunar_view_get_visible_range (THUNAR_VIEW (window->view), &start_file, NULL)) + { + /* scroll the new window to the same file */ + thunar_window_scroll_to_file (new_window, start_file, FALSE, TRUE, 0.1f, 0.1f); + + /* release the file reference */ + g_object_unref (G_OBJECT (start_file)); + } +} + + + +static void +thunar_window_action_detach_tab (ThunarWindow *window, + GtkWidget *menu_item) +{ + GtkWidget *notebook; + GtkWidget *label; + GtkWidget *view = window->view; + + _thunar_return_if_fail (THUNAR_IS_VIEW (view)); + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* create a new window */ + notebook = thunar_window_notebook_create_window (window->notebook, view, -1, -1, window); + if (notebook == NULL) + return; + + /* get the current label */ + label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (window->notebook), view); + _thunar_return_if_fail (GTK_IS_WIDGET (label)); + + /* ref object so they don't destroy when removed from the container */ + g_object_ref (label); + g_object_ref (view); + + /* remove view from the current notebook */ + gtk_container_remove (GTK_CONTAINER (window->notebook), view); + + /* insert in the new notebook */ + gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), view, label, 0); + + /* set tab child properties */ + gtk_container_child_set (GTK_CONTAINER (notebook), view, "tab-expand", TRUE, NULL); + gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (notebook), view, TRUE); + gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (notebook), view, TRUE); + + /* release */ + g_object_unref (label); + g_object_unref (view); +} + + + +static void +thunar_window_action_close_all_windows (ThunarWindow *window, + GtkWidget *menu_item) +{ + ThunarApplication *application; + GList *windows; + + /* query the list of currently open windows */ + application = thunar_application_get (); + windows = thunar_application_get_windows (application); + g_object_unref (G_OBJECT (application)); + + /* destroy all open windows */ + g_list_free_full (windows, (GDestroyNotify) gtk_widget_destroy); +} + + + +static void +thunar_window_action_close_tab (ThunarWindow *window, + GtkWidget *menu_item) +{ + if (window->view != NULL) + gtk_widget_destroy (window->view); +} + + + +static void +thunar_window_action_close_window (ThunarWindow *window, + GtkWidget *menu_item) +{ + gtk_widget_destroy (GTK_WIDGET (window)); +} + + + +static void +thunar_window_action_preferences (ThunarWindow *window, + GtkWidget *menu_item) +{ + GtkWidget *dialog; + ThunarApplication *application; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* allocate and display a preferences dialog */; + dialog = thunar_preferences_dialog_new (GTK_WINDOW (window)); + gtk_widget_show (dialog); + + /* ...and let the application take care of it */ + application = thunar_application_get (); + thunar_application_take_window (application, GTK_WINDOW (dialog)); + g_object_unref (G_OBJECT (application)); +} + + + +static void +thunar_window_action_reload (ThunarWindow *window, + GtkWidget *menu_item) +{ + gboolean result; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* force the view to reload */ + g_signal_emit (G_OBJECT (window), window_signals[RELOAD], 0, TRUE, &result); + + /* update the location bar to show the current directory */ + if (window->location_bar != NULL) + g_object_notify (G_OBJECT (window->location_bar), "current-directory"); +} + + + +static void +thunar_window_action_pathbar_changed (ThunarWindow *window) +{ + gchar *last_location_bar; + gboolean pathbar_checked; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); + pathbar_checked = exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_ENTRY)); + g_free (last_location_bar); + + if (pathbar_checked) + g_object_set (window->preferences, "last-location-bar", g_type_name (G_TYPE_NONE), NULL); + else + g_object_set (window->preferences, "last-location-bar", g_type_name (THUNAR_TYPE_LOCATION_ENTRY), NULL); +} + + + +static void +thunar_window_action_toolbar_changed (ThunarWindow *window) +{ + gchar *last_location_bar; + gboolean toolbar_checked; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + g_object_get (window->preferences, "last-location-bar", &last_location_bar, NULL); + toolbar_checked = exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_BUTTONS)); + g_free (last_location_bar); + + if (toolbar_checked) + g_object_set (window->preferences, "last-location-bar", g_type_name (G_TYPE_NONE), NULL); + else + g_object_set (window->preferences, "last-location-bar", g_type_name (THUNAR_TYPE_LOCATION_BUTTONS), NULL); +} + + + +static void +thunar_window_action_shortcuts_changed (ThunarWindow *window) +{ + gchar *last_side_pane; + gboolean shortcuts_checked; + GType type = G_TYPE_NONE; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + g_object_get (window->preferences, "last-side-pane", &last_side_pane, NULL); + shortcuts_checked = exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_SHORTCUTS_PANE)); + g_free (last_side_pane); + + if (shortcuts_checked) + type = G_TYPE_NONE; + else + type = THUNAR_TYPE_SHORTCUTS_PANE; + + thunar_window_install_sidepane (window, type); +} + + + +static void +thunar_window_action_tree_changed (ThunarWindow *window) +{ + gchar *last_side_pane; + gboolean tree_view_checked; + GType type = G_TYPE_NONE; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + g_object_get (window->preferences, "last-side-pane", &last_side_pane, NULL); + tree_view_checked = exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_TREE_PANE)); + g_free (last_side_pane); + + if (tree_view_checked) + type = G_TYPE_NONE; + else + type = THUNAR_TYPE_TREE_PANE; + + thunar_window_install_sidepane (window, type); +} + + + +static void +thunar_window_action_statusbar_changed (ThunarWindow *window) +{ + gboolean last_statusbar_visible; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + g_object_get (window->preferences, "last-statusbar-visible", &last_statusbar_visible, NULL); + + gtk_widget_set_visible (window->statusbar, !last_statusbar_visible); + + g_object_set (G_OBJECT (window->preferences), "last-statusbar-visible", !last_statusbar_visible, NULL); +} + + + +static void +thunar_window_action_menubar_changed (ThunarWindow *window) +{ + gboolean last_menubar_visible; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + g_object_get (window->preferences, "last-menubar-visible", &last_menubar_visible, NULL); + + gtk_widget_set_visible (window->menubar, !last_menubar_visible); + + g_object_set (G_OBJECT (window->preferences), "last-menubar-visible", !last_menubar_visible, NULL); +} + + + +static void +thunar_window_action_detailed_view (ThunarWindow *window) +{ + thunar_window_action_view_changed (window, THUNAR_TYPE_DETAILS_VIEW); +} + + + +static void +thunar_window_action_icon_view (ThunarWindow *window) +{ + thunar_window_action_view_changed (window, THUNAR_TYPE_ICON_VIEW); +} + + + +static void +thunar_window_action_compact_view (ThunarWindow *window) +{ + thunar_window_action_view_changed (window, THUNAR_TYPE_COMPACT_VIEW); +} + + + +static void +thunar_window_action_view_changed (ThunarWindow *window, + GType view_type) +{ + ThunarFile *file = NULL; + ThunarFile *current_directory = NULL; + GtkWidget *old_view; + ThunarHistory *history; + GList *selected_files = NULL; + + /* drop the previous view (if any) */ + old_view = window->view; + if (G_LIKELY (window->view != NULL)) + { + if (window->signal_handler_id_history_changed != 0) + { + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + g_signal_handler_disconnect (history, window->signal_handler_id_history_changed); + window->signal_handler_id_history_changed = 0; + } + + /* get first visible file in the previous view */ + if (!thunar_view_get_visible_range (THUNAR_VIEW (window->view), &file, NULL)) + file = NULL; + + /* store the active directory */ + current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (window->view)); + if (current_directory != NULL) + g_object_ref (current_directory); + + /* remember the file selection */ + selected_files = thunar_g_file_list_copy (thunar_component_get_selected_files (THUNAR_COMPONENT (old_view))); + } + window->view_type = view_type; + + /* always open a new directory */ + if (current_directory == NULL && window->current_directory != NULL) + current_directory = g_object_ref (window->current_directory); + + /* allocate a new view of the requested type */ + if (G_LIKELY (window->view_type != G_TYPE_NONE)) + { + /* create new page */ + if (current_directory != NULL) + thunar_window_notebook_insert (window, current_directory); + + /* scroll to the previously visible file in the old view */ + if (G_UNLIKELY (file != NULL)) + thunar_view_scroll_to_file (THUNAR_VIEW (window->view), file, FALSE, TRUE, 0.0f, 0.0f); + } + else + { + /* this should not happen under normal conditions */ + window->view = NULL; + } + + /* destroy the old view */ + if (old_view != NULL) + gtk_widget_destroy (old_view); + + /* restore the file selection */ + thunar_component_set_selected_files (THUNAR_COMPONENT (window->view), selected_files); + thunar_g_file_list_free (selected_files); + + /* remember the setting */ + if (gtk_widget_get_visible (GTK_WIDGET (window)) && window->view_type != G_TYPE_NONE) + g_object_set (G_OBJECT (window->preferences), "last-view", g_type_name (window->view_type), NULL); + + /* release the file references */ + if (G_UNLIKELY (file != NULL)) + g_object_unref (G_OBJECT (file)); + if (G_UNLIKELY (current_directory != NULL)) + g_object_unref (G_OBJECT (current_directory)); + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + window->signal_handler_id_history_changed = g_signal_connect_swapped (G_OBJECT (history), "history-changed", G_CALLBACK (thunar_window_history_changed), window); +} + + + +static void +thunar_window_action_go_up (ThunarWindow *window) +{ + ThunarFile *parent; + GError *error = NULL; + + parent = thunar_file_get_parent (window->current_directory, &error); + if (G_LIKELY (parent != NULL)) + { + thunar_window_set_current_directory (window, parent); + g_object_unref (G_OBJECT (parent)); + } + else + { + thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open parent folder")); + g_error_free (error); + } +} + + + +static void +thunar_window_action_back (ThunarWindow *window) +{ + ThunarHistory *history; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + thunar_history_action_back (history); +} + + + +static void +thunar_window_action_forward (ThunarWindow *window) +{ + ThunarHistory *history; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + thunar_history_action_forward (history); +} + + + +static void +thunar_window_action_open_home (ThunarWindow *window) +{ + GFile *home; + ThunarFile *home_file; + GError *error = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* determine the path to the home directory */ + home = thunar_g_file_new_for_home (); + + /* determine the file for the home directory */ + home_file = thunar_file_get (home, &error); + if (G_UNLIKELY (home_file == NULL)) + { + /* display an error to the user */ + thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open the home folder")); + g_error_free (error); + } + else + { + /* open the home folder */ + thunar_window_set_current_directory (window, home_file); + g_object_unref (G_OBJECT (home_file)); + } + + /* release our reference on the home path */ + g_object_unref (home); +} + + + +static gboolean +thunar_window_open_user_folder (ThunarWindow *window, + GUserDirectory thunar_user_dir, + const gchar *default_name) +{ + ThunarFile *user_file = NULL; + gboolean result = FALSE; + GError *error = NULL; + GFile *home_dir; + GFile *user_dir; + const gchar *path; + gint response; + GtkWidget *dialog; + gchar *parse_name; + + path = g_get_user_special_dir (thunar_user_dir); + home_dir = thunar_g_file_new_for_home (); + + /* check if there is an entry in user-dirs.dirs */ + path = g_get_user_special_dir (thunar_user_dir); + if (G_LIKELY (path != NULL)) + { + user_dir = g_file_new_for_path (path); + + /* if equal to home, leave */ + if (g_file_equal (user_dir, home_dir)) + goto is_homedir; + } + else + { + /* build a name */ + user_dir = g_file_resolve_relative_path (home_dir, default_name); + } + + /* try to load the user dir */ + user_file = thunar_file_get (user_dir, NULL); + + /* check if the directory exists */ + if (G_UNLIKELY (user_file == NULL || !thunar_file_exists (user_file))) + { + /* release the instance if it does not exist */ + if (user_file != NULL) + { + g_object_unref (user_file); + user_file = NULL; + } + + /* ask the user to create the directory */ + parse_name = g_file_get_parse_name (user_dir); + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("The directory \"%s\" does not exist. Do you want to create it?"), + parse_name); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_free (parse_name); + + if (response == GTK_RESPONSE_YES + && g_file_make_directory_with_parents (user_dir, NULL, &error)) + { + /* try again */ + user_file = thunar_file_get (user_dir, &error); + } + } + + if (G_LIKELY (user_file != NULL)) + { + /* open the folder */ + thunar_window_set_current_directory (window, user_file); + g_object_unref (G_OBJECT (user_file)); + result = TRUE; + } + else if (error != NULL) + { + parse_name = g_file_get_parse_name (user_dir); + thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open directory \"%s\""), parse_name); + g_free (parse_name); + g_error_free (error); + } + + is_homedir: + + g_object_unref (user_dir); + g_object_unref (home_dir); + + return result; +} + + + +static void +thunar_window_action_open_desktop (ThunarWindow *window) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + thunar_window_open_user_folder (window, G_USER_DIRECTORY_DESKTOP, "Desktop"); +} + + + +static void +thunar_window_action_open_computer (ThunarWindow *window) +{ + GFile *computer; + ThunarFile *computer_file; + GError *error = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* determine the computer location */ + computer = g_file_new_for_uri ("computer://"); + + /* determine the file for this location */ + computer_file = thunar_file_get (computer, &error); + if (G_UNLIKELY (computer_file == NULL)) + { + /* display an error to the user */ + thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to browse the computer")); + g_error_free (error); + } + else + { + /* open the computer location */ + thunar_window_set_current_directory (window, computer_file); + g_object_unref (G_OBJECT (computer_file)); + } + + /* release our reference on the location itself */ + g_object_unref (computer); +} + + + +static void +thunar_window_action_open_templates (ThunarWindow *window) +{ + GtkWidget *dialog; + GtkWidget *button; + GtkWidget *label; + GtkWidget *image; + GtkWidget *hbox; + GtkWidget *vbox; + gboolean show_about_templates; + gboolean success; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + success = thunar_window_open_user_folder (window, G_USER_DIRECTORY_TEMPLATES, "Templates"); + + /* check whether we should display the "About Templates" dialog */ + g_object_get (G_OBJECT (window->preferences), + "misc-show-about-templates", &show_about_templates, + NULL); + + if (G_UNLIKELY(show_about_templates && success)) + { + /* display the "About Templates" dialog */ + dialog = gtk_dialog_new_with_buttons (_("About Templates"), GTK_WINDOW (window), + GTK_DIALOG_DESTROY_WITH_PARENT, + _("_OK"), GTK_RESPONSE_OK, + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 8); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + image = gtk_image_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_DIALOG); + gtk_widget_set_halign (image, GTK_ALIGN_CENTER); + gtk_widget_set_valign (image, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + gtk_widget_show (image); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 18); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show (vbox); + + label = gtk_label_new (_("All files in this folder will appear in the \"Create Document\" menu.")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_big_bold ()); + gtk_label_set_line_wrap (GTK_LABEL (label), FALSE); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + label = gtk_label_new (_("If you frequently create certain kinds " + " of documents, make a copy of one and put it in this " + "folder. Thunar will add an entry for this document in the" + " \"Create Document\" menu.\n\n" + "You can then select the entry from the \"Create Document\" " + "menu and a copy of the document will be created in the " + "directory you are viewing.")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0f); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); + gtk_widget_show (label); + + button = gtk_check_button_new_with_mnemonic (_("Do _not display this message again")); + exo_mutual_binding_new_with_negation (G_OBJECT (window->preferences), "misc-show-about-templates", G_OBJECT (button), "active"); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + gtk_window_set_default_size (GTK_WINDOW (dialog), 600, -1); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } +} + + + +static void +thunar_window_action_open_file_system (ThunarWindow *window) +{ + GFile *root; + ThunarFile *root_file; + GError *error = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* determine the path to the root directory */ + root = thunar_g_file_new_for_root (); + + /* determine the file for the root directory */ + root_file = thunar_file_get (root, &error); + if (G_UNLIKELY (root_file == NULL)) + { + /* display an error to the user */ + thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open the file system root folder")); + g_error_free (error); + } + else + { + /* open the root folder */ + thunar_window_set_current_directory (window, root_file); + g_object_unref (G_OBJECT (root_file)); + } + + /* release our reference on the home path */ + g_object_unref (root); +} + + + +static void +thunar_window_action_open_trash (ThunarWindow *window) +{ + GFile *trash_bin; + ThunarFile *trash_bin_file; + GError *error = NULL; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* determine the path to the trash bin */ + trash_bin = thunar_g_file_new_for_trash (); + + /* determine the file for the trash bin */ + trash_bin_file = thunar_file_get (trash_bin, &error); + if (G_UNLIKELY (trash_bin_file == NULL)) + { + /* display an error to the user */ + thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to display the contents of the trash can")); + g_error_free (error); + } + else + { + /* open the trash folder */ + thunar_window_set_current_directory (window, trash_bin_file); + g_object_unref (G_OBJECT (trash_bin_file)); + } + + /* release our reference on the trash bin path */ + g_object_unref (trash_bin); +} + + + +static void +thunar_window_action_open_network (ThunarWindow *window) +{ + ThunarFile *network_file; + GError *error = NULL; + GFile *network; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* determine the network root location */ + network = g_file_new_for_uri ("network://"); + + /* determine the file for this location */ + network_file = thunar_file_get (network, &error); + if (G_UNLIKELY (network_file == NULL)) + { + /* display an error to the user */ + thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to browse the network")); + g_error_free (error); + } + else + { + /* open the network root location */ + thunar_window_set_current_directory (window, network_file); + g_object_unref (G_OBJECT (network_file)); + } + + /* release our reference on the location itself */ + g_object_unref (network); +} + + + +static gboolean +thunar_window_propagate_key_event (GtkWindow* window, + GdkEvent *key_event, + gpointer user_data) +{ + GtkWidget* focused_widget; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), GDK_EVENT_PROPAGATE); + + focused_widget = gtk_window_get_focus (window); + + /* Turn the accelerator priority around globally, + * so that the focused widget always gets the accels first. + * Implementing this cleanly while maintaining some wanted accels + * (like Ctrl+N and exo accels) is a lot of work. So we resort to + * only priorize GtkEditable, because that is the easiest way to + * fix the right-ahead problem. */ + if (focused_widget != NULL && GTK_IS_EDITABLE (focused_widget)) + return gtk_window_propagate_key_event (window, (GdkEventKey *) key_event); + + return GDK_EVENT_PROPAGATE; +} + + + +static void +thunar_window_poke_location_finish (ThunarBrowser *browser, + GFile *location, + ThunarFile *file, + ThunarFile *target_file, + GError *error, + gpointer ignored) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (browser)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + thunar_window_poke_file_finish (browser, file, target_file, error, ignored); +} + + + +static void +thunar_window_action_open_bookmark (ThunarWindow *window, + GtkWidget *menu_item) +{ + GFile *bookmark_location; + + bookmark_location = g_object_get_data (G_OBJECT (menu_item), I_("g-file")); + thunar_window_set_current_directory_gfile (THUNAR_WINDOW (window), bookmark_location); +} + + + +static void +thunar_window_action_open_location (ThunarWindow *window) +{ + /* just use the "start-open-location" callback */ + thunar_window_start_open_location (window, NULL); +} + + + +static void +thunar_window_action_contents (ThunarWindow *window) +{ + /* display the documentation index */ + xfce_dialog_show_help (GTK_WINDOW (window), "thunar", NULL, NULL); +} + + + +static void +thunar_window_action_about (ThunarWindow *window) +{ + /* just popup the about dialog */ + thunar_dialogs_show_about (GTK_WINDOW (window), PACKAGE_NAME, + _("Thunar is a fast and easy to use file manager\n" + "for the Xfce Desktop Environment.")); +} + + + +static void +thunar_window_action_show_hidden (ThunarWindow *window) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + window->show_hidden = !window->show_hidden; + gtk_container_foreach (GTK_CONTAINER (window->notebook), (GtkCallback) (void (*)(void)) thunar_view_set_show_hidden, GINT_TO_POINTER (window->show_hidden)); + thunar_side_pane_set_show_hidden (THUNAR_SIDE_PANE (window->sidepane), window->show_hidden); + + g_object_set (G_OBJECT (window->preferences), "last-show-hidden", window->show_hidden, NULL); + +} + + + +static void +thunar_window_action_open_file_menu (ThunarWindow *window) +{ + GtkWidget *file_menu; + gboolean ret; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + file_menu = gtk_container_get_children (GTK_CONTAINER (window->menubar))->data; + g_signal_emit_by_name (file_menu, "button-press-event", NULL, &ret); + gtk_menu_shell_select_first (GTK_MENU_SHELL (window->menubar), TRUE); +} + + + +static void +thunar_window_current_directory_changed (ThunarFile *current_directory, + ThunarWindow *window) +{ + gboolean show_full_path; + gchar *parse_name = NULL; + const gchar *name; + gboolean ret; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (THUNAR_IS_FILE (current_directory)); + _thunar_return_if_fail (window->current_directory == current_directory); + + /* get name of directory or full path */ + g_object_get (G_OBJECT (window->preferences), "misc-full-path-in-title", &show_full_path, NULL); + if (G_UNLIKELY (show_full_path)) + name = parse_name = g_file_get_parse_name (thunar_file_get_file (current_directory)); + else + name = thunar_file_get_display_name (current_directory); + + /* set window title */ + gtk_window_set_title (GTK_WINDOW (window), name); + g_free (parse_name); + + /* set window icon */ + thunar_window_update_window_icon (window); + + /* update the window menu. E.g. relevant for functional shortcuts after startup, + * and for keyboard navigation in the window menu */ + for (GList *lp = gtk_container_get_children (GTK_CONTAINER (window->menubar)); lp != NULL; lp = lp->next) + g_signal_emit_by_name (lp->data, "button-press-event", NULL, &ret); +} + + + +static void +thunar_window_menu_item_selected (ThunarWindow *window, + GtkWidget *menu_item) +{ + gchar *tooltip; + gint id; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* we can only display tooltips if we have a statusbar */ + if (G_LIKELY (window->statusbar != NULL)) + { + tooltip = gtk_widget_get_tooltip_text (menu_item); + if (G_LIKELY (tooltip != NULL)) + { + /* push to the statusbar */ + id = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->statusbar), "Menu tooltip"); + gtk_statusbar_push (GTK_STATUSBAR (window->statusbar), id, tooltip); + g_free (tooltip); + } + } +} + + + +static void +thunar_window_menu_item_deselected (ThunarWindow *window, + GtkWidget *menu_item) +{ + gint id; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* we can only undisplay tooltips if we have a statusbar */ + if (G_LIKELY (window->statusbar != NULL)) + { + /* drop the last tooltip from the statusbar */ + id = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->statusbar), "Menu tooltip"); + gtk_statusbar_pop (GTK_STATUSBAR (window->statusbar), id); + } +} + + + +static void +thunar_window_notify_loading (ThunarView *view, + GParamSpec *pspec, + ThunarWindow *window) +{ + GdkCursor *cursor; + + _thunar_return_if_fail (THUNAR_IS_VIEW (view)); + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + if (gtk_widget_get_realized (GTK_WIDGET (window)) + && window->view == GTK_WIDGET (view)) + { + /* setup the proper cursor */ + if (thunar_view_get_loading (view)) + { + cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (view)), GDK_WATCH); + gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), cursor); + g_object_unref (cursor); + } + else + { + gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), NULL); + } + } +} + + + +static void +thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor, + ThunarDevice *device, + GFile *root_file, + ThunarWindow *window) +{ + _thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (device_monitor)); + _thunar_return_if_fail (window->device_monitor == device_monitor); + _thunar_return_if_fail (THUNAR_IS_DEVICE (device)); + _thunar_return_if_fail (G_IS_FILE (root_file)); + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* nothing to do if we don't have a current directory */ + if (G_UNLIKELY (window->current_directory == NULL)) + return; + + /* check if the file is the current directory or an ancestor of the current directory */ + if (g_file_equal (thunar_file_get_file (window->current_directory), root_file) + || thunar_file_is_gfile_ancestor (window->current_directory, root_file)) + { + /* change to the home folder */ + thunar_window_action_open_home (window); + } +} + + + +static void +thunar_window_device_changed (ThunarDeviceMonitor *device_monitor, + ThunarDevice *device, + ThunarWindow *window) +{ + GFile *root_file; + + _thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (device_monitor)); + _thunar_return_if_fail (window->device_monitor == device_monitor); + _thunar_return_if_fail (THUNAR_IS_DEVICE (device)); + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + if (thunar_device_is_mounted (device)) + return; + + root_file = thunar_device_get_root (device); + if (root_file != NULL) + { + thunar_window_device_pre_unmount (device_monitor, device, root_file, window); + g_object_unref (root_file); + } +} + + + +static gboolean +thunar_window_save_paned (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + + g_object_set (G_OBJECT (window->preferences), "last-separator-position", + gtk_paned_get_position (GTK_PANED (window->paned)), NULL); + + /* for button release event */ + return FALSE; +} + + + +static gboolean +thunar_window_save_geometry_timer (gpointer user_data) +{ + GdkWindowState state; + ThunarWindow *window = THUNAR_WINDOW (user_data); + gboolean remember_geometry; + gint width; + gint height; + +THUNAR_THREADS_ENTER + + /* check if we should remember the window geometry */ + g_object_get (G_OBJECT (window->preferences), "misc-remember-geometry", &remember_geometry, NULL); + if (G_LIKELY (remember_geometry)) + { + /* check if the window is still visible */ + if (gtk_widget_get_visible (GTK_WIDGET (window))) + { + /* determine the current state of the window */ + state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window))); + + /* don't save geometry for maximized or fullscreen windows */ + if ((state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0) + { + /* determine the current width/height of the window... */ + gtk_window_get_size (GTK_WINDOW (window), &width, &height); + + /* ...and remember them as default for new windows */ + g_object_set (G_OBJECT (window->preferences), "last-window-width", width, "last-window-height", height, + "last-window-maximized", FALSE, NULL); + } + else + { + /* only store that the window is full screen */ + g_object_set (G_OBJECT (window->preferences), "last-window-maximized", TRUE, NULL); + } + } + } + +THUNAR_THREADS_LEAVE + + return FALSE; +} + + + +static void +thunar_window_save_geometry_timer_destroy (gpointer user_data) +{ + THUNAR_WINDOW (user_data)->save_geometry_timer_id = 0; +} + + + +/** + * thunar_window_set_zoom_level: + * @window : a #ThunarWindow instance. + * @zoom_level : the new zoom level for @window. + * + * Sets the zoom level for @window to @zoom_level. + **/ +void +thunar_window_set_zoom_level (ThunarWindow *window, + ThunarZoomLevel zoom_level) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (zoom_level < THUNAR_ZOOM_N_LEVELS); + + /* check if we have a new zoom level */ + if (G_LIKELY (window->zoom_level != zoom_level)) + { + /* remember the new zoom level */ + window->zoom_level = zoom_level; + + /* notify listeners */ + g_object_notify (G_OBJECT (window), "zoom-level"); + } +} + + + +/** + * thunar_window_get_current_directory: + * @window : a #ThunarWindow instance. + * + * Queries the #ThunarFile instance, which represents the directory + * currently displayed within @window. %NULL is returned if @window + * is not currently associated with any directory. + * + * Return value: the directory currently displayed within @window or %NULL. + **/ +ThunarFile* +thunar_window_get_current_directory (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL); + return window->current_directory; +} + + + +/** + * thunar_window_set_current_directory: + * @window : a #ThunarWindow instance. + * @current_directory : the new directory or %NULL. + **/ +void +thunar_window_set_current_directory (ThunarWindow *window, + ThunarFile *current_directory) +{ + GType type; + gchar *type_name; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory)); + + /* check if we already display the requested directory */ + if (G_UNLIKELY (window->current_directory == current_directory)) + return; + + /* disconnect from the previously active directory */ + if (G_LIKELY (window->current_directory != NULL)) + { + /* disconnect signals and release reference */ + g_signal_handlers_disconnect_by_func (G_OBJECT (window->current_directory), thunar_window_current_directory_changed, window); + g_object_unref (G_OBJECT (window->current_directory)); + } + + /* activate the new directory */ + window->current_directory = current_directory; + + /* connect to the new directory */ + if (G_LIKELY (current_directory != NULL)) + { + /* take a reference on the file and connect the "changed"/"destroy" signals */ + g_signal_connect (G_OBJECT (current_directory), "changed", G_CALLBACK (thunar_window_current_directory_changed), window); + g_object_ref (G_OBJECT (current_directory)); + + /* create a new view if the window is new */ + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) == 0) + { + /* determine the default view */ + g_object_get (G_OBJECT (window->preferences), "default-view", &type_name, NULL); + type = g_type_from_name (type_name); + g_free (type_name); + + /* determine the last selected view if the last selected view preference is not selected */ + if (g_type_is_a (type, G_TYPE_NONE) || g_type_is_a (type, G_TYPE_INVALID)) + { + g_object_get (G_OBJECT (window->preferences), "last-view", &type_name, NULL); + type = g_type_from_name (type_name); + g_free (type_name); + } + + /* fallback, in case nothing was set */ + if (g_type_is_a (type, G_TYPE_NONE) || g_type_is_a (type, G_TYPE_INVALID)) + type = THUNAR_TYPE_ICON_VIEW; + + thunar_window_action_view_changed (window, type); + } + + /* update window icon and title */ + thunar_window_current_directory_changed (current_directory, window); + + if (G_LIKELY (window->view != NULL)) + { + /* grab the focus to the main view */ + gtk_widget_grab_focus (window->view); + } + + thunar_window_history_changed (window); + gtk_widget_set_sensitive (window->location_toolbar_item_parent, !thunar_g_file_is_root (thunar_file_get_file (current_directory))); + } + + /* tell everybody that we have a new "current-directory", + * we do this first so other widgets display the new + * state already while the folder view is loading. + */ + g_object_notify (G_OBJECT (window), "current-directory"); +} + + + +static void +thunar_window_set_current_directory_gfile (ThunarWindow *window, + GFile *current_directory) +{ + ThunarFile *thunar_file; + + /* remote files possibly need to be poked first */ + if (g_file_has_uri_scheme (current_directory, "file")) + { + thunar_file = thunar_file_get (current_directory, NULL); + thunar_window_set_current_directory (THUNAR_WINDOW (window), thunar_file); + g_object_unref (thunar_file); + } + else + { + thunar_browser_poke_location (THUNAR_BROWSER (window), current_directory, THUNAR_WINDOW (window), + thunar_window_poke_location_finish, NULL); + } +} + + + +/** + * thunar_window_scroll_to_file: + * @window : a #ThunarWindow instance. + * @file : a #ThunarFile. + * @select_file : if %TRUE the @file will also be selected. + * @use_align : %TRUE to use the alignment arguments. + * @row_align : the vertical alignment. + * @col_align : the horizontal alignment. + * + * Tells the @window to scroll to the @file + * in the current view. + **/ +void +thunar_window_scroll_to_file (ThunarWindow *window, + ThunarFile *file, + gboolean select_file, + gboolean use_align, + gfloat row_align, + gfloat col_align) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (THUNAR_IS_FILE (file)); + + /* verify that we have a valid view */ + if (G_LIKELY (window->view != NULL)) + thunar_view_scroll_to_file (THUNAR_VIEW (window->view), file, select_file, use_align, row_align, col_align); +} + + + +gchar ** +thunar_window_get_directories (ThunarWindow *window, + gint *active_page) +{ + gint n; + gint n_pages; + gchar **uris; + GtkWidget *view; + ThunarFile *directory; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL); + + n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)); + if (G_UNLIKELY (n_pages == 0)) + return NULL; + + /* create array of uris */ + uris = g_new0 (gchar *, n_pages + 1); + for (n = 0; n < n_pages; n++) + { + /* get the view */ + view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), n); + _thunar_return_val_if_fail (THUNAR_IS_NAVIGATOR (view), FALSE); + + /* get the directory of the view */ + directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (view)); + _thunar_return_val_if_fail (THUNAR_IS_FILE (directory), FALSE); + + /* add to array */ + uris[n] = thunar_file_dup_uri (directory); + } + + /* selected tab */ + if (active_page != NULL) + *active_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)); + + return uris; +} + + + +gboolean +thunar_window_set_directories (ThunarWindow *window, + gchar **uris, + gint active_page) +{ + ThunarFile *directory; + guint n; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE); + _thunar_return_val_if_fail (uris != NULL, FALSE); + + for (n = 0; uris[n] != NULL; n++) + { + /* check if the string looks like an uri */ + if (!exo_str_looks_like_an_uri (uris[n])) + continue; + + /* get the file for the uri */ + directory = thunar_file_get_for_uri (uris[n], NULL); + if (G_UNLIKELY (directory == NULL)) + continue; + + /* open the directory in a new notebook */ + if (thunar_file_is_directory (directory)) + { + if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) == 0) + thunar_window_set_current_directory (window, directory); + else + thunar_window_notebook_insert (window, directory); + } + + g_object_unref (G_OBJECT (directory)); + } + + /* select the page */ + gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), active_page); + + /* we succeeded if new pages have been opened */ + return gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) > 0; +} + + + +/** + * thunar_window_get_action_entry: + * @window : Instance of a #ThunarWindow + * @action : #ThunarWindowAction for which the #XfceGtkActionEntry is requested + * + * returns a reference to the requested #XfceGtkActionEntry + * + * Return value: (transfer none): The reference to the #XfceGtkActionEntry + **/ +const XfceGtkActionEntry* +thunar_window_get_action_entry (ThunarWindow *window, + ThunarWindowAction action) +{ + return get_action_entry (action); +} + + + +/** + * thunar_window_append_menu_item: + * @window : Instance of a #ThunarWindow + * @menu : #GtkMenuShell to which the item should be added + * @action : #ThunarWindowAction to select which item should be added + * + * Adds the selected, widget specific #GtkMenuItem to the passed #GtkMenuShell + * + * Return value: (transfer none): The added #GtkMenuItem + **/ +void +thunar_window_append_menu_item (ThunarWindow *window, + GtkMenuShell *menu, + ThunarWindowAction action) +{ + GtkWidget *item; + + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + + item = xfce_gtk_menu_item_new_from_action_entry (get_action_entry (action), G_OBJECT (window), menu); + + if (action == THUNAR_WINDOW_ACTION_ZOOM_IN) + gtk_widget_set_sensitive (item, G_LIKELY (window->zoom_level < THUNAR_ZOOM_N_LEVELS - 1)); + if (action == THUNAR_WINDOW_ACTION_ZOOM_OUT) + gtk_widget_set_sensitive (item, G_LIKELY (window->zoom_level > 0)); +} + + + +/** + * thunar_window_get_launcher: + * @window : a #ThunarWindow instance. + * + * Return value: (transfer none): The single #ThunarLauncher of this #ThunarWindow + **/ +ThunarLauncher* +thunar_window_get_launcher (ThunarWindow *window) +{ + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL); + + return window->launcher; +} + + + +static void +thunar_window_redirect_menu_tooltips_to_statusbar_recursive (GtkWidget *menu_item, + ThunarWindow *window) +{ + GtkWidget *submenu; + + if (GTK_IS_MENU_ITEM (menu_item)) + { + submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item)); + if (submenu != NULL) + gtk_container_foreach (GTK_CONTAINER (submenu), (GtkCallback) (void (*)(void)) thunar_window_redirect_menu_tooltips_to_statusbar_recursive, window); + + /* this disables to show the tooltip on hover */ + gtk_widget_set_has_tooltip (menu_item, FALSE); + + /* These method will put the tooltip on the statusbar */ + g_signal_connect_swapped (G_OBJECT (menu_item), "select", G_CALLBACK (thunar_window_menu_item_selected), window); + g_signal_connect_swapped (G_OBJECT (menu_item), "deselect", G_CALLBACK (thunar_window_menu_item_deselected), window); + } +} + + + +/** + * thunar_window_redirect_menu_tooltips_to_statusbar: + * @window : a #ThunarWindow instance. + * @menu : #GtkMenu for which all tooltips should be shown in the statusbar + * + * All tooltips of the provided #GtkMenu and any submenu will not be shown directly any more. + * Instead they will be shown in the status bar of the passed #ThunarWindow + **/ +void +thunar_window_redirect_menu_tooltips_to_statusbar (ThunarWindow *window, GtkMenu *menu) +{ + _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); + _thunar_return_if_fail (GTK_IS_MENU (menu)); + + gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) (void (*)(void)) thunar_window_redirect_menu_tooltips_to_statusbar_recursive, window); +} + + + +static gboolean +thunar_window_history_clicked (GtkWidget *button, + GdkEventButton *event, + GtkWidget *data) +{ + ThunarHistory *history; + ThunarWindow *window; + + _thunar_return_val_if_fail (THUNAR_IS_WINDOW (data), FALSE); + + window = THUNAR_WINDOW (data); + + if (event->button == 3) + { + history = thunar_standard_view_get_history (THUNAR_STANDARD_VIEW (window->view)); + + if (button == window->location_toolbar_item_back) + thunar_history_show_menu (history, THUNAR_HISTORY_MENU_BACK, button); + else if (button == window->location_toolbar_item_forward) + thunar_history_show_menu (history, THUNAR_HISTORY_MENU_FORWARD, button); + else + g_warning ("This button is not able to spawn a history menu"); + } + + return FALSE; +} diff --git a/thunar/thunar-window.h b/thunar/thunar-window.h index 015525d1..5b595d6f 100644 --- a/thunar/thunar-window.h +++ b/thunar/thunar-window.h @@ -22,6 +22,9 @@ #include <thunar/thunar-enum-types.h> #include <thunar/thunar-folder.h> +#include <thunar/thunar-launcher.h> + +#include <libxfce4ui/libxfce4ui.h> G_BEGIN_DECLS; @@ -35,30 +38,90 @@ typedef struct _ThunarWindow ThunarWindow; #define THUNAR_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_WINDOW)) #define THUNAR_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_WINDOW, ThunarWindowClass)) -GType thunar_window_get_type (void) G_GNUC_CONST; - -ThunarFile *thunar_window_get_current_directory (ThunarWindow *window); -void thunar_window_set_current_directory (ThunarWindow *window, - ThunarFile *current_directory); - -void thunar_window_scroll_to_file (ThunarWindow *window, - ThunarFile *file, - gboolean select, - gboolean use_align, - gfloat row_align, - gfloat col_align); +/* #XfceGtkActionEntrys provided by this widget */ +typedef enum +{ + THUNAR_WINDOW_ACTION_FILE_MENU, + THUNAR_WINDOW_ACTION_NEW_TAB, + THUNAR_WINDOW_ACTION_NEW_WINDOW, + THUNAR_WINDOW_ACTION_DETACH_TAB, + THUNAR_WINDOW_ACTION_CLOSE_TAB, + THUNAR_WINDOW_ACTION_CLOSE_WINDOW, + THUNAR_WINDOW_ACTION_CLOSE_ALL_WINDOWS, + THUNAR_WINDOW_ACTION_EDIT_MENU, + THUNAR_WINDOW_ACTION_PREFERENCES, + THUNAR_WINDOW_ACTION_VIEW_MENU, + THUNAR_WINDOW_ACTION_RELOAD, + THUNAR_WINDOW_ACTION_RELOAD_ALT, + THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_MENU, + THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_PATHBAR, + THUNAR_WINDOW_ACTION_VIEW_LOCATION_SELECTOR_TOOLBAR, + THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_MENU, + THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_SHORTCUTS, + THUNAR_WINDOW_ACTION_VIEW_SIDE_PANE_TREE, + THUNAR_WINDOW_ACTION_TOGGLE_SIDE_PANE, + THUNAR_WINDOW_ACTION_VIEW_STATUSBAR, + THUNAR_WINDOW_ACTION_VIEW_MENUBAR, + THUNAR_WINDOW_ACTION_SHOW_HIDDEN, + THUNAR_WINDOW_ACTION_ZOOM_IN, + THUNAR_WINDOW_ACTION_ZOOM_IN_ALT, + THUNAR_WINDOW_ACTION_ZOOM_OUT, + THUNAR_WINDOW_ACTION_ZOOM_RESET, + THUNAR_WINDOW_ACTION_VIEW_AS_ICONS, + THUNAR_WINDOW_ACTION_VIEW_AS_DETAILED_LIST, + THUNAR_WINDOW_ACTION_VIEW_AS_COMPACT_LIST, + THUNAR_WINDOW_ACTION_GO_MENU, + THUNAR_WINDOW_ACTION_OPEN_PARENT, + THUNAR_WINDOW_ACTION_BACK, + THUNAR_WINDOW_ACTION_BACK_ALT, + THUNAR_WINDOW_ACTION_FORWARD, + THUNAR_WINDOW_ACTION_OPEN_FILE_SYSTEM, + THUNAR_WINDOW_ACTION_OPEN_HOME, + THUNAR_WINDOW_ACTION_OPEN_DESKTOP, + THUNAR_WINDOW_ACTION_OPEN_COMPUTER, + THUNAR_WINDOW_ACTION_OPEN_TRASH, + THUNAR_WINDOW_ACTION_OPEN_LOCATION, + THUNAR_WINDOW_ACTION_OPEN_LOCATION_ALT, + THUNAR_WINDOW_ACTION_OPEN_TEMPLATES, + THUNAR_WINDOW_ACTION_OPEN_NETWORK, + THUNAR_WINDOW_ACTION_HELP_MENU, + THUNAR_WINDOW_ACTION_CONTENTS, + THUNAR_WINDOW_ACTION_ABOUT, + THUNAR_WINDOW_ACTION_SWITCH_PREV_TAB, + THUNAR_WINDOW_ACTION_SWITCH_NEXT_TAB, -gchar **thunar_window_get_directories (ThunarWindow *window, - gint *active_page); -gboolean thunar_window_set_directories (ThunarWindow *window, - gchar **uris, - gint active_page); -void thunar_window_update_directories (ThunarWindow *window, - ThunarFile *old_directory, - ThunarFile *new_directory); -void thunar_window_notebook_insert (ThunarWindow *window, - ThunarFile *directory); +} ThunarWindowAction; +GType thunar_window_get_type (void) G_GNUC_CONST; +ThunarFile *thunar_window_get_current_directory (ThunarWindow *window); +void thunar_window_set_current_directory (ThunarWindow *window, + ThunarFile *current_directory); +void thunar_window_scroll_to_file (ThunarWindow *window, + ThunarFile *file, + gboolean select, + gboolean use_align, + gfloat row_align, + gfloat col_align); +gchar **thunar_window_get_directories (ThunarWindow *window, + gint *active_page); +gboolean thunar_window_set_directories (ThunarWindow *window, + gchar **uris, + gint active_page); +void thunar_window_update_directories (ThunarWindow *window, + ThunarFile *old_directory, + ThunarFile *new_directory); +void thunar_window_notebook_insert (ThunarWindow *window, + ThunarFile *directory); +gboolean thunar_window_has_shortcut_sidepane (ThunarWindow *window); +GtkWidget* thunar_window_get_sidepane (ThunarWindow *window); +void thunar_window_append_menu_item (ThunarWindow *window, + GtkMenuShell *menu, + ThunarWindowAction action); +ThunarLauncher* thunar_window_get_launcher (ThunarWindow *window); +void thunar_window_redirect_menu_tooltips_to_statusbar (ThunarWindow *window, + GtkMenu *menu); +const XfceGtkActionEntry* thunar_window_get_action_entry (ThunarWindow *window, + ThunarWindowAction action); G_END_DECLS; #endif /* !__THUNAR_WINDOW_H__ */ |