From bcee9bdc706d1cf65bf800c2bcc96b236dab6ec5 Mon Sep 17 00:00:00 2001 From: ZenWalker Date: Tue, 21 Jun 2016 11:33:58 +0200 Subject: 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 --- src/dlg-open-with.c | 488 +++++----------------------------------------------- 1 file changed, 47 insertions(+), 441 deletions(-) (limited to 'src') 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); } -- cgit v1.2.1