[nautilus/wip/alexpandelea/batchRename: 4/17] Handle conflicts
- From: Alexandru-Ionut Pandelea <alexpandelea src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/wip/alexpandelea/batchRename: 4/17] Handle conflicts
- Date: Tue, 5 Jul 2016 16:48:50 +0000 (UTC)
commit 0cbc349e6f89fe95bb546134076ccb58cb93ecd7
Author: Alexandru Pandelea <alexandru pandelea gmail com>
Date: Sat Jun 11 12:06:14 2016 +0300
Handle conflicts
If there are any conflicts, instead of the usual label there is used
an expander with a scrollable listbox as child. Inside the listbox are
displayed all the conflicts.
https://bugzilla.gnome.org/show_bug.cgi?id=768311
src/nautilus-batch-rename-utilities.c | 40 +++++
src/nautilus-batch-rename-utilities.h | 7 +
src/nautilus-batch-rename.c | 194 +++++++++++++++++++++-
src/nautilus-files-view.c | 14 ++
src/nautilus-files-view.h | 3 +
src/resources/ui/nautilus-batch-rename-dialog.ui | 52 ++++++-
6 files changed, 302 insertions(+), 8 deletions(-)
---
diff --git a/src/nautilus-batch-rename-utilities.c b/src/nautilus-batch-rename-utilities.c
index 85a6ae1..2572807 100644
--- a/src/nautilus-batch-rename-utilities.c
+++ b/src/nautilus-batch-rename-utilities.c
@@ -1,5 +1,6 @@
#include "nautilus-batch-rename.h"
#include "nautilus-batch-rename-utilities.h"
+#include "nautilus-files-view.h"
#include <glib.h>
#include <gtk/gtk.h>
@@ -160,4 +161,43 @@ get_new_display_name (NautilusBatchRenameModes mode,
result = get_new_name (mode, file_name, entry_text, replace_text);
return result;
+}
+
+GList*
+list_has_duplicates (NautilusFilesView *view,
+ GList *new_names,
+ GList *old_names)
+{
+ GList *l1, *l2;
+ GList *result;
+ NautilusFile *file;
+ gchar *file_name;
+
+ result = NULL;
+
+ for (l1 = new_names, l2 = old_names; l1 != NULL && l2 != NULL; l1 = l1->next, l2 = l2->next) {
+ file = NAUTILUS_FILE (l2->data);
+ file_name = strdup (nautilus_file_get_name (file));
+
+ if (strcmp (l1->data, file_name) != 0 && file_with_name_exists (view, l1->data) == TRUE) {
+ result = g_list_prepend (result,
+ (gpointer) (l1->data));
+ }
+
+ g_free (file_name);
+ }
+ return result;
+}
+
+gchar*
+concat(gchar *s1, gchar *s2)
+{
+ gchar *result;
+
+ result = malloc (strlen(s1) + strlen(s2) + 1);
+
+ memcpy(result, s1, strlen(s1));
+ memcpy(result + strlen(s1), s2, strlen(s2) + 1);
+
+ return result;
}
\ No newline at end of file
diff --git a/src/nautilus-batch-rename-utilities.h b/src/nautilus-batch-rename-utilities.h
index 68aa1ad..33e916f 100644
--- a/src/nautilus-batch-rename-utilities.h
+++ b/src/nautilus-batch-rename-utilities.h
@@ -19,4 +19,11 @@ gchar* get_new_display_name (NautilusBatchRenameModes mode,
gchar *entry_text,
gchar *replace_text);
+GList* list_has_duplicates (NautilusFilesView *view,
+ GList *names,
+ GList *old_names);
+
+gchar* concat (gchar *s1,
+ gchar *s2);
+
#endif /* NAUTILUS_BATCH_RENAME_UTILITIES_H */
\ No newline at end of file
diff --git a/src/nautilus-batch-rename.c b/src/nautilus-batch-rename.c
index 14994e6..01912fc 100644
--- a/src/nautilus-batch-rename.c
+++ b/src/nautilus-batch-rename.c
@@ -37,21 +37,27 @@ struct _NautilusBatchRename
GtkWidget *add_text_options;
GtkWidget *cancel_button;
+ GtkWidget *conflict_listbox;
GtkWidget *error_label;
+ GtkWidget *expander;
GtkWidget *name_entry;
GtkWidget *rename_button;
GtkWidget *rename_modes;
GtkWidget *find_label;
GtkWidget *left_stack;
+ GtkWidget *label_stack;
GtkWidget *right_stack;
GtkWidget *replace_entry;
GtkWidget *replace_label;
GtkWidget *replace_box;
+ GList *listbox_rows;//adauga aici rows de la listbox pt a fi sterse
GList *selection;
NautilusBatchRenameModes mode;
NautilusFilesView *view;
+
+ GtkWidget *expander_label;
};
static void batch_rename_dialog_on_closed (GtkDialog *dialog);
@@ -188,17 +194,171 @@ batch_rename_mode_changed (GtkComboBoxText *widget,
}
static void
+activate_expander (GtkExpander *expander,
+ NautilusBatchRename *dialog)
+{
+ GValue width = G_VALUE_INIT;
+
+ g_value_init (&width, G_TYPE_INT);
+
+ if (gtk_expander_get_expanded (GTK_EXPANDER (expander))) {
+
+ g_value_set_int (&width, 8);
+ gtk_container_child_set_property (GTK_CONTAINER (dialog->grid), dialog->label_stack,
"width",&width);
+ } else {
+
+ g_value_set_int (&width, 5);
+ gtk_container_child_set_property (GTK_CONTAINER (dialog->grid), dialog->label_stack,
"width",&width);
+ }
+}
+
+static void
+listbox_header_func (GtkListBoxRow *row,
+ GtkListBoxRow *before,
+ NautilusBatchRename *dialog)
+{
+ gboolean show_separator;
+
+ show_separator = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "show-separator"));
+
+ if (show_separator)
+ {
+ GtkWidget *separator;
+
+ separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_show (separator);
+
+ gtk_list_box_row_set_header (row, separator);
+ }
+}
+
+static GtkWidget*
+create_row_for_label (const gchar *text,
+ gboolean show_separator)
+{
+ GtkWidget *row;
+ GtkWidget *label;
+
+ row = gtk_list_box_row_new ();
+
+ g_object_set_data (G_OBJECT (row), "show-separator", GINT_TO_POINTER (show_separator));
+
+ label = g_object_new (GTK_TYPE_LABEL,
+ "label", text,
+ "hexpand", TRUE,
+ "xalign", 0.0,
+ "margin-start", 6,
+ NULL);
+
+ gtk_list_box_row_set_selectable (GTK_LIST_BOX_ROW (row), FALSE);
+
+ gtk_container_add (GTK_CONTAINER (row), label);
+ gtk_widget_show_all (row);
+
+ return row;
+}
+
+static void
+fill_conflict_listbox (NautilusBatchRename *dialog,
+ GList *conflict_list)
+{
+ GtkWidget *row;
+ GList *l;
+
+ /* clear rows from listbox (if there are any) */
+ if (dialog->listbox_rows != NULL)
+ for (l = dialog->listbox_rows; l != NULL; l = l->next) {
+ gtk_container_remove (GTK_CONTAINER (dialog->conflict_listbox),
+ GTK_WIDGET (l->data));
+ }
+
+ g_list_free (dialog->listbox_rows);
+ dialog->listbox_rows = NULL;
+
+ row = create_row_for_label ("These files already exist:", FALSE);
+
+ gtk_container_add (GTK_CONTAINER (dialog->conflict_listbox), row);
+
+ /* add rows to a list so that they can be removed when there appears
+ * a new conflict */
+ dialog->listbox_rows = g_list_prepend (dialog->listbox_rows,
+ (gpointer) row);
+
+ for (l = conflict_list; l != NULL; l = l->next) {
+
+ row = create_row_for_label ((gchar*) l->data, l == conflict_list);
+
+ gtk_container_add (GTK_CONTAINER (dialog->conflict_listbox), row);
+
+ dialog->listbox_rows = g_list_prepend (dialog->listbox_rows,
+ (gpointer) row);
+ }
+}
+
+static void
file_names_widget_entry_on_changed (NautilusBatchRename *dialog)
{
gchar *entry_text;
gchar *replace_text;
gchar *file_name;
+ GList *new_names;
+ GList *duplicates;
gchar *display_text = NULL;
NautilusFile *file;
+ GValue width = G_VALUE_INIT;
if(dialog->selection == NULL)
return;
+ new_names = batch_rename_get_new_names(dialog);
+ duplicates = list_has_duplicates (dialog->view, new_names, dialog->selection);
+
+ /* check if there are name conflicts and display them if they exist */
+ if (duplicates != NULL && gtk_widget_is_sensitive (dialog->rename_button)) {
+ gtk_widget_set_sensitive (dialog->rename_button, FALSE);
+
+ gtk_expander_set_expanded (GTK_EXPANDER (dialog->expander), FALSE);
+ gtk_stack_set_visible_child (GTK_STACK (dialog->label_stack), GTK_WIDGET (dialog->expander));
+
+ /* check if there is more than one conflict */
+ if (duplicates->next != NULL)
+ gtk_expander_set_label (GTK_EXPANDER (dialog->expander),
+ "Multiple file conflicts");
+ else {
+ file_name = concat ("File conflict: ", duplicates->data);
+
+ gtk_label_set_label (GTK_LABEL (dialog->expander_label), file_name);
+
+ gtk_expander_set_label_widget (GTK_EXPANDER (dialog->expander),
+ dialog->expander_label);
+
+ gtk_widget_show (dialog->expander_label);
+
+ g_free (file_name);
+ }
+
+ /* add name conflicts to the listbox */
+ fill_conflict_listbox (dialog, duplicates);
+
+ return;
+ }
+ else
+ /* re-enable the rename button if there are no more name conflicts */
+ if (duplicates == NULL && !gtk_widget_is_sensitive (dialog->rename_button)) {
+ gtk_expander_set_expanded (GTK_EXPANDER (dialog->expander), FALSE);
+
+ gtk_widget_set_sensitive (dialog->rename_button, TRUE);
+
+ gtk_stack_set_visible_child (GTK_STACK (dialog->label_stack), GTK_WIDGET
(dialog->error_label));
+
+ g_value_init (&width, G_TYPE_INT);
+ g_value_set_int (&width, 8);
+ gtk_container_child_set_property (GTK_CONTAINER (dialog->grid), dialog->label_stack,
"width",&width);
+
+
+ }
+
+ /* Update label that shows an example of the renaming result */
file = NAUTILUS_FILE (dialog->selection->data);
file_name = g_strdup (nautilus_file_get_name (file));
@@ -206,16 +366,20 @@ file_names_widget_entry_on_changed (NautilusBatchRename *dialog)
replace_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->replace_entry)));
if (entry_text == NULL ) {
- gtk_label_set_label (GTK_LABEL (dialog->error_label), file_name);
- g_free (file_name);
- return;
+ gtk_label_set_label (GTK_LABEL (dialog->error_label), file_name);
+ g_free (file_name);
+
+ return;
}
-
+
display_text = get_new_display_name (dialog->mode, file_name, entry_text, replace_text);
gtk_label_set_label (GTK_LABEL (dialog->error_label), display_text);
+ g_list_free (new_names);
+ g_list_free (duplicates);
+
g_free (entry_text);
g_free (file_name);
g_free (replace_text);
@@ -226,6 +390,7 @@ static void
batch_rename_dialog_on_closed (GtkDialog *dialog)
{
gtk_window_close (GTK_WINDOW (dialog));
+ g_message("closed this");
}
@@ -233,7 +398,9 @@ static void
file_names_widget_on_activate (NautilusBatchRename *dialog)
{
GList *new_names;
- /* check if all names are all right i.e no conflicts, valid name, etc...*/
+
+ if (!gtk_widget_is_sensitive (dialog->rename_button))
+ return;
new_names = batch_rename_get_new_names(dialog);
@@ -255,12 +422,15 @@ nautilus_batch_rename_class_init (NautilusBatchRenameClass *klass)
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, grid);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, add_text_options);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, cancel_button);
+ gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, conflict_listbox);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, error_label);
+ gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, expander);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, name_entry);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, rename_button);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, rename_modes);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, find_label);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, left_stack);
+ gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, label_stack);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, right_stack);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, replace_label);
gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, replace_entry);
@@ -291,6 +461,11 @@ nautilus_batch_rename_new (NautilusFilesView *view)
gtk_label_set_ellipsize (GTK_LABEL (dialog->error_label), PANGO_ELLIPSIZE_END);
gtk_label_set_max_width_chars (GTK_LABEL (dialog->error_label), MAX_DISPLAY_LEN);
+ gtk_label_set_ellipsize (GTK_LABEL (dialog->expander_label), PANGO_ELLIPSIZE_END);
+ gtk_label_set_max_width_chars (GTK_LABEL (dialog->expander_label), MAX_DISPLAY_LEN - 1);
+
+ gtk_widget_set_vexpand (dialog->rename_button, FALSE);
+
/* update display text */
file_names_widget_entry_on_changed (dialog);
@@ -305,5 +480,14 @@ nautilus_batch_rename_init (NautilusBatchRename *self)
gtk_combo_box_set_active (GTK_COMBO_BOX (self->add_text_options), 1);
gtk_combo_box_set_active (GTK_COMBO_BOX (self->rename_modes), 0);
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->conflict_listbox),
+ (GtkListBoxUpdateHeaderFunc) listbox_header_func,
+ self,
+ NULL);
+
+ g_signal_connect (self->expander, "activate", G_CALLBACK (activate_expander), self);
+
+ self->expander_label = gtk_label_new ("");
+
self->mode = NAUTILUS_BATCH_RENAME_PREPEND;
}
\ No newline at end of file
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index c23f97c..cda409f 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -1801,6 +1801,20 @@ file_name_widget_entry_on_changed (gpointer user_data)
g_free (name);
}
+gboolean
+file_with_name_exists (NautilusFilesView *view,
+ gchar *name)
+{
+ NautilusFile *existing_file;
+
+ existing_file = nautilus_directory_get_file_by_name (view->details->model, name);
+
+ if (existing_file == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
static void
create_folder_dialog_on_response (GtkDialog *dialog,
gint response_id,
diff --git a/src/nautilus-files-view.h b/src/nautilus-files-view.h
index 9b5a28b..89b2a46 100644
--- a/src/nautilus-files-view.h
+++ b/src/nautilus-files-view.h
@@ -367,4 +367,7 @@ void nautilus_files_view_action_show_hidden_files (NautilusFilesV
GActionGroup * nautilus_files_view_get_action_group (NautilusFilesView *view);
GtkWidget* nautilus_files_view_get_content_widget (NautilusFilesView *view);
+gboolean file_with_name_exists (NautilusFilesView *view,
+ gchar *name);
+
#endif /* NAUTILUS_FILES_VIEW_H */
diff --git a/src/resources/ui/nautilus-batch-rename-dialog.ui
b/src/resources/ui/nautilus-batch-rename-dialog.ui
index f0dfa27..8d7704e 100644
--- a/src/resources/ui/nautilus-batch-rename-dialog.ui
+++ b/src/resources/ui/nautilus-batch-rename-dialog.ui
@@ -58,9 +58,12 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="use_underline">True</property>
+ <property name="height_request">10</property>
<signal name="clicked" handler="batch_rename_dialog_on_closed" swapped="yes" />
</object>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
<property name="left-attach">5</property>
<property name="top-attach">2</property>
<property name="width">1</property>
@@ -72,22 +75,65 @@
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="can_default">True</property>
+ <property name="height_request">10</property>
<signal name="clicked" handler="file_names_widget_on_activate" swapped="yes" />
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
<property name="left-attach">6</property>
<property name="top-attach">2</property>
<property name="width">1</property>
</packing>
</child>
+
<child>
- <object class="GtkLabel" id="error_label">
+ <object class="GtkStack" id="label_stack">
<property name="visible">True</property>
- <property name="halign">start</property>
<property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="error_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkExpander" id="expander">
+ <property name="visible">True</property>
+ <property name="valign">center</property>
+ <child type="label">
+ <object class="GtkLabel" id="expander-label"/>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="height_request">100</property>
+ <property name="width_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">False</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkListBox" id="conflict_listbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
</object>
<packing>
<property name="left-attach">0</property>
@@ -95,6 +141,7 @@
<property name="width">8</property>
</packing>
</child>
+
<child>
<object class="GtkStack" id="left_stack">
<property name="visible">True</property>
@@ -153,7 +200,6 @@
<signal name="activate" handler="file_names_widget_on_activate" swapped="yes" />
</object>
</child>
-
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]