file-roller r2286 - in trunk: . src



Author: paobac
Date: Mon Jun  2 11:14:27 2008
New Revision: 2286
URL: http://svn.gnome.org/viewvc/file-roller?rev=2286&view=rev

Log:
2008-06-02  Paolo Bacchilega  <paobac svn gnome org>

	* src/*.[ch]: changed the way a FrArchive creates FrCommand objects. 
	This makes the code easier to maintain and more modularized, and can 
	be seen as a first step in the direction of a plugin system that will 
	allow to add new archive types support without changing file-roller.
	
	* configure.in: changed version to 2.23.2

2008-06-01  Paolo Bacchilega  <paobac svn gnome org>

	* src/ui.h: 
	
	Fixed bug #535967 â Meaningless message: Open Go to the next visited 
	location selected folder

Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/src/actions.c
   trunk/src/dlg-batch-add.c
   trunk/src/file-utils.c
   trunk/src/file-utils.h
   trunk/src/fr-archive.c
   trunk/src/fr-archive.h
   trunk/src/fr-command-7z.c
   trunk/src/fr-command-7z.h
   trunk/src/fr-command-ace.c
   trunk/src/fr-command-ace.h
   trunk/src/fr-command-ar.c
   trunk/src/fr-command-ar.h
   trunk/src/fr-command-arj.c
   trunk/src/fr-command-arj.h
   trunk/src/fr-command-cfile.c
   trunk/src/fr-command-cfile.h
   trunk/src/fr-command-cpio.c
   trunk/src/fr-command-cpio.h
   trunk/src/fr-command-iso.c
   trunk/src/fr-command-iso.h
   trunk/src/fr-command-jar.c
   trunk/src/fr-command-jar.h
   trunk/src/fr-command-lha.c
   trunk/src/fr-command-lha.h
   trunk/src/fr-command-rar.c
   trunk/src/fr-command-rar.h
   trunk/src/fr-command-rpm.c
   trunk/src/fr-command-rpm.h
   trunk/src/fr-command-tar.c
   trunk/src/fr-command-tar.h
   trunk/src/fr-command-unstuff.c
   trunk/src/fr-command-unstuff.h
   trunk/src/fr-command-zip.c
   trunk/src/fr-command-zip.h
   trunk/src/fr-command-zoo.c
   trunk/src/fr-command-zoo.h
   trunk/src/fr-command.c
   trunk/src/fr-command.h
   trunk/src/fr-process.c
   trunk/src/fr-process.h
   trunk/src/fr-window.c
   trunk/src/fr-window.h
   trunk/src/gio-utils.c
   trunk/src/main.c
   trunk/src/main.h
   trunk/src/preferences.c
   trunk/src/preferences.h
   trunk/src/typedefs.h
   trunk/src/ui.h

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Mon Jun  2 11:14:27 2008
@@ -2,7 +2,7 @@
 
 AC_PREREQ(2.52)
 
-AC_INIT(file-roller, 2.23.1)
+AC_INIT(file-roller, 2.23.2)
 AC_CONFIG_SRCDIR(src/main.c)
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 AM_CONFIG_HEADER(config.h)

Modified: trunk/src/actions.c
==============================================================================
--- trunk/src/actions.c	(original)
+++ trunk/src/actions.c	Mon Jun  2 11:14:27 2008
@@ -98,8 +98,8 @@
 			char      *filename)
 {
 	int i;
-	for (i = 0; save_type[i] != FR_FILE_TYPE_NULL; i++)
-		if (file_extension_is (filename, file_type_desc[save_type[i]].ext))
+	for (i = 0; save_type[i] != -1; i++)
+		if (file_extension_is (filename, mime_type_desc[save_type[i]].default_ext))
 			return TRUE;
 	return FALSE;
 }
@@ -126,8 +126,11 @@
 
 	idx = gtk_combo_box_get_active (GTK_COMBO_BOX (data->combo_box));
 	if (idx > 0) {
-		const char *path_ext = fr_archive_utils__get_file_name_ext (path);
-		char       *default_ext = file_type_desc[save_type[idx-1]].ext;
+		const char *path_ext;
+		char       *default_ext;
+		
+		path_ext = get_archive_filename_extension (path);
+		default_ext = mime_type_desc[save_type[idx-1]].default_ext;
 		if (strcmp_null_tolerant (path_ext, default_ext) != 0) {
 			full_path = g_strconcat (path, default_ext, NULL);
 			g_free (path);
@@ -206,14 +209,14 @@
 
 	/* if the user did not specify a valid extension use the filetype combobox current type
 	 * or tar.gz if automatic is selected. */
-	if (fr_archive_utils__get_file_name_ext (path) == NULL) {
+	if (get_archive_filename_extension (path) == NULL) {
 		int   idx;
 		char *new_path;
 		char *ext = NULL;
 
 		idx = gtk_combo_box_get_active (GTK_COMBO_BOX (data->combo_box));
 		if (idx > 0)
-			ext = file_type_desc[save_type[idx-1]].ext;
+			ext = mime_type_desc[save_type[idx-1]].default_ext;
 		else
 			ext = ".tar.gz";
 		new_path = g_strconcat (path, ext, NULL);
@@ -306,10 +309,10 @@
 		return;
 	}
 				
-	for (i = 0; file_type_desc[i].id != FR_FILE_TYPE_NULL; i++) {
-		if (strcmp (file_type_desc[i].ext, ext) == 0) {
-			gtk_widget_set_sensitive (data->password, file_type_desc[i].supports_password);
-			gtk_widget_set_sensitive (data->password_label, file_type_desc[i].supports_password);
+	for (i = 0; mime_type_desc[i].mime_type != NULL; i++) {
+		if (strcmp (mime_type_desc[i].default_ext, ext) == 0) {
+			gtk_widget_set_sensitive (data->password, mime_type_desc[i].supports_password);
+			gtk_widget_set_sensitive (data->password_label, mime_type_desc[i].supports_password);
 			break;
 		}
 	}
@@ -331,7 +334,7 @@
 	if (uri == NULL)
 		return;
 	
-	ext = fr_archive_utils__get_file_name_ext (uri);
+	ext = get_archive_filename_extension (uri);
 	if (ext == NULL)
 		ext = "";
 	
@@ -347,7 +350,7 @@
 	basename = file_name_from_path (uri);
 	basename_noext = g_strndup (basename, strlen (basename) - strlen (ext));
 
-	new_ext = file_type_desc[save_type[idx]].ext;
+	new_ext = mime_type_desc[save_type[idx]].default_ext;
 	new_basename = g_strconcat (basename_noext, new_ext, NULL);
 	new_basename_uft8 = g_uri_unescape_string (new_basename, NULL);
 	gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (data->file_sel), new_basename_uft8);
@@ -397,8 +400,8 @@
 
 	filter = gtk_file_filter_new ();
 	gtk_file_filter_set_name (filter, _("All archives"));
-	for (i = 0; save_type[i] != FR_FILE_TYPE_NULL; i++)
-		gtk_file_filter_add_mime_type (filter, file_type_desc[save_type[i]].mime_type);
+	for (i = 0; save_type[i] != -1; i++)
+		gtk_file_filter_add_mime_type (filter, mime_type_desc[save_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);
 
@@ -418,9 +421,9 @@
 
 	data->combo_box = gtk_combo_box_new_text ();
 	gtk_combo_box_append_text (GTK_COMBO_BOX (data->combo_box), _("Automatic"));
-	for (i = 0; save_type[i] != FR_FILE_TYPE_NULL; i++)
+	for (i = 0; save_type[i] != -1; i++)
 		gtk_combo_box_append_text (GTK_COMBO_BOX (data->combo_box),
-					   _(file_type_desc[save_type[i]].name));
+					   _(mime_type_desc[save_type[i]].name));
 	gtk_combo_box_set_active (GTK_COMBO_BOX (data->combo_box), 0);
 	gtk_box_pack_start (GTK_BOX (hbox), data->combo_box, TRUE, TRUE, 0);
 	gtk_widget_show_all (hbox);
@@ -523,8 +526,8 @@
 
 	filter = gtk_file_filter_new ();
 	gtk_file_filter_set_name (filter, _("All archives"));
-	for (i = 0; open_type[i] != FR_FILE_TYPE_NULL; i++)
-		gtk_file_filter_add_mime_type (filter, file_type_desc[open_type[i]].mime_type);
+	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);
 
@@ -644,8 +647,8 @@
 
 	filter = gtk_file_filter_new ();
 	gtk_file_filter_set_name (filter, _("All archives"));
-	for (i = 0; save_type[i] != FR_FILE_TYPE_NULL; i++)
-		gtk_file_filter_add_mime_type (filter, file_type_desc[save_type[i]].mime_type);
+	for (i = 0; save_type[i] != -1; i++)
+		gtk_file_filter_add_mime_type (filter, mime_type_desc[save_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);
 
@@ -673,9 +676,9 @@
 
 	data->combo_box = gtk_combo_box_new_text ();
 	gtk_combo_box_append_text (GTK_COMBO_BOX (data->combo_box), _("Automatic"));
-	for (i = 0; save_type[i] != FR_FILE_TYPE_NULL; i++)
+	for (i = 0; save_type[i] != -1; i++)
 		gtk_combo_box_append_text (GTK_COMBO_BOX (data->combo_box),
-					   _(file_type_desc[save_type[i]].name));
+					   _(mime_type_desc[save_type[i]].name));
 	gtk_combo_box_set_active (GTK_COMBO_BOX (data->combo_box), 0);
 	gtk_table_attach (GTK_TABLE (table), data->combo_box, 1, 2, 0, 1,
 			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),

Modified: trunk/src/dlg-batch-add.c
==============================================================================
--- trunk/src/dlg-batch-add.c	(original)
+++ trunk/src/dlg-batch-add.c	Mon Jun  2 11:14:27 2008
@@ -80,8 +80,8 @@
 static const char *
 get_ext (DialogData *data)
 {
-	FRFileType *save_type_list;
-	int         idx;
+	int *save_type_list;
+	int  idx;
 
 	if (data->single_file)
 		save_type_list = single_file_save_type;
@@ -90,7 +90,7 @@
 
 	idx = gtk_combo_box_get_active (GTK_COMBO_BOX (data->a_archive_type_combo_box));
 
-	return file_type_desc[save_type_list[idx]].ext;
+	return mime_type_desc[save_type_list[idx]].default_ext;
 }
 
 
@@ -326,7 +326,7 @@
 archive_type_combo_box_changed_cb (GtkComboBox *combo_box,
 				   DialogData  *data)
 {
-	FRFileType *save_type_list;
+	int        *save_type_list;
 	const char *mime_type;
 	int         idx = gtk_combo_box_get_active (combo_box);
 
@@ -334,7 +334,7 @@
 		save_type_list = single_file_save_type;
 	else
 		save_type_list =  save_type;
-	mime_type = file_type_desc[save_type_list[idx]].mime_type;
+	mime_type = mime_type_desc[save_type_list[idx]].mime_type;
 
 	gtk_image_set_from_pixbuf (GTK_IMAGE (data->add_image), get_mime_type_pixbuf (mime_type, ARCHIVE_ICON_SIZE, NULL));
 }
@@ -344,9 +344,9 @@
 update_archive_type_combo_box_from_ext (DialogData  *data,
 					const char  *ext)
 {
-	FRFileType *save_type_list;
-	int         idx = 0;
-	int         i;
+	int *save_type_list;
+	int  idx = 0;
+	int  i;
 
 	if (ext == NULL) {
 		gtk_combo_box_set_active (GTK_COMBO_BOX (data->a_archive_type_combo_box), 0);
@@ -358,8 +358,8 @@
 	else
 		save_type_list =  save_type;
 
-	for (i = 0; save_type_list[i] != FR_FILE_TYPE_NULL; i++)
-		if (strcmp (ext, file_type_desc[save_type_list[i]].ext) == 0) {
+	for (i = 0; save_type_list[i] != -1; i++)
+		if (strcmp (ext, mime_type_desc[save_type_list[i]].default_ext) == 0) {
 			idx = i;
 			break;
 		}
@@ -381,7 +381,7 @@
 	const char *first_filename;
 	char       *parent;
 	int         i;
-	FRFileType *save_type_list;
+	int        *save_type_list;
 
 	if (file_list == NULL)
 		return;
@@ -446,9 +446,9 @@
 	else
 		save_type_list = save_type;
 
-	for (i = 0; save_type_list[i] != FR_FILE_TYPE_NULL; i++) {
+	for (i = 0; save_type_list[i] != -1; i++) {
 		gtk_combo_box_append_text (GTK_COMBO_BOX (data->a_archive_type_combo_box),
-					   file_type_desc[save_type_list[i]].ext);
+					   mime_type_desc[save_type_list[i]].default_ext);
 	}
 
 	gtk_box_pack_start (GTK_BOX (a_archive_type_box), data->a_archive_type_combo_box, TRUE, TRUE, 0);

Modified: trunk/src/file-utils.c
==============================================================================
--- trunk/src/file-utils.c	(original)
+++ trunk/src/file-utils.c	Mon Jun  2 11:14:27 2008
@@ -367,6 +367,20 @@
 
 
 time_t
+get_file_mtime_for_path (const char *path)
+{
+	char   *uri;
+	time_t  result;
+	
+	uri = g_filename_to_uri (path, NULL, NULL);
+	result = get_file_mtime (uri);
+	g_free (uri);
+	
+	return result;
+}
+
+
+time_t
 get_file_ctime (const char *uri)
 {
 	return get_file_time_type (uri, G_FILE_ATTRIBUTE_TIME_CREATED);
@@ -580,6 +594,37 @@
 }
 
 
+const char *
+get_file_extension (const char *filename)
+{
+	const char *ptr = filename;
+	int         len;
+	int         p;
+	const char *ext;
+	
+	if (filename == NULL)
+		return NULL;
+
+	len = strlen (filename);
+	if (len <= 1)
+		return NULL;
+
+	p = len - 1;
+	while ((p >= 0) && (ptr[p] != '.'))
+		p--;
+	if (p < 0)
+		return NULL;
+
+	ext = filename + p;	
+	if (ext - 4 > filename) {
+		const char *test = ext - 4;
+		if (strncmp (test, ".tar", 4) == 0)
+			ext = ext - 4;
+	} 
+	return ext;
+}
+
+
 gboolean
 file_extension_is (const char *filename,
 		   const char *ext)

Modified: trunk/src/file-utils.h
==============================================================================
--- trunk/src/file-utils.h	(original)
+++ trunk/src/file-utils.h	Mon Jun  2 11:14:27 2008
@@ -48,8 +48,9 @@
 gboolean            path_in_path                 (const char  *path_src,
 						  const char  *path_dest);
 goffset             get_file_size                (const char  *uri);
-time_t              get_file_mtime               (const char  *s);
-time_t              get_file_ctime               (const char  *s);
+time_t              get_file_mtime               (const char  *uri);
+time_t              get_file_mtime_for_path      (const char  *path);
+time_t              get_file_ctime               (const char  *uri);
 gboolean            make_directory_tree          (GFile       *dir,
 		     				  mode_t       mode,
 		     				  GError     **error);
@@ -65,6 +66,7 @@
 char *              remove_level_from_path       (const char  *path);
 char *              remove_extension_from_path   (const char  *path);
 char *              remove_ending_separator      (const char  *path);
+const char *        get_file_extension           (const char  *filename);
 gboolean            file_extension_is            (const char  *filename,
 						  const char  *ext);
 gboolean            is_mime_type                 (const char  *type,

Modified: trunk/src/fr-archive.c
==============================================================================
--- trunk/src/fr-archive.c	(original)
+++ trunk/src/fr-archive.c	Mon Jun  2 11:14:27 2008
@@ -36,24 +36,10 @@
 #include "file-data.h"
 #include "fr-archive.h"
 #include "fr-command.h"
-#include "fr-command-ace.h"
-#include "fr-command-ar.h"
-#include "fr-command-arj.h"
-#include "fr-command-cfile.h"
-#include "fr-command-cpio.h"
-#include "fr-command-iso.h"
-#include "fr-command-jar.h"
-#include "fr-command-lha.h"
-#include "fr-command-rar.h"
-#include "fr-command-rpm.h"
-#include "fr-command-tar.h"
-#include "fr-command-unstuff.h"
-#include "fr-command-zip.h"
-#include "fr-command-zoo.h"
-#include "fr-command-7z.h"
 #include "fr-error.h"
 #include "fr-marshal.h"
 #include "fr-process.h"
+#include "main.h"
 
 #ifndef NCARGS
 #define NCARGS _POSIX_ARG_MAX
@@ -70,7 +56,7 @@
 	char          *dest_dir;
 	gboolean       update;
 	char          *password;
-	FRCompression  compression;
+	FrCompression  compression;
 } DroppedItemsData;
 
 
@@ -81,7 +67,7 @@
 			const char    *dest_dir,
 			gboolean       update,
 			const char    *password,
-			FRCompression  compression)
+			FrCompression  compression)
 {
 	DroppedItemsData *data;
 
@@ -114,7 +100,7 @@
 }
 
 
-struct _FRArchivePrivData {
+struct _FrArchivePrivData {
 	FakeLoadFunc         fake_load_func;                /* If returns TRUE, archives are not read when
 							     * fr_archive_load is invoked, used
 							     * in batch mode. */
@@ -138,12 +124,12 @@
 	FrArchive      *archive;
 	char           *uri;
 	char           *password;
-	FRAction        action;
+	FrAction        action;
 	GList          *file_list;
 	char           *base_uri;
 	char           *dest_dir;
 	gboolean        update;
-	FRCompression   compression;
+	FrCompression   compression;
 	char           *tmp_dir;
 	guint           source_id;
 } XferData;
@@ -306,8 +292,8 @@
 
 void
 fr_archive_action_completed (FrArchive       *archive,
-			     FRAction         action,
-			     FRProcErrorType  error_type,
+			     FrAction         action,
+			     FrProcErrorType  error_type,
 			     const char      *error_details)
 {
 	archive->error.type = error_type;
@@ -490,84 +476,6 @@
 }
 
 
-/* filename must not be escaped. */
-static gboolean
-create_command_from_mime_type (FrArchive  *archive,
-			       const char *mime_type)
-{
-	char *filename;
-	
-	archive->is_compressed_file = FALSE;
-
-	filename = g_file_get_path (archive->local_copy);
-	if (is_mime_type (mime_type, "application/x-tar")) {
-		archive->command = fr_command_tar_new (archive->process,
-						       filename,
-						       FR_COMPRESS_PROGRAM_NONE);
-	} 
-	else if (is_mime_type (mime_type, "application/x-compressed-tar")) {
-		archive->command = fr_command_tar_new (archive->process,
-						       filename,
-						       FR_COMPRESS_PROGRAM_GZIP);
-	} 
-	else if (is_mime_type (mime_type, "application/x-bzip-compressed-tar")) {
-		archive->command = fr_command_tar_new (archive->process,
-						       filename,
-						       FR_COMPRESS_PROGRAM_BZIP2);
-	} 
-	else if (is_mime_type (mime_type, "application/zip") ||
-		   is_mime_type (mime_type, "application/x-zip") ||
-		   is_mime_type (mime_type, "application/octet-stream")) {
-		archive->command = fr_command_zip_new (archive->process,
-						       filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-zoo")) {
-		archive->command = fr_command_zoo_new (archive->process,
-						       filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-rar")) {
-		archive->command = fr_command_rar_new (archive->process,
-						       filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-arj")) {
-		archive->command = fr_command_arj_new (archive->process,
-						       filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-stuffit")) {
-		archive->command = fr_command_unstuff_new (archive->process,
-							   filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-rpm")) {
-		archive->command = fr_command_rpm_new (archive->process,
-						       filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-cd-image")) {
-		archive->command = fr_command_iso_new (archive->process,
-						       filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-deb") ||
-		   is_mime_type (mime_type, "application/x-ar")) {
-		archive->command = fr_command_ar_new (archive->process,
-						      filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-ace")) {
-		archive->command = fr_command_ace_new (archive->process,
-						       filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-7zip")) {
-		archive->command = fr_command_7z_new (archive->process,
-						      filename);
-	} 
-	else if (is_mime_type (mime_type, "application/x-cpio")) {
-		archive->command = fr_command_cpio_new (archive->process,
-							filename);
-	} 
-	g_free (filename);
-	
-	return (archive->command != NULL);
-}
-
-
 static const char *
 get_mime_type_from_content (GFile *file)
 {
@@ -592,232 +500,72 @@
 
 
 static gboolean
-hexcmp (const char *first_bytes,
-	const char *buffer,
-	int         len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		if (first_bytes[i] != buffer[i])
-			return FALSE;
-
-	return TRUE;
-}
-
-
-/* filename must not be escaped. */
-static const char *
-get_mime_type_from_sniffer (GFile *file)
+create_command_from_mime_type (FrArchive  *archive,
+			       const char *mime_type,
+			       gboolean    loading)
 {
-	static struct {
-		const char *mime_type;
-		const char *first_bytes;
-		int         len;
-	} sniffer_data [] = {
-		{"application/zip",                   "\x50\x4B\x03\x04", 4},
-		/* FIXME
-		   {"application/x-compressed-tar",      "\x1F\x8B\x08\x08", 4},
-		   {"application/x-bzip-compressed-tar", "\x42\x5A\x68\x39", 4},
-		 */
-		{ NULL, NULL, 0 }
-	};
-	char             *filename;
-	GFileInputStream *stream;
-	char              buffer[5];
-	int               n, i;
-
-	if (! g_file_has_uri_scheme (file, "file"))
-		return NULL;
-
-	filename = g_file_get_path (file);
-	if (file_extension_is (filename, ".jar")) {
-		g_free (filename);
-		return NULL;
+	FrCommandCaps  requested_capabilities = FR_COMMAND_CAP_NONE;
+	GType          command_type;
+	char          *filename;
+	
+	if (mime_type == NULL)
+		return FALSE;
+	
+	archive->is_compressed_file = FALSE;
+	
+	requested_capabilities |= FR_COMMAND_CAP_READ;
+	if (! loading) {
+		requested_capabilities |= FR_COMMAND_CAP_WRITE;	
+		if (! archive->can_create_compressed_file)
+			requested_capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
 	}
-	g_free (filename);
-		
-	stream = g_file_read (file, NULL , NULL);
-	if (stream == NULL) 
-		return NULL;
+	command_type = get_command_type_from_mime_type (mime_type, requested_capabilities);
 	
-	n = g_input_stream_read (G_INPUT_STREAM (stream), buffer, sizeof (buffer) - 1, NULL, NULL);
-	g_object_unref (stream);
+	if (command_type == 0)
+		return FALSE;
 	
-	if (n == -1)
-		return NULL;
-		
-	buffer[n] = 0;
-	for (i = 0; sniffer_data[i].mime_type != NULL; i++) {
-		const char *first_bytes = sniffer_data[i].first_bytes;
-		int         len         = sniffer_data[i].len;
-
-		if (hexcmp (first_bytes, buffer, len))
-			return sniffer_data[i].mime_type;
+	filename = g_file_get_path (archive->local_copy);
+	archive->command = FR_COMMAND (g_object_new (command_type,
+					             "process", archive->process,
+					             "filename", filename,
+					             "mime-type", mime_type,
+					             NULL));
+	g_free (filename);
+	
+	if (! fr_command_is_capable_of (archive->command, requested_capabilities)) {
+		g_object_unref (archive->command);
+		archive->command = NULL;
 	}
-
-	return NULL;
+	else if (archive->command != NULL)
+		archive->is_compressed_file = ! fr_command_is_capable_of (archive->command, FR_COMMAND_CAP_ARCHIVE_MANY_FILES);
+	
+	return (archive->command != NULL);
 }
 
 
-/* filename must not be escaped. */
 static gboolean
 create_command_from_filename (FrArchive *archive,
 			      gboolean   loading)
 {
-	char *filename;
+	char     *filename;
+	gboolean  result = FALSE;
 	
-	archive->is_compressed_file = FALSE;
+	if (archive->local_copy == NULL)
+		return FALSE;
 	
 	filename = g_file_get_path (archive->local_copy);
-	if (file_extension_is (filename, ".tar.gz")
-	    || file_extension_is (filename, ".tgz")) 
-	{
-		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")) 
-	{
-		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")) 
-	{
-		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")) 
-	{
-		archive->command = fr_command_tar_new (archive->process,
-						       filename,
-						       FR_COMPRESS_PROGRAM_COMPRESS);
-	}
-	else if (file_extension_is (filename, ".tar.lzma")
-	         || file_extension_is (filename, ".tzma")) 
-	{
-		archive->command = fr_command_tar_new (archive->process,
-						       filename,
-						       FR_COMPRESS_PROGRAM_LZMA);
-	}
-	else 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")) 
-	{
-		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, ".war")
-	         || file_extension_is (filename, ".exe")) 
-	{
-		archive->command = fr_command_zip_new (archive->process,
-						       filename);
-	}
-	else if (file_extension_is (filename, ".jar")) {
-		archive->command = fr_command_jar_new (archive->process,
-						       filename);
-	}
-	else if (file_extension_is (filename, ".zoo")) {
-		archive->command = fr_command_zoo_new (archive->process,
-						       filename);
-	}
-	else if (file_extension_is (filename, ".lzh")
-	         || file_extension_is (filename, ".lha")) 
-	{
-		archive->command = fr_command_lha_new (archive->process,
-						       filename);
-	}
-	else if (file_extension_is (filename, ".rar")) {
-		archive->command = fr_command_rar_new (archive->process,
-						       filename);
-	}
-	else if (file_extension_is (filename, ".arj")) {
-		archive->command = fr_command_arj_new (archive->process,
-						       filename);
-	}
-	else if (file_extension_is (filename, ".ar")) {
-		archive->command = fr_command_ar_new (archive->process,
-						      filename);
-	}
-	else if (file_extension_is (filename, ".7z")) {
-		archive->command = fr_command_7z_new (archive->process,
-						      filename);
-	}
-	else 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")) {
-			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")) {
-			archive->command = fr_command_cfile_new (archive->process, filename, FR_COMPRESS_PROGRAM_BZIP2);
-			archive->is_compressed_file = TRUE;
-		}
-		else if (file_extension_is (filename, ".lzma")) {
-			archive->command = fr_command_cfile_new (archive->process, filename, FR_COMPRESS_PROGRAM_LZMA);
-			archive->is_compressed_file = TRUE;
-		}
-		else 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, ".cpio")) {
-			archive->command = fr_command_cpio_new (archive->process,
-								filename);
-		}
-		else if (! archive->can_create_compressed_file) {
-			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")) {
-				archive->command = fr_command_rpm_new (archive->process,
-								       filename);
-			}
-			else if (file_extension_is (filename, ".iso")) {
-				archive->command = fr_command_iso_new (archive->process,
-							      	       filename);
-			} 
-			else if (file_extension_is (filename, ".deb")) {
-				archive->command = fr_command_ar_new (archive->process,
-							              filename);
-			}
-			else if (file_extension_is (filename, ".ace")) {
-				archive->command = fr_command_ace_new (archive->process,
-							       	       filename);
-			}
-		}
-	}
+	result = create_command_from_mime_type (archive, 
+					        get_mime_type_from_extension (get_file_extension (filename)), 
+					        loading);
 	g_free (filename);
 	
-	return (archive->command != NULL);
+	return result;
 }
 
 
 static void
 action_started (FrCommand *command,
-		FRAction   action,
+		FrAction   action,
 		FrArchive *archive)
 {
 #ifdef DEBUG
@@ -836,10 +584,10 @@
 
 static void
 fr_archive_copy_done (FrArchive *archive,
-		      FRAction   action,
+		      FrAction   action,
 		      GError    *error)
 {
-	FRProcErrorType  error_type = FR_PROC_ERROR_NONE;
+	FrProcErrorType  error_type = FR_PROC_ERROR_NONE;
 	const char      *error_details = NULL;
 
 	if (error != NULL) {
@@ -881,7 +629,7 @@
 
 static void
 copy_to_remote_location (FrArchive  *archive,
-			 FRAction    action)
+			 FrAction    action)
 {
 	XferData *xfer_data;
 	
@@ -1036,8 +784,8 @@
 
 static void
 action_performed (FrCommand   *command,
-		  FRAction     action,
-		  FRProcError *error,
+		  FrAction     action,
+		  FrProcError *error,
 		  FrArchive   *archive)
 {
 #ifdef DEBUG
@@ -1214,13 +962,11 @@
 
 	archive->read_only = ! check_permissions (uri, W_OK);
 
-	/* find mime type */
+	/* find out the archive mime type */
 
 	tmp_command = archive->command;
-	mime_type = get_mime_type_from_sniffer (archive->local_copy);
-	if (mime_type == NULL)
-		mime_type = get_mime_type_from_content (archive->local_copy);
-	if ((mime_type == NULL) || ! create_command_from_mime_type (archive, mime_type)) {
+	mime_type = get_mime_type_from_content (archive->local_copy);
+	if (! create_command_from_mime_type (archive, mime_type, TRUE)) {
 		if (! create_command_from_filename (archive, TRUE)) {
 			archive->command = tmp_command;
 			fr_archive_action_completed (archive,
@@ -1237,10 +983,9 @@
 
 	archive->content_type = mime_type;
 
-	if ((archive->command->file_type == FR_FILE_TYPE_ZIP)
-	    && (! is_program_in_path ("zip")))
+	if (! fr_command_is_capable_of (archive->command, FR_COMMAND_CAP_WRITE)) 
 		archive->read_only = TRUE;
-
+	
 	g_signal_connect (G_OBJECT (archive->command),
 			  "start",
 			  G_CALLBACK (action_started),
@@ -1418,12 +1163,12 @@
 {
 	g_return_if_fail (archive != NULL);
 
-	if (archive->is_compressed_file)
+	if (archive->is_compressed_file) {
 		/* If the archive is a compressed file we have to reload it,
 		 * because in this case the 'content' of the archive changes
 		 * too. */
 		fr_archive_load (archive, filename, NULL);
-
+	}
 	else {
 		g_object_unref (archive->file);
 		archive->file = g_file_new_for_path (filename);
@@ -1611,7 +1356,7 @@
 		const char    *dest_dir,
 		gboolean       update,
 		const char    *password,
-		FRCompression  compression)
+		FrCompression  compression)
 {
 	GList    *new_file_list = NULL;
 	gboolean  base_dir_created = FALSE;
@@ -1759,7 +1504,7 @@
 			    const char    *dest_dir,
 			    gboolean       update,
 			    const char    *password,
-			    FRCompression  compression)
+			    FrCompression  compression)
 {
 	fr_archive_stoppable (archive, TRUE);
 	fr_process_clear (archive->process);
@@ -1819,7 +1564,7 @@
 		   const char    *dest_dir,
 		   gboolean       update,
 		   const char    *password,
-		   FRCompression  compression,
+		   FrCompression  compression,
 		   const char    *tmp_dir)
 {
 	GList      *sources = NULL, *destinations = NULL;
@@ -1915,7 +1660,7 @@
 		      const char    *dest_dir,
 		      gboolean       update,
 		      const char    *password,
-		      FRCompression  compression)
+		      FrCompression  compression)
 {
 	if (uri_is_local (base_dir)) {
 		char *local_dir = g_filename_from_uri (base_dir, NULL, NULL);
@@ -1949,7 +1694,7 @@
 	char          *dest_dir;
 	gboolean       update;
 	char          *password;
-	FRCompression  compression;
+	FrCompression  compression;
 } AddWithWildcardData;
 
 
@@ -2012,7 +1757,7 @@
 			      gboolean       recursive,
 			      gboolean       follow_links,
 			      const char    *password,
-			      FRCompression  compression)
+			      FrCompression  compression)
 {
 	AddWithWildcardData *aww_data;
 
@@ -2056,7 +1801,7 @@
 	char          *dest_dir;
 	gboolean       update;
 	char          *password;
-	FRCompression  compression;
+	FrCompression  compression;
 } AddDirectoryData;
 
 
@@ -2120,7 +1865,7 @@
 			  const char    *dest_dir,
 			  gboolean       update,
 			  const char    *password,
-			  FRCompression  compression)
+			  FrCompression  compression)
 
 {
 	AddDirectoryData *ad_data;
@@ -2157,7 +1902,7 @@
 		      const char    *dest_dir,
 		      gboolean       update,
 		      const char    *password,
-		      FRCompression  compression)
+		      FrCompression  compression)
 
 {
 	AddDirectoryData *ad_data;
@@ -2354,7 +2099,7 @@
 			      const char    *dest_dir,
 			      gboolean       update,
 			      const char    *password,
-			      FRCompression  compression)
+			      FrCompression  compression)
 {
 	GList *scan;
 	char  *archive_uri;
@@ -2422,15 +2167,8 @@
 archive_type_has_issues_deleting_non_empty_folders (FrArchive *archive)
 {
 	/*if ((archive->command->files == NULL) || (archive->command->files->len == 0))
-		return FALSE;  FIXME: test with extract_here */
-		
-	return ((archive->command->file_type == FR_FILE_TYPE_TAR)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_BZ)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_BZ2)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_GZ)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_LZMA)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_LZOP)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_COMPRESS));
+		return FALSE;  FIXME: test with extract_here */		
+	return ! archive->command->propCanDeleteNonEmptyFolders;
 }
 
 
@@ -2526,7 +2264,7 @@
 void
 fr_archive_remove (FrArchive     *archive,
 		   GList         *file_list,
-		   FRCompression  compression)
+		   FrCompression  compression)
 {
 	g_return_if_fail (archive != NULL);
 
@@ -2763,14 +2501,7 @@
 {
 	/*if ((archive->command->files == NULL) || (archive->command->files->len == 0))
 		return FALSE;  FIXME: test with extract_here */
-		
-	return ((archive->command->file_type == FR_FILE_TYPE_TAR)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_BZ)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_BZ2)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_GZ)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_LZMA)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_LZOP)
-		|| (archive->command->file_type == FR_FILE_TYPE_TAR_COMPRESS));
+	return ! archive->command->propCanExtractNonEmptyFolders;
 }
 
 
@@ -2965,7 +2696,7 @@
 		if (! archive->command->propExtractCanSkipOlder
 		    && skip_older
 		    && g_file_test (dest_filename, G_FILE_TEST_EXISTS)
-		    && (fdata->modified < get_file_mtime (dest_filename)))
+		    && (fdata->modified < get_file_mtime_for_path (dest_filename)))
 			continue;
 
 		if (! archive->command->propExtractCanAvoidOverwrite
@@ -3098,7 +2829,7 @@
 	directory_uri = g_file_get_uri (directory);
 	
 	name = g_file_get_basename (file);
-	ext = fr_archive_utils__get_file_name_ext (name);
+	ext = get_archive_filename_extension (name);
 	if (ext == NULL)
 		/* if no extension is present add a suffix to the name... */
 		new_name = g_strconcat (name, "_FILES", NULL);
@@ -3209,87 +2940,25 @@
 }
 
 
-/*
- * Remember to keep the ext array in alphanumeric order and to scan the array
- * in reverse order, this is because the file 'foo.tar.gz' must return the
- * '.tar.gz' and not the '.gz' extension.
- */
-G_CONST_RETURN char *
-fr_archive_utils__get_file_name_ext (const char *filename)
-{
-	static char * ext[] = {
-		".7z",
-		".ace",
-		".ar",
-		".arj",
-		".bin",
-		".bz",
-		".bz2",
-		".cpio",
-		".deb",
-		".ear",
-		".gz",
-		".iso",
-		".jar",
-		".lzh",
-		".lzma",
-		".lzo",
-		".rar",
-		".rpm",
-		".sit",
-		".tar",
-		".tar.bz",
-		".tar.bz2",
-		".tar.gz",
-		".tar.lzma",
-		".tar.lzo",
-		".tar.Z",
-		".taz",
-		".tbz",
-		".tbz2",
-		".tgz",
-		".tzo",
-		".war",
-		".z",
-		".zip",
-		".zoo",
-		".Z"
-	};
-	int n = sizeof (ext) / sizeof (char*);
-	int i;
-
-	if (filename == NULL)
-		return NULL;
-
-	for (i = n - 1; i >= 0; i--)
-		if (file_extension_is (filename, ext[i]))
-			return ext[i];
-
-	return NULL;
-}
-
-
 gboolean
-fr_archive_utils__file_is_archive (const char *filename)
+uri_is_archive (const char *uri)
 {
 	GFile      *file;
 	const char *mime_type;
 
-	file = g_file_new_for_uri (filename);
-	
-	mime_type = get_mime_type_from_sniffer (file);
-	if (mime_type != NULL) {
-		g_object_unref (file);
-		return TRUE;
-	}
-		
+	file = g_file_new_for_uri (uri);
 	mime_type = get_mime_type_from_content (file);
 	if (mime_type != NULL) {
-		g_object_unref (file);
-		return TRUE;
+		int i;
+		
+		for (i = 0; mime_type_desc[i].mime_type != NULL; i++) {
+			if (strcmp (mime_type_desc[i].mime_type, mime_type) == 0) {
+				g_object_unref (file);
+				return TRUE;
+			}
+		}
 	}
-	
 	g_object_unref (file);
 
-	return fr_archive_utils__get_file_name_ext (filename) != NULL;
+	return get_archive_filename_extension (uri) != NULL;
 }

Modified: trunk/src/fr-archive.h
==============================================================================
--- trunk/src/fr-archive.h	(original)
+++ trunk/src/fr-archive.h	Mon Jun  2 11:14:27 2008
@@ -35,8 +35,8 @@
 #define FR_ARCHIVE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), FR_TYPE_ARCHIVE, FrArchiveClass))
 
 typedef struct _FrArchive         FrArchive;
-typedef struct _FRArchiveClass    FrArchiveClass;
-typedef struct _FRArchivePrivData FrArchivePrivData;
+typedef struct _FrArchiveClass    FrArchiveClass;
+typedef struct _FrArchivePrivData FrArchivePrivData;
 
 typedef gboolean (*FakeLoadFunc) (FrArchive *archive, gpointer data);
 
@@ -49,7 +49,7 @@
 	const char  *content_type;
 	FrCommand   *command;
 	FrProcess   *process;
-	FRProcError  error;
+	FrProcError  error;
 	gboolean     can_create_compressed_file;
 	gboolean     is_compressed_file;         /* Whether the file is an 
 						  * archive or a compressed 
@@ -60,16 +60,16 @@
 	FrArchivePrivData *priv;
 };
 
-struct _FRArchiveClass {
+struct _FrArchiveClass {
 	GObjectClass __parent_class;
 
 	/* -- Signals -- */
 
 	void (*start)     (FrArchive   *archive,
-			   FRAction     action); 
+			   FrAction     action); 
 	void (*done)      (FrArchive   *archive,
-			   FRAction     action, 
-			   FRProcError *error);
+			   FrAction     action, 
+			   FrProcError *error);
 	void (*progress)  (FrArchive   *archive,
 			   double       fraction);
 	void (*message)   (FrArchive   *archive,
@@ -91,8 +91,8 @@
 						  gboolean       stoppable);
 void        fr_archive_stop	                 (FrArchive     *archive);
 void        fr_archive_action_completed          (FrArchive       *archive,
-						  FRAction         action,
-						  FRProcErrorType  error_type,
+						  FrAction         action,
+						  FrProcErrorType  error_type,
 						  const char      *error_details);
 
 /**/
@@ -118,10 +118,10 @@
 						  const char    *dest_dir,
 						  gboolean       update,
 						  const char    *password,
-						  FRCompression  compression);
+						  FrCompression  compression);
 void        fr_archive_remove                    (FrArchive     *archive,
 						  GList         *file_list,
-						  FRCompression  compression);
+						  FrCompression  compression);
 void        fr_archive_extract                   (FrArchive     *archive,
 						  GList         *file_list,
 						  const char    *dest_uri,
@@ -153,7 +153,7 @@
 						  const char    *dest_dir,
 						  gboolean       update,
 						  const char    *password,
-						  FRCompression  compression);
+						  FrCompression  compression);
 void        fr_archive_add_with_wildcard         (FrArchive     *archive,
 						  const char    *include_files,
 						  const char    *exclude_files,
@@ -164,34 +164,33 @@
 						  gboolean       recursive,
 						  gboolean       follow_links,
 						  const char    *password,
-						  FRCompression  compression);
+						  FrCompression  compression);
 void        fr_archive_add_directory             (FrArchive     *archive,
 						  const char    *directory,
 						  const char    *base_dir,
 						  const char    *dest_dir,
 						  gboolean       update,
 						  const char    *password,
-						  FRCompression  compression);
+						  FrCompression  compression);
 void        fr_archive_add_items                 (FrArchive     *archive,
 						  GList         *item_list,
 						  const char    *base_dir,
 						  const char    *dest_dir,
 						  gboolean       update,
 						  const char    *password,
-						  FRCompression  compression);
+						  FrCompression  compression);
 void        fr_archive_add_dropped_items         (FrArchive     *archive,
 						  GList         *item_list,
 						  const char    *base_dir,
 						  const char    *dest_dir,
 						  gboolean       update,
 						  const char    *password,
-						  FRCompression  compression);
+						  FrCompression  compression);
 void        fr_archive_test                      (FrArchive     *archive,
 						  const char    *password);
 
 /* utils */
 
-G_CONST_RETURN char * fr_archive_utils__get_file_name_ext (const char *filename);
-gboolean              fr_archive_utils__file_is_archive   (const char *filename);
+gboolean              uri_is_archive             (const char *uri);
 
 #endif /* ARCHIVE_H */

Modified: trunk/src/fr-command-7z.c
==============================================================================
--- trunk/src/fr-command-7z.c	(original)
+++ trunk/src/fr-command-7z.c	Mon Jun  2 11:14:27 2008
@@ -229,7 +229,7 @@
 		   const char    *base_dir,
 		   gboolean       update,
 		   const char    *password,
-		   FRCompression  compression)
+		   FrCompression  compression)
 {
 	GList *scan;
 
@@ -354,7 +354,7 @@
 
 static void
 fr_command_7z_handle_error (FrCommand   *comm,
-			    FRProcError *error)
+			    FrProcError *error)
 {
 	if (error->type == FR_PROC_ERROR_COMMAND_ERROR) {
 		if (error->status <= 1)
@@ -364,6 +364,22 @@
 
 
 static void
+fr_command_7z_set_mime_type (FrCommand  *comm,
+			     const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("7za")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	else if (is_program_in_path ("7zr")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	else if (is_program_in_path ("7z")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+}
+
+
+static void
 fr_command_7z_class_init (FrCommand7zClass *class)
 {
 	GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
@@ -380,14 +396,13 @@
 	afc->extract        = fr_command_7z_extract;
 	afc->test           = fr_command_7z_test;
 	afc->handle_error   = fr_command_7z_handle_error;
+	afc->set_mime_type  = fr_command_7z_set_mime_type;
 }
 
 
 static void
 fr_command_7z_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_7ZIP;
-
 	comm->propAddCanUpdate             = TRUE;
 	comm->propAddCanReplace            = TRUE;
 	comm->propAddCanStoreFolders       = TRUE;
@@ -437,22 +452,3 @@
 
 	return type;
 }
-
-
-FrCommand *
-fr_command_7z_new (FrProcess  *process,
-		   const char *filename)
-{
-	FrCommand *comm;
-
-	if (! is_program_in_path("7za")
-	    && ! is_program_in_path("7zr")
-	    && ! is_program_in_path("7z")) { 
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_7Z, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-7z.h
==============================================================================
--- trunk/src/fr-command-7z.h	(original)
+++ trunk/src/fr-command-7z.h	Mon Jun  2 11:14:27 2008
@@ -49,8 +49,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_7z_get_type        (void);
-FrCommand*   fr_command_7z_new             (FrProcess *process,
-					    const char *filename);
+GType fr_command_7z_get_type (void);
 
 #endif /* FR_COMMAND_7Z_H */

Modified: trunk/src/fr-command-ace.c
==============================================================================
--- trunk/src/fr-command-ace.c	(original)
+++ trunk/src/fr-command-ace.c	Mon Jun  2 11:14:27 2008
@@ -199,12 +199,24 @@
 
 static void
 fr_command_ace_handle_error (FrCommand   *comm, 
-			     FRProcError *error)
+			     FrProcError *error)
 {
 	/* FIXME */
 }
 
 
+static void
+fr_command_ace_set_mime_type (FrCommand  *comm,
+			      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("unace")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ;
+}
+
+
 static void 
 fr_command_ace_class_init (FrCommandAceClass *class)
 {
@@ -220,14 +232,13 @@
 	afc->extract        = fr_command_ace_extract;
 	afc->test           = fr_command_ace_test;
 	afc->handle_error   = fr_command_ace_handle_error;
+	afc->set_mime_type  = fr_command_ace_set_mime_type;
 }
 
  
 static void 
 fr_command_ace_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_ACE;
-
 	comm->propCanModify                = FALSE;
 	comm->propAddCanUpdate             = TRUE;
 	comm->propAddCanReplace            = TRUE;
@@ -277,19 +288,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_ace_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if(! is_program_in_path ("unace")) 
-		return NULL;
-	
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_ACE, NULL));
-	fr_command_construct (comm, process, filename);
-	
-	return comm;
-}

Modified: trunk/src/fr-command-ace.h
==============================================================================
--- trunk/src/fr-command-ace.h	(original)
+++ trunk/src/fr-command-ace.h	Mon Jun  2 11:14:27 2008
@@ -49,8 +49,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_ace_get_type        (void);
-FrCommand*   fr_command_ace_new             (FrProcess *process,
-					     const char *filename);
+GType fr_command_ace_get_type (void);
 
 #endif /* FR_COMMAND_ACE_H */

Modified: trunk/src/fr-command-ar.c
==============================================================================
--- trunk/src/fr-command-ar.c	(original)
+++ trunk/src/fr-command-ar.c	Mon Jun  2 11:14:27 2008
@@ -209,7 +209,7 @@
 		   const char    *base_dir,
 		   gboolean       update,
 		   const char    *password,
-		   FRCompression  compression)
+		   FrCompression  compression)
 {
 	GList *scan;
 
@@ -277,12 +277,24 @@
 
 static void
 fr_command_ar_handle_error (FrCommand   *comm, 
-			    FRProcError *error)
+			    FrProcError *error)
 {
 	/* FIXME */
 }
 
 
+static void
+fr_command_ar_set_mime_type (FrCommand  *comm,
+			     const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("ar")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+}
+
+
 static void 
 fr_command_ar_class_init (FrCommandArClass *class)
 {
@@ -299,14 +311,13 @@
 	afc->delete         = fr_command_ar_delete;
 	afc->extract        = fr_command_ar_extract;
 	afc->handle_error   = fr_command_ar_handle_error;
+	afc->set_mime_type  = fr_command_ar_set_mime_type;
 }
 
  
 static void 
 fr_command_ar_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_AR;
-
 	comm->propCanModify                = TRUE;
 	comm->propAddCanUpdate             = TRUE;
 	comm->propAddCanReplace            = TRUE;
@@ -357,19 +368,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_ar_new (FrProcess  *process,
-		   const char *filename)
-{
-	FrCommand *comm;
-
-	if(! is_program_in_path ("ar")) 
-		return NULL;
-	
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_AR, NULL));
-	fr_command_construct (comm, process, filename);
-	
-	return comm;
-}

Modified: trunk/src/fr-command-ar.h
==============================================================================
--- trunk/src/fr-command-ar.h	(original)
+++ trunk/src/fr-command-ar.h	Mon Jun  2 11:14:27 2008
@@ -47,8 +47,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_ar_get_type        (void);
-FrCommand*   fr_command_ar_new             (FrProcess  *process,
-					    const char *filename);
+GType fr_command_ar_get_type (void);
 
 #endif /* FR_COMMAND_AR_H */

Modified: trunk/src/fr-command-arj.c
==============================================================================
--- trunk/src/fr-command-arj.c	(original)
+++ trunk/src/fr-command-arj.c	Mon Jun  2 11:14:27 2008
@@ -183,7 +183,7 @@
 		    const char    *base_dir,
 		    gboolean       update,
 		    const char    *password,
-		    FRCompression  compression)
+		    FrCompression  compression)
 {
 	GList *scan;
 
@@ -321,7 +321,7 @@
 
 static void
 fr_command_arj_handle_error (FrCommand   *comm,
-			     FRProcError *error)
+			     FrProcError *error)
 {
 	if (error->type == FR_PROC_ERROR_COMMAND_ERROR) {
  		if (error->status <= 1)
@@ -333,6 +333,18 @@
 
 
 static void
+fr_command_arj_set_mime_type (FrCommand  *comm,
+		 	      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("arj")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+}
+
+
+static void
 fr_command_arj_class_init (FrCommandArjClass *class)
 {
 	GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
@@ -349,14 +361,13 @@
 	afc->extract        = fr_command_arj_extract;
 	afc->test           = fr_command_arj_test;
 	afc->handle_error   = fr_command_arj_handle_error;
+	afc->set_mime_type  = fr_command_arj_set_mime_type;
 }
 
 
 static void
 fr_command_arj_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_ARJ;
-
 	comm->propAddCanUpdate             = TRUE;
 	comm->propAddCanReplace            = TRUE;
 	comm->propAddCanStoreFolders       = FALSE;
@@ -409,20 +420,3 @@
 
 	return type;
 }
-
-
-FrCommand *
-fr_command_arj_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if (!is_program_in_path("arj")) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_ARJ, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-arj.h
==============================================================================
--- trunk/src/fr-command-arj.h	(original)
+++ trunk/src/fr-command-arj.h	Mon Jun  2 11:14:27 2008
@@ -51,8 +51,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_arj_get_type        (void);
-FrCommand*   fr_command_arj_new             (FrProcess  *process,
-					     const char *filename);
+GType fr_command_arj_get_type (void);
 
 #endif /* FR_COMMAND_ARJ_H */

Modified: trunk/src/fr-command-cfile.c
==============================================================================
--- trunk/src/fr-command-cfile.c	(original)
+++ trunk/src/fr-command-cfile.c	Mon Jun  2 11:14:27 2008
@@ -48,13 +48,12 @@
 get_uncompressed_name_from_archive (FrCommand  *comm, 
 				    const char *e_filename)
 {
-	FrCommandCFile *comm_cfile = FR_COMMAND_CFILE (comm);
-	int             fd;
-	char            buffer[11];
-	char           *filename = NULL;
-	GString        *str = NULL;
+	int      fd;
+	char     buffer[11];
+	char    *filename = NULL;
+	GString *str = NULL;
 
-	if (comm_cfile->compress_prog != FR_COMPRESS_PROGRAM_GZIP)
+	if (is_mime_type (comm->mime_type, "application/x-gzip"))
 		return NULL;
 	
 	fd = open (e_filename, O_RDONLY);
@@ -132,7 +131,7 @@
 
 	fdata->original_path = fdata->full_path + 1;
 	fdata->link = NULL;
-	fdata->modified = get_file_mtime (comm->filename);
+	fdata->modified = get_file_mtime_for_path (comm->filename);
 	
 	fdata->name = g_strdup (file_name_from_path (fdata->full_path));
 	fdata->path = remove_level_from_path (fdata->full_path);
@@ -150,7 +149,7 @@
 {
 	FrCommandCFile *comm_cfile = FR_COMMAND_CFILE (comm);
 
-	if (comm_cfile->compress_prog == FR_COMPRESS_PROGRAM_GZIP) {
+	if (is_mime_type (comm->mime_type, "application/x-gzip")) {
 		/* gzip let us known the uncompressed size */
 
 		fr_process_set_out_line_func (FR_COMMAND (comm)->process, 
@@ -183,7 +182,7 @@
 		fdata->original_path = fdata->full_path + 1;
 		fdata->link = NULL;
 		fdata->size = get_file_size (comm->filename);
-		fdata->modified = get_file_mtime (comm->filename);
+		fdata->modified = get_file_mtime_for_path (comm->filename);
 		
 		fdata->name = g_strdup (file_name_from_path (fdata->full_path));
 		fdata->path = remove_level_from_path (fdata->full_path);
@@ -209,13 +208,12 @@
 		      const char    *base_dir,
 		      gboolean       update,
 		      const char    *password,
-		      FRCompression  compression)
+		      FrCompression  compression)
 {
-	FrCommandCFile *comm_cfile = FR_COMMAND_CFILE (comm);
-	const char     *filename;
-	char           *temp_dir;
-	char           *e_temp_dir;
-	char           *temp_file;
+	const char *filename;
+	char       *temp_dir;
+	char       *e_temp_dir;
+	char       *temp_file;
 
 	if ((file_list == NULL) || (file_list->data == NULL))
 		return;
@@ -241,52 +239,36 @@
 
 	/**/
 
-	switch (comm_cfile->compress_prog) {
-	case FR_COMPRESS_PROGRAM_NONE:
-		break;
-		
-	case FR_COMPRESS_PROGRAM_GZIP:
+	if (is_mime_type (comm->mime_type, "application/x-gzip")) {
 		fr_process_begin_command (comm->process, "gzip");
 		fr_process_set_working_dir (comm->process, temp_dir);
 		fr_process_add_arg (comm->process, "--");
 		fr_process_add_arg (comm->process, filename);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP:
-		fr_process_begin_command (comm->process, "bzip");
-		fr_process_set_working_dir (comm->process, temp_dir);
-		fr_process_add_arg (comm->process, "--");
-		fr_process_add_arg (comm->process, filename);
-		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP2:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-bzip")) {
 		fr_process_begin_command (comm->process, "bzip2");
 		fr_process_set_working_dir (comm->process, temp_dir);
 		fr_process_add_arg (comm->process, "--");
 		fr_process_add_arg (comm->process, filename);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_COMPRESS: 
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-gzip")) {
 		fr_process_begin_command (comm->process, "compress");
 		fr_process_set_working_dir (comm->process, temp_dir);
 		fr_process_add_arg (comm->process, "-f");
 		fr_process_add_arg (comm->process, "--");
 		fr_process_add_arg (comm->process, filename);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZMA:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzma")) {
 		fr_process_begin_command (comm->process, "lzma");
 		fr_process_set_working_dir (comm->process, temp_dir);
 		fr_process_add_arg (comm->process, "--");
 		fr_process_add_arg (comm->process, filename);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZOP: /* FIXME: untested. */
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzop")) {
 		fr_process_begin_command (comm->process, "lzop");
 		fr_process_set_working_dir (comm->process, temp_dir);
 		fr_process_add_arg (comm->process, "-fU");
@@ -294,10 +276,8 @@
 		fr_process_add_arg (comm->process, "--");
 		fr_process_add_arg (comm->process, filename);
 		fr_process_end_command (comm->process);
-		break;
 	}
 
-
       	/* copy compressed file to the dest dir */
 
 	fr_process_begin_command (comm->process, "cp");
@@ -340,16 +320,15 @@
 			  gboolean    junk_paths,
 			  const char *password)
 {
-	FrCommandCFile *comm_cfile = FR_COMMAND_CFILE (comm);
-	char           *temp_dir;
-	char           *e_temp_dir;
-	char           *dest_file;
-	char           *e_dest_file;
-	char           *temp_file;
-	char           *e_temp_file;
-	char           *uncompr_file;
-	char           *e_uncompr_file;
-	char           *compr_file;
+	char *temp_dir;
+	char *e_temp_dir;
+	char *dest_file;
+	char *e_dest_file;
+	char *temp_file;
+	char *e_temp_file;
+	char *uncompr_file;
+	char *e_uncompr_file;
+	char *compr_file;
 
 	/* create a temp dir. */
 
@@ -372,51 +351,35 @@
 
 	/* uncompress the file */
 
-	switch (comm_cfile->compress_prog) {
-	case FR_COMPRESS_PROGRAM_NONE:
-		break;
-		
-	case FR_COMPRESS_PROGRAM_GZIP:
+	if (is_mime_type (comm->mime_type, "application/x-gzip")) {
 		fr_process_begin_command (comm->process, "gzip");
 		fr_process_add_arg (comm->process, "-f");
 		fr_process_add_arg (comm->process, "-d");
 		fr_process_add_arg (comm->process, "-n");
 		fr_process_add_arg (comm->process, e_temp_file);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP:
-		fr_process_begin_command (comm->process, "bzip");
-		fr_process_add_arg (comm->process, "-f");
-		fr_process_add_arg (comm->process, "-d");
-		fr_process_add_arg (comm->process, e_temp_file);
-		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP2:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-bzip")) {
 		fr_process_begin_command (comm->process, "bzip2");
 		fr_process_add_arg (comm->process, "-f");
 		fr_process_add_arg (comm->process, "-d");
 		fr_process_add_arg (comm->process, e_temp_file);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_COMPRESS: 
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-gzip")) {
 		fr_process_begin_command (comm->process, "uncompress");
 		fr_process_add_arg (comm->process, "-f");
 		fr_process_add_arg (comm->process, e_temp_file);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZMA:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzma")) {
 		fr_process_begin_command (comm->process, "lzma");
 		fr_process_add_arg (comm->process, "-f");
 		fr_process_add_arg (comm->process, "-d");
 		fr_process_add_arg (comm->process, e_temp_file);
 		fr_process_end_command (comm->process);
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZOP:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzop")) {
 		fr_process_begin_command (comm->process, "lzop");
 		fr_process_set_working_dir (comm->process, temp_dir);
 		fr_process_add_arg (comm->process, "-d");
@@ -424,7 +387,6 @@
 		fr_process_add_arg (comm->process, "--no-stdin");
 		fr_process_add_arg (comm->process, e_temp_file);
 		fr_process_end_command (comm->process);
-		break;
 	}
 
 	/* copy uncompress file to the dest dir */
@@ -467,6 +429,37 @@
 }
 
 
+static void
+fr_command_cfile_set_mime_type (FrCommand  *comm,
+			        const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	if (is_mime_type (comm->mime_type, "application/x-gzip")) {
+		if (is_program_in_path ("gzip"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-bzip")) {
+		if (is_program_in_path ("bzip2"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-gzip")) {
+		if (is_program_in_path ("compress"))
+			comm->capabilities |= FR_COMMAND_CAP_WRITE;
+		if (is_program_in_path ("uncompress"))
+			comm->capabilities |= FR_COMMAND_CAP_READ;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzma")) {
+		if (is_program_in_path ("lzma"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzop")) {
+		if (is_program_in_path ("lzop"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+}
+
+
 static void 
 fr_command_cfile_class_init (FrCommandCFileClass *class)
 {
@@ -478,10 +471,11 @@
 
         gobject_class->finalize = fr_command_cfile_finalize;
 
-        afc->list         = fr_command_cfile_list;
-	afc->add          = fr_command_cfile_add;
-	afc->delete       = fr_command_cfile_delete;
-	afc->extract      = fr_command_cfile_extract;
+        afc->list          = fr_command_cfile_list;
+	afc->add           = fr_command_cfile_add;
+	afc->delete        = fr_command_cfile_delete;
+	afc->extract       = fr_command_cfile_extract;
+	afc->set_mime_type = fr_command_cfile_set_mime_type;
 }
 
  
@@ -540,62 +534,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_cfile_new (FrProcess         *process,
-		      const char        *filename,
-		      FRCompressProgram  prog)
-{
-	FrCommand *comm;
-
-	if ((prog == FR_COMPRESS_PROGRAM_GZIP) &&
-	    (!is_program_in_path("gzip"))) {
-		return NULL;
-	}
-
-	if ((prog == FR_COMPRESS_PROGRAM_BZIP) &&
-	    (!is_program_in_path("bzip"))) { 
-		return NULL;
-	}
-
-	if ((prog == FR_COMPRESS_PROGRAM_BZIP2) &&
-	    (!is_program_in_path("bzip2"))) {
-		return NULL;
-	}
-
-	if ((prog == FR_COMPRESS_PROGRAM_COMPRESS) && 
-	    ((!is_program_in_path("compress")) || 
-	     (!is_program_in_path("uncompress")))) {
-		return NULL;
-	}
-
-	if ((prog == FR_COMPRESS_PROGRAM_LZMA) &&
-	    (!is_program_in_path("lzma"))) {
-		return NULL;
-	}
-
-	if ((prog == FR_COMPRESS_PROGRAM_LZOP) &&
-	    (!is_program_in_path("lzop"))) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_CFILE, NULL));
-	fr_command_construct (comm, process, filename);
-	FR_COMMAND_CFILE (comm)->compress_prog = prog;
-
-	if (prog == FR_COMPRESS_PROGRAM_GZIP)
-		comm->file_type = FR_FILE_TYPE_GZIP;
-	else if (prog == FR_COMPRESS_PROGRAM_BZIP)
-		comm->file_type = FR_FILE_TYPE_BZIP;
-	else if (prog == FR_COMPRESS_PROGRAM_BZIP2)
-		comm->file_type = FR_FILE_TYPE_BZIP2;
-	else if (prog == FR_COMPRESS_PROGRAM_COMPRESS)
-		comm->file_type = FR_FILE_TYPE_COMPRESS;
-	else if (prog == FR_COMPRESS_PROGRAM_LZMA)
-		comm->file_type = FR_FILE_TYPE_LZMA;
-	else if (prog == FR_COMPRESS_PROGRAM_LZOP)
-		comm->file_type = FR_FILE_TYPE_LZOP;
-
-	return comm;
-}

Modified: trunk/src/fr-command-cfile.h
==============================================================================
--- trunk/src/fr-command-cfile.h	(original)
+++ trunk/src/fr-command-cfile.h	Mon Jun  2 11:14:27 2008
@@ -43,8 +43,7 @@
 
 	/*<private>*/
 
-	FRCompressProgram compress_prog;
-	FRProcError error;
+	FrProcError error;
 };
 
 struct _FrCommandCFileClass
@@ -52,9 +51,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_cfile_get_type   (void);
-FrCommand*   fr_command_cfile_new        (FrProcess *process,
-					  const char *filename,
-					  FRCompressProgram prog);
+GType fr_command_cfile_get_type (void);
 
 #endif /* FR_COMMAND_CFILE_H */

Modified: trunk/src/fr-command-cpio.c
==============================================================================
--- trunk/src/fr-command-cpio.c	(original)
+++ trunk/src/fr-command-cpio.c	Mon Jun  2 11:14:27 2008
@@ -185,6 +185,18 @@
 }
 
 
+static void
+fr_command_cpio_set_mime_type (FrCommand  *comm,
+		 	       const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("cpio")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+}
+
+
 static void 
 fr_command_cpio_class_init (FrCommandCpioClass *class)
 {
@@ -198,14 +210,13 @@
 
         afc->list           = fr_command_cpio_list;
 	afc->extract        = fr_command_cpio_extract;
+	afc->set_mime_type  = fr_command_cpio_set_mime_type;
 }
 
  
 static void 
 fr_command_cpio_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_CPIO;
-
 	comm->propCanModify                = FALSE;
 	comm->propAddCanUpdate             = FALSE;
 	comm->propAddCanReplace            = FALSE;
@@ -256,20 +267,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_cpio_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if (!is_program_in_path("cpio")) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_CPIO, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-cpio.h
==============================================================================
--- trunk/src/fr-command-cpio.h	(original)
+++ trunk/src/fr-command-cpio.h	Mon Jun  2 11:14:27 2008
@@ -48,8 +48,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_cpio_get_type        (void);
-FrCommand*   fr_command_cpio_new             (FrProcess *process,
-					      const char *filename);
+GType fr_command_cpio_get_type (void);
 
 #endif /* FR_COMMAND_CPIO_H */

Modified: trunk/src/fr-command-iso.c
==============================================================================
--- trunk/src/fr-command-iso.c	(original)
+++ trunk/src/fr-command-iso.c	Mon Jun  2 11:14:27 2008
@@ -214,6 +214,18 @@
 
 
 static void
+fr_command_iso_set_mime_type (FrCommand  *comm,
+		 	      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("isoinfo")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ;
+}
+
+
+static void
 fr_command_iso_class_init (FrCommandIsoClass *class)
 {
 	GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
@@ -224,8 +236,9 @@
 
 	gobject_class->finalize = fr_command_iso_finalize;
 
-	afc->list    = fr_command_iso_list;
-	afc->extract = fr_command_iso_extract;
+	afc->list           = fr_command_iso_list;
+	afc->extract        = fr_command_iso_extract;
+	afc->set_mime_type  = fr_command_iso_set_mime_type;
 }
 
 
@@ -234,8 +247,6 @@
 {
 	FrCommandIso *comm_iso = FR_COMMAND_ISO (comm);
 
-	comm->file_type = FR_FILE_TYPE_ISO;
-
 	comm_iso->cur_path = NULL;
 	comm_iso->joliet = TRUE;
 
@@ -296,20 +307,3 @@
 
 	return type;
 }
-
-
-FrCommand *
-fr_command_iso_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if (! is_program_in_path ("isoinfo")) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_ISO, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-iso.h
==============================================================================
--- trunk/src/fr-command-iso.h	(original)
+++ trunk/src/fr-command-iso.h	Mon Jun  2 11:14:27 2008
@@ -49,8 +49,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_iso_get_type        (void);
-FrCommand*   fr_command_iso_new             (FrProcess *process,
-					     const char *filename);
+GType fr_command_iso_get_type (void);
 
 #endif /* FR_COMMAND_ISO_H */

Modified: trunk/src/fr-command-jar.c
==============================================================================
--- trunk/src/fr-command-jar.c	(original)
+++ trunk/src/fr-command-jar.c	Mon Jun  2 11:14:27 2008
@@ -54,7 +54,7 @@
 		    const char    *base_dir,
 		    gboolean       update,
 		    const char    *password,
-		    FRCompression  compression)
+		    FrCompression  compression)
 {
 	FrProcess *proc = comm->process;
 	GList     *zip_list = NULL, *jardata_list = NULL, *jar_list = NULL;
@@ -207,16 +207,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_jar_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_JAR, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-jar.h
==============================================================================
--- trunk/src/fr-command-jar.h	(original)
+++ trunk/src/fr-command-jar.h	Mon Jun  2 11:14:27 2008
@@ -46,8 +46,6 @@
 	FrCommandZipClass __parent_class;
 };
 
-GType        fr_command_jar_get_type        (void);
-FrCommand*   fr_command_jar_new             (FrProcess  *process,
-					     const char *filename);
+GType fr_command_jar_get_type (void);
 
 #endif /* FR_COMMAND_JAR_H */

Modified: trunk/src/fr-command-lha.c
==============================================================================
--- trunk/src/fr-command-lha.c	(original)
+++ trunk/src/fr-command-lha.c	Mon Jun  2 11:14:27 2008
@@ -231,7 +231,7 @@
 		    const char    *base_dir,
 		    gboolean       update,
 		    const char    *password,
-		    FRCompression  compression)
+		    FrCompression  compression)
 {
 	GList *scan;
 
@@ -304,6 +304,18 @@
 }
 
 
+static void
+fr_command_lha_set_mime_type (FrCommand  *comm,
+		 	      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("lha")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+}
+
+
 static void 
 fr_command_lha_class_init (FrCommandLhaClass *class)
 {
@@ -315,18 +327,17 @@
 
 	gobject_class->finalize = fr_command_lha_finalize;
 
-        afc->list         = fr_command_lha_list;
-	afc->add          = fr_command_lha_add;
-	afc->delete       = fr_command_lha_delete;
-	afc->extract      = fr_command_lha_extract;
+        afc->list           = fr_command_lha_list;
+	afc->add            = fr_command_lha_add;
+	afc->delete         = fr_command_lha_delete;
+	afc->extract        = fr_command_lha_extract;
+	afc->set_mime_type  = fr_command_lha_set_mime_type;
 }
 
  
 static void 
 fr_command_lha_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_LHA;
-
 	comm->propAddCanUpdate             = TRUE; 
 	comm->propAddCanReplace            = TRUE; 
 	comm->propAddCanStoreFolders       = TRUE;
@@ -376,20 +387,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_lha_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if (!is_program_in_path("lha")) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_LHA, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-lha.h
==============================================================================
--- trunk/src/fr-command-lha.h	(original)
+++ trunk/src/fr-command-lha.h	Mon Jun  2 11:14:27 2008
@@ -47,8 +47,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_lha_get_type        (void);
-FrCommand*   fr_command_lha_new             (FrProcess *process,
-					     const char *filename);
+GType fr_command_lha_get_type (void);
 
 #endif /* FR_COMMAND_LHA_H */

Modified: trunk/src/fr-command-rar.c
==============================================================================
--- trunk/src/fr-command-rar.c	(original)
+++ trunk/src/fr-command-rar.c	Mon Jun  2 11:14:27 2008
@@ -229,7 +229,7 @@
 		    const char    *base_dir,
 		    gboolean       update,
 		    const char    *password,
-		    FRCompression  compression)
+		    FrCompression  compression)
 {
 	GList *scan;
 
@@ -369,7 +369,7 @@
 
 static void
 fr_command_rar_handle_error (FrCommand   *comm,
-			     FRProcError *error)
+			     FrProcError *error)
 {
 	if (error->type == FR_PROC_ERROR_COMMAND_ERROR) {
 		if (error->status <= 1)
@@ -393,6 +393,20 @@
 
 
 static void
+fr_command_rar_set_mime_type (FrCommand  *comm,
+		 	      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("rar")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	else if (is_program_in_path ("unrar")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ;
+}
+
+
+static void
 fr_command_rar_class_init (FrCommandRarClass *class)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (class);
@@ -403,20 +417,19 @@
 
 	gobject_class->finalize = fr_command_rar_finalize;
 
-	afc->list         = fr_command_rar_list;
-	afc->add          = fr_command_rar_add;
-	afc->delete       = fr_command_rar_delete;
-	afc->extract      = fr_command_rar_extract;
-	afc->test         = fr_command_rar_test;
-	afc->handle_error = fr_command_rar_handle_error;
+	afc->list           = fr_command_rar_list;
+	afc->add            = fr_command_rar_add;
+	afc->delete         = fr_command_rar_delete;
+	afc->extract        = fr_command_rar_extract;
+	afc->test           = fr_command_rar_test;
+	afc->handle_error   = fr_command_rar_handle_error;
+	afc->set_mime_type  = fr_command_rar_set_mime_type;
 }
 
 
 static void
 fr_command_rar_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_RAR;
-
 	comm->propAddCanUpdate             = TRUE;
 	comm->propAddCanReplace            = TRUE;
 	comm->propAddCanStoreFolders       = TRUE;
@@ -466,19 +479,3 @@
 
 	return type;
 }
-
-
-FrCommand *
-fr_command_rar_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if ((!is_program_in_path("rar")) && (!is_program_in_path("unrar")))
-		return NULL;
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_RAR, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-rar.h
==============================================================================
--- trunk/src/fr-command-rar.h	(original)
+++ trunk/src/fr-command-rar.h	Mon Jun  2 11:14:27 2008
@@ -52,8 +52,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_rar_get_type        (void);
-FrCommand*   fr_command_rar_new             (FrProcess *process,
-					     const char *filename);
+GType fr_command_rar_get_type (void);
 
 #endif /* FR_COMMAND_RAR_H */

Modified: trunk/src/fr-command-rpm.c
==============================================================================
--- trunk/src/fr-command-rpm.c	(original)
+++ trunk/src/fr-command-rpm.c	Mon Jun  2 11:14:27 2008
@@ -186,6 +186,18 @@
 }
 
 
+static void
+fr_command_rpm_set_mime_type (FrCommand  *comm,
+		 	      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("rpm2cpio")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ;
+}
+
+
 static void 
 fr_command_rpm_class_init (FrCommandRpmClass *class)
 {
@@ -199,14 +211,13 @@
 
         afc->list           = fr_command_rpm_list;
 	afc->extract        = fr_command_rpm_extract;
+	afc->set_mime_type  = fr_command_rpm_set_mime_type;
 }
 
  
 static void 
 fr_command_rpm_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_RPM;
-
 	comm->propCanModify                = FALSE;
 	comm->propAddCanUpdate             = FALSE;
 	comm->propAddCanReplace            = FALSE;
@@ -256,20 +267,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_rpm_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if (!is_program_in_path("rpm2cpio")) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_RPM, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-rpm.h
==============================================================================
--- trunk/src/fr-command-rpm.h	(original)
+++ trunk/src/fr-command-rpm.h	Mon Jun  2 11:14:27 2008
@@ -48,8 +48,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_rpm_get_type        (void);
-FrCommand*   fr_command_rpm_new             (FrProcess *process,
-					     const char *filename);
+GType fr_command_rpm_get_type (void);
 
 #endif /* FR_COMMAND_RPM_H */

Modified: trunk/src/fr-command-tar.c
==============================================================================
--- trunk/src/fr-command-tar.c	(original)
+++ trunk/src/fr-command-tar.c	Mon Jun  2 11:14:27 2008
@@ -189,39 +189,16 @@
 static void
 add_compress_arg (FrCommand *comm)
 {
-	FrCommandTar *comm_tar = FR_COMMAND_TAR (comm);
-
-	switch (comm_tar->compress_prog) {
-	case FR_COMPRESS_PROGRAM_NONE:
-		break;
-
-	case FR_COMPRESS_PROGRAM_GZIP:
+	if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) 
 		fr_process_add_arg (comm->process, "-z");
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP:
-		fr_process_add_arg (comm->process,
-				    "--use-compress-program=bzip");
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP2:
+	else if (is_mime_type (comm->mime_type, "application/x-bzip-compressed-tar"))
 		fr_process_add_arg (comm->process, "--use-compress-program=bzip2");
-		break;
-
-	case FR_COMPRESS_PROGRAM_COMPRESS:
+	else if (is_mime_type (comm->mime_type, "application/x-compressed-tar"))
 		fr_process_add_arg (comm->process, "-Z");
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZMA:
-		fr_process_add_arg (comm->process,
-				    "--use-compress-program=lzma");
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZOP:
-		fr_process_add_arg (comm->process,
-				    "--use-compress-program=lzop");
-		break;
-	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzma-compressed-tar"))
+		fr_process_add_arg (comm->process, "--use-compress-program=lzma");
+	else if (is_mime_type (comm->mime_type, "application/x-lzop-compressed-tar"))
+		fr_process_add_arg (comm->process, "--use-compress-program=lzop");
 }
 
 
@@ -303,7 +280,7 @@
 		    const char    *base_dir,
 		    gboolean       update,
 		    const char    *password,
-		    FRCompression  compression)
+		    FrCompression  compression)
 {
 	FrCommandTar *c_tar = FR_COMMAND_TAR (comm);
 	GList        *scan;
@@ -444,16 +421,12 @@
 
 static void
 fr_command_tar_recompress (FrCommand     *comm,
-			   FRCompression  compression)
+			   FrCompression  compression)
 {
 	FrCommandTar *c_tar = FR_COMMAND_TAR (comm);
 	char         *new_name = NULL;
 
-	switch (c_tar->compress_prog) {
-	case FR_COMPRESS_PROGRAM_NONE:
-		break;
-
-	case FR_COMPRESS_PROGRAM_GZIP:
+	if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) {
 		fr_process_begin_command (comm->process, "gzip");
 		fr_process_set_sticky (comm->process, TRUE);
 		fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
@@ -471,31 +444,9 @@
 		fr_process_add_arg (comm->process, c_tar->uncomp_filename);
 		fr_process_end_command (comm->process);
 
-		new_name = g_strconcat (c_tar->uncomp_filename, ".gz", NULL);
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP:
-		fr_process_begin_command (comm->process, "bzip");
-		fr_process_set_sticky (comm->process, TRUE);
-		fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
-		switch (compression) {
-		case FR_COMPRESSION_VERY_FAST:
-			fr_process_add_arg (comm->process, "-1"); break;
-		case FR_COMPRESSION_FAST:
-			fr_process_add_arg (comm->process, "-3"); break;
-		case FR_COMPRESSION_NORMAL:
-			fr_process_add_arg (comm->process, "-6"); break;
-		case FR_COMPRESSION_MAXIMUM:
-			fr_process_add_arg (comm->process, "-9"); break;
-		}
-		fr_process_add_arg (comm->process, "-f");
-		fr_process_add_arg (comm->process, c_tar->uncomp_filename);
-		fr_process_end_command (comm->process);
-
-		new_name = g_strconcat (c_tar->uncomp_filename, ".bz", NULL);
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP2:
+		new_name = g_strconcat (c_tar->uncomp_filename, ".gz", NULL); 
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-bzip-compressed-tar")) {
 		fr_process_begin_command (comm->process, "bzip2");
 		fr_process_set_sticky (comm->process, TRUE);
 		fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
@@ -514,9 +465,8 @@
 		fr_process_end_command (comm->process);
 
 		new_name = g_strconcat (c_tar->uncomp_filename, ".bz2", NULL);
-		break;
-
-	case FR_COMPRESS_PROGRAM_COMPRESS:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) {
 		fr_process_begin_command (comm->process, "compress");
 		fr_process_set_sticky (comm->process, TRUE);
 		fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
@@ -525,9 +475,8 @@
 		fr_process_end_command (comm->process);
 
 		new_name = g_strconcat (c_tar->uncomp_filename, ".Z", NULL);
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZMA:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzma-compressed-tar")) {
 		fr_process_begin_command (comm->process, "lzma");
 		fr_process_set_sticky (comm->process, TRUE);
 		fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
@@ -546,9 +495,8 @@
 		fr_process_end_command (comm->process);
 
 		new_name = g_strconcat (c_tar->uncomp_filename, ".lzma", NULL);
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZOP:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzop-compressed-tar")) {
 		fr_process_begin_command (comm->process, "lzop");
 		fr_process_set_sticky (comm->process, TRUE);
 		fr_process_set_begin_func (comm->process, begin_func__recompress, comm);
@@ -568,7 +516,6 @@
 		fr_process_end_command (comm->process);
 
 		new_name = g_strconcat (c_tar->uncomp_filename, ".lzo", NULL);
-		break;
 	}
 
 	if (c_tar->name_modified) {
@@ -613,69 +560,54 @@
 get_uncompressed_name (FrCommandTar *c_tar,
 		       const char   *e_filename)
 {
-	char *new_name = g_strdup (e_filename);
-	int   l = strlen (new_name);
-
-	switch (c_tar->compress_prog) {
-	case FR_COMPRESS_PROGRAM_NONE:
-		break;
+	FrCommand *comm = FR_COMMAND (c_tar);
+	char      *new_name = g_strdup (e_filename);
+	int        l = strlen (new_name);
 
-	case FR_COMPRESS_PROGRAM_GZIP:
+	if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) { 
 		/* X.tgz     -->  X.tar
 		 * X.tar.gz  -->  X.tar */
 		if (file_extension_is (e_filename, ".tgz")) {
 			new_name[l - 2] = 'a';
 			new_name[l - 1] = 'r';
-		} else if (file_extension_is (e_filename, ".tar.gz"))
-			new_name[l - 3] = 0;
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP:
-		/* X.tbz     -->  X.tar
-		 * X.tar.bz  -->  X.tar */
-		if (file_extension_is (e_filename, ".tbz")) {
-			new_name[l - 2] = 'a';
-			new_name[l - 1] = 'r';
-		} else if (file_extension_is (e_filename, ".tar.bz"))
+		} 
+		else if (file_extension_is (e_filename, ".tar.gz"))
 			new_name[l - 3] = 0;
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP2:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-bzip-compressed-tar")) {
 		/* X.tbz2    -->  X.tar
 		 * X.tar.bz2 -->  X.tar */
 		if (file_extension_is (e_filename, ".tbz2")) {
 			new_name[l - 3] = 'a';
 			new_name[l - 2] = 'r';
 			new_name[l - 1] = 0;
-		} else if (file_extension_is (e_filename, ".tar.bz2"))
+		} 
+		else if (file_extension_is (e_filename, ".tar.bz2"))
 			new_name[l - 4] = 0;
-		break;
-
-	case FR_COMPRESS_PROGRAM_COMPRESS:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) {
 		/* X.taz   -->  X.tar
 		 * X.tar.Z -->  X.tar */
 		if (file_extension_is (e_filename, ".taz"))
 			new_name[l - 1] = 'r';
 		else if (file_extension_is (e_filename, ".tar.Z"))
 			new_name[l - 2] = 0;
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZMA:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzma-compressed-tar")) {
 		/* X.tar.lzma --> X.tar 
 		 * (There doesn't seem to be a shorthand suffix) */
 		if (file_extension_is (e_filename, ".tar.lzma"))
 			new_name[l - 5] = 0;
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZOP:
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzop-compressed-tar")) {
 		/* X.tzo     -->  X.tar
 		 * X.tar.lzo -->  X.tar */
 		if (file_extension_is (e_filename, ".tzo")) {
 			new_name[l - 2] = 'a';
 			new_name[l - 1] = 'r';
-		} else if (file_extension_is (e_filename, ".tar.lzo"))
+		} 
+		else if (file_extension_is (e_filename, ".tar.lzo"))
 			new_name[l - 4] = 0;
-		break;
 	}
 
 	return new_name;
@@ -724,7 +656,7 @@
 		g_free (uri);
 	}
 
-	c_tar->name_modified = c_tar->compress_prog != FR_COMPRESS_PROGRAM_NONE;
+	c_tar->name_modified = ! is_mime_type (comm->mime_type, "application/x-tar");
 	if (c_tar->name_modified) {
 		tmp_name = get_temp_name (c_tar, comm->filename);
 		if (archive_exists) {
@@ -738,12 +670,8 @@
 	else
 		tmp_name = g_strdup (comm->e_filename);
 
-	switch (c_tar->compress_prog) {
-	case FR_COMPRESS_PROGRAM_NONE:
-		break;
-
-	case FR_COMPRESS_PROGRAM_GZIP:
-		if (archive_exists) {
+	if (archive_exists) {
+		if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) { 
 			fr_process_begin_command (comm->process, "gzip");
 			fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
 			fr_process_add_arg (comm->process, "-f");
@@ -751,21 +679,7 @@
 			fr_process_add_arg (comm->process, tmp_name);
 			fr_process_end_command (comm->process);
 		}
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP:
-		if (archive_exists) {
-			fr_process_begin_command (comm->process, "bzip");
-			fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
-			fr_process_add_arg (comm->process, "-f");
-			fr_process_add_arg (comm->process, "-d");
-			fr_process_add_arg (comm->process, tmp_name);
-			fr_process_end_command (comm->process);
-		}
-		break;
-
-	case FR_COMPRESS_PROGRAM_BZIP2:
-		if (archive_exists) {
+		else if (is_mime_type (comm->mime_type, "application/x-bzip-compressed-tar")) {
 			fr_process_begin_command (comm->process, "bzip2");
 			fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
 			fr_process_add_arg (comm->process, "-f");
@@ -773,20 +687,14 @@
 			fr_process_add_arg (comm->process, tmp_name);
 			fr_process_end_command (comm->process);
 		}
-		break;
-
-	case FR_COMPRESS_PROGRAM_COMPRESS:
-		if (archive_exists) {
+		else if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) {
 			fr_process_begin_command (comm->process, "uncompress");
 			fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
 			fr_process_add_arg (comm->process, "-f");
 			fr_process_add_arg (comm->process, tmp_name);
 			fr_process_end_command (comm->process);
 		}
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZMA:
-		if (archive_exists) {
+		else if (is_mime_type (comm->mime_type, "application/x-lzma-compressed-tar")) {
 			fr_process_begin_command (comm->process, "lzma");
 			fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
 			fr_process_add_arg (comm->process, "-f");
@@ -794,10 +702,7 @@
 			fr_process_add_arg (comm->process, tmp_name);
 			fr_process_end_command (comm->process);
 		}
-		break;
-
-	case FR_COMPRESS_PROGRAM_LZOP:
-		if (archive_exists) {
+		else if (is_mime_type (comm->mime_type, "application/x-lzop-compressed-tar")) {
 			fr_process_begin_command (comm->process, "lzop");
 			fr_process_set_begin_func (comm->process, begin_func__uncompress, comm);
 			fr_process_add_arg (comm->process, "-dfU");
@@ -805,7 +710,6 @@
 			fr_process_add_arg (comm->process, tmp_name);
 			fr_process_end_command (comm->process);
 		}
-		break;
 	}
 
 	c_tar->uncomp_filename = get_uncompressed_name (c_tar, tmp_name);
@@ -831,7 +735,7 @@
 
 static void
 fr_command_tar_handle_error (FrCommand   *comm,
-			     FRProcError *error)
+			     FrProcError *error)
 {
 	if (error->type == FR_PROC_ERROR_COMMAND_ERROR) {
 		if (error->status <= 1)
@@ -841,6 +745,47 @@
 
 
 static void
+fr_command_tar_set_mime_type (FrCommand  *comm,
+		 	      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+
+	/* In solaris gtar is present under /usr/sfw/bin */
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	
+	if (! is_program_in_path ("tar") && ! is_program_in_path ("/usr/sfw/bin/gtar")) 
+		return;
+
+	if (is_mime_type (comm->mime_type, "application/x-tar")) {
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) {
+		if (is_program_in_path ("gzip"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-bzip-compressed-tar")) {
+		if (is_program_in_path ("bzip2"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-compressed-tar")) {
+		if (is_program_in_path ("compress"))
+			comm->capabilities |= FR_COMMAND_CAP_WRITE;
+		if (is_program_in_path ("uncompress"))
+			comm->capabilities |= FR_COMMAND_CAP_READ;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzma-compressed-tar")) {
+		if (is_program_in_path ("lzma"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+	else if (is_mime_type (comm->mime_type, "application/x-lzop-compressed-tar")) {
+		if (is_program_in_path ("lzop"))
+			comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+	}
+}
+
+
+static void
 fr_command_tar_class_init (FrCommandTarClass *class)
 {
         GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
@@ -851,16 +796,17 @@
 
 	gobject_class->finalize = fr_command_tar_finalize;
 
-        afc->list         = fr_command_tar_list;
-	afc->add          = fr_command_tar_add;
-	afc->delete       = fr_command_tar_delete;
-	afc->extract      = fr_command_tar_extract;
-	afc->handle_error = fr_command_tar_handle_error;
+        afc->list           = fr_command_tar_list;
+	afc->add            = fr_command_tar_add;
+	afc->delete         = fr_command_tar_delete;
+	afc->extract        = fr_command_tar_extract;
+	afc->handle_error   = fr_command_tar_handle_error;
+	afc->set_mime_type  = fr_command_tar_set_mime_type;
 
-	afc->recompress   = fr_command_tar_recompress;
-	afc->uncompress   = fr_command_tar_uncompress;
+	afc->recompress     = fr_command_tar_recompress;
+	afc->uncompress     = fr_command_tar_uncompress;
 
-	afc->escape       = fr_command_tar_escape;
+	afc->escape         = fr_command_tar_escape;
 }
 
 
@@ -869,19 +815,20 @@
 {
 	FrCommandTar *comm_tar = (FrCommandTar*) comm;
 
-	comm->file_type = FR_FILE_TYPE_TAR;
-
-	comm->propCanModify                = TRUE;
-	comm->propAddCanUpdate             = FALSE;
-	comm->propAddCanReplace            = FALSE;
-	comm->propAddCanStoreFolders       = TRUE;
-	comm->propExtractCanAvoidOverwrite = TRUE;
-	comm->propExtractCanSkipOlder      = TRUE;
-	comm->propExtractCanJunkPaths      = FALSE;
-	comm->propPassword                 = FALSE;
-	comm->propTest                     = FALSE;
+	comm->propCanModify                 = TRUE;
+	comm->propAddCanUpdate              = FALSE;
+	comm->propAddCanReplace             = FALSE;
+	comm->propAddCanStoreFolders        = TRUE;
+	comm->propExtractCanAvoidOverwrite  = TRUE;
+	comm->propExtractCanSkipOlder       = TRUE;
+	comm->propExtractCanJunkPaths       = FALSE;
+	comm->propPassword                  = FALSE;
+	comm->propTest                      = FALSE;
+	comm->propCanDeleteNonEmptyFolders  = FALSE;
+	comm->propCanExtractNonEmptyFolders = FALSE;
 
 	comm_tar->msg = NULL;
+	comm_tar->uncomp_filename = NULL;	
 }
 
 
@@ -937,57 +884,3 @@
 
         return type;
 }
-
-
-FrCommand *
-fr_command_tar_new (FrProcess         *process,
-		    const char        *filename,
-		    FRCompressProgram  prog)
-{
-	FrCommand *comm;
-
-	/* In solaris gtar is present under /usr/sfw/bin */
-
-	if ((!is_program_in_path("/usr/sfw/bin/gtar")) &&
-	    (!is_program_in_path("tar"))) {
-		return NULL;
-	}
-
-	if ((prog == FR_COMPRESS_PROGRAM_GZIP) &&
-            (!is_program_in_path("gzip"))) {
-                return NULL;
-        }
-
-        if ((prog == FR_COMPRESS_PROGRAM_BZIP) &&
-            (!is_program_in_path("bzip"))) {
-                return NULL;
-        }
-
-        if ((prog == FR_COMPRESS_PROGRAM_BZIP2) &&
-            (!is_program_in_path("bzip2"))) {
-                return NULL;
-        }
-
-        if ((prog == FR_COMPRESS_PROGRAM_COMPRESS) &&
-            ((!is_program_in_path("compress")) ||
-             (!is_program_in_path("uncompress")))) {
-                return NULL;
-        }
-
-        if ((prog == FR_COMPRESS_PROGRAM_LZMA) &&
-            (!is_program_in_path("lzma"))) {
-                return NULL;
-        }
-
-        if ((prog == FR_COMPRESS_PROGRAM_LZOP) &&
-            (!is_program_in_path("lzop"))) {
-                return NULL;
-        }
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_TAR, NULL));
-	fr_command_construct (comm, process, filename);
-	FR_COMMAND_TAR (comm)->compress_prog = prog;
-	FR_COMMAND_TAR (comm)->uncomp_filename = NULL;
-
-	return comm;
-}

Modified: trunk/src/fr-command-tar.h
==============================================================================
--- trunk/src/fr-command-tar.h	(original)
+++ trunk/src/fr-command-tar.h	Mon Jun  2 11:14:27 2008
@@ -44,7 +44,6 @@
 
 	/*<private>*/
 
-	FRCompressProgram  compress_prog;
 	char              *uncomp_filename;
 	gboolean           name_modified;
 
@@ -56,9 +55,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_tar_get_type        (void);
-FrCommand*   fr_command_tar_new             (FrProcess *process,
-					     const char *filename,
-					     FRCompressProgram prog);
+GType fr_command_tar_get_type (void);
 
 #endif /* FR_COMMAND_TAR_H */

Modified: trunk/src/fr-command-unstuff.c
==============================================================================
--- trunk/src/fr-command-unstuff.c	(original)
+++ trunk/src/fr-command-unstuff.c	Mon Jun  2 11:14:27 2008
@@ -258,7 +258,7 @@
 
 static void
 fr_command_unstuff_handle_error (FrCommand   *comm,
-			     FRProcError *error)
+			     FrProcError *error)
 {
 	if ((error->type == FR_PROC_ERROR_COMMAND_ERROR)
 	    && (error->status <= 1))
@@ -267,6 +267,18 @@
 
 
 static void
+fr_command_unstuff_set_mime_type (FrCommand  *comm,
+			          const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("unstuff")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ;
+}
+
+
+static void
 fr_command_unstuff_class_init (FrCommandUnstuffClass *class)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (class);
@@ -277,19 +289,18 @@
 
 	gobject_class->finalize = fr_command_unstuff_finalize;
 
-	afc->list         = fr_command_unstuff_list;
-	afc->add          = NULL;
-	afc->delete       = NULL;
-	afc->extract      = fr_command_unstuff_extract;
-	afc->handle_error = fr_command_unstuff_handle_error;
+	afc->list           = fr_command_unstuff_list;
+	afc->add            = NULL;
+	afc->delete         = NULL;
+	afc->extract        = fr_command_unstuff_extract;
+	afc->handle_error   = fr_command_unstuff_handle_error;
+	afc->set_mime_type  = fr_command_unstuff_set_mime_type;
 }
 
 
 static void
 fr_command_unstuff_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_STUFFIT;
-
 	comm->propCanModify                = FALSE;
 	comm->propAddCanUpdate             = FALSE;
 	comm->propAddCanReplace            = FALSE;
@@ -345,20 +356,3 @@
 
 	return type;
 }
-
-
-FrCommand *
-fr_command_unstuff_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if (!is_program_in_path("unstuff")) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_UNSTUFF, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-unstuff.h
==============================================================================
--- trunk/src/fr-command-unstuff.h	(original)
+++ trunk/src/fr-command-unstuff.h	Mon Jun  2 11:14:27 2008
@@ -51,8 +51,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_unstuff_get_type        (void);
-FrCommand*   fr_command_unstuff_new             (FrProcess *process,
-					         const char *filename);
+GType fr_command_unstuff_get_type (void);
 
 #endif /* FR_COMMAND_UNSTUFF_H */

Modified: trunk/src/fr-command-zip.c
==============================================================================
--- trunk/src/fr-command-zip.c	(original)
+++ trunk/src/fr-command-zip.c	Mon Jun  2 11:14:27 2008
@@ -283,7 +283,7 @@
 		    const char    *base_dir,
 		    gboolean       update,
 		    const char    *password,
-		    FRCompression  compression)
+		    FrCompression  compression)
 {
 	GList *scan;
 
@@ -414,7 +414,7 @@
 
 static void
 fr_command_zip_handle_error (FrCommand   *comm,
-			     FRProcError *error)
+			     FrProcError *error)
 {
 	if (error->type == FR_PROC_ERROR_COMMAND_ERROR) {
 		if (error->status <= 1)
@@ -444,6 +444,24 @@
 
 
 static void
+fr_command_zip_set_mime_type (FrCommand  *comm,
+			      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("zip")) {
+		if (strcmp (comm->mime_type, "application/x-ms-dos-executable") == 0)
+			comm->capabilities |= FR_COMMAND_CAP_READ;
+		else
+			comm->capabilities |= FR_COMMAND_CAP_ALL;
+	} 
+	else if (is_program_in_path ("unzip")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ;
+}
+
+
+static void
 fr_command_zip_class_init (FrCommandZipClass *class)
 {
 	GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
@@ -460,6 +478,7 @@
 	afc->extract        = fr_command_zip_extract;
 	afc->test           = fr_command_zip_test;
 	afc->handle_error   = fr_command_zip_handle_error;
+	afc->set_mime_type  = fr_command_zip_set_mime_type;
 
 	afc->escape         = fr_command_zip_escape;
 }
@@ -468,8 +487,6 @@
 static void
 fr_command_zip_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_ZIP;
-
 	comm->propAddCanUpdate             = TRUE;
 	comm->propAddCanReplace            = TRUE;
 	comm->propAddCanStoreFolders       = TRUE;
@@ -521,21 +538,3 @@
 
 	return type;
 }
-
-
-FrCommand *
-fr_command_zip_new (FrProcess  *process,
-		    const char *filename)
-{
-	FrCommand *comm;
-
-	if (!is_program_in_path ("zip") &&
-	    !is_program_in_path ("unzip")) {
-		return NULL;
-	}
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_ZIP, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-zip.h
==============================================================================
--- trunk/src/fr-command-zip.h	(original)
+++ trunk/src/fr-command-zip.h	Mon Jun  2 11:14:27 2008
@@ -48,8 +48,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_zip_get_type        (void);
-FrCommand*   fr_command_zip_new             (FrProcess *process,
-					     const char *filename);
+GType fr_command_zip_get_type (void);
 
 #endif /* FR_COMMAND_ZIP_H */

Modified: trunk/src/fr-command-zoo.c
==============================================================================
--- trunk/src/fr-command-zoo.c	(original)
+++ trunk/src/fr-command-zoo.c	Mon Jun  2 11:14:27 2008
@@ -241,7 +241,7 @@
 		    const char    *base_dir,
 		    gboolean       update,
 		    const char    *password,
-		    FRCompression  compression)
+		    FrCompression  compression)
 {
 	GList        *scan;
 
@@ -323,6 +323,18 @@
 }
 
 
+static void
+fr_command_zoo_set_mime_type (FrCommand  *comm,
+			      const char *mime_type)
+{
+	FR_COMMAND_CLASS (parent_class)->set_mime_type (comm, mime_type);
+	
+	comm->capabilities |= FR_COMMAND_CAP_ARCHIVE_MANY_FILES;
+	if (is_program_in_path ("zoo")) 
+		comm->capabilities |= FR_COMMAND_CAP_READ_WRITE;
+}
+
+
 static void 
 fr_command_zoo_class_init (FrCommandZooClass *class)
 {
@@ -334,19 +346,18 @@
 
 	gobject_class->finalize = fr_command_zoo_finalize;
 
-        afc->list         = fr_command_zoo_list;
-	afc->add          = fr_command_zoo_add;
-	afc->delete       = fr_command_zoo_delete;
-	afc->extract      = fr_command_zoo_extract;
-	afc->test         = fr_command_zoo_test;
+        afc->list          = fr_command_zoo_list;
+	afc->add           = fr_command_zoo_add;
+	afc->delete        = fr_command_zoo_delete;
+	afc->extract       = fr_command_zoo_extract;
+	afc->test          = fr_command_zoo_test;
+	afc->set_mime_type = fr_command_zoo_set_mime_type;
 }
 
  
 static void 
 fr_command_zoo_init (FrCommand *comm)
 {
-	comm->file_type = FR_FILE_TYPE_ZOO;
-
 	comm->propAddCanUpdate             = TRUE;
 	comm->propAddCanReplace            = FALSE; 
 	comm->propExtractCanAvoidOverwrite = FALSE;
@@ -395,19 +406,3 @@
 
         return type;
 }
-
-FrCommand *
-fr_command_zoo_new (FrProcess         *process,
-		    const char        *filename)
-{
-	FrCommand *comm;
-
-	if (!is_program_in_path("zoo")) {
-		return NULL;
-	}	
-
-	comm = FR_COMMAND (g_object_new (FR_TYPE_COMMAND_ZOO, NULL));
-	fr_command_construct (comm, process, filename);
-
-	return comm;
-}

Modified: trunk/src/fr-command-zoo.h
==============================================================================
--- trunk/src/fr-command-zoo.h	(original)
+++ trunk/src/fr-command-zoo.h	Mon Jun  2 11:14:27 2008
@@ -48,8 +48,6 @@
 	FrCommandClass __parent_class;
 };
 
-GType        fr_command_zoo_get_type        (void);
-FrCommand*   fr_command_zoo_new             (FrProcess *process,
-					     const char *filename);
+GType fr_command_zoo_get_type (void);
 
 #endif /* FR_COMMAND_ZOO_H */

Modified: trunk/src/fr-command.c
==============================================================================
--- trunk/src/fr-command.c	(original)
+++ trunk/src/fr-command.c	Mon Jun  2 11:14:27 2008
@@ -33,6 +33,7 @@
 
 #define INITIAL_SIZE 256
 
+/* Signals */
 enum {
 	START,
 	DONE,
@@ -41,6 +42,14 @@
 	LAST_SIGNAL
 };
 
+/* Properties */
+enum {
+        PROP_0,
+        PROP_FILENAME,
+        PROP_MIME_TYPE,
+        PROP_PROCESS
+};
+
 static GObjectClass *parent_class = NULL;
 static guint fr_command_signals[LAST_SIGNAL] = { 0 };
 
@@ -103,7 +112,7 @@
 		     const char    *base_dir,
 		     gboolean       update,
 		     const char    *password,
-		     FRCompression  compression)
+		     FrCompression  compression)
 {
 }
 
@@ -142,7 +151,7 @@
 
 static void
 base_fr_command_recompress (FrCommand     *comm,
-			    FRCompression  compression)
+			    FrCompression  compression)
 {
 }
 
@@ -157,18 +166,169 @@
 
 static void
 base_fr_command_handle_error (FrCommand *comm,
-			      FRProcError *error)
+			      FrProcError *error)
+{
+}
+
+
+static void
+base_fr_command_set_mime_type (FrCommand  *comm,
+			       const char *mime_type)
+{
+	comm->mime_type = get_static_string (mime_type);
+}
+
+
+static void
+fr_command_start (FrProcess *process,
+		  gpointer   data)
 {
+	FrCommand *comm = FR_COMMAND (data);
+	
+	g_signal_emit (G_OBJECT (comm),
+		       fr_command_signals[START], 
+		       0,
+		       comm->action);
+}
+
+
+static void
+fr_command_done (FrProcess   *process,
+		 gpointer     data)
+{
+	FrCommand *comm = FR_COMMAND (data);
+
+	comm->process->restart = FALSE;
+	if (process->error.type != FR_PROC_ERROR_NONE)
+		fr_command_handle_error (comm, &process->error);
+
+	if (comm->process->restart)
+		fr_process_start (comm->process);
+	else
+		g_signal_emit (G_OBJECT (comm),
+			       fr_command_signals[DONE], 
+			       0,
+			       comm->action, 
+			       &process->error);
+}
+
+
+static void
+fr_command_set_process (FrCommand  *comm,
+		        FrProcess  *process)
+{
+	if (comm->process != NULL) {
+		g_signal_handlers_disconnect_matched (G_OBJECT (comm->process),
+					      G_SIGNAL_MATCH_DATA, 
+					      0, 
+					      0, NULL, 
+					      0,
+					      comm);
+		g_object_unref (G_OBJECT (comm->process));
+		comm->process = NULL;
+	}
+	
+	if (process == NULL)
+		return;
+	
+	g_object_ref (G_OBJECT (process));
+	comm->process = process;
+	g_signal_connect (G_OBJECT (comm->process),
+			  "start",
+			  G_CALLBACK (fr_command_start),
+			  comm);
+	g_signal_connect (G_OBJECT (comm->process),
+			  "done",
+			  G_CALLBACK (fr_command_done),
+			  comm);
+}
+
+
+static void
+fr_command_set_property (GObject      *object,
+			 guint         prop_id,
+			 const GValue *value,
+			 GParamSpec   *pspec)
+{
+        FrCommand *comm;
+
+        comm = FR_COMMAND (object);
+
+        switch (prop_id) {
+        case PROP_PROCESS:
+                fr_command_set_process (comm, g_value_get_object (value));
+                break;
+        case PROP_FILENAME:
+        	fr_command_set_filename (comm, g_value_get_string (value));
+                break;
+        case PROP_MIME_TYPE:
+        	fr_command_set_mime_type (comm, g_value_get_string (value));
+                break;
+        default:
+                break;
+        }
+}
+
+
+static void
+fr_command_get_property (GObject    *object,
+			 guint       prop_id,
+			 GValue     *value,
+			 GParamSpec *pspec)
+{
+        FrCommand *comm;
+
+        comm = FR_COMMAND (object);
+
+        switch (prop_id) {
+        case PROP_PROCESS:
+                g_value_set_object (value, comm->process);
+                break;
+        case PROP_FILENAME:
+        	g_value_set_string (value, comm->filename);
+                break;
+        case PROP_MIME_TYPE:
+                g_value_set_static_string (value, comm->mime_type);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
 }
 
 
 static void
 fr_command_class_init (FrCommandClass *class)
 {
-	GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+	GObjectClass *gobject_class;
 
 	parent_class = g_type_class_peek_parent (class);
 
+	gobject_class = G_OBJECT_CLASS (class);
+	
+	/* virtual functions */
+	
+	gobject_class->finalize = fr_command_finalize;
+	gobject_class->set_property = fr_command_set_property;
+        gobject_class->get_property = fr_command_get_property;
+               
+	class->list           = base_fr_command_list;
+	class->add            = base_fr_command_add;
+	class->delete         = base_fr_command_delete;
+	class->extract        = base_fr_command_extract;
+	class->test           = base_fr_command_test;
+	class->uncompress     = base_fr_command_uncompress;
+	class->recompress     = base_fr_command_recompress;
+	class->escape         = base_fr_command_escape;
+	class->handle_error   = base_fr_command_handle_error;
+	class->set_mime_type  = base_fr_command_set_mime_type;
+	class->start          = NULL;
+	class->done           = NULL;
+	class->progress       = NULL;
+	class->message        = NULL;
+	
+	/* signals */
+	
 	fr_command_signals[START] =
 		g_signal_new ("start",
 			      G_TYPE_FROM_CLASS (class),
@@ -206,25 +366,30 @@
 			      fr_marshal_VOID__STRING,
 			      G_TYPE_NONE, 1,
 			      G_TYPE_STRING);
-
-	gobject_class->finalize = fr_command_finalize;
-
-	class->list           = base_fr_command_list;
-	class->add            = base_fr_command_add;
-	class->delete         = base_fr_command_delete;
-	class->extract        = base_fr_command_extract;
-	class->test           = base_fr_command_test;
-
-	class->uncompress     = base_fr_command_uncompress;
-	class->recompress     = base_fr_command_recompress;
-
-	class->escape         = base_fr_command_escape;
-	class->handle_error   = base_fr_command_handle_error;
-
-	class->start          = NULL;
-	class->done           = NULL;
-	class->progress       = NULL;
-	class->message        = NULL;
+			      
+	/* properties */
+	
+	g_object_class_install_property (gobject_class,
+					 PROP_PROCESS,
+					 g_param_spec_object ("process",
+							      "Processs",
+							      "The process object used by the command",
+							      FR_TYPE_PROCESS,
+							      G_PARAM_READWRITE));
+	g_object_class_install_property (gobject_class,
+					 PROP_FILENAME,
+					 g_param_spec_string ("filename",
+							      "Filename",
+							      "The archive filename",
+							      NULL,
+							      G_PARAM_READWRITE));
+	g_object_class_install_property (gobject_class,
+					 PROP_MIME_TYPE,
+					 g_param_spec_string ("mime-type",
+							      "Mime type",
+							      "The file mime-type",
+							      NULL,
+							      G_PARAM_READWRITE));	
 }
 
 
@@ -246,61 +411,9 @@
 	comm->propExtractCanJunkPaths = FALSE;
 	comm->propPassword = FALSE;
 	comm->propTest = FALSE;
-	comm->propCanExtractAll = TRUE;
-}
-
-
-static void
-fr_command_start (FrProcess *process,
-		  gpointer   data)
-{
-	FrCommand *comm = FR_COMMAND (data);
-	
-	g_signal_emit (G_OBJECT (comm),
-		       fr_command_signals[START], 
-		       0,
-		       comm->action);
-}
-
-
-static void
-fr_command_done (FrProcess   *process,
-		 gpointer     data)
-{
-	FrCommand *comm = FR_COMMAND (data);
-
-	comm->process->restart = FALSE;
-	if (process->error.type != FR_PROC_ERROR_NONE)
-		fr_command_handle_error (comm, &process->error);
-
-	if (comm->process->restart)
-		fr_process_start (comm->process);
-	else
-		g_signal_emit (G_OBJECT (comm),
-			       fr_command_signals[DONE], 
-			       0,
-			       comm->action, 
-			       &process->error);
-}
-
-
-void
-fr_command_construct (FrCommand  *comm,
-		      FrProcess  *process,
-		      const char *fr_command_name)
-{
-	fr_command_set_filename (comm, fr_command_name);
-
-	g_object_ref (G_OBJECT (process));
-	comm->process = process;
-	g_signal_connect (G_OBJECT (comm->process),
-			  "start",
-			  G_CALLBACK (fr_command_start),
-			  comm);
-	g_signal_connect (G_OBJECT (comm->process),
-			  "done",
-			  G_CALLBACK (fr_command_done),
-			  comm);
+	comm->propCanExtractAll = TRUE; 	
+	comm->propCanDeleteNonEmptyFolders = TRUE;
+	comm->propCanExtractNonEmptyFolders = TRUE;
 }
 
 
@@ -316,20 +429,11 @@
 
 	if (comm->filename != NULL)
 		g_free (comm->filename);
-
 	if (comm->e_filename != NULL)
 		g_free (comm->e_filename);
-
 	if (comm->files != NULL) 
 		g_ptr_array_free_full (comm->files, (GFunc) file_data_free, NULL);
-
-	g_signal_handlers_disconnect_matched (G_OBJECT (comm->process),
-					      G_SIGNAL_MATCH_DATA, 
-					      0, 
-					      0, NULL, 
-					      0,
-					      comm);
-	g_object_unref (G_OBJECT (comm->process));
+	fr_command_set_process (comm, NULL);
 
 	/* Chain up */
 	if (G_OBJECT_CLASS (parent_class)->finalize)
@@ -343,21 +447,30 @@
 {
 	g_return_if_fail (FR_IS_COMMAND (comm));
 
-	if (comm->filename != NULL)
+	if (comm->filename != NULL) {
 		g_free (comm->filename);
+		comm->filename = NULL;
+	}
 
-	if (comm->e_filename != NULL)
+	if (comm->e_filename != NULL) {
 		g_free (comm->e_filename);
+		comm->e_filename = NULL;
+	}
+	
+	if (filename == NULL)
+		return;
 
 	if (! g_path_is_absolute (filename)) {
 		char *current_dir;
+
 		current_dir = g_get_current_dir ();
 		comm->filename = g_strconcat (current_dir,
 					      "/", 
 					      filename, 
 					      NULL);
 		g_free (current_dir);
-	} else
+	} 
+	else
 		comm->filename = g_strdup (filename);
 
 	comm->e_filename = shell_escape (comm->filename);
@@ -395,7 +508,7 @@
 		const char    *base_dir,
 		gboolean       update,
 		const char    *password,
-		FRCompression  compression)
+		FrCompression  compression)
 {
 	fr_command_progress (comm, -1.0);
 
@@ -475,7 +588,7 @@
 
 void
 fr_command_recompress (FrCommand     *comm,
-		       FRCompression  compression)
+		       FrCompression  compression)
 {
 	fr_command_progress (comm, -1.0);	
 	FR_COMMAND_GET_CLASS (G_OBJECT (comm))->recompress (comm, compression);
@@ -483,13 +596,21 @@
 
 
 char *
-fr_command_escape (FrCommand     *comm,
-		   const char    *str)
+fr_command_escape (FrCommand  *comm,
+		   const char *str)
 {
 	return FR_COMMAND_GET_CLASS (G_OBJECT (comm))->escape (comm, str);
 }
 
 
+gboolean
+fr_command_is_capable_of (FrCommand     *comm, 
+			  FrCommandCaps  requested_capabilities)
+{
+	return (((comm->capabilities ^ requested_capabilities) & requested_capabilities) == 0);
+}
+
+
 /* fraction == -1 means : I don't known how much time the current operation
  *                        will take, the dialog will display this info pulsing 
  *                        the progress bar. 
@@ -537,8 +658,16 @@
 
 
 void
+fr_command_set_mime_type (FrCommand  *comm,
+			  const char *mime_type)
+{
+	FR_COMMAND_GET_CLASS (G_OBJECT (comm))->set_mime_type (comm, mime_type);
+}
+
+
+void
 fr_command_handle_error (FrCommand *comm,
-			 FRProcError *error)
+			 FrProcError *error)
 {
 	FR_COMMAND_GET_CLASS (G_OBJECT (comm))->handle_error (comm, error);
 }

Modified: trunk/src/fr-command.h
==============================================================================
--- trunk/src/fr-command.h	(original)
+++ trunk/src/fr-command.h	Mon Jun  2 11:14:27 2008
@@ -55,7 +55,7 @@
 	FR_ACTION_COPYING_FILES_TO_REMOTE,    /* copying extracted files to a remote location */
 	FR_ACTION_CREATING_ARCHIVE,           /* creating a local archive */
 	FR_ACTION_SAVING_REMOTE_ARCHIVE       /* copying the archive to a remote location */
-} FRAction;
+} FrAction;
 
 #ifdef DEBUG
 extern char *action_names[];
@@ -65,7 +65,6 @@
 {
 	GObject  __parent;
 
-	FRFileType  file_type;
 	GPtrArray  *files;           /* Array of FileData* */
 	
 	/*<protected>*/
@@ -82,6 +81,8 @@
 	guint       propPassword : 1;
 	guint       propTest : 1;
 	guint       propCanExtractAll : 1;
+	guint       propCanDeleteNonEmptyFolders : 1;
+	guint       propCanExtractNonEmptyFolders : 1;
 
 	/* progress data */
 	
@@ -92,10 +93,12 @@
 
 	FrProcess  *process;         /* the process object used to execute
 				      * commands. */
-	FRAction    action;          /* current action. */
+	FrAction    action;          /* current action. */
 	char       *filename;        /* archive file path. */
 	char       *e_filename;      /* escaped archive filename. */
-
+	const char *mime_type;
+	FrCommandCaps capabilities;
+	
 	gboolean    fake_load;       /* if TRUE does nothing when the list
 				      * operation is invoked. */
 };
@@ -113,7 +116,7 @@
 				       const char    *base_dir,
 				       gboolean       update,
 				       const char    *password,
-				       FRCompression  compression); 
+				       FrCompression  compression); 
 	void        (*delete)         (FrCommand     *comm,
 				       GList         *file_list); 
 	void        (*extract)        (FrCommand     *comm,
@@ -127,19 +130,24 @@
 				       const char    *password);
 	void        (*uncompress)     (FrCommand     *comm);
 	void        (*recompress)     (FrCommand     *comm,
-				       FRCompression  compression);
+				       FrCompression  compression);
 	void        (*handle_error)   (FrCommand     *comm,
-				       FRProcError   *error);
+				       FrProcError   *error);
 	char *      (*escape)         (FrCommand     *comm,
 				       const char    *str);
 
+	/*<protected virtual functions>*/
+	
+	void        (*set_mime_type)  (FrCommand     *comm,
+				       const char    *mime_type);
+
 	/*<signals>*/
 
 	void        (*start)          (FrCommand   *comm,
-				       FRAction     action); 
+				       FrAction     action); 
 	void        (*done)           (FrCommand   *comm,
-				       FRAction     action,
-				       FRProcError *error);
+				       FrAction     action,
+				       FrProcError *error);
 	void        (*progress)       (FrCommand   *comm,
 				       double       fraction);
 	void        (*message)        (FrCommand   *comm,
@@ -147,9 +155,6 @@
 };
 
 GType          fr_command_get_type           (void);
-void           fr_command_construct          (FrCommand     *comm,
-					      FrProcess     *process,
-					      const char    *filename);
 void           fr_command_set_filename       (FrCommand     *comm,
 					      const char    *filename);
 void           fr_command_list               (FrCommand     *comm,
@@ -159,7 +164,7 @@
 					      const char    *base_dir,
 					      gboolean       update,
 					      const char    *password,
-					      FRCompression  compression); 
+					      FrCompression  compression); 
 void           fr_command_delete             (FrCommand     *comm,
 					      GList         *file_list); 
 void           fr_command_extract            (FrCommand     *comm,
@@ -173,9 +178,11 @@
 					      const char    *password);
 void           fr_command_uncompress         (FrCommand     *comm);
 void           fr_command_recompress         (FrCommand     *comm,
-					      FRCompression  compression);
+					      FrCompression  compression);
 char *         fr_command_escape             (FrCommand     *comm,
 					      const char    *str);
+gboolean       fr_command_is_capable_of      (FrCommand     *comm, 
+					      FrCommandCaps  capabilities);
 
 /* protected functions */
 
@@ -187,10 +194,12 @@
 					      int            n_files);
 void           fr_command_add_file           (FrCommand     *comm,
 					      FileData      *fdata);
+void           fr_command_set_mime_type      (FrCommand     *comm,
+					      const char    *mime_type);
 
 /* private functions */
 
 void           fr_command_handle_error       (FrCommand     *comm,
-					      FRProcError   *error);
+					      FrProcError   *error);
 
 #endif /* FR_COMMAND_H */

Modified: trunk/src/fr-process.c
==============================================================================
--- trunk/src/fr-process.c	(original)
+++ trunk/src/fr-process.c	Mon Jun  2 11:14:27 2008
@@ -51,12 +51,12 @@
 static void fr_process_finalize   (GObject        *object);
 
 
-static FRCommandInfo *
+static FrCommandInfo *
 fr_command_info_new (void)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
-	c_info = g_new0 (FRCommandInfo, 1);
+	c_info = g_new0 (FrCommandInfo, 1);
 	c_info->args = NULL;
 	c_info->dir = NULL;
 	c_info->sticky = FALSE;
@@ -67,7 +67,7 @@
 
 
 static void
-fr_command_info_free (FRCommandInfo * c_info)
+fr_command_info_free (FrCommandInfo * c_info)
 {
 	if (c_info == NULL)
 		return;
@@ -246,7 +246,7 @@
 fr_process_begin_command (FrProcess  *fr_proc,
 			  const char *arg)
 {
-	FRCommandInfo * c_info;
+	FrCommandInfo * c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -265,7 +265,7 @@
 			     const char *arg,
 			     int         index)
 {
-	FRCommandInfo *c_info, *old_c_info;
+	FrCommandInfo *c_info, *old_c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 	g_return_if_fail (index >= 0 && index <= fr_proc->n_comm);
@@ -288,7 +288,7 @@
 fr_process_set_working_dir (FrProcess  *fr_proc,
 			    const char *dir)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -303,7 +303,7 @@
 fr_process_set_sticky (FrProcess *fr_proc,
 		       gboolean   sticky)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -316,7 +316,7 @@
 fr_process_set_ignore_error (FrProcess *fr_proc,
 			     gboolean   ignore_error)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -329,7 +329,7 @@
 fr_process_add_arg (FrProcess  *fr_proc,
 		    const char *arg)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -344,7 +344,7 @@
 		       int         n_arg,
 		       const char *arg_value)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 	GList         *arg;
 
 	g_return_if_fail (fr_proc != NULL);
@@ -363,7 +363,7 @@
 			   ProcFunc      func,
 			   gpointer      func_data)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -378,7 +378,7 @@
 			 ProcFunc      func,
 			 gpointer      func_data)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -393,7 +393,7 @@
 			      ContinueFunc  func,
 			      gpointer      func_data)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -409,7 +409,7 @@
 void
 fr_process_end_command (FrProcess *fr_proc)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 
 	g_return_if_fail (fr_proc != NULL);
 
@@ -426,7 +426,7 @@
 	g_return_if_fail (fr_proc != NULL);
 
 	for (i = 0; i <= fr_proc->n_comm; i++) {
-		FRCommandInfo *c_info;
+		FrCommandInfo *c_info;
 
 		c_info = g_ptr_array_index (fr_proc->comm, i);
 		fr_command_info_free (c_info);
@@ -580,7 +580,7 @@
 static void
 start_current_command (FrProcess *fr_proc)
 {
-	FRCommandInfo  *c_info;
+	FrCommandInfo  *c_info;
 	GList          *arg_list, *scan;
 	GString        *command;
 	char           *dir;
@@ -671,7 +671,7 @@
 command_is_sticky (FrProcess *fr_proc,
 		   int        i)
 {
-	FRCommandInfo *c_info;
+	FrCommandInfo *c_info;
 	c_info = g_ptr_array_index (fr_proc->comm, i);
 	return c_info->sticky;
 }
@@ -703,7 +703,7 @@
 check_child (gpointer data)
 {
 	FrProcess      *fr_proc = data;
-	FRCommandInfo  *c_info;
+	FrCommandInfo  *c_info;
 	pid_t           pid;
 	int             status;
 	gboolean        continue_process;

Modified: trunk/src/fr-process.h
==============================================================================
--- trunk/src/fr-process.h	(original)
+++ trunk/src/fr-process.h	Mon Jun  2 11:14:27 2008
@@ -62,7 +62,7 @@
 
 	ProcFunc     end_func;
 	gpointer     end_data;
-} FRCommandInfo;
+} FrCommandInfo;
 
 
 struct _FrProcess {
@@ -80,7 +80,7 @@
 
 	/*< private >*/
 
-	GPtrArray   *comm;             /* FRCommandInfo elements. */
+	GPtrArray   *comm;             /* FrCommandInfo elements. */
 	gint         n_comm;           /* total number of commands */
 	gint         current_comm;     /* currenlty editing command. */
 
@@ -104,8 +104,8 @@
 	ProcLineFunc e_proc_line_func;
 	gpointer     e_proc_line_data;
 
-	FRProcError  error;
-	FRProcError  first_error;
+	FrProcError  error;
+	FrProcError  first_error;
 
 	gboolean     running;
 	gboolean     stopping;

Modified: trunk/src/fr-window.c
==============================================================================
--- trunk/src/fr-window.c	(original)
+++ trunk/src/fr-window.c	Mon Jun  2 11:14:27 2008
@@ -256,7 +256,7 @@
 	GtkWidget *      up_arrows[5];
 	GtkWidget *      down_arrows[5];
 
-	FRAction         action;
+	FrAction         action;
 	gboolean         archive_present;
 	gboolean         archive_new;        /* A new archive has been created
 					      * but it doesn't contain any
@@ -283,19 +283,19 @@
 	gboolean         single_click;
 	GtkTreePath     *path_clicked;
 
-	FRWindowSortMethod sort_method;
+	FrWindowSortMethod sort_method;
 	GtkSortType      sort_type;
 
 	char *           last_location;
 
 	gboolean         view_folders;
-	FRWindowListMode list_mode;
-	FRWindowListMode last_list_mode;
+	FrWindowListMode list_mode;
+	FrWindowListMode last_list_mode;
 	GList *          history;
 	GList *          history_current;
 	char *           password;
 	char *           password_for_paste;
-	FRCompression    compression;
+	FrCompression    compression;
 
 	guint            activity_timeout_handle;   /* activity timeout
 						     * handle. */
@@ -347,7 +347,7 @@
 	gboolean   progress_pulse;
 	guint      progress_timeout;  /* Timeout to display the progress dialog. */
 	guint      hide_progress_timeout;  /* Timeout to hide the progress dialog. */
-	FRAction   pd_last_action;
+	FrAction   pd_last_action;
 	char      *pd_last_archive;
 
 	/* update dialog data */
@@ -1229,7 +1229,7 @@
 
 
 static int
-get_column_from_sort_method (FRWindowSortMethod sort_method)
+get_column_from_sort_method (FrWindowSortMethod sort_method)
 {
 	switch (sort_method) {
 	case FR_WINDOW_SORT_BY_NAME: return COLUMN_NAME;
@@ -1263,7 +1263,7 @@
 
 
 /*static const char *
-get_action_from_sort_method (FRWindowSortMethod sort_method)
+get_action_from_sort_method (FrWindowSortMethod sort_method)
 {
 	switch (sort_method) {
 	case FR_WINDOW_SORT_BY_NAME: return "SortByName";
@@ -2123,7 +2123,7 @@
 
 
 static const char*
-get_message_from_action (FRAction action)
+get_message_from_action (FrAction action)
 {
 	char *message = "";
 
@@ -2175,7 +2175,7 @@
 
 static void
 progress_dialog__set_last_action (FrWindow *window,
-				  FRAction  action)
+				  FrAction  action)
 {
 	const char *title;
 	char       *markup;
@@ -2425,7 +2425,7 @@
 
 static void
 action_started (FrArchive *archive,
-		FRAction   action,
+		FrAction   action,
 		gpointer   data)
 {
 	FrWindow   *window = data;
@@ -2577,8 +2577,8 @@
 static gboolean
 handle_errors (FrWindow    *window,
 	       FrArchive   *archive,
-	       FRAction     action,
-	       FRProcError *error)
+	       FrAction     action,
+	       FrProcError *error)
 {
 	if (error->type == FR_PROC_ERROR_ASK_PASSWORD) {
 		dlg_ask_password (window);
@@ -2689,8 +2689,8 @@
 
 static void
 convert__action_performed (FrArchive   *archive,
-			   FRAction     action,
-			   FRProcError *error,
+			   FrAction     action,
+			   FrProcError *error,
 			   gpointer     data)
 {
 	FrWindow *window = data;
@@ -2771,8 +2771,8 @@
 
 static void
 action_performed (FrArchive   *archive,
-		  FRAction     action,
-		  FRProcError *error,
+		  FrAction     action,
+		  FrProcError *error,
 		  gpointer     data)
 {
 	FrWindow *window = data;
@@ -3698,7 +3698,7 @@
 
 	one_file = (list->next == NULL);
 	if (one_file)
-		is_an_archive = fr_archive_utils__file_is_archive (list->data);
+		is_an_archive = uri_is_archive (list->data);
 	else
 		is_an_archive = FALSE;
 
@@ -4919,8 +4919,8 @@
 
 	filter = gtk_recent_filter_new ();
 	gtk_recent_filter_set_name (filter, _("All archives"));
-	for (i = 0; open_type[i] != FR_FILE_TYPE_NULL; i++)
-		gtk_recent_filter_add_mime_type (filter, file_type_desc[open_type[i]].mime_type);
+	for (i = 0; open_type[i] != -1; i++)
+		gtk_recent_filter_add_mime_type (filter, mime_type_desc[open_type[i]].mime_type);
 	gtk_recent_filter_add_application (filter, "File Roller");
 	gtk_recent_chooser_add_filter (chooser, filter);
 
@@ -6054,7 +6054,7 @@
 				 const char    *dest_dir,
 				 gboolean       update,
 				 const char    *password,
-				 FRCompression  compression)
+				 FrCompression  compression)
 {
 	fr_archive_add_directory (window->archive,
 				  directory,
@@ -6073,7 +6073,7 @@
 			     const char    *dest_dir,
 			     gboolean       update,
 			     const char    *password,
-			     FRCompression  compression)
+			     FrCompression  compression)
 {
 	fr_archive_add_items (window->archive,
 			      item_list,
@@ -6103,7 +6103,7 @@
 void
 fr_window_archive_remove (FrWindow      *window,
 			  GList         *file_list,
-			  FRCompression  compression)
+			  FrCompression  compression)
 {
 	fr_window_clipboard_remove_file_list (window, file_list);
 
@@ -6364,7 +6364,7 @@
 }
 
 
-FRCompression
+FrCompression
 fr_window_get_compression (FrWindow *window)
 {
 	return window->priv->compression;
@@ -6473,7 +6473,7 @@
 
 void
 fr_window_set_list_mode (FrWindow         *window,
-			 FRWindowListMode  list_mode)
+			 FrWindowListMode  list_mode)
 {
 	g_return_if_fail (window != NULL);
 
@@ -7285,8 +7285,8 @@
 
 static void
 copy_from_archive_action_performed_cb (FrArchive   *archive,
-		  	   	       FRAction     action,
-		  	   	       FRProcError *error,
+		  	   	       FrAction     action,
+		  	   	       FrProcError *error,
 		  	   	       gpointer     data)
 {
 	FrWindow *window = data;
@@ -7780,8 +7780,8 @@
 
 static void
 fr_window_open_files__extract_done_cb (FrArchive   *archive,
-				       FRAction     action,
-				       FRProcError *error,
+				       FrAction     action,
+				       FrProcError *error,
 				       gpointer     callback_data)
 {
 	OpenFilesData *odata = callback_data;

Modified: trunk/src/fr-window.h
==============================================================================
--- trunk/src/fr-window.h	(original)
+++ trunk/src/fr-window.h	Mon Jun  2 11:14:27 2008
@@ -137,20 +137,20 @@
 						 const char    *dest_dir,
 						 gboolean       update,
 						 const char    *password,
-						 FRCompression  compression);
+						 FrCompression  compression);
 void        fr_window_archive_add_items         (FrWindow      *window,
 						 GList         *dir_list,
 						 const char    *base_dir,
 						 const char    *dest_dir,
 						 gboolean       update,
 						 const char    *password,
-						 FRCompression  compression);
+						 FrCompression  compression);
 void        fr_window_archive_add_dropped_items (FrWindow      *window,
 						 GList         *item_list,
 						 gboolean       update);
 void        fr_window_archive_remove            (FrWindow      *window,
 						 GList         *file_list,
-						 FRCompression  compression);
+						 FrCompression  compression);
 void        fr_window_archive_extract           (FrWindow      *window,
 						 GList         *file_list,
 						 const char    *extract_to_dir,
@@ -170,7 +170,7 @@
 void        fr_window_set_password_for_paste    (FrWindow      *window,
 					         const char    *password);						 
 const char *fr_window_get_password              (FrWindow      *window);
-FRCompression fr_window_get_compression 	(FrWindow      *window);
+FrCompression fr_window_get_compression 	(FrWindow      *window);
 void        fr_window_view_folder_after_extract (FrWindow      *window,
 					 	 gboolean       view);
 
@@ -186,7 +186,7 @@
 void       fr_window_current_folder_activated   (FrWindow       *window,
 						 gboolean        from_sidebar);
 void       fr_window_set_list_mode              (FrWindow       *window,
-						 FRWindowListMode  list_mode);
+						 FrWindowListMode  list_mode);
 
 /**/
 

Modified: trunk/src/gio-utils.c
==============================================================================
--- trunk/src/gio-utils.c	(original)
+++ trunk/src/gio-utils.c	Mon Jun  2 11:14:27 2008
@@ -75,7 +75,8 @@
 static void
 filter_destroy (Filter *filter)
 {	
-	g_return_if_fail (filter != NULL);
+	if (filter == NULL)
+		return;
 
 	g_free (filter->pattern);
 	if (filter->regexps != NULL) 

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	(original)
+++ trunk/src/main.c	Mon Jun  2 11:14:27 2008
@@ -28,6 +28,22 @@
 #include <libgnomeui/libgnomeui.h>
 #include "file-utils.h"
 #include "glib-utils.h"
+#include "fr-command.h"
+#include "fr-command-ace.h"
+#include "fr-command-ar.h"
+#include "fr-command-arj.h"
+#include "fr-command-cfile.h"
+#include "fr-command-cpio.h"
+#include "fr-command-iso.h"
+#include "fr-command-jar.h"
+#include "fr-command-lha.h"
+#include "fr-command-rar.h"
+#include "fr-command-rpm.h"
+#include "fr-command-tar.h"
+#include "fr-command-unstuff.h"
+#include "fr-command-zip.h"
+#include "fr-command-zoo.h"
+#include "fr-command-7z.h"
 #include "fr-process.h"
 #include "fr-stock.h"
 #include "gconf-utils.h"
@@ -49,94 +65,135 @@
 GList        *CommandList = NULL;
 gint          ForceDirectoryCreation;
 GHashTable   *ProgramsCache = NULL;
+GPtrArray    *Registered_Commands = NULL;
 
-static gchar **remaining_args;
+static char **remaining_args;
 
-static gchar *add_to = NULL;
-static gint   add;
-static gchar *extract_to = NULL;
-static gint   extract;
-static gint   extract_here;
-static gchar *default_url = NULL;
-
-FRFileTypeDescription file_type_desc[] = {
-	{ FR_FILE_TYPE_ACE,          ".ace",     "application/x-ace", N_("Ace (.ace)"), FALSE },
-	{ FR_FILE_TYPE_AR,           ".ar",      "application/x-ar", N_("Ar (.ar)"), FALSE },
-	{ FR_FILE_TYPE_ARJ,          ".arj",     "application/x-arj", N_("Arj (.arj)"), TRUE },
-	{ FR_FILE_TYPE_BZIP,         ".bz",      "application/x-bzip", NULL, FALSE },
-	{ FR_FILE_TYPE_BZIP2,        ".bz2",     "application/x-bzip", NULL, FALSE },
-	{ FR_FILE_TYPE_COMPRESS,     ".Z",       "application/x-compress", NULL, FALSE },
-	{ FR_FILE_TYPE_CPIO,         ".cpio",    "application/x-cpio", NULL, FALSE },
-	{ FR_FILE_TYPE_DEB,          ".deb",     "application/x-deb", NULL, FALSE },
-	{ FR_FILE_TYPE_ISO,          ".iso",     "application/x-cd-image", NULL, FALSE },
-	{ FR_FILE_TYPE_EAR,          ".ear",     "application/x-ear", N_("Ear (.ear)"), TRUE },
-	{ FR_FILE_TYPE_EXE,          ".exe",     "application/x-ms-dos-executable", N_("Self-extracting zip (.exe)"), FALSE },
-	{ FR_FILE_TYPE_GZIP,         ".gz",      "application/x-gzip", NULL, FALSE },
-	{ FR_FILE_TYPE_JAR,          ".jar",     "application/x-jar", N_("Jar (.jar)"), TRUE },
-	{ FR_FILE_TYPE_LHA,          ".lzh",     "application/x-lha", N_("Lha (.lzh)"), FALSE },
-	{ FR_FILE_TYPE_LZMA,         ".lzma",    "application/x-lzma", NULL, FALSE },
-	{ FR_FILE_TYPE_LZOP,         ".lzo",     "application/x-lzop", NULL, FALSE },
-	{ FR_FILE_TYPE_RAR,          ".rar",     "application/x-rar", N_("Rar (.rar)"), TRUE },
-	{ FR_FILE_TYPE_RPM,          ".rpm",     "application/x-rpm", NULL, FALSE },
-	{ FR_FILE_TYPE_TAR,          ".tar",     "application/x-tar", N_("Tar uncompressed (.tar)"), FALSE },
-	{ FR_FILE_TYPE_TAR_BZ,       ".tar.bz",  "application/x-bzip-compressed-tar", N_("Tar compressed with bzip (.tar.bz)"), FALSE },
-	{ FR_FILE_TYPE_TAR_BZ2,      ".tar.bz2", "application/x-bzip-compressed-tar", N_("Tar compressed with bzip2 (.tar.bz2)"), FALSE },
-	{ FR_FILE_TYPE_TAR_GZ,       ".tar.gz",  "application/x-compressed-tar", N_("Tar compressed with gzip (.tar.gz)"), FALSE },
-	{ FR_FILE_TYPE_TAR_LZMA,     ".tar.lzma","application/x-lzma-compressed-tar", N_("Tar compressed with lzma (.tar.lzma)"), FALSE },
-	{ FR_FILE_TYPE_TAR_LZOP,     ".tar.lzo", "application/x-lzop-compressed-tar", N_("Tar compressed with lzop (.tar.lzo)"), FALSE },
-	{ FR_FILE_TYPE_TAR_COMPRESS, ".tar.Z",   "application/x-compressed-tar", N_("Tar compressed with compress (.tar.Z)"), FALSE },
-	{ FR_FILE_TYPE_STUFFIT,      ".sit",     "application/x-stuffit", NULL, FALSE },
-	{ FR_FILE_TYPE_WAR,          ".war",     "application/zip", N_("War (.war)"), TRUE },
-	{ FR_FILE_TYPE_ZIP,          ".zip",     "application/zip", N_("Zip (.zip)"), TRUE },
-	{ FR_FILE_TYPE_ZOO,          ".zoo",     "application/x-zoo", N_("Zoo (.zoo)"), FALSE },
-	{ FR_FILE_TYPE_7ZIP,         ".7z",      "application/x-7z-compressed", N_("7-Zip (.7z)"), TRUE },
-	{ FR_FILE_TYPE_NULL, NULL, NULL, NULL, FALSE }
+static char  *add_to = NULL;
+static int    add;
+static char  *extract_to = NULL;
+static int    extract;
+static int    extract_here;
+static char  *default_url = NULL;
+
+FrMimeTypeDescription mime_type_desc[] = {
+	{ "application/x-ace",                 ".ace",      N_("Ace (.ace)"), FALSE, FALSE },
+	{ "application/x-ar",                  ".ar",       N_("Ar (.ar)"), FALSE, TRUE },
+	{ "application/x-arj",                 ".arj",      N_("Arj (.arj)"), TRUE, TRUE },
+	{ "application/x-bzip",                ".bz2",      NULL, FALSE, FALSE },
+	{ "application/x-bzip1",               ".bz",       NULL, FALSE, FALSE },
+	{ "application/x-compress",            ".Z",        NULL, FALSE, FALSE },
+	{ "application/x-cpio",                ".cpio",     NULL, FALSE, TRUE },
+	{ "application/x-deb",                 ".deb",      NULL, FALSE, TRUE },
+	{ "application/x-cd-image",            ".iso",      NULL, FALSE, TRUE },
+	{ "application/x-ear",                 ".ear",      N_("Ear (.ear)"), TRUE, TRUE },
+	{ "application/x-ms-dos-executable",   ".exe",      N_("Self-extracting zip (.exe)"), FALSE, TRUE },
+	{ "application/x-gzip",                ".gz",       NULL, FALSE, FALSE },
+	{ "application/x-jar",                 ".jar",      N_("Jar (.jar)"), TRUE, TRUE },
+	{ "application/x-lha",                 ".lzh",      N_("Lha (.lzh)"), FALSE, TRUE },
+	{ "application/x-lzma",                ".lzma",     NULL, FALSE, FALSE },
+	{ "application/x-lzop",                ".lzo",      NULL, FALSE, FALSE },
+	{ "application/x-rar",                 ".rar",      N_("Rar (.rar)"), TRUE, TRUE },
+	{ "application/x-rpm",                 ".rpm",      NULL, FALSE, TRUE },
+	{ "application/x-tar",                 ".tar",      N_("Tar uncompressed (.tar)"), FALSE, TRUE },
+	{ "application/x-bzip1-compressed-tar", ".tar.bz",   N_("Tar compressed with bzip (.tar.bz)"), FALSE, TRUE },
+	{ "application/x-bzip-compressed-tar", ".tar.bz2",  N_("Tar compressed with bzip2 (.tar.bz2)"), FALSE, TRUE },
+	{ "application/x-compressed-tar",      ".tar.gz",   N_("Tar compressed with gzip (.tar.gz)"), FALSE, TRUE },
+	{ "application/x-lzma-compressed-tar", ".tar.lzma", N_("Tar compressed with lzma (.tar.lzma)"), FALSE, TRUE },
+	{ "application/x-lzop-compressed-tar", ".tar.lzo",  N_("Tar compressed with lzop (.tar.lzo)"), FALSE, TRUE },
+	{ "application/x-compressed-tar",      ".tar.Z",    N_("Tar compressed with compress (.tar.Z)"), FALSE, TRUE },
+	{ "application/x-stuffit",             ".sit",      NULL, FALSE, TRUE },
+	{ "application/x-war",                 ".war",      N_("War (.war)"), TRUE, TRUE },
+	{ "application/zip",                   ".zip",      N_("Zip (.zip)"), TRUE, TRUE },
+	{ "application/x-zoo",                 ".zoo",      N_("Zoo (.zoo)"), FALSE, TRUE },
+	{ "application/x-7z-compressed",       ".7z",       N_("7-Zip (.7z)"), TRUE, TRUE },
+	{ NULL, NULL, NULL, FALSE, FALSE }
 };
 
+FrExtensionType file_ext_type[] = {
+	{ ".7z", "application/x-7z-compressed" },
+	{ ".ace", "application/x-ace" },
+	{ ".ar", "application/x-ar" },
+	{ ".arj", "application/x-arj" },
+	{ ".bin", "application/x-stuffit" },
+	{ ".bz", "application/x-bzip" },
+	{ ".bz2", "application/x-bzip" },
+	{ ".cpio", "application/x-cpio" },
+	{ ".deb", "application/x-deb" },
+	{ ".ear", "application/x-ear" },
+	{ ".exe", "application/x-ms-dos-executable" },
+	{ ".gz", "application/x-gzip" },
+	{ ".iso", "application/x-cd-image" },
+	{ ".jar", "application/x-jar" },
+	{ ".lha", "application/x-lha" },
+	{ ".lzh", "application/x-lha" },
+	{ ".lzma", "application/x-lzma" },
+	{ ".lzo", "application/x-lzop" },
+	{ ".rar", "application/x-rar" },
+	{ ".rpm", "application/x-rpm" },
+	{ ".sit", "application/x-stuffit" },
+	{ ".tar", "application/x-tar" },
+	{ ".tar.bz", "application/x-bzip-compressed-tar" },
+	{ ".tar.bz2", "application/x-bzip-compressed-tar" },
+	{ ".tar.gz", "application/x-compressed-tar" },
+	{ ".tar.lzma", "application/x-lzma-compressed-tar" },
+	{ ".tar.lzo", "application/x-lzop-compressed-tar" },
+	{ ".tar.Z", "application/x-compressed-tar" },
+	{ ".taz", "application/x-compressed-tar" },
+	{ ".tbz", "application/x-bzip-compressed-tar" },
+	{ ".tbz2", "application/x-bzip-compressed-tar" },
+	{ ".tgz", "application/x-compressed-tar" },
+	{ ".tzma", "application/x-lzma-compressed-tar" },
+	{ ".tzo", "application/x-lzop-compressed-tar" },
+	{ ".war", "application/x-war" },
+	{ ".z", "application/x-gzip" },
+	{ ".Z", "application/x-gzip" },
+	{ ".zip", "application/zip" },
+	{ ".zoo", "application/x-zoo" }
+};
 
-FRFileType single_file_save_type[32];
-FRFileType save_type[32];
-FRFileType open_type[32];
-
-
-FRCommandDescription command_desc[] = {
-	{ "tar",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_TAR },
-	{ "zip",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_ZIP },
-	{ "unzip",      TRUE,  FALSE, TRUE,  FR_FILE_TYPE_ZIP },
-	{ "rar",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_RAR },
-	{ "unrar",      TRUE,  FALSE, TRUE,  FR_FILE_TYPE_RAR },
-	{ "gzip",       TRUE,  TRUE,  FALSE, FR_FILE_TYPE_GZIP },
-	{ "bzip2",      TRUE,  TRUE,  FALSE, FR_FILE_TYPE_BZIP2 },
-	{ "unace",      TRUE,  FALSE, TRUE,  FR_FILE_TYPE_ACE },
-	{ "ar",         TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_AR },
-	{ "ar",         TRUE,  FALSE, TRUE,  FR_FILE_TYPE_DEB },
-	{ "arj",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_ARJ },
-	{ "bzip2",      TRUE,  FALSE, FALSE, FR_FILE_TYPE_BZIP },
-	{ "compress",   TRUE,  TRUE,  FALSE, FR_FILE_TYPE_COMPRESS },
-	{ "cpio",       TRUE,  FALSE, FALSE, FR_FILE_TYPE_CPIO },
-	{ "isoinfo",    TRUE,  FALSE, TRUE,  FR_FILE_TYPE_ISO },
-	{ "zip",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_EAR },
-	{ "zip",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_JAR },
-	{ "zip",        TRUE,  FALSE,  TRUE,  FR_FILE_TYPE_EXE },
-	{ "lha",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_LHA },
-	{ "lzma",       TRUE,  TRUE,  FALSE, FR_FILE_TYPE_LZMA },
-	{ "lzop",       TRUE,  TRUE,  FALSE, FR_FILE_TYPE_LZOP },
-	{ "rpm2cpio",   TRUE,  FALSE, TRUE,  FR_FILE_TYPE_RPM },
-	{ "uncompress", TRUE,  FALSE, FALSE, FR_FILE_TYPE_COMPRESS },
-	{ "unstuff",    TRUE,  FALSE, FALSE, FR_FILE_TYPE_STUFFIT },
-	{ "zip",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_WAR },
-	{ "zoo",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_ZOO },
-	{ "7za",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_7ZIP },
-	{ "7zr",        TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_7ZIP }
+int single_file_save_type[32];
+int save_type[32];
+int open_type[32];
+
+FrCommandDescription command_desc[] = {
+	{ "tar",        "application/x-tar", TRUE, TRUE },
+	{ "zip",        "application/zip",  TRUE, TRUE },
+	{ "unzip",      "application/zip", TRUE, FALSE },
+	{ "rar",        "application/x-rar", TRUE, TRUE },
+	{ "unrar",      "application/x-rar", TRUE, FALSE },
+	{ "gzip",       "application/x-gzip", TRUE, TRUE },
+	{ "bzip2",      "application/x-bzip", TRUE, TRUE },
+	{ "unace",      "application/x-ace", TRUE, FALSE },
+	{ "ar",         "application/x-ar", TRUE, TRUE },
+	{ "ar",         "application/x-deb", TRUE, FALSE },
+	{ "arj",        "application/x-arj", TRUE, TRUE },
+	{ "bzip2",      "application/x-bzip1", TRUE, FALSE },
+	{ "compress",   "application/x-gzip", TRUE, TRUE },
+	{ "cpio",       "application/x-cpio", TRUE, FALSE },
+	{ "isoinfo",    "application/x-cd-image", TRUE, FALSE },
+	{ "zip",        "application/x-ear", TRUE, TRUE },
+	{ "zip",        "application/x-jar", TRUE, TRUE },
+	{ "zip",        "application/x-war", TRUE, TRUE },
+	{ "zip",        "application/x-ms-dos-executable", TRUE, FALSE },
+	{ "lha",        "application/x-lha", TRUE, TRUE },
+	{ "lzma",       "application/x-lzma", TRUE, TRUE },
+	{ "lzop",       "application/x-lzop", TRUE, TRUE },
+	{ "rpm2cpio",   "application/x-rpm", TRUE, FALSE },
+	{ "uncompress", "application/x-gzip", TRUE, FALSE },
+	{ "unstuff",    "application/x-stuffit", TRUE, FALSE },
+	{ "zoo",        "application/x-zoo", TRUE, TRUE },
+	{ "7za",        "application/x-7z-compressed", TRUE, TRUE },
+	{ "7zr",        "application/x-7z-compressed", TRUE, TRUE }
 };
 
-FRCommandDescription tar_command_desc[] = {
-	{ "gzip",      TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_TAR_GZ },
-	{ "bzip2",     TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_TAR_BZ2 },
-	{ "bzip",      FALSE, TRUE,  TRUE,  FR_FILE_TYPE_TAR_BZ },
-	{ "lzma",      TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_TAR_LZMA },
-	{ "lzop",      TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_TAR_LZOP },
-	{ "compress",  TRUE,  TRUE,  TRUE,  FR_FILE_TYPE_TAR_COMPRESS }
+FrCommandDescription tar_command_desc[] = {
+	{ "gzip",      "application/x-compressed-tar", TRUE, TRUE },
+	{ "bzip2",     "application/x-bzip-compressed-tar", TRUE, TRUE },
+	/*{ "bzip",     "application/x-bzip1-compressed-tar", FALSE, TRUE },*/
+	{ "lzma",      "application/x-lzma-compressed-tar", TRUE, TRUE },
+	{ "lzop",      "application/x-lzop-compressed-tar", TRUE, TRUE },
+	{ "compress",  "application/x-compressed-tar", TRUE, TRUE }
 };
 
 
@@ -376,40 +433,291 @@
 }
 
 
+/* -- FrRegisteredCommand -- */
+
+
+FrRegisteredCommand *
+fr_registered_command_new (GType command_type)
+{
+	FrRegisteredCommand *reg_com;
+	
+	reg_com = g_new0 (FrRegisteredCommand, 1);
+	reg_com->ref = 1;
+	reg_com->type = command_type;
+	reg_com->caps = g_ptr_array_new ();
+	
+	return reg_com;
+}
+
+
+void
+fr_registered_command_ref (FrRegisteredCommand *reg_com)
+{
+	reg_com->ref++;
+}
+
+
+void
+fr_registered_command_unref (FrRegisteredCommand *reg_com)
+{
+	if (--(reg_com->ref) != 0)
+		return;
+	
+	g_ptr_array_foreach (reg_com->caps, (GFunc) g_free, NULL);
+	g_ptr_array_free (reg_com->caps, TRUE);
+	g_free (reg_com); 
+}
+
+
+void
+fr_registered_command_add_mime_type (FrRegisteredCommand *reg_com,
+				     const char          *mime_type,
+				     FrCommandCaps        capabilities)
+{
+	FrMimeTypeCap *cap;
+	
+	cap = g_new0 (FrMimeTypeCap, 1);
+	cap->mime_type = mime_type;
+	cap->capabilities = capabilities;
+	
+	g_ptr_array_add (reg_com->caps, cap);
+}
+
+
+FrCommandCaps  
+fr_registered_command_get_capabilities (FrRegisteredCommand *reg_com,
+				        const char          *mime_type)
+{
+	int i;
+		
+	for (i = 0; i < reg_com->caps->len; i++) {
+		FrMimeTypeCap *cap;
+		
+		cap = g_ptr_array_index (reg_com->caps, i);
+		if (strcmp (mime_type, cap->mime_type) == 0) 
+			return cap->capabilities;
+	}
+	
+	return FR_COMMAND_CAP_NONE;
+}
+
+
+void
+register_command (GType command_type, ...)
+{
+	va_list              args;
+	FrRegisteredCommand *command;
+	const char          *mime_type;
+	FrCommandCap         capabilities;
+		
+	if (Registered_Commands == NULL)
+		Registered_Commands = g_ptr_array_sized_new (5);
+	
+	command = fr_registered_command_new (command_type);
+	
+	va_start (args, command_type);
+	while ((mime_type = va_arg (args, const char *)) != NULL) {
+		capabilities = va_arg (args, FrCommandCap);
+		fr_registered_command_add_mime_type (command, mime_type, capabilities); 
+	}
+	va_end (args);
+	
+	g_ptr_array_add (Registered_Commands, command);
+}
+
+
+gboolean
+unregister_command (GType command_type)
+{
+	int i;
+	
+	for (i = 0; i < Registered_Commands->len; i++) {
+		FrRegisteredCommand *command;
+		
+		command = g_ptr_array_index (Registered_Commands, i);
+		if (command->type == command_type) {
+			g_ptr_array_remove_index (Registered_Commands, i);
+			fr_registered_command_unref (command);
+			return TRUE;
+		}
+	}
+	
+	return FALSE;
+}
+
+
+static void
+register_commands (void)
+{
+	register_command (FR_TYPE_COMMAND_7Z, 
+			  "application/x-7z-compressed", FR_COMMAND_CAP_ALL,
+			  NULL);	
+	register_command (FR_TYPE_COMMAND_ACE, 
+			  "application/x-ace", FR_COMMAND_CAP_READ_WRITE,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_AR, 
+			  "application/x-ar", FR_COMMAND_CAP_ALL,
+			  "application/x-deb", FR_COMMAND_CAP_READ,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_ARJ, 
+			  "application/x-arj", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_CFILE, 
+			  "application/x-gzip", FR_COMMAND_CAP_READ_WRITE,
+			  "application/x-bzip", FR_COMMAND_CAP_READ_WRITE,
+			  "application/x-compress", FR_COMMAND_CAP_READ_WRITE,
+			  "application/x-lzma", FR_COMMAND_CAP_READ_WRITE,
+			  "application/x-lzop", FR_COMMAND_CAP_READ_WRITE,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_CPIO, 
+			  "application/x-cpio", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_ISO, 
+			  "application/x-cd-image", FR_COMMAND_CAP_READ,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_JAR,
+			  "application/x-jar", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_LHA,
+			  "application/x-lha", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_RAR,
+			  "application/x-rar", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_RPM,
+			  "application/x-rpm", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_TAR, 
+			  "application/x-tar", FR_COMMAND_CAP_ALL,
+			  "application/x-compressed-tar", FR_COMMAND_CAP_ALL,
+			  "application/x-bzip-compressed-tar", FR_COMMAND_CAP_ALL,
+			  "application/x-lzma-compressed-tar", FR_COMMAND_CAP_ALL,
+			  "application/x-lzop-compressed-tar", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_UNSTUFF,
+			  "application/x-stuffit", FR_COMMAND_CAP_READ,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_ZIP,
+			  "application/zip", FR_COMMAND_CAP_ALL,
+			  "application/x-ear", FR_COMMAND_CAP_ALL,
+			  "application/x-war", FR_COMMAND_CAP_ALL,
+			  "application/x-ms-dos-executable", FR_COMMAND_CAP_ALL,
+			  NULL);
+	register_command (FR_TYPE_COMMAND_ZOO,
+			  "application/x-zoo", FR_COMMAND_CAP_ALL,
+			  NULL);
+}
+
+
+GType
+get_command_type_from_mime_type (const char    *mime_type,
+				 FrCommandCaps  requested_capabilities)
+{
+	int i;
+	
+	if (mime_type == NULL)
+		return 0;
+	
+	for (i = 0; i < Registered_Commands->len; i++) {
+		FrRegisteredCommand *command;
+		FrCommandCaps        capabilities;
+		
+		command = g_ptr_array_index (Registered_Commands, i);
+		capabilities = fr_registered_command_get_capabilities (command, mime_type);
+			
+		/* the command must support all the requested capabilities */
+		if (((capabilities ^ requested_capabilities) & requested_capabilities) == 0)
+			return command->type;
+	}
+	
+	return 0;
+}
+
+
+const char *
+get_mime_type_from_extension (const char *ext)
+{
+	int i;
+	
+	for (i = G_N_ELEMENTS (file_ext_type) - 1; i >= 0; i--) 
+		if (strcmp (ext, file_ext_type[i].ext) == 0) 
+			return get_static_string (file_ext_type[i].mime_type);
+	return NULL;
+}
+
+
+const char *
+get_archive_filename_extension (const char *filename)
+{
+	const char *ext;
+	int         i;
+		
+	if (filename == NULL)
+		return NULL;
+
+	ext = get_file_extension (filename);
+	for (i = G_N_ELEMENTS (file_ext_type) - 1; i >= 0; i--) 
+		if (strcmp (ext, file_ext_type[i].ext) == 0)
+			return ext;
+	return NULL;
+}
+
+
+static int
+get_mime_type_index (const char *mime_type)
+{
+	int i;
+	
+	for (i = 0; i < G_N_ELEMENTS (mime_type_desc); i++) 
+		if (strcmp (mime_type_desc[i].mime_type, mime_type) == 0)
+			return i;
+	return -1;
+}
+
+
 static void
 compute_supported_archive_types (void)
 {
 	int i, j;
 	int sf_i = 0, s_i = 0, o_i = 0;
-
+	int idx;
+	
 	for (i = 0; i < G_N_ELEMENTS (command_desc); i++) {
-		FRCommandDescription com = command_desc[i];
+		FrCommandDescription comm_desc = command_desc[i];
 
-		if (!is_program_in_path (com.command))
+		if (! is_program_in_path (comm_desc.command))
 			continue;
 
-		if (strcmp (com.command, "tar") == 0)
+		if (strcmp (comm_desc.command, "tar") == 0) {
 			for (j = 0; j < G_N_ELEMENTS (tar_command_desc); j++) {
-				FRCommandDescription com2 = tar_command_desc[j];
+				FrCommandDescription comm_desc_2 = tar_command_desc[j];
 
-				if (!is_program_in_path (com2.command))
+				if (!is_program_in_path (comm_desc_2.command))
 					continue;
-				open_type[o_i++] = com2.file_type;
-				save_type[s_i++] = com2.file_type;
-				single_file_save_type[sf_i++] = com2.file_type;
+					
+				idx = get_mime_type_index (comm_desc_2.mime_type);
+				if (idx >= 0) {
+					open_type[o_i++] = idx;
+					save_type[s_i++] = idx;
+					single_file_save_type[sf_i++] = idx;
+				}
 			}
-
-		if (com.can_open)
-			open_type[o_i++] = com.file_type;
-		if (com.can_save && com.support_many_files)
-			save_type[s_i++] = com.file_type;
-		if (com.can_save)
-			single_file_save_type[sf_i++] = com.file_type;
+		}
+		
+		idx = get_mime_type_index (comm_desc.mime_type);
+		if (idx >= 0) {
+			if (comm_desc.can_open)
+				open_type[o_i++] = idx;
+			if (comm_desc.can_save && mime_type_desc[idx].supports_many_files)
+				save_type[s_i++] = idx;
+			if (comm_desc.can_save)
+				single_file_save_type[sf_i++] = idx;
+		}
 	}
 
-	open_type[o_i++] = FR_FILE_TYPE_NULL;
-	save_type[s_i++] = FR_FILE_TYPE_NULL;
-	single_file_save_type[sf_i++] = FR_FILE_TYPE_NULL;
+	open_type[o_i++] = -1;
+	save_type[s_i++] = -1;
+	single_file_save_type[sf_i++] = -1;
 }
 
 
@@ -466,6 +774,7 @@
 	if (eel_gconf_get_boolean (PREF_MIGRATE_DIRECTORIES, TRUE))
 		migrate_to_new_directories ();
 
+	register_commands ();
 	compute_supported_archive_types ();
 
 	if (session_is_restored ()) {

Modified: trunk/src/main.h
==============================================================================
--- trunk/src/main.h	(original)
+++ trunk/src/main.h	Mon Jun  2 11:14:27 2008
@@ -58,13 +58,20 @@
 extern GList       *CommandList;
 extern gint         ForceDirectoryCreation;
 extern GHashTable  *ProgramsCache;
+extern GPtrArray   *Registered_Commands;
 
-extern FRFileTypeDescription file_type_desc[];
-extern FRFileType single_file_save_type[]; /* File types that can be saved when
-					    * a single file is selected.  
-					    * Includes single file compressors
-					    * such as gzip, compress, etc. */
-extern FRFileType save_type[];             /* File types that can be saved. */
-extern FRFileType open_type[];             /* File types that can be opened. */
+extern FrMimeTypeDescription mime_type_desc[];
+extern FrExtensionType file_ext_type[];
+extern int single_file_save_type[]; /* File types that can be saved when
+				     * a single file is selected.  
+				     * Includes single file compressors
+				     * such as gzip, compress, etc. */
+extern int save_type[];             /* File types that can be saved. */
+extern int open_type[];             /* File types that can be opened. */
+ 
+GType        get_command_type_from_mime_type (const char    *mime_type,
+				 	      FrCommandCaps  requested_capabilities);
+const char * get_mime_type_from_extension    (const char    *ext);
+const char * get_archive_filename_extension  (const char *uri);
 
 #endif /* MAIN_H */

Modified: trunk/src/preferences.c
==============================================================================
--- trunk/src/preferences.c	(original)
+++ trunk/src/preferences.c	Mon Jun  2 11:14:27 2008
@@ -110,7 +110,7 @@
 /* --------------- */
 
 
-FRWindowSortMethod
+FrWindowSortMethod
 preferences_get_sort_method (void)
 {
 	char *s_value;
@@ -120,12 +120,12 @@
 	i_value = get_enum_from_string (sort_method_table, s_value);
 	g_free (s_value);
 
-	return (FRWindowSortMethod) i_value;
+	return (FrWindowSortMethod) i_value;
 }
 
 
 void
-preferences_set_sort_method (FRWindowSortMethod i_value)
+preferences_set_sort_method (FrWindowSortMethod i_value)
 {
 	char *s_value;
 
@@ -158,7 +158,7 @@
 }
 
 
-FRWindowListMode
+FrWindowListMode
 preferences_get_list_mode (void)
 {
 	char *s_value;
@@ -168,12 +168,12 @@
 	i_value = get_enum_from_string (list_mode_table, s_value);
 	g_free (s_value);
 
-	return (FRWindowListMode) i_value;
+	return (FrWindowListMode) i_value;
 }
 
 
 void
-preferences_set_list_mode (FRWindowListMode i_value)
+preferences_set_list_mode (FrWindowListMode i_value)
 {
 	char *s_value;
 
@@ -182,7 +182,7 @@
 }
 
 
-FRCompression
+FrCompression
 preferences_get_compression_level (void)
 {
 	char *s_value;
@@ -192,12 +192,12 @@
 	i_value = get_enum_from_string (compression_level_table, s_value);
 	g_free (s_value);
 
-	return (FRCompression) i_value;
+	return (FrCompression) i_value;
 }
 
 
 void
-preferences_set_compression_level (FRCompression i_value)
+preferences_set_compression_level (FrCompression i_value)
 {
 	char *s_value;
 

Modified: trunk/src/preferences.h
==============================================================================
--- trunk/src/preferences.h	(original)
+++ trunk/src/preferences.h	Mon Jun  2 11:14:27 2008
@@ -72,14 +72,14 @@
 #define PREF_DESKTOP_TOOLBAR_DETACHABLE "/desktop/gnome/interface/toolbar_detachable"
 #define PREF_NAUTILUS_CLICK_POLICY "/apps/nautilus/preferences/click_policy"
 
-FRWindowSortMethod  preferences_get_sort_method       (void);
-void                preferences_set_sort_method       (FRWindowSortMethod  i_value);
+FrWindowSortMethod  preferences_get_sort_method       (void);
+void                preferences_set_sort_method       (FrWindowSortMethod  i_value);
 GtkSortType         preferences_get_sort_type         (void);
 void                preferences_set_sort_type         (GtkSortType         i_value);
-FRWindowListMode    preferences_get_list_mode         (void);
-void                preferences_set_list_mode         (FRWindowListMode    i_value);
-FRCompression       preferences_get_compression_level (void);
-void                preferences_set_compression_level (FRCompression       i_value);
+FrWindowListMode    preferences_get_list_mode         (void);
+void                preferences_set_list_mode         (FrWindowListMode    i_value);
+FrCompression       preferences_get_compression_level (void);
+void                preferences_set_compression_level (FrCompression       i_value);
 void                pref_util_save_window_geometry    (GtkWindow          *window,
 						       const char         *dialog);
 void                pref_util_restore_window_geometry (GtkWindow          *window,

Modified: trunk/src/typedefs.h
==============================================================================
--- trunk/src/typedefs.h	(original)
+++ trunk/src/typedefs.h	Mon Jun  2 11:14:27 2008
@@ -38,29 +38,19 @@
 	FR_WINDOW_SORT_BY_TYPE = 2,
 	FR_WINDOW_SORT_BY_TIME = 3,
 	FR_WINDOW_SORT_BY_PATH = 4
-} FRWindowSortMethod;
+} FrWindowSortMethod;
 
 typedef enum {
 	FR_WINDOW_LIST_MODE_FLAT,
 	FR_WINDOW_LIST_MODE_AS_DIR
-} FRWindowListMode;
-
-typedef enum {
-	FR_COMPRESS_PROGRAM_NONE,
-	FR_COMPRESS_PROGRAM_GZIP,
-	FR_COMPRESS_PROGRAM_BZIP,
-	FR_COMPRESS_PROGRAM_BZIP2,
-	FR_COMPRESS_PROGRAM_COMPRESS,
-	FR_COMPRESS_PROGRAM_LZMA,
-	FR_COMPRESS_PROGRAM_LZOP
-} FRCompressProgram;
+} FrWindowListMode;
 
 typedef enum {
 	FR_COMPRESSION_VERY_FAST,
 	FR_COMPRESSION_FAST,
 	FR_COMPRESSION_NORMAL,
 	FR_COMPRESSION_MAXIMUM
-} FRCompression;
+} FrCompression;
 
 typedef enum {
 	FR_PROC_ERROR_NONE,
@@ -71,63 +61,56 @@
 	FR_PROC_ERROR_SPAWN,
 	FR_PROC_ERROR_STOPPED,
 	FR_PROC_ERROR_ASK_PASSWORD
-} FRProcErrorType;
+} FrProcErrorType;
 
 typedef struct {
-	FRProcErrorType  type;
+	FrProcErrorType  type;
 	int              status;
 	GError          *gerror;
-} FRProcError;
-
-typedef enum {
-	FR_FILE_TYPE_ACE,
-	FR_FILE_TYPE_AR,
-	FR_FILE_TYPE_ARJ,
-	FR_FILE_TYPE_BZIP,
-	FR_FILE_TYPE_BZIP2,
-	FR_FILE_TYPE_COMPRESS,
-	FR_FILE_TYPE_CPIO,
-	FR_FILE_TYPE_DEB,
-	FR_FILE_TYPE_ISO,
-	FR_FILE_TYPE_EAR,
-	FR_FILE_TYPE_EXE,
-	FR_FILE_TYPE_GZIP,
-	FR_FILE_TYPE_JAR,
-	FR_FILE_TYPE_LHA,
-	FR_FILE_TYPE_LZMA,
-	FR_FILE_TYPE_LZOP,
-	FR_FILE_TYPE_RAR,
-	FR_FILE_TYPE_RPM,
-	FR_FILE_TYPE_TAR,
-	FR_FILE_TYPE_TAR_BZ,
-	FR_FILE_TYPE_TAR_BZ2,
-	FR_FILE_TYPE_TAR_GZ,
-	FR_FILE_TYPE_TAR_LZMA,
-	FR_FILE_TYPE_TAR_LZOP,
-	FR_FILE_TYPE_TAR_COMPRESS,
-	FR_FILE_TYPE_STUFFIT,
-	FR_FILE_TYPE_WAR,
-	FR_FILE_TYPE_ZIP,
-	FR_FILE_TYPE_ZOO,
-	FR_FILE_TYPE_7ZIP,
-	FR_FILE_TYPE_NULL
-} FRFileType;
+} FrProcError;
 
 typedef struct {
-	FRFileType  id;
-	char       *ext;
 	char       *mime_type;
+	char       *default_ext;
 	char       *name;
 	gboolean    supports_password;
-} FRFileTypeDescription;
+	gboolean    supports_many_files;
+} FrMimeTypeDescription;
+
+typedef struct {
+	char *ext;
+	char *mime_type;
+} FrExtensionType;
 
 typedef struct {
 	char       *command;
+	const char *mime_type;
 	gboolean    can_open;
 	gboolean    can_save;
-	gboolean    support_many_files;
-	FRFileType  file_type;
-} FRCommandDescription;
+} FrCommandDescription;
+
+typedef enum {
+	FR_COMMAND_CAP_NONE = 0,
+	FR_COMMAND_CAP_READ = 1 << 0,
+	FR_COMMAND_CAP_WRITE = 1 << 1,
+	FR_COMMAND_CAP_ARCHIVE_MANY_FILES = 1 << 2
+} FrCommandCap;
+
+#define FR_COMMAND_CAP_READ_WRITE (FR_COMMAND_CAP_READ | FR_COMMAND_CAP_WRITE)
+#define FR_COMMAND_CAP_ALL (FR_COMMAND_CAP_READ | FR_COMMAND_CAP_WRITE | FR_COMMAND_CAP_ARCHIVE_MANY_FILES)
+
+typedef guint8 FrCommandCaps;
+
+typedef struct {
+	const char    *mime_type;
+	FrCommandCaps  capabilities;
+} FrMimeTypeCap;
+
+typedef struct {
+	int        ref;
+	GType      type;
+	GPtrArray *caps;  /* array of FrMimeTypeCap */
+} FrRegisteredCommand;
 
 #endif /* TYPEDEFS_H */
 

Modified: trunk/src/ui.h
==============================================================================
--- trunk/src/ui.h	(original)
+++ trunk/src/ui.h	Mon Jun  2 11:14:27 2008
@@ -200,7 +200,7 @@
 	  G_CALLBACK (activate_action_go_back) },
 	{ "GoForward", GTK_STOCK_GO_FORWARD,
 	  NULL, NULL,
-	  N_("Open Go to the next visited location selected folder"),
+	  N_("Go to the next visited location"),
 	  G_CALLBACK (activate_action_go_forward) },
 	{ "GoUp", GTK_STOCK_GO_UP,
 	  NULL, NULL,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]