summaryrefslogtreecommitdiffstats
path: root/src/nautilus-file-conflict-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nautilus-file-conflict-dialog.c')
-rw-r--r--src/nautilus-file-conflict-dialog.c390
1 files changed, 390 insertions, 0 deletions
diff --git a/src/nautilus-file-conflict-dialog.c b/src/nautilus-file-conflict-dialog.c
new file mode 100644
index 0000000..fdcaf2d
--- /dev/null
+++ b/src/nautilus-file-conflict-dialog.c
@@ -0,0 +1,390 @@
+/* nautilus-file-conflict-dialog: dialog that handles file conflicts
+ * during transfer operations.
+ *
+ * Copyright (C) 2008-2010 Cosimo Cecchi
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Cosimo Cecchi <cosimoc@gnome.org>
+ */
+
+#include <config.h>
+#include "nautilus-file-conflict-dialog.h"
+
+#include <string.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+#include <pango/pango.h>
+#include <eel/eel-vfs-extensions.h>
+
+#include "nautilus-file.h"
+#include "nautilus-icon-info.h"
+#include "nautilus-operations-ui-manager.h"
+
+struct _NautilusFileConflictDialog
+{
+ GtkDialog parent_instance;
+
+ gchar *conflict_name;
+
+ /* UI objects */
+ GtkWidget *titles_vbox;
+ GtkWidget *first_hbox;
+ GtkWidget *second_hbox;
+ GtkWidget *expander;
+ GtkWidget *entry;
+ GtkWidget *checkbox;
+ GtkWidget *skip_button;
+ GtkWidget *rename_button;
+ GtkWidget *replace_button;
+ GtkWidget *dest_image;
+ GtkWidget *src_image;
+};
+
+G_DEFINE_TYPE (NautilusFileConflictDialog, nautilus_file_conflict_dialog, GTK_TYPE_DIALOG);
+
+void
+nautilus_file_conflict_dialog_set_text (NautilusFileConflictDialog *fcd,
+ gchar *primary_text,
+ gchar *secondary_text)
+{
+ GtkWidget *label;
+ PangoAttrList *attr_list;
+
+ label = gtk_label_new (primary_text);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_box_pack_start (GTK_BOX (fcd->titles_vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ attr_list = pango_attr_list_new ();
+ pango_attr_list_insert (attr_list, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+ pango_attr_list_insert (attr_list, pango_attr_scale_new (PANGO_SCALE_LARGE));
+ g_object_set (label, "attributes", attr_list, NULL);
+
+ pango_attr_list_unref (attr_list);
+
+ label = gtk_label_new (secondary_text);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+ gtk_box_pack_start (GTK_BOX (fcd->titles_vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+}
+
+void
+nautilus_file_conflict_dialog_set_images (NautilusFileConflictDialog *fcd,
+ GdkPixbuf *destination_pixbuf,
+ GdkPixbuf *source_pixbuf)
+{
+ if (fcd->dest_image == NULL)
+ {
+ fcd->dest_image = gtk_image_new_from_pixbuf (destination_pixbuf);
+ gtk_box_pack_start (GTK_BOX (fcd->first_hbox), fcd->dest_image, FALSE, FALSE, 0);
+ gtk_widget_show (fcd->dest_image);
+ }
+ else
+ {
+ gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->dest_image), destination_pixbuf);
+ }
+
+ if (fcd->src_image == NULL)
+ {
+ fcd->src_image = gtk_image_new_from_pixbuf (source_pixbuf);
+ gtk_box_pack_start (GTK_BOX (fcd->second_hbox), fcd->src_image, FALSE, FALSE, 0);
+ gtk_widget_show (fcd->src_image);
+ }
+ else
+ {
+ gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->src_image), source_pixbuf);
+ }
+}
+
+void
+nautilus_file_conflict_dialog_set_file_labels (NautilusFileConflictDialog *fcd,
+ gchar *destination_label,
+ gchar *source_label)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), destination_label);
+ gtk_box_pack_start (GTK_BOX (fcd->first_hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), source_label);
+ gtk_box_pack_start (GTK_BOX (fcd->second_hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+}
+
+void
+nautilus_file_conflict_dialog_set_conflict_name (NautilusFileConflictDialog *fcd,
+ gchar *conflict_name)
+{
+ fcd->conflict_name = g_strdup (conflict_name);
+
+ gtk_entry_set_text (GTK_ENTRY (fcd->entry), fcd->conflict_name);
+}
+
+void
+nautilus_file_conflict_dialog_set_replace_button_label (NautilusFileConflictDialog *fcd,
+ gchar *label)
+{
+ gtk_button_set_label (GTK_BUTTON (fcd->replace_button), label);
+}
+
+void
+nautilus_file_conflict_dialog_disable_skip (NautilusFileConflictDialog *fcd)
+{
+ gtk_widget_hide (fcd->skip_button);
+}
+
+void
+nautilus_file_conflict_dialog_disable_replace (NautilusFileConflictDialog *fcd)
+{
+ gtk_widget_set_sensitive (fcd->replace_button, FALSE);
+}
+
+void
+nautilus_file_conflict_dialog_disable_apply_to_all (NautilusFileConflictDialog *fcd)
+{
+ gtk_widget_hide (fcd->checkbox);
+}
+
+static void
+entry_text_changed_cb (GtkEditable *entry,
+ NautilusFileConflictDialog *dialog)
+{
+ /* The rename button is visible only if there's text
+ * in the entry.
+ */
+ if (g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (entry)), "") != 0 &&
+ g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (entry)), dialog->conflict_name) != 0)
+ {
+ gtk_widget_hide (dialog->replace_button);
+ gtk_widget_show (dialog->rename_button);
+
+ gtk_widget_set_sensitive (dialog->checkbox, FALSE);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), CONFLICT_RESPONSE_RENAME);
+ }
+ else
+ {
+ gtk_widget_hide (dialog->rename_button);
+ gtk_widget_show (dialog->replace_button);
+
+ gtk_widget_set_sensitive (dialog->checkbox, TRUE);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), CONFLICT_RESPONSE_REPLACE);
+ }
+}
+
+static void
+expander_activated_cb (GtkExpander *w,
+ NautilusFileConflictDialog *dialog)
+{
+ int start_pos, end_pos;
+
+ if (!gtk_expander_get_expanded (w))
+ {
+ if (g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (dialog->entry)), dialog->conflict_name) == 0)
+ {
+ gtk_widget_grab_focus (dialog->entry);
+
+ eel_filename_get_rename_region (dialog->conflict_name, &start_pos, &end_pos);
+ gtk_editable_select_region (GTK_EDITABLE (dialog->entry), start_pos, end_pos);
+ }
+ }
+}
+
+static void
+checkbox_toggled_cb (GtkToggleButton *t,
+ NautilusFileConflictDialog *dialog)
+{
+ gtk_widget_set_sensitive (dialog->expander, !gtk_toggle_button_get_active (t));
+ gtk_widget_set_sensitive (dialog->rename_button, !gtk_toggle_button_get_active (t));
+
+ if (!gtk_toggle_button_get_active (t) &&
+ g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (dialog->entry)), "") != 0 &&
+ g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (dialog->entry)), dialog->conflict_name) != 0)
+ {
+ gtk_widget_hide (dialog->replace_button);
+ gtk_widget_show (dialog->rename_button);
+ }
+ else
+ {
+ gtk_widget_hide (dialog->rename_button);
+ gtk_widget_show (dialog->replace_button);
+ }
+}
+
+static void
+reset_button_clicked_cb (GtkButton *w,
+ NautilusFileConflictDialog *dialog)
+{
+ int start_pos, end_pos;
+
+ gtk_entry_set_text (GTK_ENTRY (dialog->entry), dialog->conflict_name);
+ gtk_widget_grab_focus (dialog->entry);
+ eel_filename_get_rename_region (dialog->conflict_name, &start_pos, &end_pos);
+ gtk_editable_select_region (GTK_EDITABLE (dialog->entry), start_pos, end_pos);
+}
+
+static void
+nautilus_file_conflict_dialog_init (NautilusFileConflictDialog *fcd)
+{
+ GtkWidget *hbox, *vbox, *vbox2;
+ GtkWidget *widget, *dialog_area;
+ GtkDialog *dialog;
+
+ dialog = GTK_DIALOG (fcd);
+
+ /* Setup the main hbox */
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+ dialog_area = gtk_dialog_get_content_area (dialog);
+ gtk_box_pack_start (GTK_BOX (dialog_area), hbox, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+
+ /* Setup the dialog image */
+ widget = gtk_image_new_from_icon_name ("dialog-warning",
+ GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+ gtk_widget_set_valign (widget, GTK_ALIGN_START);
+
+ /* Setup the vbox containing the dialog body */
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+
+ /* Setup the vbox for the dialog labels */
+ widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+ fcd->titles_vbox = widget;
+
+ /* Setup the hboxes to pack file infos into */
+ vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
+ gtk_widget_set_halign (vbox2, GTK_ALIGN_START);
+ gtk_widget_set_margin_start (vbox2, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
+ fcd->first_hbox = hbox;
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+ gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
+ fcd->second_hbox = hbox;
+
+ /* Setup the expander for the rename action */
+ fcd->expander = gtk_expander_new_with_mnemonic (_("_Select a new name for the destination"));
+ gtk_box_pack_start (GTK_BOX (vbox2), fcd->expander, FALSE, FALSE, 0);
+ g_signal_connect (fcd->expander, "activate",
+ G_CALLBACK (expander_activated_cb), dialog);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_container_add (GTK_CONTAINER (fcd->expander), hbox);
+
+ widget = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 6);
+ fcd->entry = widget;
+ g_signal_connect (widget, "changed",
+ G_CALLBACK (entry_text_changed_cb), dialog);
+ gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
+
+ widget = gtk_button_new_with_label (_("Reset"));
+ gtk_button_set_image (GTK_BUTTON (widget),
+ gtk_image_new_from_icon_name ("edit-undo",
+ GTK_ICON_SIZE_MENU));
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 6);
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (reset_button_clicked_cb), dialog);
+
+ gtk_widget_show_all (vbox2);
+
+ /* Setup the checkbox to apply the action to all files */
+ widget = gtk_check_button_new_with_mnemonic (_("Apply this action to all files and folders"));
+
+ gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
+ fcd->checkbox = widget;
+ g_signal_connect (widget, "toggled",
+ G_CALLBACK (checkbox_toggled_cb), dialog);
+
+ /* Add buttons */
+ gtk_dialog_add_button (dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
+
+ fcd->skip_button = gtk_dialog_add_button (dialog,
+ _("_Skip"),
+ CONFLICT_RESPONSE_SKIP);
+
+ fcd->rename_button = gtk_dialog_add_button (dialog,
+ _("Re_name"),
+ CONFLICT_RESPONSE_RENAME);
+ gtk_widget_hide (fcd->rename_button);
+
+ fcd->replace_button = gtk_dialog_add_button (dialog,
+ _("Re_place"),
+ CONFLICT_RESPONSE_REPLACE);
+ gtk_widget_grab_focus (fcd->replace_button);
+
+ /* Setup HIG properties */
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (dialog)), 14);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+ gtk_widget_show_all (dialog_area);
+}
+
+static void
+do_finalize (GObject *self)
+{
+ NautilusFileConflictDialog *dialog = NAUTILUS_FILE_CONFLICT_DIALOG (self);
+
+ g_free (dialog->conflict_name);
+
+ G_OBJECT_CLASS (nautilus_file_conflict_dialog_parent_class)->finalize (self);
+}
+
+static void
+nautilus_file_conflict_dialog_class_init (NautilusFileConflictDialogClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = do_finalize;
+}
+
+char *
+nautilus_file_conflict_dialog_get_new_name (NautilusFileConflictDialog *dialog)
+{
+ return g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->entry)));
+}
+
+gboolean
+nautilus_file_conflict_dialog_get_apply_to_all (NautilusFileConflictDialog *dialog)
+{
+ return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->checkbox));
+}
+
+NautilusFileConflictDialog *
+nautilus_file_conflict_dialog_new (GtkWindow *parent)
+{
+ NautilusFileConflictDialog *dialog;
+
+ dialog = NAUTILUS_FILE_CONFLICT_DIALOG (g_object_new (NAUTILUS_TYPE_FILE_CONFLICT_DIALOG,
+ "use-header-bar", TRUE,
+ "modal", TRUE,
+ NULL));
+
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
+
+ return dialog;
+}