From cbbe010884fe1e3ad1deabbed7f89a77b0098a2f Mon Sep 17 00:00:00 2001 From: Stefano Karapetsas Date: Sat, 16 Jun 2012 11:31:39 +0200 Subject: add diff button for text files in file conflict dialog --- libcaja-private/caja-file-conflict-dialog.c | 67 +++++++++++++++++++++++++++++ libcaja-private/caja-file.c | 45 +++++++++++++++++++ libcaja-private/caja-file.h | 1 + 3 files changed, 113 insertions(+) diff --git a/libcaja-private/caja-file-conflict-dialog.c b/libcaja-private/caja-file-conflict-dialog.c index b37bb879..d0b09f42 100644 --- a/libcaja-private/caja-file-conflict-dialog.c +++ b/libcaja-private/caja-file-conflict-dialog.c @@ -56,6 +56,7 @@ struct _CajaFileConflictDialogDetails GtkWidget *entry; GtkWidget *checkbox; GtkWidget *rename_button; + GtkWidget *diff_button; GtkWidget *replace_button; GtkWidget *dest_image; GtkWidget *src_image; @@ -335,6 +336,25 @@ file_list_ready_cb (GList *files, gtk_button_set_label (GTK_BUTTON (details->replace_button), _("Merge")); } + + /* If meld is installed, and source and destination arent binary + * files, show the diff button + */ + gtk_widget_hide (details->diff_button); + if (!source_is_dir && !dest_is_dir) + { + if (g_find_program_in_path ("meld")) { + + gboolean src_is_binary; + gboolean dest_is_binary; + + src_is_binary = caja_file_is_binary (details->source); + dest_is_binary = caja_file_is_binary (details->destination); + + if (!src_is_binary && !dest_is_binary) + gtk_widget_show (details->diff_button); + } + } caja_file_monitor_add (src, fcd, CAJA_FILE_ATTRIBUTES_FOR_ICON); caja_file_monitor_add (dest, fcd, CAJA_FILE_ATTRIBUTES_FOR_ICON); @@ -486,6 +506,44 @@ reset_button_clicked_cb (GtkButton *w, } +static void +diff_button_clicked_cb (GtkButton *w, + CajaFileConflictDialog *dialog) +{ + CajaFileConflictDialogDetails *details; + details = dialog->details; + + GError *error; + char *command; + char **argv; + + command = g_find_program_in_path ("meld"); + if (command) + { + argv = g_new (char *, 4); + argv[0] = command; + argv[1] = g_file_get_path (caja_file_get_location (details->source)); + argv[2] = g_file_get_path (caja_file_get_location (details->destination)); + argv[3] = NULL; + + error = NULL; + if (!g_spawn_async_with_pipes (NULL, + argv, + NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, + NULL /* user_data */, + NULL, + NULL, NULL, NULL, + &error)) + { + g_warning ("Error opening meld to show differences: %s\n", error->message); + g_error_free (error); + } + g_strfreev (argv); + } +} + static void caja_file_conflict_dialog_init (CajaFileConflictDialog *fcd) { @@ -558,6 +616,15 @@ caja_file_conflict_dialog_init (CajaFileConflictDialog *fcd) gtk_widget_show_all (alignment); + /* Setup the diff button for text files */ + details->diff_button = gtk_button_new_with_label (_("Differences...")); + gtk_button_set_image (GTK_BUTTON (details->diff_button), + gtk_image_new_from_stock (GTK_STOCK_FIND, + GTK_ICON_SIZE_MENU)); + gtk_box_pack_start (GTK_BOX (vbox), details->diff_button, FALSE, FALSE, 6); + g_signal_connect (details->diff_button, "clicked", + G_CALLBACK (diff_button_clicked_cb), dialog); + gtk_widget_hide (details->diff_button); /* Setup the checkbox to apply the action to all files */ widget = gtk_check_button_new_with_mnemonic (_("Apply this action to all files")); diff --git a/libcaja-private/caja-file.c b/libcaja-private/caja-file.c index 7877f7d2..2f43eec2 100644 --- a/libcaja-private/caja-file.c +++ b/libcaja-private/caja-file.c @@ -7134,6 +7134,51 @@ caja_file_contains_text (CajaFile *file) return caja_file_is_mime_type (file, "text/plain"); } +/** + * caja_file_is_binary + * + * Check if this file is a binary file. + * This is private and is used to decide whether or not to show the diff + * button in the file conflict dialog. + * @file: CajaFile representing the file in question. + * + * Returns: TRUE if @file is a binary file. + * + **/ +gboolean +caja_file_is_binary (CajaFile *file) +{ + if (!caja_file_can_read(file)) + { + return FALSE; + } + + gboolean is_binary = FALSE; + int c; + int i; + FILE *fp; + + /* Check the first 4096 bytes of the files. If these contains a 0, + * we can assume the file is binary. + * This idea is taken from python code of meld. + */ + + fp = g_fopen (g_file_get_path (caja_file_get_location (file)), "r"); + for (i = 0; i < 4096; i++) { + c = fgetc(fp); + if (c == EOF) { + break; + } + else if (c == 0) { + is_binary = TRUE; + break; + } + } + fclose(fp); + + return is_binary; +} + /** * caja_file_is_executable * diff --git a/libcaja-private/caja-file.h b/libcaja-private/caja-file.h index ec0845c0..e79dacfc 100644 --- a/libcaja-private/caja-file.h +++ b/libcaja-private/caja-file.h @@ -161,6 +161,7 @@ void caja_file_invalidate_all_attributes (CajaFile /* Basic attributes for file objects. */ gboolean caja_file_contains_text (CajaFile *file); +gboolean caja_file_is_binary (CajaFile *file); char * caja_file_get_display_name (CajaFile *file); char * caja_file_get_edit_name (CajaFile *file); char * caja_file_get_name (CajaFile *file); -- cgit v1.2.1