diff options
author | ZenWalker <[email protected]> | 2016-06-21 11:33:58 +0200 |
---|---|---|
committer | ZenWalker <[email protected]> | 2016-06-21 11:33:58 +0200 |
commit | bcee9bdc706d1cf65bf800c2bcc96b236dab6ec5 (patch) | |
tree | 49b2abd7fa9c6b8180fbe97d10fa620ca6f466ad | |
parent | e03db39aa221d404e14ee3cf1d282e8d2f362c2d (diff) | |
download | engrampa-bcee9bdc706d1cf65bf800c2bcc96b236dab6ec5.tar.bz2 engrampa-bcee9bdc706d1cf65bf800c2bcc96b236dab6ec5.tar.xz |
Use the Gtk+ app chooser dialog for the "Open With" command
file-roller commits:
https://git.gnome.org/browse/file-roller/commit/?id=d13a515c819c68051cd7788814dca7645d899511
https://git.gnome.org/browse/file-roller/commit/?id=9714c3a6a2c49f09d4c753b2573baf55aa3d6b9f
-rw-r--r-- | data/ui/Makefile.am | 7 | ||||
-rw-r--r-- | data/ui/open-with.ui | 245 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/dlg-open-with.c | 488 |
4 files changed, 50 insertions, 691 deletions
diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am index ecac3aa..09f9f79 100644 --- a/data/ui/Makefile.am +++ b/data/ui/Makefile.am @@ -1,13 +1,12 @@ uidir = $(datadir)/engrampa/ui ui_DATA = \ - add-options.ui \ + add-options.ui \ batch-add-files.ui \ batch-password.ui \ delete.ui \ - new.ui \ - open-with.ui \ + new.ui \ password.ui \ - properties.ui \ + properties.ui \ update.ui EXTRA_DIST = $(ui_DATA) diff --git a/data/ui/open-with.ui b/data/ui/open-with.ui deleted file mode 100644 index 0dd361b..0000000 --- a/data/ui/open-with.ui +++ /dev/null @@ -1,245 +0,0 @@ -<?xml version="1.0"?> -<interface> - <requires lib="gtk+" version="2.14"/> - <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkDialog" id="open_with_dialog"> - <property name="border_width">5</property> - <property name="title" translatable="yes">Open Files</property> - <property name="window_position">center-on-parent</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox13"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <object class="GtkVBox" id="vbox7"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="spacing">12</property> - <child> - <object class="GtkVBox" id="vbox16"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label42"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">A_vailable application:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">o_app_list_tree_view</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox25"> - <property name="visible">True</property> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow7"> - <property name="width_request">340</property> - <property name="height_request">120</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTreeView" id="o_app_list_tree_view"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - </object> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="vbox17"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label44"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">R_ecent applications:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">o_recent_tree_view</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox26"> - <property name="visible">True</property> - <child> - <object class="GtkVBox" id="vbox9"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow8"> - <property name="width_request">340</property> - <property name="height_request">120</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTreeView" id="o_recent_tree_view"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - </object> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox15"> - <property name="visible">True</property> - <child> - <object class="GtkButton" id="o_del_button"> - <property name="label">gtk-remove</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">0</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkHBox" id="hbox10"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <object class="GtkLabel" id="label24"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Application:</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">o_app_entry</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="o_app_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="activates_default">True</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area13"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="o_cancel_button"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="o_ok_button"> - <property name="label">gtk-open</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="0">o_cancel_button</action-widget> - <action-widget response="0">o_ok_button</action-widget> - </action-widgets> - </object> -</interface> diff --git a/po/POTFILES.in b/po/POTFILES.in index f52307e..c0786de 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -14,7 +14,6 @@ data/engrampa.desktop.in.in [type: gettext/glade]data/ui/batch-password.ui [type: gettext/glade]data/ui/delete.ui [type: gettext/glade]data/ui/new.ui -[type: gettext/glade]data/ui/open-with.ui [type: gettext/glade]data/ui/password.ui [type: gettext/glade]data/ui/properties.ui [type: gettext/glade]data/ui/update.ui diff --git a/src/dlg-open-with.c b/src/dlg-open-with.c index 3e90eb4..2bd5df9 100644 --- a/src/dlg-open-with.c +++ b/src/dlg-open-with.c @@ -32,466 +32,72 @@ #include "dlg-open-with.h" -#define TEMP_DOCS "temp_docs" - -enum { ICON_COLUMN, TEXT_COLUMN, DATA_COLUMN, N_COLUMNS }; - typedef struct { - FrWindow *window; - GSettings *settings; - GtkBuilder *builder; - - GtkWidget *dialog; - GtkWidget *o_app_tree_view; - GtkWidget *o_recent_tree_view; - GtkWidget *o_app_entry; - GtkWidget *o_del_button; - GtkWidget *ok_button; - - GList *app_list; - GList *file_list; - - GtkTreeModel *app_model; - GtkTreeModel *recent_model; - - GtkWidget *last_clicked_list; -} DialogData; - - -/* called when the main dialog is closed. */ -static void -open_with__destroy_cb (GtkWidget *widget, - DialogData *data) -{ - if (data->app_list != NULL) - g_list_free (data->app_list); - - if (data->file_list != NULL) - path_list_free (data->file_list); - g_object_unref (data->builder); - g_object_unref (data->settings); - g_free (data); -} - - -static void -open_cb (GtkWidget *widget, - gpointer callback_data) -{ - DialogData *data = callback_data; - const char *application; - gboolean present = FALSE; - char *command = NULL; - GList *scan; - char **editors; - int i; - - application = gtk_entry_get_text (GTK_ENTRY (data->o_app_entry)); - - for (scan = data->app_list; scan; scan = scan->next) { - GAppInfo *app = scan->data; - if (strcmp (g_app_info_get_executable (app), application) == 0) { - fr_window_open_files_with_application (data->window, data->file_list, app); - gtk_widget_destroy (data->dialog); - return; - } - } - - /* add the command to the editors list if not already present. */ - - editors = g_settings_get_strv (data->settings, PREF_GENERAL_EDITORS); - for (i = 0; ! present && editors[i] != NULL; i++) { - if (strcmp (editors[i], application) == 0) { - command = g_strdup (editors[i]); - present = TRUE; - } - } - - if (! present) { - char **new_editors; - - new_editors = _g_strv_prepend (editors, g_strdup (application)); - command = g_strdup (application); - g_settings_set_strv (data->settings, PREF_GENERAL_EDITORS, (const gchar * const *) new_editors); - - g_strfreev (new_editors); - } - - g_strfreev (editors); - - /* exec the application */ - - if (command != NULL) { - fr_window_open_files_with_command (data->window, data->file_list, command); - g_free (command); - } - - gtk_widget_destroy (data->dialog); -} - - -static void -app_list_selection_changed_cb (GtkTreeSelection *selection, - gpointer p) -{ - DialogData *data = p; - GtkTreeIter iter; - GAppInfo *app; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->o_app_tree_view)); - if (selection == NULL) - return; - - if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) - return; - - gtk_tree_model_get (data->app_model, &iter, - DATA_COLUMN, &app, - -1); - _gtk_entry_set_locale_text (GTK_ENTRY (data->o_app_entry), g_app_info_get_executable (app)); - data->last_clicked_list = data->o_app_tree_view; -} - - -static void -app_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - gpointer callback_data) -{ - DialogData *data = callback_data; - GtkTreeIter iter; - GAppInfo *app; - - if (! gtk_tree_model_get_iter (data->app_model, &iter, path)) - return; - - gtk_tree_model_get (data->app_model, &iter, - DATA_COLUMN, &app, - -1); - - _gtk_entry_set_locale_text (GTK_ENTRY (data->o_app_entry), g_app_info_get_executable (app)); - - open_cb (NULL, data); -} - - -static void -recent_list_selection_changed_cb (GtkTreeSelection *selection, - gpointer p) -{ - DialogData *data = p; - GtkTreeIter iter; - char *editor; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->o_recent_tree_view)); - if (selection == NULL) - return; - - if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) - return; - - gtk_tree_model_get (data->recent_model, &iter, - 0, &editor, - -1); - _gtk_entry_set_locale_text (GTK_ENTRY (data->o_app_entry), editor); - g_free (editor); - data->last_clicked_list = data->o_recent_tree_view; -} - - -static void -recent_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - gpointer callback_data) -{ - DialogData *data = callback_data; - GtkTreeIter iter; - char *editor; - - if (! gtk_tree_model_get_iter (data->recent_model, &iter, path)) - return; - - gtk_tree_model_get (data->recent_model, &iter, - 0, &editor, - -1); - _gtk_entry_set_locale_text (GTK_ENTRY (data->o_app_entry), editor); - g_free (editor); - - open_cb (NULL, data); -} + FrWindow *window; + GList *file_list; +} OpenData; static void -app_entry__changed_cb (GtkEditable *editable, - gpointer user_data) +open_data_free (OpenData *o_data) { - DialogData *data = user_data; - const char *text; - - text = eat_void_chars (gtk_entry_get_text (GTK_ENTRY (data->o_app_entry))); - gtk_widget_set_sensitive (data->ok_button, strlen (text) > 0); + path_list_free (o_data->file_list); + g_free (o_data); } static void -delete_recent_cb (GtkWidget *widget, - gpointer callback_data) +app_chooser_response_cb (GtkDialog *dialog, + int response_id, + gpointer user_data) { - DialogData *data = callback_data; - GtkTreeSelection *selection; - GtkTreeIter iter; - - - if (data->last_clicked_list == data->o_recent_tree_view) { - char *editor; - char **editors; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->o_recent_tree_view)); - if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) - return; - - gtk_tree_model_get (data->recent_model, &iter, - 0, &editor, - -1); - gtk_list_store_remove (GTK_LIST_STORE (data->recent_model), &iter); - - /**/ - - editors = g_settings_get_strv (data->settings, PREF_GENERAL_EDITORS); - if (_g_strv_remove (editors, editor)) - g_settings_set_strv (data->settings, PREF_GENERAL_EDITORS, (const gchar * const *) editors); - g_strfreev (editors); - g_free (editor); - } - else if (data->last_clicked_list == data->o_app_tree_view) { - GAppInfo *app; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->o_app_tree_view)); - if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) - return; - - gtk_tree_model_get (data->app_model, &iter, - DATA_COLUMN, &app, - -1); - gtk_list_store_remove (GTK_LIST_STORE (data->app_model), &iter); - - if (g_app_info_can_remove_supports_type (app)) { - const char *mime_type; - - mime_type = get_file_mime_type_for_path ((char*) data->file_list->data, FALSE); - g_app_info_remove_supports_type (app, mime_type, NULL); + OpenData *o_data = user_data; + GAppInfo *app_info; + + switch (response_id) { + case GTK_RESPONSE_OK: + app_info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (dialog)); + if (app_info != NULL) { + fr_window_open_files_with_application (o_data->window, o_data->file_list, app_info); + g_object_unref (app_info); } + open_data_free (o_data); + gtk_widget_destroy (GTK_WIDGET (dialog)); + break; + + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: + open_data_free (o_data); + gtk_widget_destroy (GTK_WIDGET (dialog)); + break; + + default: + break; } } -/* create the "open with" dialog. */ void dlg_open_with (FrWindow *window, GList *file_list) { - DialogData *data; - GAppInfo *app; - GList *scan, *app_names = NULL; - char **editors; - int i; - GtkWidget *cancel_button; - GtkTreeIter iter; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkIconTheme *theme; - int icon_size; - - if (file_list == NULL) - return; - - data = g_new0 (DialogData, 1); - data->settings = g_settings_new (ENGRAMPA_SCHEMA_GENERAL); - data->builder = _gtk_builder_new_from_file ("open-with.ui"); - if (data->builder == NULL) { - g_free (data); - return; - } - - data->file_list = path_list_dup (file_list); - data->window = window; - - /* Get the widgets. */ - - data->dialog = _gtk_builder_get_widget (data->builder, "open_with_dialog"); - data->o_app_tree_view = _gtk_builder_get_widget (data->builder, "o_app_list_tree_view"); - data->o_recent_tree_view = _gtk_builder_get_widget (data->builder, "o_recent_tree_view"); - data->o_app_entry = _gtk_builder_get_widget (data->builder, "o_app_entry"); - data->o_del_button = _gtk_builder_get_widget (data->builder, "o_del_button"); - data->ok_button = _gtk_builder_get_widget (data->builder, "o_ok_button"); - cancel_button = _gtk_builder_get_widget (data->builder, "o_cancel_button"); - - gtk_widget_set_sensitive (data->ok_button, FALSE); - - /* Set the signals handlers. */ - - g_signal_connect (G_OBJECT (data->dialog), - "destroy", - G_CALLBACK (open_with__destroy_cb), - data); - - g_signal_connect (G_OBJECT (data->o_app_entry), - "changed", - G_CALLBACK (app_entry__changed_cb), - data); - - g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (data->o_app_tree_view))), - "changed", - G_CALLBACK (app_list_selection_changed_cb), - data); - g_signal_connect (G_OBJECT (data->o_app_tree_view), - "row_activated", - G_CALLBACK (app_activated_cb), - data); - - g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (data->o_recent_tree_view))), - "changed", - G_CALLBACK (recent_list_selection_changed_cb), - data); - g_signal_connect (G_OBJECT (data->o_recent_tree_view), - "row_activated", - G_CALLBACK (recent_activated_cb), - data); - - g_signal_connect (G_OBJECT (data->ok_button), - "clicked", - G_CALLBACK (open_cb), - data); - g_signal_connect_swapped (G_OBJECT (cancel_button), - "clicked", - G_CALLBACK (gtk_widget_destroy), - G_OBJECT (data->dialog)); - g_signal_connect (G_OBJECT (data->o_del_button), - "clicked", - G_CALLBACK (delete_recent_cb), - data); - - /* Set data. */ - - /* * registered applications list. */ - - data->app_list = NULL; - for (scan = data->file_list; scan; scan = scan->next) { - const char *mime_type; - const char *name = scan->data; - - mime_type = get_file_mime_type_for_path (name, FALSE); - if ((mime_type != NULL) && ! g_content_type_is_unknown (mime_type)) - data->app_list = g_list_concat (data->app_list, g_app_info_get_all_for_type (mime_type)); - } - - data->app_model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS, - GDK_TYPE_PIXBUF, - G_TYPE_STRING, - G_TYPE_POINTER)); - - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->app_model), - TEXT_COLUMN, - GTK_SORT_ASCENDING); - - gtk_tree_view_set_model (GTK_TREE_VIEW (data->o_app_tree_view), - data->app_model); - g_object_unref (G_OBJECT (data->app_model)); - - theme = gtk_icon_theme_get_default (); - icon_size = get_folder_pixbuf_size_for_list (GTK_WIDGET (data->dialog)); - - for (scan = data->app_list; scan; scan = scan->next) { - gboolean found; - char *utf8_name; - GdkPixbuf *icon_image = NULL; - - app = scan->data; - - found = FALSE; - if (app_names != NULL) { - GList *p; - for (p = app_names; p && !found; p = p->next) - if (g_strcmp0 ((char*)p->data, g_app_info_get_executable (app)) == 0) - found = TRUE; - } - - if (found) - continue; - - app_names = g_list_prepend (app_names, (char*) g_app_info_get_executable (app)); - - utf8_name = g_locale_to_utf8 (g_app_info_get_name (app), -1, NULL, NULL, NULL); - icon_image = get_icon_pixbuf (g_app_info_get_icon (app), icon_size, theme); - - gtk_list_store_append (GTK_LIST_STORE (data->app_model), - &iter); - gtk_list_store_set (GTK_LIST_STORE (data->app_model), - &iter, - ICON_COLUMN, icon_image, - TEXT_COLUMN, utf8_name, - DATA_COLUMN, app, - -1); - - g_free (utf8_name); - } - - column = gtk_tree_view_column_new (); - - renderer = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - gtk_tree_view_column_set_attributes (column, renderer, - "pixbuf", ICON_COLUMN, - NULL); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, - renderer, - TRUE); - gtk_tree_view_column_set_attributes (column, renderer, - "text", TEXT_COLUMN, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (data->o_app_tree_view), - column); - - if (app_names) - g_list_free (app_names); - - /* * recent editors list. */ - - data->recent_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING)); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->recent_model), 0, GTK_SORT_ASCENDING); - - gtk_tree_view_set_model (GTK_TREE_VIEW (data->o_recent_tree_view), - data->recent_model); - g_object_unref (G_OBJECT (data->recent_model)); - - editors = g_settings_get_strv (data->settings, PREF_GENERAL_EDITORS); - for (i = 0; editors[i] != NULL; i++) { - gtk_list_store_append (GTK_LIST_STORE (data->recent_model), &iter); - gtk_list_store_set (GTK_LIST_STORE (data->recent_model), &iter, - 0, editors[i], - -1); - } - g_strfreev (editors); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (NULL, - renderer, - "text", 0, - NULL); - gtk_tree_view_column_set_sort_column_id (column, 0); - gtk_tree_view_append_column (GTK_TREE_VIEW (data->o_recent_tree_view), - column); - - /* Run dialog. */ - gtk_window_set_transient_for (GTK_WINDOW (data->dialog), - GTK_WINDOW (window)); - gtk_window_set_modal (GTK_WINDOW (data->dialog), TRUE); - gtk_widget_show_all (data->dialog); + OpenData *o_data; + GtkWidget *app_chooser; + GFile *first_file; + + o_data = g_new0 (OpenData, 1); + o_data->window = window; + o_data->file_list = file_list; + + first_file = g_file_new_for_path (file_list->data); + app_chooser = gtk_app_chooser_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_MODAL, + first_file); + g_signal_connect (app_chooser, + "response", + G_CALLBACK (app_chooser_response_cb), + o_data); + gtk_widget_show (app_chooser); } |