Commit fcdeac4a authored by Paolo Bacchilega's avatar Paolo Bacchilega Committed by Paolo Bacchilega
Browse files

Added ability to create compressed files from the Nautilus context menu

2004-12-07  Paolo Bacchilega  <paobac@cvs.gnome.org>

        * src/fr-archive.h:
        * src/window.h:
        * src/window.c (window_archive__open_add):
        * src/fr-archive.c (create_command_from_filename):
        * src/dlg-batch-add.c (add_clicked_cb):
        * src/fr-command-cfile.c (fr_command_cfile_add): Added ability to
        create compressed files from the Nautilus context menu command.

        Fixed bug #160617: "Create archive" context menu item does not support
        single-file bz2 or gz

        * src/file_roller.glade:
        * src/dlg-batch-add.c (dlg_batch_add_files): Added ability to select a
        destination folder.

        Fixed bug #160401: create archive doesn't work on read-only CD-ROM

        * src/file-utils.c (check_permissions): new function.
parent 44ccf927
2004-12-07 Paolo Bacchilega <paobac@cvs.gnome.org>
* src/fr-archive.h:
* src/window.h:
* src/window.c (window_archive__open_add):
* src/fr-archive.c (create_command_from_filename):
* src/dlg-batch-add.c (add_clicked_cb):
* src/fr-command-cfile.c (fr_command_cfile_add): Added ability to
create compressed files from the Nautilus context menu command.
Fixed bug #160617: "Create archive" context menu item does not support
single-file bz2 or gz
* src/file_roller.glade:
* src/dlg-batch-add.c (dlg_batch_add_files): Added ability to select a
destination folder.
Fixed bug #160401: create archive doesn't work on read-only CD-ROM
* src/file-utils.c (check_permissions): new function.
2004-12-04 Paolo Bacchilega <paobac@cvs.gnome.org>
* src/fr-command.c (fr_command_list):
......
......@@ -252,7 +252,7 @@ nautilus_fr_get_file_items (NautilusMenuProvider *provider,
items = g_list_append (items, item);
} else if (one_archive && !can_write) {
} else if (one_archive && ! can_write) {
NautilusMenuItem *item;
item = nautilus_menu_item_new ("NautilusFr::extract_to",
......
......@@ -3,7 +3,7 @@
/*
* File-Roller
*
* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
* Copyright (C) 2001, 2003, 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
......@@ -28,6 +28,7 @@
#include <glade/glade.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-mime.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include "file-utils.h"
#include "fr-stock.h"
......@@ -50,6 +51,7 @@ typedef struct {
GtkWidget *dialog;
GtkWidget *a_add_to_entry;
GtkWidget *a_location_filechooserbutton;
GtkWidget *add_image;
GList *file_list;
......@@ -131,26 +133,6 @@ add_clicked_cb (GtkWidget *widget,
return;
}
/**/
if (path_is_dir (archive_name)) {
GtkWidget *d;
d = _gtk_message_dialog_new (GTK_WINDOW (window->app),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_DIALOG_ERROR,
_("Could not create the archive"),
_("You have to specify an archive name."),
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
gtk_dialog_run (GTK_DIALOG (d));
gtk_widget_destroy (GTK_WIDGET (d));
g_free (archive_name);
return;
}
/* if the user do not specify an extension use tgz as default */
if (strchr (archive_name, '.') == NULL) {
char *new_archive_name;
......@@ -179,7 +161,27 @@ add_clicked_cb (GtkWidget *widget,
/* Check directory existence. */
archive_dir = remove_level_from_path ((char*) data->file_list->data);
archive_dir = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (data->a_location_filechooserbutton));
if (! check_permissions (archive_dir, R_OK|W_OK|X_OK)) {
GtkWidget *d;
d = _gtk_message_dialog_new (GTK_WINDOW (window->app),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_DIALOG_ERROR,
_("Could not create the archive"),
_("You don't have the right permissions to create an archive in the destination folder."),
GTK_STOCK_OK, GTK_RESPONSE_CANCEL,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_CANCEL);
gtk_dialog_run (GTK_DIALOG (d));
gtk_widget_destroy (GTK_WIDGET (d));
g_free (archive_dir);
g_free (archive_name);
return;
}
if (! path_is_dir (archive_dir)) {
GtkWidget *d;
int r;
......@@ -196,6 +198,8 @@ add_clicked_cb (GtkWidget *widget,
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_YES);
r = gtk_dialog_run (GTK_DIALOG (d));
gtk_widget_destroy (GTK_WIDGET (d));
do_not_add = (r != GTK_RESPONSE_YES);
}
if (! do_not_add && ! ensure_dir_exists (archive_dir, 0755)) {
......@@ -240,11 +244,65 @@ add_clicked_cb (GtkWidget *widget,
return;
}
/**/
archive_file = g_build_filename (archive_dir, archive_name, NULL);
archive_ext = fr_archive_utils__get_file_name_ext (archive_name);
eel_gconf_set_string (PREF_BATCH_ADD_DEFAULT_EXTENSION, archive_ext);
if (path_is_dir (archive_file)) {
GtkWidget *d;
d = _gtk_message_dialog_new (GTK_WINDOW (window->app),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_DIALOG_ERROR,
_("Could not create the archive"),
_("You have to specify an archive name."),
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
gtk_dialog_run (GTK_DIALOG (d));
gtk_widget_destroy (GTK_WIDGET (d));
g_free (archive_name);
g_free (archive_dir);
g_free (archive_file);
return;
}
if (path_is_file (archive_file)
&& ((strcmp (archive_ext, ".gz") == 0)
|| (strcmp (archive_ext, ".z") == 0)
|| (strcmp (archive_ext, ".Z") == 0)
|| (strcmp (archive_ext, ".bz") == 0)
|| (strcmp (archive_ext, ".bz2") == 0)
|| (strcmp (archive_ext, ".lzo") == 0))) {
GtkWidget *d;
int r;
d = _gtk_message_dialog_new (GTK_WINDOW (data->dialog),
GTK_DIALOG_MODAL,
GTK_STOCK_DIALOG_QUESTION,
_("The archive is already present. Do you want to overwrite it?"),
NULL,
GTK_STOCK_NO, GTK_RESPONSE_NO,
_("_Overwrite"), GTK_RESPONSE_YES,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_YES);
r = gtk_dialog_run (GTK_DIALOG (d));
gtk_widget_destroy (GTK_WIDGET (d));
if (r == GTK_RESPONSE_YES)
gnome_vfs_unlink (archive_file);
else {
g_free (archive_name);
g_free (archive_dir);
g_free (archive_file);
return;
}
}
if (! path_is_file (archive_file)) {
if (window->dropped_file_list != NULL)
path_list_free (window->dropped_file_list);
......@@ -254,7 +312,7 @@ add_clicked_cb (GtkWidget *widget,
} else {
window->add_after_opening = TRUE;
window_batch_mode_add_next_action (window,
FR_BATCH_ACTION_ADD,
path_list_dup (data->file_list),
......@@ -401,6 +459,8 @@ dlg_batch_add_files (FRWindow *window,
GtkWidget *add_button;
char *path, *automatic_name = NULL;
char *default_ext;
const char *first_filename;
char *parent;
data = g_new (DialogData, 1);
......@@ -418,6 +478,7 @@ dlg_batch_add_files (FRWindow *window,
data->dialog = glade_xml_get_widget (data->gui, "batch_add_files_dialog");
data->a_add_to_entry = glade_xml_get_widget (data->gui, "a_add_to_entry");
data->a_location_filechooserbutton = glade_xml_get_widget (data->gui, "a_location_filechooserbutton");
add_button = glade_xml_get_widget (data->gui, "a_add_button");
cancel_button = glade_xml_get_widget (data->gui, "a_cancel_button");
......@@ -426,14 +487,13 @@ dlg_batch_add_files (FRWindow *window,
/* Set widgets data. */
if (file_list->next == NULL)
automatic_name = g_strdup (file_name_from_path ((char*) file_list->data));
else {
const char *first_filename = (char*) file_list->data;
char *parent = remove_level_from_path (first_filename);
first_filename = (char*) file_list->data;
parent = remove_level_from_path (first_filename);
if (file_list->next == NULL) {
automatic_name = g_strdup (file_name_from_path ((char*) file_list->data));
} else {
automatic_name = g_strdup (file_name_from_path (parent));
g_free (parent);
if ((automatic_name == NULL) || (automatic_name[0] == '\0')) {
g_free (automatic_name);
......@@ -441,6 +501,13 @@ dlg_batch_add_files (FRWindow *window,
}
}
if (check_permissions (parent, R_OK|W_OK|X_OK))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (data->a_location_filechooserbutton), parent);
else
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (data->a_location_filechooserbutton), g_get_home_dir());
g_free (parent);
default_ext = eel_gconf_get_string (PREF_BATCH_ADD_DEFAULT_EXTENSION, DEFAULT_EXTENSION);
path = g_strconcat (automatic_name, default_ext, NULL);
g_free (default_ext);
......
......@@ -1095,3 +1095,70 @@ str_substitute (const char *str,
return g_string_free (gstr, FALSE);
}
char *
escape_uri (const char *uri)
{
const char *start = NULL;
const char *uri_no_method;
char *method;
char *epath, *euri;
if (uri == NULL)
return NULL;
start = strstr (uri, "://");
if (start != NULL) {
uri_no_method = start + strlen ("://");
method = g_strndup (uri, start - uri);
} else {
uri_no_method = uri;
method = NULL;
}
epath = gnome_vfs_escape_host_and_path_string (uri_no_method);
if (method != NULL) {
euri = g_strdup_printf ("%s://%s", method, epath);
g_free (epath);
} else
euri = epath;
g_free (method);
return euri;
}
gboolean
check_permissions (const char *path,
int mode)
{
GnomeVFSFileInfo *info;
GnomeVFSResult vfs_result;
char *escaped;
info = gnome_vfs_file_info_new ();
escaped = escape_uri (path);
vfs_result = gnome_vfs_get_file_info (escaped,
info,
(GNOME_VFS_FILE_INFO_DEFAULT
| GNOME_VFS_FILE_INFO_FOLLOW_LINKS
| GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS));
g_free (escaped);
if (vfs_result != GNOME_VFS_OK)
return FALSE;
if ((mode & R_OK) && ! (info->permissions & GNOME_VFS_PERM_ACCESS_READABLE))
return FALSE;
if ((mode & W_OK) && ! (info->permissions & GNOME_VFS_PERM_ACCESS_WRITABLE))
return FALSE;
if ((mode & X_OK) && ! (info->permissions & GNOME_VFS_PERM_ACCESS_WRITABLE))
return FALSE;
return TRUE;
}
......@@ -141,4 +141,7 @@ char* file_list__get_prev_field (const char *line,
int start_from,
int field_n);
gboolean check_permissions (const char *path,
int mode);
#endif /* FILE_UTILS_H */
......@@ -269,10 +269,13 @@
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="hbox24">
<widget class="GtkTable" id="table5">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="spacing">5</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<widget class="GtkLabel" id="label28">
......@@ -283,16 +286,19 @@
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">a_add_to_entry</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
......@@ -309,9 +315,54 @@
<property name="activates_default">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label46">
<property name="visible">True</property>
<property name="label" translatable="yes">Location:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkFileChooserButton" id="a_location_filechooserbutton">
<property name="visible">True</property>
<property name="title" translatable="yes">Location</property>
<property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
<property name="local_only">True</property>
<property name="show_hidden">False</property>
<property name="width_chars">15</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
</widget>
......
......@@ -192,6 +192,7 @@ fr_archive_init (FRArchive *archive)
archive->filename = NULL;
archive->command = NULL;
archive->is_compressed_file = FALSE;
archive->can_create_compressed_file = FALSE;
archive->fake_load_func = NULL;
archive->fake_load_data = NULL;
......@@ -377,89 +378,151 @@ create_command_from_filename (FRArchive *archive,
archive->command = fr_command_tar_new (archive->process,
filename,
FR_COMPRESS_PROGRAM_GZIP);
} else if (file_extension_is (filename, ".tar.bz2")
|| file_extension_is (filename, ".tbz2")) {
return TRUE;
}
if (file_extension_is (filename, ".tar.bz2")
|| file_extension_is (filename, ".tbz2")) {
archive->command = fr_command_tar_new (archive->process,
filename,
FR_COMPRESS_PROGRAM_BZIP2);
} else if (file_extension_is (filename, ".tar.bz")
|| file_extension_is (filename, ".tbz")) {
return TRUE;
}
if (file_extension_is (filename, ".tar.bz")
|| file_extension_is (filename, ".tbz")) {
archive->command = fr_command_tar_new (archive->process,
filename,
FR_COMPRESS_PROGRAM_BZIP);
} else if (file_extension_is (filename, ".tar.Z")
|| file_extension_is (filename, ".taz")) {
return TRUE;
}
if (file_extension_is (filename, ".tar.Z")
|| file_extension_is (filename, ".taz")) {
archive->command = fr_command_tar_new (archive->process,
filename,
FR_COMPRESS_PROGRAM_COMPRESS);
} else if (file_extension_is (filename, ".tar.lzo")
|| file_extension_is (filename, ".tzo")) {
return TRUE;
}
if (file_extension_is (filename, ".tar.lzo")
|| file_extension_is (filename, ".tzo")) {
archive->command = fr_command_tar_new (archive->process,
filename,
FR_COMPRESS_PROGRAM_LZOP);
} else if (file_extension_is (filename, ".tar")) {
return TRUE;
}
if (file_extension_is (filename, ".tar")) {
archive->command = fr_command_tar_new (archive->process,
filename,
FR_COMPRESS_PROGRAM_NONE);
} else if (file_extension_is (filename, ".zip")
|| file_extension_is (filename, ".ear")
|| file_extension_is (filename, ".jar")
|| file_extension_is (filename, ".war")) {
return TRUE;
}
if (file_extension_is (filename, ".zip")
|| file_extension_is (filename, ".ear")
|| file_extension_is (filename, ".jar")
|| file_extension_is (filename, ".war")) {
archive->command = fr_command_zip_new (archive->process,
filename);
} else if (file_extension_is (filename, ".zoo")) {
return TRUE;
}
if (file_extension_is (filename, ".zoo")) {
archive->command = fr_command_zoo_new (archive->process,
filename);
} else if (file_extension_is (filename, ".lzh")) {
return TRUE;
}
if (file_extension_is (filename, ".lzh")) {
archive->command = fr_command_lha_new (archive->process,
filename);
} else if (file_extension_is (filename, ".rar")) {
return TRUE;
}
if (file_extension_is (filename, ".rar")) {
archive->command = fr_command_rar_new (archive->process,
filename);
} else if (file_extension_is (filename, ".arj")) {
return TRUE;
}
if (file_extension_is (filename, ".arj")) {
archive->command = fr_command_arj_new (archive->process,
filename);
} else if (file_extension_is (filename, ".ar")) {
return TRUE;
}
if (file_extension_is (filename, ".ar")) {
archive->command = fr_command_ar_new (archive->process,
filename);
} else if (file_extension_is (filename, ".7z")) {
return TRUE;
}
if (file_extension_is (filename, ".7z")) {
archive->command = fr_command_7z_new (archive->process,
filename);
} else if (loading) {
return TRUE;
}
if (loading || archive->can_create_compressed_file) {
if (file_extension_is (filename, ".gz")
|| file_extension_is (filename, ".z")
|| file_extension_is (filename, ".Z")) {
archive->command = fr_command_cfile_new (archive->process, filename, FR_COMPRESS_PROGRAM_GZIP);
archive->is_compressed_file = TRUE;
} else if (file_extension_is (filename, ".bz")) {
return TRUE;
}
if (file_extension_is (filename, ".bz")) {
archive->command = fr_command_cfile_new (archive->process, filename, FR_COMPRESS_PROGRAM_BZIP);
archive->is_compressed_file = TRUE;
} else if (file_extension_is (filename, ".bz2")) {
return TRUE;
}
if (file_extension_is (filename, ".bz2")) {
archive->command = fr_command_cfile_new (archive->process, filename, FR_COMPRESS_PROGRAM_BZIP2);
archive->is_compressed_file = TRUE;
} else if (file_extension_is (filename, ".lzo")) {
return TRUE;
}
if (file_extension_is (filename, ".lzo")) {
archive->command = fr_command_cfile_new (archive->process, filename, FR_COMPRESS_PROGRAM_LZOP);
archive->is_compressed_file = TRUE;
} else if (file_extension_is (filename, ".bin")
|| file_extension_is (filename, ".sit")) {
return TRUE;
}
}
if (loading) {
if (file_extension_is (filename, ".bin")
|| file_extension_is (filename, ".sit")) {
archive->command = fr_command_unstuff_new (archive->process,
filename);
} else if (file_extension_is (filename, ".rpm")) {
return TRUE;
}
if (file_extension_is (filename, ".rpm")) {
archive->command = fr_command_rpm_new (archive->process,
filename);
} else if (file_extension_is (filename, ".iso")) {
return TRUE;
}
if (file_extension_is (filename, ".iso")) {
archive->command = fr_command_iso_new (archive->process,
filename);
} else if (file_extension_is (filename, ".deb")) {
return TRUE;
}
if (file_extension_is (filename, ".deb")) {
archive->command = fr_command_ar_new (archive->process,
filename);
return TRUE;
}
}
} else
return FALSE;
} else
return FALSE;
return TRUE;
return FALSE;
}
......
......@@ -51,6 +51,7 @@ struct _FRArchive {
* or a compressed file. */
gboolean read_only; /* Whether archive is read-only
* or not. */
gboolean can_create_compressed_file;