/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * MATE Search Tool * * File: gsearchtool-callbacks.c * * (C) 2002 the Free Software Foundation * * Authors: Dennis Cranston * George Lebl * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include "gsearchtool.h" #include "gsearchtool-callbacks.h" #include "gsearchtool-support.h" #define SILENT_WINDOW_OPEN_LIMIT 5 #ifdef HAVE_GETPGID extern pid_t getpgid (pid_t); #endif gboolean row_selected_by_button_press_event; static void store_window_state_and_geometry (GSearchWindow *gsearch) { gsearch->window_width = MAX (gsearch->window_width, MINIMUM_WINDOW_WIDTH); gsearch->window_height = MAX (gsearch->window_height, MINIMUM_WINDOW_HEIGHT); g_settings_set_int (gsearch->mate_search_tool_settings, "default-window-width", gsearch->window_width); g_settings_set_int (gsearch->mate_search_tool_settings, "default-window-height", gsearch->window_height); g_settings_set_boolean (gsearch->mate_search_tool_settings, "default-window-maximized", gsearch->is_window_maximized); } static void quit_application (GSearchWindow * gsearch) { GSearchCommandDetails * command_details = gsearch->command_details; if (command_details->command_status == RUNNING) { #ifdef HAVE_GETPGID pid_t pgid; #endif command_details->command_status = MAKE_IT_QUIT; #ifdef HAVE_GETPGID pgid = getpgid (command_details->command_pid); if ((pgid > 1) && (pgid != getpid ())) { kill (-(getpgid (command_details->command_pid)), SIGKILL); } else { kill (command_details->command_pid, SIGKILL); } #else kill (command_details->command_pid, SIGKILL); #endif wait (NULL); } store_window_state_and_geometry (gsearch); gtk_main_quit (); } void version_cb (const gchar * option_name, const gchar * value, gpointer data, GError ** error) { g_print ("%s %s\n", g_get_application_name (), VERSION); exit (0); } void quit_session_cb (EggSMClient * client, gpointer data) { quit_application ((GSearchWindow *) data); } void quit_cb (GtkWidget * widget, GdkEvent * event, gpointer data) { quit_application ((GSearchWindow *) data); } void click_close_cb (GtkWidget * widget, gpointer data) { quit_application ((GSearchWindow *) data); } void click_find_cb (GtkWidget * widget, gpointer data) { GSearchWindow * gsearch = data; gchar * command; if (gsearch->command_details->is_command_timeout_enabled == TRUE) { return; } if ((gsearch->command_details->command_status == STOPPED) || (gsearch->command_details->command_status == ABORTED)) { command = build_search_command (gsearch, TRUE); if (command != NULL) { spawn_search_command (gsearch, command); g_free (command); } } } void click_stop_cb (GtkWidget * widget, gpointer data) { GSearchWindow * gsearch = data; if (gsearch->command_details->command_status == RUNNING) { #ifdef HAVE_GETPGID pid_t pgid; #endif gtk_widget_set_sensitive (gsearch->stop_button, FALSE); gsearch->command_details->command_status = MAKE_IT_STOP; #ifdef HAVE_GETPGID pgid = getpgid (gsearch->command_details->command_pid); if ((pgid > 1) && (pgid != getpid ())) { kill (-(getpgid (gsearch->command_details->command_pid)), SIGKILL); } else { kill (gsearch->command_details->command_pid, SIGKILL); } #else kill (gsearch->command_details->command_pid, SIGKILL); #endif wait (NULL); } } void click_help_cb (GtkWidget * widget, gpointer data) { GtkWidget * window = data; GError * error = NULL; gtk_show_uri (gtk_widget_get_screen (widget), "help:mate-search-tool", gtk_get_current_event_time (), &error); if (error) { GtkWidget * dialog; dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not open help document.")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), error->message, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); g_error_free (error); } } void click_expander_cb (GObject * object, GParamSpec * param_spec, gpointer data) { GSearchWindow * gsearch = data; if (gtk_expander_get_expanded (GTK_EXPANDER (object)) == TRUE) { gtk_widget_show (gsearch->available_options_vbox); gtk_window_set_geometry_hints (GTK_WINDOW (gsearch->window), GTK_WIDGET (gsearch->window), &gsearch->window_geometry, GDK_HINT_MIN_SIZE); } else { GdkGeometry default_geometry = {MINIMUM_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT}; gtk_widget_hide (gsearch->available_options_vbox); gtk_window_set_geometry_hints (GTK_WINDOW (gsearch->window), GTK_WIDGET (gsearch->window), &default_geometry, GDK_HINT_MIN_SIZE); } } void size_allocate_cb (GtkWidget * widget, GtkAllocation * allocation, gpointer data) { GtkWidget * button = data; gtk_widget_set_size_request (button, allocation->width, -1); } void add_constraint_cb (GtkWidget * widget, gpointer data) { GSearchWindow * gsearch = data; gint idx; idx = gtk_combo_box_get_active (GTK_COMBO_BOX (gsearch->available_options_combo_box)); add_constraint (gsearch, idx, NULL, FALSE); } void remove_constraint_cb (GtkWidget * widget, gpointer data) { GList * list = data; GSearchWindow * gsearch = g_list_first (list)->data; GSearchConstraint * constraint = g_list_last (list)->data; gsearch->window_geometry.min_height -= WINDOW_HEIGHT_STEP; gtk_window_set_geometry_hints (GTK_WINDOW (gsearch->window), GTK_WIDGET (gsearch->window), &gsearch->window_geometry, GDK_HINT_MIN_SIZE); gtk_container_remove (GTK_CONTAINER (gsearch->available_options_vbox), gtk_widget_get_parent (widget)); gsearch->available_options_selected_list = g_list_remove (gsearch->available_options_selected_list, constraint); set_constraint_selected_state (gsearch, constraint->constraint_id, FALSE); set_constraint_gsettings_boolean (constraint->constraint_id, FALSE); g_slice_free (GSearchConstraint, constraint); g_list_free (list); } void constraint_activate_cb (GtkWidget * widget, gpointer data) { GSearchWindow * gsearch = data; if ((gtk_widget_get_visible (gsearch->find_button)) && (gtk_widget_get_sensitive (gsearch->find_button))) { click_find_cb (gsearch->find_button, data); } } void constraint_update_info_cb (GtkWidget * widget, gpointer data) { static gchar * string; GSearchConstraint * opt = data; string = (gchar *) gtk_entry_get_text (GTK_ENTRY (widget)); update_constraint_info (opt, string); } void name_contains_activate_cb (GtkWidget * widget, gpointer data) { GSearchWindow * gsearch = data; if ((gtk_widget_get_visible (gsearch->find_button)) && (gtk_widget_get_sensitive (gsearch->find_button))) { click_find_cb (gsearch->find_button, data); } } void look_in_folder_changed_cb (GtkWidget * widget, gpointer data) { GSearchWindow * gsearch = data; gchar * value; value = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (gsearch->look_in_folder_button)); if (value != NULL) { g_settings_set_string (gsearch->mate_search_tool_settings, "look-in-folder", value); } g_free (value); } static gint display_dialog_file_open_limit (GtkWidget * window, gint count) { GtkWidget * dialog; GtkWidget * button; gchar * primary; gchar * secondary; gint response; primary = g_strdup_printf (ngettext ("Are you sure you want to open %d document?", "Are you sure you want to open %d documents?", count), count); secondary = g_strdup_printf (ngettext ("This will open %d separate window.", "This will open %d separate windows.", count), count); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), secondary, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); button = gtk_button_new_from_stock ("gtk-open"); gtk_widget_set_can_default (button, TRUE); gtk_widget_show (button); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_free (primary); g_free (secondary); return response; } static void display_dialog_could_not_open_file (GtkWidget * window, const gchar * file, const gchar * message) { GtkWidget * dialog; gchar * primary; primary = g_strdup_printf (_("Could not open document \"%s\"."), file); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), message, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); g_free (primary); } static void display_dialog_could_not_open_folder (GtkWidget * window, const gchar * folder) { GtkWidget * dialog; gchar * primary; primary = g_strdup_printf (_("Could not open folder \"%s\"."), folder); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("The caja file manager is not running.")); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); g_free (primary); } void open_file_event_cb (GtkWidget * widget, GdkEventButton * event, gpointer data) { open_file_cb ((GtkMenuItem *) widget, data); } void open_file_cb (GtkMenuItem * action, gpointer data) { GSearchWindow * gsearch = data; GtkTreeModel * model; GList * list; guint idx; if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { return; } list = gtk_tree_selection_get_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection), &model); if (g_list_length (list) > SILENT_WINDOW_OPEN_LIMIT) { gint response; response = display_dialog_file_open_limit (gsearch->window, g_list_length (list)); if (response == GTK_RESPONSE_CANCEL) { g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); return; } } for (idx = 0; idx < g_list_length (list); idx++) { gboolean no_files_found = FALSE; gchar * utf8_name; gchar * locale_file; GtkTreeIter iter; gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, g_list_nth_data (list, idx)); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_NAME, &utf8_name, COLUMN_LOCALE_FILE, &locale_file, COLUMN_NO_FILES_FOUND, &no_files_found, -1); if (!no_files_found) { GAppInfo * app = NULL; if (GTK_IS_MENU_ITEM (action)) { app = g_object_get_data (G_OBJECT (action), "app"); } if (!g_file_test (locale_file, G_FILE_TEST_EXISTS)) { gtk_tree_selection_unselect_iter (GTK_TREE_SELECTION (gsearch->search_results_selection), &iter); display_dialog_could_not_open_file (gsearch->window, utf8_name, _("The document does not exist.")); } else if (open_file_with_application (gsearch->window, locale_file, app) == FALSE) { if (launch_file (locale_file) == FALSE) { if (g_file_test (locale_file, G_FILE_TEST_IS_DIR)) { if (open_file_with_filemanager (gsearch->window, locale_file) == FALSE) { display_dialog_could_not_open_folder (gsearch->window, utf8_name); } } else { display_dialog_could_not_open_file (gsearch->window, utf8_name, _("There is no installed viewer capable " "of displaying the document.")); } } } } g_free (utf8_name); g_free (locale_file); } g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); } static gint display_dialog_folder_open_limit (GtkWidget * window, gint count) { GtkWidget * dialog; GtkWidget * button; gchar * primary; gchar * secondary; gint response; primary = g_strdup_printf (ngettext ("Are you sure you want to open %d folder?", "Are you sure you want to open %d folders?", count), count); secondary = g_strdup_printf (ngettext ("This will open %d separate window.", "This will open %d separate windows.", count), count); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), secondary, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); button = gtk_button_new_from_stock ("gtk-open"); gtk_widget_set_can_default (button, TRUE); gtk_widget_show (button); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_free (primary); g_free (secondary); return response; } void open_folder_cb (GtkAction * action, gpointer data) { GSearchWindow * gsearch = data; GtkTreeModel * model; GFile * g_file = NULL; GFileInfo * g_file_info = NULL; GAppInfo * g_app_info = NULL; GList * list; guint idx; if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { return; } list = gtk_tree_selection_get_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection), &model); if (g_list_length (list) > SILENT_WINDOW_OPEN_LIMIT) { gint response; response = display_dialog_folder_open_limit (gsearch->window, g_list_length (list)); if (response == GTK_RESPONSE_CANCEL) { g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); return; } } for (idx = 0; idx < g_list_length (list); idx++) { gchar * locale_folder; gchar * utf8_folder; gchar * locale_file; GtkTreeIter iter; gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, g_list_nth_data (list, idx)); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_RELATIVE_PATH, &utf8_folder, COLUMN_LOCALE_FILE, &locale_file, -1); locale_folder = g_path_get_dirname (locale_file); if (idx == 0) { g_file = g_file_new_for_path (locale_folder); g_file_info = g_file_query_info (g_file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_app_info = g_app_info_get_default_for_type (g_file_info_get_content_type (g_file_info), FALSE); } if (open_file_with_application (gsearch->window, locale_folder, g_app_info) == FALSE) { if (open_file_with_filemanager (gsearch->window, locale_folder) == FALSE) { display_dialog_could_not_open_folder (gsearch->window, utf8_folder); g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); g_free (locale_folder); g_free (utf8_folder); g_object_unref (g_file); g_object_unref (g_file_info); g_object_unref (g_app_info); return; } } g_free (locale_folder); g_free (locale_file); g_free (utf8_folder); } g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); g_object_unref (g_file); g_object_unref (g_file_info); g_object_unref (g_app_info); } void file_changed_cb (GFileMonitor * handle, const gchar * monitor_uri, const gchar * info_uri, GFileMonitorEvent event_type, gpointer data) { GSearchMonitor * monitor = data; GSearchWindow * gsearch = monitor->gsearch; GtkTreeModel * model; GtkTreePath * path; GtkTreeIter iter; switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: path = gtk_tree_row_reference_get_path (monitor->reference); model = gtk_tree_row_reference_get_model (monitor->reference); gtk_tree_model_get_iter (model, &iter, path); tree_model_iter_free_monitor (model, NULL, &iter, NULL); gtk_list_store_remove (GTK_LIST_STORE (model), &iter); update_search_counts (gsearch); break; default: break; } } static void display_dialog_could_not_move_to_trash (GtkWidget * window, const gchar * file, const gchar * message) { GtkWidget * dialog; gchar * primary; primary = g_strdup_printf (_("Could not move \"%s\" to trash."), file); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), message, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); g_free (primary); } static gint display_dialog_delete_permanently (GtkWidget * window, const gchar * file) { GtkWidget * dialog; GtkWidget * button; gchar * primary; gchar * secondary; gint response; primary = g_strdup_printf (_("Do you want to delete \"%s\" permanently?"), g_path_get_basename (file)); secondary = g_strdup_printf (_("Trash is unavailable. Could not move \"%s\" to the trash."), file); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), secondary, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); button = gtk_button_new_from_stock ("gtk-delete"); gtk_widget_set_can_default (button, TRUE); gtk_widget_show (button); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET(dialog)); g_free (primary); g_free (secondary); return response; } static void display_dialog_could_not_delete (GtkWidget * window, const gchar * file, const gchar * message) { GtkWidget * dialog; gchar * primary; primary = g_strdup_printf (_("Could not delete \"%s\"."), file); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), message, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); g_free (primary); } void move_to_trash_cb (GtkAction * action, gpointer data) { GSearchWindow * gsearch = data; GtkTreePath * last_selected_path = NULL; gint total; gint idx; if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { return; } total = gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)); for (idx = 0; idx < total; idx++) { gboolean no_files_found = FALSE; GtkTreeModel * model; GtkTreeIter iter; GList * list; GFile * g_file; GError * error = NULL; gchar * utf8_basename; gchar * utf8_filename; gchar * locale_filename; gboolean result; list = gtk_tree_selection_get_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection), &model); gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, g_list_nth_data (list, 0)); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_NAME, &utf8_basename, COLUMN_LOCALE_FILE, &locale_filename, COLUMN_NO_FILES_FOUND, &no_files_found, -1); if (no_files_found) { g_free (utf8_basename); g_free (locale_filename); return; } utf8_filename = g_filename_display_name (locale_filename); if (idx + 1 == total) { last_selected_path = gtk_tree_model_get_path (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter); } if ((!g_file_test (locale_filename, G_FILE_TEST_EXISTS)) && (!g_file_test (locale_filename, G_FILE_TEST_IS_SYMLINK))) { gtk_tree_selection_unselect_iter (GTK_TREE_SELECTION (gsearch->search_results_selection), &iter); display_dialog_could_not_move_to_trash (gsearch->window, utf8_basename, _("The document does not exist.")); } g_file = g_file_new_for_path (locale_filename); result = g_file_trash (g_file, NULL, &error); gtk_tree_selection_unselect_iter (GTK_TREE_SELECTION (gsearch->search_results_selection), &iter); g_object_unref (g_file); if (result == TRUE) { tree_model_iter_free_monitor (GTK_TREE_MODEL (gsearch->search_results_list_store), NULL, &iter, NULL); gtk_list_store_remove (GTK_LIST_STORE (gsearch->search_results_list_store), &iter); } else { gint response; gtk_tree_selection_unselect_iter (GTK_TREE_SELECTION (gsearch->search_results_selection), &iter); response = display_dialog_delete_permanently (gsearch->window, utf8_filename); if (response == GTK_RESPONSE_OK) { GFile * g_file_tmp; GError * error_tmp = NULL; g_file_tmp = g_file_new_for_path (locale_filename); result = g_file_delete (g_file_tmp, NULL, &error_tmp); g_object_unref (g_file_tmp); if (result == TRUE) { tree_model_iter_free_monitor (GTK_TREE_MODEL (gsearch->search_results_list_store), NULL, &iter, NULL); gtk_list_store_remove (GTK_LIST_STORE (gsearch->search_results_list_store), &iter); } else { gchar * message; message = g_strdup_printf (_("Deleting \"%s\" failed: %s."), utf8_filename, error_tmp->message); display_dialog_could_not_delete (gsearch->window, utf8_basename, message); g_error_free (error_tmp); g_free (message); } } else { gchar * message; message = g_strdup_printf (_("Moving \"%s\" failed: %s."), utf8_filename, error->message); display_dialog_could_not_move_to_trash (gsearch->window, utf8_basename, message); g_error_free (error); g_free (message); } } g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); g_free (locale_filename); g_free (utf8_filename); g_free (utf8_basename); } /* Bugzilla #397945: Select next row in the search results list */ if (last_selected_path != NULL) { if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { gtk_tree_selection_select_path (GTK_TREE_SELECTION (gsearch->search_results_selection), last_selected_path); if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { gtk_tree_path_prev (last_selected_path); gtk_tree_selection_select_path (GTK_TREE_SELECTION (gsearch->search_results_selection), last_selected_path); } } gtk_tree_path_free (last_selected_path); } if (gsearch->command_details->command_status != RUNNING) { update_search_counts (gsearch); } } gboolean file_button_press_event_cb (GtkWidget * widget, GdkEventButton * event, gpointer data) { GtkTreeView * tree = data; GtkTreePath * path; row_selected_by_button_press_event = TRUE; if (event->window != gtk_tree_view_get_bin_window (tree)) { return FALSE; } if (gtk_tree_view_get_path_at_pos (tree, event->x, event->y, &path, NULL, NULL, NULL)) { if ((event->button == 1 || event->button == 2 || event->button == 3) && gtk_tree_selection_path_is_selected (gtk_tree_view_get_selection (tree), path)) { row_selected_by_button_press_event = FALSE; } gtk_tree_path_free (path); } else { gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (tree)); } return !(row_selected_by_button_press_event); } gboolean file_key_press_event_cb (GtkWidget * widget, GdkEventKey * event, gpointer data) { if (event->keyval == GDK_KEY_space || event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) { if (event->state != GDK_CONTROL_MASK) { open_file_cb ((GtkMenuItem *) NULL, data); return TRUE; } } else if (event->keyval == GDK_KEY_Delete) { move_to_trash_cb ((GtkAction *) NULL, data); return TRUE; } return FALSE; } static gint open_with_list_sort (gconstpointer a, gconstpointer b) { const gchar * a_app_name = g_app_info_get_name ((GAppInfo *) a); const gchar * b_app_name = g_app_info_get_name ((GAppInfo *) b); gchar * a_utf8; gchar * b_utf8; gint result; a_utf8 = g_utf8_casefold (a_app_name, -1); b_utf8 = g_utf8_casefold (b_app_name, -1); result = g_utf8_collate (a_utf8, b_utf8); g_free (a_utf8); g_free (b_utf8); return result; } static void build_popup_menu_for_file (GSearchWindow * gsearch, gchar * file) { GtkWidget * new1, * image1, * separatormenuitem1; GtkWidget * new2; gint i; if (GTK_IS_MENU (gsearch->search_results_popup_menu) == TRUE) { g_object_ref_sink (gsearch->search_results_popup_menu); g_object_unref (gsearch->search_results_popup_menu); } if (GTK_IS_MENU (gsearch->search_results_popup_submenu) == TRUE) { g_object_ref_sink (gsearch->search_results_popup_submenu); g_object_unref (gsearch->search_results_popup_submenu); } gsearch->search_results_popup_menu = gtk_menu_new (); if (file == NULL || g_file_test (file, G_FILE_TEST_IS_DIR) == TRUE) { /* Popup menu item: Open */ new1 = gtk_image_menu_item_new_with_mnemonic (_("_Open")); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), new1); gtk_widget_show (new1); image1 = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image1); gtk_widget_show (image1); g_signal_connect (G_OBJECT (new1), "activate", G_CALLBACK (open_file_cb), (gpointer) gsearch); } else { GFile * g_file; GFileInfo * file_info; GIcon * file_icon; GList * list; gchar * str; gint list_length; g_file = g_file_new_for_path (file); file_info = g_file_query_info (g_file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); list = g_app_info_get_all_for_type (g_file_info_get_content_type (file_info)); list_length = g_list_length (list); if (list_length <= 0) { /* Popup menu item: Open */ new1 = gtk_image_menu_item_new_with_mnemonic (_("_Open")); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), new1); gtk_widget_show (new1); image1 = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image1); gtk_widget_show (image1); g_signal_connect (G_OBJECT (new1), "activate", G_CALLBACK (open_file_cb), (gpointer) gsearch); } else { if (list_length >= 3) { /* Sort all except first application by name */ GList * tmp; tmp = g_list_first (list); list = g_list_remove_link (list, tmp); list = g_list_sort (list, open_with_list_sort); list = g_list_prepend (list, tmp->data); g_list_free (tmp); } /* Popup menu item: Open with (default) */ str = g_strdup_printf (_("_Open with %s"), g_app_info_get_name (list->data)); new1 = gtk_image_menu_item_new_with_mnemonic (str); g_free (str); gtk_widget_show (new1); g_object_set_data_full (G_OBJECT (new1), "app", (GAppInfo *)list->data, (GDestroyNotify) g_object_unref); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), new1); g_signal_connect ((gpointer) new1, "activate", G_CALLBACK (open_file_cb), (gpointer) gsearch); if (g_app_info_get_icon ((GAppInfo *)list->data) != NULL) { file_icon = g_object_ref (g_app_info_get_icon ((GAppInfo *)list->data)); gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (new1), file_icon != NULL); if (file_icon == NULL) { file_icon = g_themed_icon_new (GTK_STOCK_OPEN); } image1 = gtk_image_new_from_gicon (file_icon, GTK_ICON_SIZE_MENU); g_object_unref (file_icon); gtk_widget_show (image1); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image1); } separatormenuitem1 = gtk_separator_menu_item_new (); gtk_widget_show (separatormenuitem1); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), separatormenuitem1); gtk_widget_set_sensitive (separatormenuitem1, FALSE); for (list = g_list_next (list), i = 0; list != NULL; list = g_list_next (list), i++) { /* Popup menu item: Open with (others) */ if (list_length < 4) { str = g_strdup_printf (_("Open with %s"), g_app_info_get_name (list->data)); } else { str = g_strdup_printf ("%s", g_app_info_get_name (list->data)); } new1 = gtk_image_menu_item_new_with_mnemonic (str); g_free (str); gtk_widget_show (new1); g_object_set_data_full (G_OBJECT (new1), "app", (GAppInfo *)list->data, (GDestroyNotify) g_object_unref); if (list_length >= 4) { if (g_app_info_get_icon ((GAppInfo *)list->data) != NULL) { file_icon = g_object_ref (g_app_info_get_icon ((GAppInfo *)list->data)); gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (new1), file_icon != NULL); if (file_icon == NULL) { file_icon = g_themed_icon_new (GTK_STOCK_OPEN); } image1 = gtk_image_new_from_gicon (file_icon, GTK_ICON_SIZE_MENU); g_object_unref (file_icon); gtk_widget_show (image1); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image1); } if (i == 0) { gsearch->search_results_popup_submenu = gtk_menu_new (); /* Popup menu item: Open With */ new2 = gtk_menu_item_new_with_mnemonic (_("Open Wit_h")); gtk_widget_show (new2); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), new2); gtk_menu_item_set_submenu (GTK_MENU_ITEM (new2), gsearch->search_results_popup_submenu); } gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_submenu), new1); /* For submenu items, the "activate" signal is only emitted if the user first clicks on the parent menu item. Since submenus in gtk+ are automatically displayed when the user hovers over them, most will never click on the parent menu item. The work-around is to connect to "button-press-event". */ g_signal_connect (G_OBJECT(new1), "button-press-event", G_CALLBACK (open_file_event_cb), (gpointer) gsearch); } else { if (g_app_info_get_icon ((GAppInfo *)list->data) != NULL) { file_icon = g_object_ref (g_app_info_get_icon ((GAppInfo *)list->data)); gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (new1), file_icon != NULL); if (file_icon == NULL) { file_icon = g_themed_icon_new (GTK_STOCK_OPEN); } image1 = gtk_image_new_from_gicon (file_icon, GTK_ICON_SIZE_MENU); g_object_unref (file_icon); gtk_widget_show (image1); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image1); } gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), new1); g_signal_connect ((gpointer) new1, "activate", G_CALLBACK (open_file_cb), (gpointer) gsearch); } } if (list_length >= 2) { separatormenuitem1 = gtk_separator_menu_item_new (); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), separatormenuitem1); gtk_widget_show (separatormenuitem1); } } } /* Popup menu item: Open Containing Folder */ new1 = gtk_image_menu_item_new_with_mnemonic (_("Open Containing _Folder")); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), new1); gtk_widget_show (new1); image1 = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image1); gtk_widget_show (image1); g_signal_connect (G_OBJECT (new1), "activate", G_CALLBACK (open_folder_cb), (gpointer) gsearch); /* Popup menu item: Move to Trash */ separatormenuitem1 = gtk_separator_menu_item_new (); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), separatormenuitem1); gtk_widget_show (separatormenuitem1); new1 = gtk_image_menu_item_new_with_mnemonic (_("Mo_ve to Trash")); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), new1); gtk_widget_show (new1); GtkIconTheme *icon_theme; GdkPixbuf *pixbuf; icon_theme = gtk_icon_theme_get_default (); pixbuf = gtk_icon_theme_load_icon (icon_theme, "user-trash", GTK_ICON_SIZE_MENU, 0, NULL); image1 = gtk_image_new_from_pixbuf (pixbuf); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image1); gtk_widget_show (image1); g_signal_connect (G_OBJECT (new1), "activate", G_CALLBACK (move_to_trash_cb), (gpointer) gsearch); /* Popup menu item: Save Results As... */ separatormenuitem1 = gtk_separator_menu_item_new (); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), separatormenuitem1); gtk_widget_show (separatormenuitem1); gsearch->search_results_save_results_as_item = gtk_image_menu_item_new_with_mnemonic (_("_Save Results As...")); gtk_container_add (GTK_CONTAINER (gsearch->search_results_popup_menu), gsearch->search_results_save_results_as_item); gtk_widget_show (gsearch->search_results_save_results_as_item); if (gsearch->command_details->command_status == RUNNING) { gtk_widget_set_sensitive (gsearch->search_results_save_results_as_item, FALSE); } image1 = gtk_image_new_from_icon_name ("document-save", GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gsearch->search_results_save_results_as_item), image1); gtk_widget_show (image1); g_signal_connect (G_OBJECT (gsearch->search_results_save_results_as_item), "activate", G_CALLBACK (show_file_selector_cb), (gpointer) gsearch); } gboolean file_button_release_event_cb (GtkWidget * widget, GdkEventButton * event, gpointer data) { GSearchWindow * gsearch = data; if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (gsearch->search_results_tree_view))) { return FALSE; } if (event->button == 1 || event->button == 2) { GtkTreePath *path; if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (gsearch->search_results_tree_view), event->x, event->y, &path, NULL, NULL, NULL)) { if ((event->state & GDK_SHIFT_MASK) || (event->state & GDK_CONTROL_MASK)) { if (row_selected_by_button_press_event) { gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW(gsearch->search_results_tree_view)), path); } else { gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (GTK_TREE_VIEW(gsearch->search_results_tree_view)), path); } } else { if (gsearch->is_search_results_single_click_to_activate == FALSE) { gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW(gsearch->search_results_tree_view))); } gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW(gsearch->search_results_tree_view)), path); } } gtk_tree_path_free (path); } if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { return FALSE; } if (event->button == 3) { gboolean no_files_found = FALSE; GtkTreeModel * model; GtkTreeIter iter; GList * list; gchar * utf8_name_first; gchar * locale_file_first; list = gtk_tree_selection_get_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection), &model); gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, g_list_first (list)->data); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_NAME, &utf8_name_first, COLUMN_LOCALE_FILE, &locale_file_first, COLUMN_NO_FILES_FOUND, &no_files_found, -1); if (!no_files_found) { gboolean show_app_list = TRUE; GAppInfo * first_app_info = NULL; GTimer * timer; GList * tmp; gchar * locale_file_tmp; gchar * file = NULL; gint idx; timer = g_timer_new (); g_timer_start (timer); if (g_list_length (list) >= 2) { /* Verify the selected files each have the same default handler. */ for (tmp = g_list_first (list), idx = 0; tmp != NULL; tmp = g_list_next (tmp), idx++) { GFile * g_file; GAppInfo * app_info; gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, tmp->data); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_LOCALE_FILE, &locale_file_tmp, -1); g_file = g_file_new_for_path (locale_file_tmp); app_info = g_file_query_default_handler (g_file, NULL, NULL); if (G_IS_APP_INFO (app_info) == FALSE) { show_app_list = FALSE; } else { if (idx == 0) { first_app_info = g_app_info_dup (app_info); g_object_unref (app_info); continue; } show_app_list = g_app_info_equal (app_info, first_app_info); g_object_unref (app_info); /* Break out, if more that 1.5 seconds have passed */ if (g_timer_elapsed (timer, NULL) > 1.50) { show_app_list = FALSE; } } g_object_unref (g_file); g_free (locale_file_tmp); if (show_app_list == FALSE) { break; } } g_timer_destroy (timer); if (first_app_info != NULL) { g_object_unref (first_app_info); } } file = g_strdup (((show_app_list == TRUE) ? locale_file_first : NULL)); build_popup_menu_for_file (gsearch, file); gtk_menu_popup (GTK_MENU (gsearch->search_results_popup_menu), NULL, NULL, NULL, NULL, event->button, event->time); g_free (file); } g_free (locale_file_first); g_free (utf8_name_first); g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); } else if (event->button == 1 || event->button == 2) { if (gsearch->is_search_results_single_click_to_activate == TRUE) { if (!(event->state & GDK_CONTROL_MASK) && !(event->state & GDK_SHIFT_MASK)) { open_file_cb ((GtkMenuItem *) NULL, data); } } } return FALSE; } gboolean file_event_after_cb (GtkWidget * widget, GdkEventButton * event, gpointer data) { GSearchWindow * gsearch = data; if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (gsearch->search_results_tree_view))) { return FALSE; } if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { return FALSE; } if (!(event->state & GDK_CONTROL_MASK) && !(event->state & GDK_SHIFT_MASK)) { if (gsearch->is_search_results_single_click_to_activate == FALSE) { if (event->type == GDK_2BUTTON_PRESS) { open_file_cb ((GtkMenuItem *) NULL, data); return TRUE; } } } return FALSE; } gboolean file_motion_notify_cb (GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { GSearchWindow * gsearch = user_data; GdkCursor * cursor; GtkTreePath * last_hover_path; GtkTreeIter iter; if (gsearch->is_search_results_single_click_to_activate == FALSE) { return FALSE; } if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (gsearch->search_results_tree_view))) { return FALSE; } last_hover_path = gsearch->search_results_hover_path; gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), event->x, event->y, &gsearch->search_results_hover_path, NULL, NULL, NULL); if (gsearch->search_results_hover_path != NULL) { cursor = gdk_cursor_new (GDK_HAND2); } else { cursor = NULL; } gdk_window_set_cursor (event->window, cursor); /* Redraw if the hover row has changed */ if (!(last_hover_path == NULL && gsearch->search_results_hover_path == NULL) && (!(last_hover_path != NULL && gsearch->search_results_hover_path != NULL) || gtk_tree_path_compare (last_hover_path, gsearch->search_results_hover_path))) { if (last_hover_path) { gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, last_hover_path); gtk_tree_model_row_changed (GTK_TREE_MODEL (gsearch->search_results_list_store), last_hover_path, &iter); } if (gsearch->search_results_hover_path) { gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, gsearch->search_results_hover_path); gtk_tree_model_row_changed (GTK_TREE_MODEL (gsearch->search_results_list_store), gsearch->search_results_hover_path, &iter); } } gtk_tree_path_free (last_hover_path); return FALSE; } gboolean file_leave_notify_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data) { GSearchWindow * gsearch = user_data; GtkTreeIter iter; if (gsearch->is_search_results_single_click_to_activate && (gsearch->search_results_hover_path != NULL)) { gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, gsearch->search_results_hover_path); gtk_tree_model_row_changed (GTK_TREE_MODEL (gsearch->search_results_list_store), gsearch->search_results_hover_path, &iter); gtk_tree_path_free (gsearch->search_results_hover_path); gsearch->search_results_hover_path = NULL; return TRUE; } return FALSE; } void drag_begin_file_cb (GtkWidget * widget, GdkDragContext * context, gpointer data) { GSearchWindow * gsearch = data; gint number_of_selected_rows; number_of_selected_rows = gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)); if (number_of_selected_rows > 1) { gtk_drag_set_icon_stock (context, GTK_STOCK_DND_MULTIPLE, 0, 0); } else if (number_of_selected_rows == 1) { GdkPixbuf * pixbuf; GtkTreeModel * model; GtkTreeIter iter; GList * list; list = gtk_tree_selection_get_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection), &model); gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, g_list_first (list)->data); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_ICON, &pixbuf, -1); g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); if (pixbuf) { gtk_drag_set_icon_pixbuf (context, pixbuf, 0, 0); } else { gtk_drag_set_icon_stock (context, GTK_STOCK_DND, 0, 0); } } } void drag_file_cb (GtkWidget * widget, GdkDragContext * context, GtkSelectionData * selection_data, guint info, guint drag_time, gpointer data) { GSearchWindow * gsearch = data; gchar * uri_list = NULL; GList * list; GtkTreeModel * model; GtkTreeIter iter; guint idx; if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { return; } list = gtk_tree_selection_get_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection), &model); for (idx = 0; idx < g_list_length (list); idx++) { gboolean no_files_found = FALSE; gchar * utf8_name; gchar * locale_file; gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, g_list_nth_data (list, idx)); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_NAME, &utf8_name, COLUMN_LOCALE_FILE, &locale_file, COLUMN_NO_FILES_FOUND, &no_files_found, -1); if (!no_files_found) { gchar * tmp_uri = g_filename_to_uri (locale_file, NULL, NULL); if (uri_list == NULL) { uri_list = g_strdup (tmp_uri); } else { uri_list = g_strconcat (uri_list, "\n", tmp_uri, NULL); } gtk_selection_data_set (selection_data, gtk_selection_data_get_target (selection_data), 8, (guchar *) uri_list, strlen (uri_list)); g_free (tmp_uri); } else { gtk_selection_data_set_text (selection_data, utf8_name, -1); } g_free (utf8_name); g_free (locale_file); } g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); g_free (uri_list); } void show_file_selector_cb (GtkAction * action, gpointer data) { GSearchWindow * gsearch = data; GtkWidget * file_chooser; file_chooser = gtk_file_chooser_dialog_new (_("Save Search Results As..."), GTK_WINDOW (gsearch->window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (file_chooser), TRUE); if (gsearch->save_results_as_default_filename != NULL) { gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (file_chooser), gsearch->save_results_as_default_filename); } g_signal_connect (G_OBJECT (file_chooser), "response", G_CALLBACK (save_results_cb), gsearch); gtk_window_set_modal (GTK_WINDOW (file_chooser), TRUE); gtk_window_set_position (GTK_WINDOW (file_chooser), GTK_WIN_POS_CENTER_ON_PARENT); gtk_widget_show (GTK_WIDGET (file_chooser)); } static void display_dialog_could_not_save_no_name (GtkWidget * window) { GtkWidget * dialog; gchar * primary; gchar * secondary; primary = g_strdup (_("Could not save document.")); secondary = g_strdup (_("You did not select a document name.")); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), secondary, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); g_free (primary); g_free (secondary); } static void display_dialog_could_not_save_to (GtkWidget * window, const gchar * file, const gchar * message) { GtkWidget * dialog; gchar * primary; primary = g_strdup_printf (_("Could not save \"%s\" document to \"%s\"."), g_path_get_basename (file), g_path_get_dirname (file)); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, primary, NULL); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), message, NULL); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); gtk_widget_show (dialog); g_free (primary); } static gint display_dialog_could_not_save_exists (GtkWidget * window, const gchar * file) { GtkWidget * dialog; GtkWidget * button; gchar * primary; gchar * secondary; gint response; primary = g_strdup_printf (_("The document \"%s\" already exists. " "Would you like to replace it?"), g_path_get_basename (file)); secondary = g_strdup (_("If you replace an existing file, " "its contents will be overwritten.")); dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL, "%s", primary); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", secondary); gtk_window_set_title (GTK_WINDOW (dialog), ""); gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); button = gsearchtool_button_new_with_stock_icon (_("_Replace"), GTK_STOCK_OK); gtk_widget_set_can_default (button, TRUE); gtk_widget_show (button); gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET(dialog)); g_free (primary); g_free (secondary); return response; } void save_results_cb (GtkWidget * chooser, gint response, gpointer data) { GSearchWindow * gsearch = data; GtkListStore * store; GtkTreeIter iter; FILE * fp; gchar * utf8 = NULL; if (response != GTK_RESPONSE_OK) { gtk_widget_destroy (GTK_WIDGET (chooser)); return; } store = gsearch->search_results_list_store; g_free (gsearch->save_results_as_default_filename); gsearch->save_results_as_default_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); gtk_widget_destroy (chooser); if (gsearch->save_results_as_default_filename != NULL) { utf8 = g_filename_to_utf8 (gsearch->save_results_as_default_filename, -1, NULL, NULL, NULL); } if (utf8 == NULL) { display_dialog_could_not_save_no_name (gsearch->window); return; } if (g_file_test (gsearch->save_results_as_default_filename, G_FILE_TEST_IS_DIR)) { display_dialog_could_not_save_to (gsearch->window, utf8, _("The document name you selected is a folder.")); g_free (utf8); return; } if (g_file_test (gsearch->save_results_as_default_filename, G_FILE_TEST_EXISTS)) { gint response; response = display_dialog_could_not_save_exists (gsearch->window, utf8); if (response != GTK_RESPONSE_OK) { g_free (utf8); return; } } if ((fp = fopen (gsearch->save_results_as_default_filename, "w")) != NULL) { gint idx; for (idx = 0; idx < gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL); idx++) { if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter, NULL, idx) == TRUE) { gchar * locale_file; gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COLUMN_LOCALE_FILE, &locale_file, -1); fprintf (fp, "%s\n", locale_file); g_free (locale_file); } } fclose (fp); } else { display_dialog_could_not_save_to (gsearch->window, utf8, _("You may not have write permissions to the document.")); } g_free (utf8); } void save_session_cb (EggSMClient * client, GKeyFile * state_file, gpointer client_data) { GSearchWindow * gsearch = client_data; char ** argv; int argc; set_clone_command (gsearch, &argc, &argv, "mate-search-tool", FALSE); egg_sm_client_set_restart_command (client, argc, (const char **) argv); } gboolean key_press_cb (GtkWidget * widget, GdkEventKey * event, gpointer data) { GSearchWindow * gsearch = data; g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); if (event->keyval == GDK_KEY_Escape) { if (gsearch->command_details->command_status == RUNNING) { click_stop_cb (widget, data); } else if (gsearch->command_details->is_command_timeout_enabled == FALSE) { quit_cb (widget, (GdkEvent *) NULL, data); } } else if (event->keyval == GDK_KEY_F10) { if (event->state & GDK_SHIFT_MASK) { gboolean no_files_found = FALSE; GtkTreeModel * model; GtkTreeIter iter; GList * list; if (gtk_tree_selection_count_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection)) == 0) { return FALSE; } list = gtk_tree_selection_get_selected_rows (GTK_TREE_SELECTION (gsearch->search_results_selection), &model); gtk_tree_model_get_iter (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, g_list_first (list)->data); gtk_tree_model_get (GTK_TREE_MODEL (gsearch->search_results_list_store), &iter, COLUMN_NO_FILES_FOUND, &no_files_found, -1); g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); if (!no_files_found) { gtk_menu_popup (GTK_MENU (gsearch->search_results_popup_menu), NULL, NULL, NULL, NULL, event->keyval, event->time); return TRUE; } } } return FALSE; } gboolean not_running_timeout_cb (gpointer data) { GSearchWindow * gsearch = data; gsearch->command_details->is_command_timeout_enabled = FALSE; return FALSE; } void disable_quick_search_cb (GtkWidget * dialog, gint response, gpointer data) { GSearchWindow * gsearch = data; gtk_widget_destroy (GTK_WIDGET (dialog)); if (response == GTK_RESPONSE_OK) { g_settings_set_boolean (gsearch->mate_search_tool_settings, "disable-quick-search", TRUE); } } void single_click_to_activate_key_changed_cb (GSettings * settings, gchar * key, gpointer user_data) { GSearchWindow * gsearch = user_data; gchar * value; value = g_settings_get_string (settings, key); gsearch->is_search_results_single_click_to_activate = (strncmp (value, "single", 6) == 0) ? TRUE : FALSE; g_free (value); } void columns_changed_cb (GtkTreeView * treeview, gpointer user_data) { GVariantBuilder array_builder; GSearchWindow * gsearch = user_data; GSList * order; GSList * iter; order = gsearchtool_get_columns_order (treeview); g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("ai")); for (iter = order; iter; iter = iter->next) g_variant_builder_add (&array_builder, "i", GPOINTER_TO_INT (iter->data)); if (g_slist_length (order) == NUM_VISIBLE_COLUMNS) { g_settings_set_value (gsearch->mate_search_tool_settings, "columns-order", g_variant_new ("ai", &array_builder)); } g_slist_free (order); } gboolean window_state_event_cb (GtkWidget * widget, GdkEventWindowState * event, gpointer data) { GSearchWindow * gsearch = data; if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) { gsearch->is_window_maximized = TRUE; } else { gsearch->is_window_maximized = FALSE; } return FALSE; }