/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Engrampa * * Copyright (C) 2004 Free Software Foundation, Inc. * * 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 #include #include #include #include #include #include #include "actions.h" #include "dlg-add-files.h" #include "dlg-add-folder.h" #include "dlg-extract.h" #include "dlg-delete.h" #include "dlg-new.h" #include "dlg-open-with.h" #include "dlg-password.h" #include "dlg-prop.h" #include "gtk-utils.h" #include "fr-window.h" #include "file-utils.h" #include "fr-process.h" #include "glib-utils.h" #include "fr-init.h" #include "typedefs.h" /* -- new archive -- */ static void new_archive (DlgNewData *data, char *uri) { GtkWidget *archive_window; gboolean new_window; const char *password; gboolean encrypt_header; int volume_size; new_window = fr_window_archive_is_present (data->window) && ! fr_window_is_batch_mode (data->window); if (new_window) archive_window = fr_window_new (); else archive_window = (GtkWidget *) data->window; password = dlg_new_data_get_password (data); encrypt_header = dlg_new_data_get_encrypt_header (data); volume_size = dlg_new_data_get_volume_size (data); fr_window_set_password (FR_WINDOW (archive_window), password); fr_window_set_encrypt_header (FR_WINDOW (archive_window), encrypt_header); fr_window_set_volume_size (FR_WINDOW (archive_window), volume_size); if (fr_window_archive_new (FR_WINDOW (archive_window), uri)) { gtk_widget_destroy (data->dialog); if (! fr_window_is_batch_mode (FR_WINDOW (archive_window))) gtk_window_present (GTK_WINDOW (archive_window)); } else if (new_window) gtk_widget_destroy (archive_window); } /* when on Automatic the user provided extension needs to be supported, otherwise an existing unsupported archive can be deleted (if the user provided name matches with its name) before we find out that the archive is unsupported */ static gboolean is_supported_extension (GtkWidget *file_sel, char *filename, int *file_type) { int i; for (i = 0; file_type[i] != -1; i++) if (file_extension_is (filename, mime_type_desc[file_type[i]].default_ext)) return TRUE; return FALSE; } static char * get_full_uri (DlgNewData *data) { char *full_uri = NULL; char *uri; const char *filename; int idx; uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (data->dialog)); if ((uri == NULL) || (*uri == 0)) return NULL; filename = file_name_from_path (uri); if ((filename == NULL) || (*filename == 0)) { g_free (uri); return NULL; } idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (data->format_chooser), uri); if (idx > 0) { const char *uri_ext; const char *default_ext; uri_ext = get_archive_filename_extension (uri); default_ext = mime_type_desc[data->supported_types[idx-1]].default_ext; if (strcmp_null_tolerant (uri_ext, default_ext) != 0) full_uri = g_strconcat (uri, default_ext, NULL); } if (full_uri == NULL) full_uri = uri; else g_free (uri); return full_uri; } static char * get_archive_filename_from_selector (DlgNewData *data) { char *uri = NULL; GFile *file, *dir; GFileInfo *info; GError *err = NULL; uri = get_full_uri (data); if ((uri == NULL) || (*uri == 0)) { GtkWidget *dialog; g_free (uri); dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog), GTK_DIALOG_DESTROY_WITH_PARENT, NULL, _("Could not create the archive"), "%s", _("You have to specify an archive name.")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); return NULL; } file = g_file_new_for_uri (uri); dir = g_file_get_parent (file); info = g_file_query_info (dir, G_FILE_ATTRIBUTE_ACCESS_CAN_READ "," G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "," G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE, 0, NULL, &err); if (err != NULL) { g_warning ("Failed to get permission for extraction dir: %s", err->message); g_clear_error (&err); g_object_unref (info); g_object_unref (dir); g_object_unref (file); g_free (uri); return NULL; } if (! g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) { GtkWidget *dialog; g_object_unref (info); g_object_unref (dir); g_object_unref (file); g_free (uri); dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog), GTK_DIALOG_DESTROY_WITH_PARENT, NULL, _("Could not create the archive"), "%s", _("You don't have permission to create an archive in this folder")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); return NULL; } g_object_unref (info); g_object_unref (dir); if ((data->original_file != NULL) && (g_file_equal (file, data->original_file))) { GtkWidget *dialog; dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog), GTK_DIALOG_MODAL, NULL, _("Could not create the archive"), "%s", _("New name is the same as old one, please type other name.")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); g_object_unref (info); g_object_unref (file); return NULL; } /* if the user did not specify a valid extension use the filetype combobox current type * or tar.gz if automatic is selected. */ if (get_archive_filename_extension (uri) == NULL) { int idx; char *new_uri; const char *ext = NULL; idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (data->format_chooser), uri); if (idx > 0) ext = mime_type_desc[data->supported_types[idx-1]].default_ext; else ext = ".tar.gz"; new_uri = g_strconcat (uri, ext, NULL); g_free (uri); uri = new_uri; } debug (DEBUG_INFO, "create/save %s\n", uri); if (uri_exists (uri)) { if (! is_supported_extension (data->dialog, uri, data->supported_types)) { GtkWidget *dialog; dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog), GTK_DIALOG_MODAL, NULL, _("Could not create the archive"), "%s", _("Archive type not supported.")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); g_free (uri); return NULL; } g_file_delete (file, NULL, &err); if (err != NULL) { GtkWidget *dialog; dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog), GTK_DIALOG_DESTROY_WITH_PARENT, NULL, _("Could not delete the old archive."), "%s", err->message); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); g_error_free (err); g_free (uri); g_object_unref (file); return NULL; } } g_object_unref (file); return uri; } static void new_file_response_cb (GtkWidget *w, int response, DlgNewData *data) { char *path; if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) { fr_archive_action_completed (data->window->archive, FR_ACTION_CREATING_NEW_ARCHIVE, FR_PROC_ERROR_STOPPED, NULL); gtk_widget_destroy (data->dialog); return; } if (response == GTK_RESPONSE_HELP) { show_help_dialog (GTK_WINDOW (data->dialog), "engrampa-create"); return; } path = get_archive_filename_from_selector (data); if (path != NULL) { new_archive (data, path); g_free (path); } } void show_new_archive_dialog (FrWindow *window, const char *archive_name) { DlgNewData *data; if (archive_name != NULL) data = dlg_save_as (window, archive_name); else data = dlg_new (window); g_signal_connect (G_OBJECT (data->dialog), "response", G_CALLBACK (new_file_response_cb), data); gtk_window_present (GTK_WINDOW (data->dialog)); } void activate_action_new (GtkAction *action, gpointer data) { show_new_archive_dialog ((FrWindow*)data, NULL); } /* -- open archive -- */ static void window_archive_loaded_cb (FrWindow *window, gboolean success, GtkWidget *file_sel) { if (success) { g_signal_handlers_disconnect_by_data (window, file_sel); gtk_widget_destroy (file_sel); } else { FrWindow *original_window = g_object_get_data (G_OBJECT (file_sel), "fr_window"); if (window != original_window) fr_window_destroy_with_error_dialog (window); } } static void open_file_response_cb (GtkWidget *w, int response, GtkWidget *file_sel) { FrWindow *window = NULL; char *uri; if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) { gtk_widget_destroy (file_sel); return; } window = g_object_get_data (G_OBJECT (file_sel), "fr_window"); uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (file_sel)); if ((window == NULL) || (uri == NULL)) return; if (fr_window_archive_is_present (window)) window = (FrWindow *) fr_window_new (); g_signal_connect (G_OBJECT (window), "archive_loaded", G_CALLBACK (window_archive_loaded_cb), file_sel); fr_window_archive_open (window, uri, GTK_WINDOW (file_sel)); g_free (uri); } void activate_action_open (GtkAction *action, gpointer data) { GtkWidget *file_sel; FrWindow *window = data; GtkFileFilter *filter; int i; file_sel = gtk_file_chooser_dialog_new (_("Open"), GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN, "gtk-cancel", GTK_RESPONSE_CANCEL, "gtk-open", GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (file_sel), GTK_RESPONSE_OK); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (file_sel), FALSE); gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (file_sel), fr_window_get_open_default_dir (window)); filter = gtk_file_filter_new (); gtk_file_filter_set_name (filter, _("All archives")); for (i = 0; open_type[i] != -1; i++) gtk_file_filter_add_mime_type (filter, mime_type_desc[open_type[i]].mime_type); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_sel), filter); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (file_sel), filter); filter = gtk_file_filter_new (); gtk_file_filter_set_name (filter, _("All files")); gtk_file_filter_add_pattern (filter, "*"); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_sel), filter); /**/ g_object_set_data (G_OBJECT (file_sel), "fr_window", window); g_signal_connect (G_OBJECT (file_sel), "response", G_CALLBACK (open_file_response_cb), file_sel); gtk_window_set_modal (GTK_WINDOW (file_sel), TRUE); gtk_widget_show (file_sel); } /* -- save archive -- */ static void save_file_response_cb (GtkWidget *w, gint response, DlgNewData *data) { char *path; const char *password; gboolean encrypt_header; int volume_size; GSettings *settings; if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) { gtk_widget_destroy (data->dialog); return; } if (response == GTK_RESPONSE_HELP) { show_help_dialog (GTK_WINDOW (data->dialog), "engrampa-create#engrampa-convert-archive"); return; } path = get_archive_filename_from_selector (data); if (path == NULL) return; password = dlg_new_data_get_password (data); encrypt_header = dlg_new_data_get_encrypt_header (data); volume_size = dlg_new_data_get_volume_size (data); settings = g_settings_new (ENGRAMPA_SCHEMA_BATCH_ADD); g_settings_set_int (settings, PREF_BATCH_ADD_VOLUME_SIZE, volume_size); g_object_unref (settings); fr_window_archive_save_as (data->window, path, password, encrypt_header, volume_size); gtk_widget_destroy (data->dialog); g_free (path); } void activate_action_save_as (GtkAction *action, gpointer callback_data) { FrWindow *window = callback_data; DlgNewData *data; GFile *file = NULL; char *archive_name = NULL; if (fr_window_get_archive_uri (window)) { const char *uri; GFileInfo *info; GError *err = NULL; uri = fr_window_get_archive_uri (window); file = g_file_new_for_uri (uri); info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, &err); if (err != NULL) { g_warning ("Failed to get display name for uri %s: %s", uri, err->message); g_clear_error (&err); } else archive_name = g_strdup (g_file_info_get_display_name (info)); g_object_unref (info); } data = dlg_save_as (window, archive_name); data->original_file = file; g_signal_connect (G_OBJECT (data->dialog), "response", G_CALLBACK (save_file_response_cb), data); gtk_window_present (GTK_WINDOW (data->dialog)); g_free (archive_name); } void activate_action_test_archive (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_archive_test (window); } void activate_action_properties (GtkAction *action, gpointer data) { FrWindow *window = data; dlg_prop (window); } void activate_action_close (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_close (window); } void activate_action_add_files (GtkAction *action, gpointer data) { add_files_cb (NULL, data); } void activate_action_add_folder (GtkAction *action, gpointer data) { add_folder_cb (NULL, data); } void activate_action_extract (GtkAction *action, gpointer data) { dlg_extract (NULL, data); } void activate_action_extract_folder_from_sidebar (GtkAction *action, gpointer data) { dlg_extract_folder_from_sidebar (NULL, data); } void activate_action_copy (GtkAction *action, gpointer data) { fr_window_copy_selection ((FrWindow*) data, FALSE); } void activate_action_cut (GtkAction *action, gpointer data) { fr_window_cut_selection ((FrWindow*) data, FALSE); } void activate_action_paste (GtkAction *action, gpointer data) { fr_window_paste_selection ((FrWindow*) data, FALSE); } void activate_action_rename (GtkAction *action, gpointer data) { fr_window_rename_selection ((FrWindow*) data, FALSE); } void activate_action_delete (GtkAction *action, gpointer data) { dlg_delete (NULL, data); } void activate_action_copy_folder_from_sidebar (GtkAction *action, gpointer data) { fr_window_copy_selection ((FrWindow*) data, TRUE); } void activate_action_cut_folder_from_sidebar (GtkAction *action, gpointer data) { fr_window_cut_selection ((FrWindow*) data, TRUE); } void activate_action_paste_folder_from_sidebar (GtkAction *action, gpointer data) { fr_window_paste_selection ((FrWindow*) data, TRUE); } void activate_action_rename_folder_from_sidebar (GtkAction *action, gpointer data) { fr_window_rename_selection ((FrWindow*) data, TRUE); } void activate_action_delete_folder_from_sidebar (GtkAction *action, gpointer data) { dlg_delete_from_sidebar (NULL, data); } void activate_action_find (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_find (window); } void activate_action_select_all (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_select_all (window); } void activate_action_deselect_all (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_unselect_all (window); } void activate_action_open_with (GtkAction *action, gpointer data) { open_with_cb (NULL, (FrWindow*) data); } void activate_action_view_or_open (GtkAction *action, gpointer data) { FrWindow *window = data; GList *file_list; file_list = fr_window_get_file_list_selection (window, FALSE, NULL); if (file_list == NULL) return; fr_window_open_files (window, file_list, FALSE); path_list_free (file_list); } void activate_action_open_folder (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_current_folder_activated (window, FALSE); } void activate_action_open_folder_from_sidebar (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_current_folder_activated (window, TRUE); } void activate_action_password (GtkAction *action, gpointer data) { dlg_password (NULL, (FrWindow*) data); } void activate_action_view_toolbar (GtkAction *action, gpointer data) { GSettings *settings; settings = g_settings_new (ENGRAMPA_SCHEMA_UI); g_settings_set_boolean (settings, PREF_UI_VIEW_TOOLBAR, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); g_object_unref (settings); } void activate_action_view_statusbar (GtkAction *action, gpointer data) { GSettings *settings; settings = g_settings_new (ENGRAMPA_SCHEMA_UI); g_settings_set_boolean (settings, PREF_UI_VIEW_STATUSBAR, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); g_object_unref (settings); } void activate_action_view_folders (GtkAction *action, gpointer data) { GSettings *settings; settings = g_settings_new (ENGRAMPA_SCHEMA_UI); g_settings_set_boolean (settings, PREF_UI_VIEW_FOLDERS, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))); g_object_unref (settings); } void activate_action_stop (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_stop (window); } void activate_action_reload (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_archive_reload (window); } void activate_action_sort_reverse_order (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_set_sort_type (window, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING); } void activate_action_last_output (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_view_last_output (window, _("Last Output")); } void activate_action_go_back (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_go_back (window); } void activate_action_go_forward (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_go_forward (window); } void activate_action_go_up (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_go_up_one_level (window); } void activate_action_go_home (GtkAction *action, gpointer data) { FrWindow *window = data; fr_window_go_to_location (window, "/", FALSE); } void activate_action_manual (GtkAction *action, gpointer data) { FrWindow *window = data; show_help_dialog (GTK_WINDOW (window) , NULL); } #define ABOUT_GROUP "About" #define EMAILIFY(string) (g_strdelimit ((string), "%", '@')) void activate_action_about (GtkAction *action, gpointer gp) { FrWindow *window = gp; const char *documenters [] = { "Alexander Kirillov", "Breda McColgan", NULL }; const char *license[] = { N_("Engrampa 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."), N_("Engrampa 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."), N_("You should have received a copy of the GNU General Public License " "along with Engrampa; if not, write to the Free Software Foundation, Inc., " "51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA") }; char *license_text; GKeyFile *key_file; GBytes *bytes; const guint8 *data; gsize data_len; GError *error = NULL; char **authors; gsize n_authors = 0, i; bytes = g_resources_lookup_data (ENGRAMPA_RESOURCE_UI_PATH G_DIR_SEPARATOR_S "engrampa.about", G_RESOURCE_LOOKUP_FLAGS_NONE, &error); g_assert_no_error (error); data = g_bytes_get_data (bytes, &data_len); key_file = g_key_file_new (); g_key_file_load_from_data (key_file, (const char *) data, data_len, 0, &error); g_assert_no_error (error); authors = g_key_file_get_string_list (key_file, ABOUT_GROUP, "Authors", &n_authors, NULL); g_key_file_free (key_file); g_bytes_unref (bytes); for (i = 0; i < n_authors; ++i) authors[i] = EMAILIFY (authors[i]); license_text = g_strjoin ("\n\n", _(license[0]), _(license[1]), _(license[2]), NULL); gtk_show_about_dialog (GTK_WINDOW (window), "version", VERSION, "copyright", _("Copyright \xc2\xa9 2001–2010 Free Software Foundation, Inc.\n" "Copyright \xc2\xa9 2012–2021 The MATE developers"), "comments", _("Engrampa is an archive manager for the MATE Desktop Environment."), "authors", authors, "documenters", documenters, "translator-credits", _("translator-credits"), "logo-icon-name", "engrampa", "license", license_text, "wrap-license", TRUE, "website", PACKAGE_URL, NULL); g_strfreev (authors); g_free (license_text); }