summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@gnome.org>2015-08-15 17:20:21 +0200
committerCarlos Soriano <csoriano@gnome.org>2015-08-16 14:53:54 +0200
commit328348c6f76bc72823c1a8464937b7f4208674d9 (patch)
treed901e2155586dd3d14d7e3d3f56f24b0fde2649c /src
parentedaa65f4ee7d6219c0c6ca1cecdf84be2bc2a63d (diff)
downloadnautilus-328348c6f76bc72823c1a8464937b7f4208674d9.tar.gz
nautilus-view: use popover for renaming
Some users felt it quite disruptive to us a dialog, even if the attention has to be on the name entry. Also it's the way that GtkFileChooser implemented it and it actually feels less disruptive and desigerns agreed it works better. So continue to use a dialog for the new folder creation, but use a popover for renaming.
Diffstat (limited to 'src')
-rw-r--r--src/nautilus-canvas-view.c18
-rw-r--r--src/nautilus-create-folder-dialog.ui (renamed from src/nautilus-file-name-dialog.ui)6
-rw-r--r--src/nautilus-list-view.c42
-rw-r--r--src/nautilus-rename-file-popover.ui66
-rw-r--r--src/nautilus-view.c436
-rw-r--r--src/nautilus-view.h2
-rw-r--r--src/nautilus.gresource.xml3
7 files changed, 364 insertions, 209 deletions
diff --git a/src/nautilus-canvas-view.c b/src/nautilus-canvas-view.c
index 53e37d9d5..8d42d6f83 100644
--- a/src/nautilus-canvas-view.c
+++ b/src/nautilus-canvas-view.c
@@ -1172,6 +1172,23 @@ nautilus_canvas_view_reveal_selection (NautilusView *view)
nautilus_file_list_free (selection);
}
+static GdkRectangle*
+nautilus_canvas_view_compute_rename_popover_relative_to (NautilusView *view)
+{
+ GArray *bounding_boxes;
+ GdkRectangle *bounding_box;
+ NautilusCanvasContainer *canvas_container;
+
+ canvas_container = get_canvas_container (NAUTILUS_CANVAS_VIEW (view));
+ bounding_boxes = nautilus_canvas_container_get_selected_icons_bounding_box (canvas_container);
+ /* We only allow renaming one item at once */
+ bounding_box = &g_array_index (bounding_boxes, GdkRectangle, 0);
+
+ g_array_free (bounding_boxes, FALSE);
+
+ return bounding_box;
+}
+
static GArray *
nautilus_canvas_view_get_selected_icon_locations (NautilusView *view)
{
@@ -1877,6 +1894,7 @@ nautilus_canvas_view_class_init (NautilusCanvasViewClass *klass)
nautilus_view_class->end_loading = nautilus_canvas_view_end_loading;
nautilus_view_class->file_changed = nautilus_canvas_view_file_changed;
nautilus_view_class->get_selected_icon_locations = nautilus_canvas_view_get_selected_icon_locations;
+ nautilus_view_class->compute_rename_popover_relative_to = nautilus_canvas_view_compute_rename_popover_relative_to;
nautilus_view_class->get_selection = nautilus_canvas_view_get_selection;
nautilus_view_class->get_selection_for_file_transfer = nautilus_canvas_view_get_selection;
nautilus_view_class->is_empty = nautilus_canvas_view_is_empty;
diff --git a/src/nautilus-file-name-dialog.ui b/src/nautilus-create-folder-dialog.ui
index 4e2c4c770..21bf6b2ad 100644
--- a/src/nautilus-file-name-dialog.ui
+++ b/src/nautilus-create-folder-dialog.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.14"/>
- <object class="GtkDialog" id="file_name_dialog">
+ <object class="GtkDialog" id="create_folder_dialog">
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
@@ -32,8 +32,8 @@
<object class="GtkEntry" id="name_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <signal name="notify::text" handler="nautilus_view_file_name_dialog_entry_on_validate" swapped="no" />
- <signal name="activate" handler="nautilus_view_file_name_dialog_entry_on_activate" swapped="no" />
+ <signal name="changed" handler="create_folder_dialog_entry_on_changed" swapped="no" />
+ <signal name="activate" handler="create_folder_dialog_entry_on_activate" swapped="no" />
</object>
<packing>
<property name="expand">False</property>
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 20a4882c4..35a7472f6 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -59,6 +59,12 @@
#define DEBUG_FLAG NAUTILUS_DEBUG_LIST_VIEW
#include <libnautilus-private/nautilus-debug.h>
+/* We use a rectangle to make the popover point to the right column. In an
+ * ideal world with GtkListBox we would just point to the GtkListBoxRow. In our case, we
+ * need to use a rectangle and we provide some width to not make the popover arrow pointy
+ * in the edges if the window is small */
+#define RENAME_POPOVER_RELATIVE_TO_RECTANGLE_WIDTH 40
+
struct NautilusListViewDetails {
GtkTreeView *tree_view;
NautilusListModel *model;
@@ -3240,6 +3246,41 @@ nautilus_list_view_get_id (NautilusView *view)
return NAUTILUS_LIST_VIEW_ID;
}
+static GdkRectangle*
+nautilus_list_view_compute_rename_popover_relative_to (NautilusView *view)
+{
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+ GdkRectangle *rect;
+ GtkTreeModel *model;
+ GtkTreeView *tree_view;
+ GList *list;
+ NautilusListView *list_view;
+
+ rect = g_malloc0 (sizeof(GdkRectangle));
+ list_view = NAUTILUS_LIST_VIEW (view);
+ tree_view = list_view->details->tree_view;
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list_view->details->tree_view));
+ model = GTK_TREE_MODEL (list_view->details->model);
+ list = gtk_tree_selection_get_selected_rows (selection, &model);
+ path = list->data;
+ gtk_tree_view_get_cell_area (tree_view, path, NULL, rect);
+ gtk_tree_view_convert_bin_window_to_widget_coords (tree_view,
+ rect->x, rect->y,
+ &rect->x, &rect->y);
+
+ rect->x = CLAMP (gtk_widget_get_allocated_width (GTK_WIDGET (tree_view)) * 0.5 -
+ RENAME_POPOVER_RELATIVE_TO_RECTANGLE_WIDTH * 0.5,
+ 0,
+ gtk_widget_get_allocated_width (GTK_WIDGET (tree_view)) -
+ RENAME_POPOVER_RELATIVE_TO_RECTANGLE_WIDTH);
+ rect->width = RENAME_POPOVER_RELATIVE_TO_RECTANGLE_WIDTH;
+
+ g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
+
+ return rect;
+}
+
static void
nautilus_list_view_class_init (NautilusListViewClass *class)
{
@@ -3277,6 +3318,7 @@ nautilus_list_view_class_init (NautilusListViewClass *class)
nautilus_view_class->get_view_id = nautilus_list_view_get_id;
nautilus_view_class->get_first_visible_file = nautilus_list_view_get_first_visible_file;
nautilus_view_class->scroll_to_file = list_view_scroll_to_file;
+ nautilus_view_class->compute_rename_popover_relative_to = nautilus_list_view_compute_rename_popover_relative_to;
}
static void
diff --git a/src/nautilus-rename-file-popover.ui b/src/nautilus-rename-file-popover.ui
new file mode 100644
index 000000000..5214857c2
--- /dev/null
+++ b/src/nautilus-rename-file-popover.ui
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkPopover" id="rename_file_popover">
+ <property name="position">bottom</property>
+ <signal name="closed" handler="rename_file_popover_on_closed"/>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="margin">10</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Name</property>
+ <property name="halign">start</property>
+ <property name="mnemonic_widget">name_entry</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="name_entry">
+ <property name="visible">True</property>
+ <property name="activates-default">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="rename_button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="label" translatable="yes">_Rename</property>
+ <property name="use_underline">True</property>
+ <property name="can_default">True</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="error_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">2</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 073bacc0e..d5ec6a121 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -116,8 +116,8 @@
#define MAX_MENU_LEVELS 5
#define TEMPLATE_LIMIT 30
-/* Time to show the duplicated folder label */
-#define DIALOG_DUPLICATED_NAME_ERROR_LABEL_TIMEOUT 500
+/* Delay to show the duplicated label when creating a folder */
+#define CREATE_FOLDER_DUPLICATED_LABEL_TIMEOUT 500
/* Delay to show the Loading... floating bar */
#define FLOATING_BAR_LOADING_DELAY 500 /* ms */
@@ -159,7 +159,8 @@ struct NautilusViewDetails
NautilusFile *directory_as_file;
guint dir_merge_id;
- gint dialog_duplicated_name_label_timeout_id;
+ gint create_folder_duplicated_label_timeout_id;
+ GtkWidget *rename_file_popover;
gboolean supports_zooming;
@@ -1699,16 +1700,18 @@ context_menu_to_file_operation_position (NautilusView *view)
typedef struct {
NautilusView *view;
- GtkWidget *dialog;
+ GtkWidget *widget;
GtkWidget *error_label;
GtkWidget *name_entry;
gboolean target_is_folder;
NautilusFile *target_file;
+ GtkWidget *activate_button;
gboolean duplicated_is_folder;
-} FileNameDialogData;
+} FileNameWidgetData;
typedef struct {
NautilusView *view;
+ GtkWidget *widget;
GtkWidget *name_entry;
NautilusFile *target_file;
} RenameDialogData;
@@ -1720,143 +1723,152 @@ typedef struct {
} NewFolderDialogData;
static gboolean
-duplicated_file_label_show (FileNameDialogData *data)
+duplicated_file_label_show (FileNameWidgetData *data)
{
if (data->duplicated_is_folder)
gtk_label_set_label (GTK_LABEL (data->error_label), _("A folder with that name already exists."));
else
gtk_label_set_label (GTK_LABEL (data->error_label), _("A file with that name already exists."));
- data->view->details->dialog_duplicated_name_label_timeout_id = 0;
- return FALSE;
+ data->view->details->create_folder_duplicated_label_timeout_id = 0;
+
+ return G_SOURCE_REMOVE;
}
-static void
-nautilus_view_file_name_dialog_validate_name (FileNameDialogData *data)
+static gchar*
+validate_file_name (const gchar *name,
+ gboolean is_folder)
{
- gboolean duplicated_name;
- gboolean valid_name;
- gchar *name;
- GList *files;
- GList *node;
- NautilusFile *file;
-
- g_assert (data != NULL);
- g_assert (GTK_IS_ENTRY (data->name_entry));
- g_assert (GTK_IS_LABEL (data->error_label));
- g_assert (GTK_IS_DIALOG (data->dialog));
- g_assert (NAUTILUS_IS_VIEW (data->view));
+ gchar *error_message = NULL;
- name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
- duplicated_name = FALSE;
- valid_name = FALSE;
- files = nautilus_directory_get_file_list (data->view->details->model);
-
- for (node = files; node != NULL; node = node->next) {
- file = node->data;
-
- if (nautilus_file_compare_display_name (file, name) == 0) {
- /* If we are renaming, we don't want to block the user to
- * rename the file with the current file name */
- if (data->target_file == NULL ||
- nautilus_file_compare_display_name (data->target_file, name) != 0) {
- duplicated_name = TRUE;
- data->duplicated_is_folder = nautilus_file_is_directory (file);
- break;
- }
- }
- }
-
- nautilus_file_list_free (files);
-
- /* Remove any sources left behind by
- * previous calls of this function.
- */
- if (data->view->details->dialog_duplicated_name_label_timeout_id > 0) {
- g_source_remove (data->view->details->dialog_duplicated_name_label_timeout_id);
- data->view->details->dialog_duplicated_name_label_timeout_id = 0;
- }
-
- if (duplicated_name) {
- data->view->details->dialog_duplicated_name_label_timeout_id =
- g_timeout_add (DIALOG_DUPLICATED_NAME_ERROR_LABEL_TIMEOUT,
- (GSourceFunc)duplicated_file_label_show,
- data);
- } else if (strstr (name, "/") != NULL) {
- if (data->target_is_folder)
- gtk_label_set_label (GTK_LABEL (data->error_label), _("Folder names cannot contain “/”."));
+ if (strstr (name, "/") != NULL) {
+ if (is_folder)
+ error_message = _("Folder names cannot contain “/”.");
else
- gtk_label_set_label (GTK_LABEL (data->error_label), _("Files names cannot contain “/”."));
+ error_message = _("Files names cannot contain “/”.");
} else if (strcmp (name, ".") == 0){
- if (data->target_is_folder)
- gtk_label_set_label (GTK_LABEL (data->error_label), _("A folder can not be called “.”."));
+ if (is_folder)
+ error_message = _("A folder can not be called “.”.");
else
- gtk_label_set_label (GTK_LABEL (data->error_label), _("A file can not be called “.”."));
+ error_message = _("A file can not be called “.”.");
} else if (strcmp (name, "..") == 0){
- if (data->target_is_folder)
- gtk_label_set_label (GTK_LABEL (data->error_label), _("A folder can not be called “..”."));
+ if (is_folder)
+ error_message = _("A folder can not be called “..”.");
else
- gtk_label_set_label (GTK_LABEL (data->error_label), _("A file can not be called “..”."));
- } else {
- /* No errors detected, empty the label */
- gtk_label_set_label (GTK_LABEL (data->error_label), NULL);
- valid_name = strlen (name) > 0;
+ error_message = _("A file can not be called “..”.");
}
- gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
- GTK_RESPONSE_OK,
- valid_name);
- g_free (name);
+ return error_message;
}
static void
-nautilus_view_file_name_dialog_entry_on_validate (GObject *object,
- GParamSpec *params,
- gpointer user_data)
+create_folder_dialog_entry_on_changed (GtkEntry *entry,
+ gpointer user_data)
{
- FileNameDialogData *data;
+ FileNameWidgetData *data;
+ NautilusFile *existing_file;
+ gchar *name;
+ gchar *error_message;
+ gboolean valid_name;
+ gboolean can_create_folder;
+
+ data = (FileNameWidgetData *) user_data;
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
+ error_message = validate_file_name (name, TRUE);
+ gtk_label_set_label (GTK_LABEL (data->error_label), error_message);
+
+ existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name);
+
+ valid_name = strlen (name) > 0 && error_message == NULL;
+ can_create_folder = existing_file == NULL && valid_name;
+ gtk_widget_set_sensitive (data->activate_button, can_create_folder);
- data = (FileNameDialogData *) user_data;
+ if (data->view->details->create_folder_duplicated_label_timeout_id > 0) {
+ g_source_remove (data->view->details->create_folder_duplicated_label_timeout_id);
+ data->view->details->create_folder_duplicated_label_timeout_id = 0;
+ }
+
+ /* Report duplicated file only if not other message shown (for instance,
+ * folders like "." or ".." will always exists, but we consider it as an
+ * error, not as a duplicated file) */
+ if (existing_file != NULL && valid_name) {
+ data->duplicated_is_folder = nautilus_file_is_directory (existing_file);
+ data->view->details->create_folder_duplicated_label_timeout_id =
+ g_timeout_add (CREATE_FOLDER_DUPLICATED_LABEL_TIMEOUT,
+ (GSourceFunc)duplicated_file_label_show,
+ data);
+ }
- nautilus_view_file_name_dialog_validate_name (data);
+ if (existing_file != NULL)
+ nautilus_file_unref (existing_file);
}
static void
-nautilus_view_file_name_dialog_entry_on_activate (GtkWidget *entry,
- gpointer user_data)
+rename_file_popover_entry_on_changed (GtkEntry *entry,
+ gpointer user_data)
{
- FileNameDialogData *data;
- GtkWidget *create_button;
+ FileNameWidgetData *data;
+ gboolean valid_name;
+ gchar *name;
+ gchar *error_message;
- data = (FileNameDialogData *) user_data;
- create_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (data->dialog),
- GTK_RESPONSE_OK);
+ data = (FileNameWidgetData *) user_data;
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
+ error_message = validate_file_name (name, nautilus_file_is_directory (data->target_file));
+ gtk_label_set_label (GTK_LABEL (data->error_label), error_message);
- /* nautilus_view_new_folder_dialog_validate_name performs
- * all the necessary validation, and it's not needed to check
- * it all again. Checking if the "Create" button is sensitive
- * is enough.
- */
- if (gtk_widget_get_sensitive (create_button)) {
- gtk_dialog_response (GTK_DIALOG (data->dialog),
+ valid_name = strlen (name) > 0 && error_message == NULL;
+ gtk_widget_set_sensitive (data->activate_button, valid_name);
+
+ g_free (name);
+}
+
+static void
+create_folder_dialog_entry_on_activate (GtkWidget *entry,
+ gpointer user_data)
+{
+ FileNameWidgetData *data;
+ NautilusFile *existing_file;
+ gchar *name;
+ gchar *error_message;
+ gboolean valid_name;
+ gboolean can_create_folder;
+
+ data = (FileNameWidgetData *) user_data;
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (data->name_entry))));
+ existing_file = nautilus_directory_get_file_by_name (data->view->details->model, name);
+ error_message = validate_file_name (name, TRUE);
+ valid_name = strlen (name) > 0 && error_message == NULL;
+ can_create_folder = existing_file == NULL && valid_name;
+
+ if (data->view->details->create_folder_duplicated_label_timeout_id > 0) {
+ g_source_remove (data->view->details->create_folder_duplicated_label_timeout_id);
+ data->view->details->create_folder_duplicated_label_timeout_id = 0;
+ }
+
+ if (can_create_folder) {
+ gtk_dialog_response (GTK_DIALOG (data->widget),
GTK_RESPONSE_OK);
- } else {
- NautilusView *view = data->view;
+ } else {
+ /* Report duplicated file only if not other message shown (for instance,
+ * folders like "." or ".." will always exists, but we consider it as an
+ * error, not as a duplicated file) */
+ if (existing_file != NULL && valid_name) {
+ data->duplicated_is_folder = nautilus_file_is_directory (existing_file);
+ /* Show it inmediatily since the user tried to trigger the action */
+ duplicated_file_label_show (data);
+ }
+ }
- /* Since typos are immediately shown, only
- * handle name collisions here.
- */
- if (view->details->dialog_duplicated_name_label_timeout_id > 0) {
- g_source_remove (view->details->dialog_duplicated_name_label_timeout_id);
- duplicated_file_label_show (data);
- }
- }
+ if (existing_file != NULL)
+ nautilus_file_unref (existing_file);
+
+ g_free (name);
}
static void
-nautilus_view_rename_dialog_on_response (GtkDialog *dialog,
- gint response_id,
- gpointer user_data)
+rename_file_popover_rename_button_on_clicked (GtkButton *entry,
+ gpointer *user_data)
{
RenameDialogData *rename_data;
gchar *name;
@@ -1867,96 +1879,113 @@ nautilus_view_rename_dialog_on_response (GtkDialog *dialog,
g_assert (GTK_IS_ENTRY (rename_data->name_entry));
g_assert (NAUTILUS_IS_FILE (rename_data->target_file));
- if (response_id == GTK_RESPONSE_OK) {
- name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (rename_data->name_entry))));
- nautilus_rename_file (rename_data->target_file, name, NULL, NULL);
- g_free (name);
- }
+ name = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (rename_data->name_entry))));
+ nautilus_rename_file (rename_data->target_file, name, NULL, NULL);
+ g_free (name);
+
nautilus_view_select_file (rename_data->view, rename_data->target_file);
nautilus_view_reveal_selection (rename_data->view);
- /* If there's any resources left from the delayed
- * message, it should be removed before it gets
- * triggered.
- */
- if (rename_data->view->details->dialog_duplicated_name_label_timeout_id > 0) {
- g_source_remove (rename_data->view->details->dialog_duplicated_name_label_timeout_id);
- rename_data->view->details->dialog_duplicated_name_label_timeout_id = 0;
- }
+ gtk_widget_hide (rename_data->widget);
- g_free (user_data);
- gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_free (rename_data);
+}
+
+static void
+rename_file_popover_on_closed (GtkPopover *popover,
+ gpointer user_data)
+{
+ FileNameWidgetData *widget_data;
+
+ widget_data = (FileNameWidgetData *) user_data;
+ widget_data->view->details->rename_file_popover = NULL;
+ g_free (widget_data);
+}
+
+static GdkRectangle*
+nautilus_view_compute_rename_popover_relative_to (NautilusView *view)
+{
+ return NAUTILUS_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->compute_rename_popover_relative_to (view);
}
static void
-nautilus_view_rename_dialog_new (NautilusView *view,
- NautilusFile *target_file)
+nautilus_view_rename_file_popover_new (NautilusView *view,
+ NautilusFile *target_file)
{
- FileNameDialogData *dialog_data;
- RenameDialogData *user_data;
- GtkWidget *button_ok;
+ FileNameWidgetData *widget_data;
+ RenameDialogData *rename_data;
GtkWidget *label_file_name;
GtkBuilder *builder;
gint start_offset, end_offset;
- gchar *file_name;
- gchar *title;
+ GdkRectangle *relative_to;
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-file-name-dialog.ui");
- button_ok = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button"));
- label_file_name = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
+ if (view->details->rename_file_popover != NULL)
+ return;
- dialog_data = g_new (FileNameDialogData, 1);
- dialog_data->view = view;
- dialog_data->dialog = GTK_WIDGET (gtk_builder_get_object (builder, "file_name_dialog"));
- dialog_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
- dialog_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
- dialog_data->target_is_folder = nautilus_file_is_directory (target_file);
- dialog_data->target_file = target_file;
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-rename-file-popover.ui");
+ label_file_name = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
- user_data = g_new (RenameDialogData, 1);
- user_data->view = view;
- user_data->target_file = target_file;
- user_data->name_entry = dialog_data->name_entry;
+ widget_data = g_new (FileNameWidgetData, 1);
+ widget_data->view = view;
+ widget_data->widget = GTK_WIDGET (gtk_builder_get_object (builder, "rename_file_popover"));
+ widget_data->activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "rename_button"));
+ widget_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
+ widget_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
+ widget_data->target_is_folder = nautilus_file_is_directory (target_file);
+ widget_data->target_file = target_file;
- gtk_window_set_transient_for (GTK_WINDOW (dialog_data->dialog),
- GTK_WINDOW (nautilus_view_get_window (view)));
+ view->details->rename_file_popover = widget_data->widget;
- /* Connect signals */
- gtk_builder_add_callback_symbols (builder,
- "nautilus_view_file_name_dialog_entry_on_validate",
- G_CALLBACK (nautilus_view_file_name_dialog_entry_on_validate),
- "nautilus_view_file_name_dialog_entry_on_activate",
- G_CALLBACK (nautilus_view_file_name_dialog_entry_on_activate),
- NULL);
+ rename_data = g_new (RenameDialogData, 1);
+ rename_data->view = view;
+ rename_data->widget = widget_data->widget;
+ rename_data->target_file = target_file;
+ rename_data->name_entry = widget_data->name_entry;
- dialog_data->target_is_folder = nautilus_file_is_directory (target_file);
- gtk_button_set_label (GTK_BUTTON (button_ok), _("Rename"));
- file_name = nautilus_file_get_display_name (target_file);
- title = g_strdup_printf (_("Rename “%s”"), file_name);
- gtk_window_set_title (GTK_WINDOW (dialog_data->dialog), title);
- g_free (file_name);
- g_free (title);
- if (dialog_data->target_is_folder)
+ if (widget_data->target_is_folder)
gtk_label_set_text (GTK_LABEL (label_file_name), _("Folder name"));
else
gtk_label_set_text (GTK_LABEL (label_file_name), _("File name"));
- gtk_entry_set_text (GTK_ENTRY (dialog_data->name_entry), nautilus_file_get_name (target_file));
- gtk_builder_connect_signals (builder, dialog_data);
-
- g_signal_connect (dialog_data->dialog,
- "response",
- G_CALLBACK (nautilus_view_rename_dialog_on_response),
- user_data);
+ gtk_entry_set_text (GTK_ENTRY (widget_data->name_entry), nautilus_file_get_name (target_file));
+
+ g_signal_connect (widget_data->activate_button,
+ "clicked",
+ G_CALLBACK (rename_file_popover_rename_button_on_clicked),
+ rename_data);
+
+ g_signal_connect (widget_data->name_entry,
+ "changed",
+ G_CALLBACK (rename_file_popover_entry_on_changed),
+ widget_data);
+
+ g_signal_connect (GTK_POPOVER (widget_data->widget),
+ "closed",
+ G_CALLBACK (rename_file_popover_on_closed),
+ widget_data);
+
+ g_signal_connect (GTK_POPOVER (widget_data->widget),
+ "unmap",
+ G_CALLBACK (gtk_widget_destroy),
+ NULL);
+
+ relative_to = nautilus_view_compute_rename_popover_relative_to (view);
+ gtk_popover_set_default_widget (GTK_POPOVER (widget_data->widget),
+ widget_data->activate_button);
+ gtk_popover_set_pointing_to (GTK_POPOVER (widget_data->widget), relative_to);
+ gtk_popover_set_relative_to (GTK_POPOVER (widget_data->widget),
+ GTK_WIDGET (view));
+ gtk_widget_show (widget_data->widget);
- gtk_widget_show_all (dialog_data->dialog);
/* Select the name part withouth the file extension */
eel_filename_get_rename_region (nautilus_file_get_name (target_file),
&start_offset, &end_offset);
- gtk_editable_select_region (GTK_EDITABLE (dialog_data->name_entry),
+ gtk_editable_select_region (GTK_EDITABLE (widget_data->name_entry),
start_offset, end_offset);
- /* Update the ok button status */
- nautilus_view_file_name_dialog_validate_name (dialog_data);
+ /* Update the rename button status */
+ rename_file_popover_entry_on_changed (GTK_ENTRY (widget_data->name_entry),
+ widget_data);
+
g_object_unref (builder);
}
@@ -2000,70 +2029,67 @@ nautilus_view_new_folder_dialog_on_response (GtkDialog *dialog,
g_free (name);
}
- /* If there's any resources left from the delayed
- * message, it should be removed before it gets
- * triggered.
- */
- if (new_folder_data->view->details->dialog_duplicated_name_label_timeout_id > 0) {
- g_source_remove (new_folder_data->view->details->dialog_duplicated_name_label_timeout_id);
- new_folder_data->view->details->dialog_duplicated_name_label_timeout_id = 0;
- }
+ if (new_folder_data->view->details->create_folder_duplicated_label_timeout_id > 0) {
+ g_source_remove (new_folder_data->view->details->create_folder_duplicated_label_timeout_id);
+ new_folder_data->view->details->create_folder_duplicated_label_timeout_id = 0;
+ }
- g_free (user_data);
gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_free (user_data);
}
static void
nautilus_view_new_folder_dialog_new (NautilusView *view,
gboolean with_selection)
{
- FileNameDialogData *dialog_data;
+ FileNameWidgetData *widget_data;
NewFolderDialogData *user_data;
- GtkWidget *button_ok;
GtkWidget *label_file_name;
GtkBuilder *builder;
- builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-file-name-dialog.ui");
- button_ok = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button"));
+ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/nautilus-create-folder-dialog.ui");
label_file_name = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
- dialog_data = g_new (FileNameDialogData, 1);
- dialog_data->view = view;
- dialog_data->dialog = GTK_WIDGET (gtk_builder_get_object (builder, "file_name_dialog"));
- dialog_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
- dialog_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
- dialog_data->target_is_folder = TRUE;
- dialog_data->target_file = NULL;
+ widget_data = g_new (FileNameWidgetData, 1);
+ widget_data->view = view;
+ widget_data->widget = GTK_WIDGET (gtk_builder_get_object (builder, "create_folder_dialog"));
+ widget_data->activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button"));
+ widget_data->error_label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
+ widget_data->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
+ widget_data->target_is_folder = TRUE;
+ widget_data->target_file = NULL;
user_data = g_new (NewFolderDialogData, 1);
user_data->view = view;
user_data->with_selection = with_selection;
- user_data->name_entry = dialog_data->name_entry;
+ user_data->name_entry = widget_data->name_entry;
- gtk_window_set_transient_for (GTK_WINDOW (dialog_data->dialog),
+ gtk_window_set_transient_for (GTK_WINDOW (widget_data->widget),
GTK_WINDOW (nautilus_view_get_window (view)));
/* Connect signals */
gtk_builder_add_callback_symbols (builder,
- "nautilus_view_file_name_dialog_entry_on_validate",
- G_CALLBACK (nautilus_view_file_name_dialog_entry_on_validate),
- "nautilus_view_file_name_dialog_entry_on_activate",
- G_CALLBACK (nautilus_view_file_name_dialog_entry_on_activate),
+ "create_folder_dialog_entry_on_changed",
+ G_CALLBACK (create_folder_dialog_entry_on_changed),
+ "create_folder_dialog_entry_on_activate",
+ G_CALLBACK (create_folder_dialog_entry_on_activate),
NULL);
- gtk_builder_connect_signals (builder, dialog_data);
- gtk_button_set_label (GTK_BUTTON (button_ok), _("Create"));
+ gtk_builder_connect_signals (builder, widget_data);
+ gtk_button_set_label (GTK_BUTTON (widget_data->activate_button),
+ _("Create"));
gtk_label_set_text (GTK_LABEL (label_file_name), _("Folder name"));
- gtk_window_set_title (GTK_WINDOW (dialog_data->dialog), _("New Folder"));
+ gtk_window_set_title (GTK_WINDOW (widget_data->widget), _("New Folder"));
- g_signal_connect (dialog_data->dialog,
+ g_signal_connect (widget_data->widget,
"response",
G_CALLBACK (nautilus_view_new_folder_dialog_on_response),
user_data);
- gtk_widget_show_all (dialog_data->dialog);
+ gtk_widget_show_all (widget_data->widget);
/* Update the ok button status */
- nautilus_view_file_name_dialog_validate_name (dialog_data);
+ create_folder_dialog_entry_on_changed (GTK_ENTRY (widget_data->name_entry),
+ widget_data);
g_object_unref (builder);
}
@@ -5488,7 +5514,7 @@ real_action_rename (NautilusView *view,
* they are always pre-selected as a whole */
select_all = nautilus_file_is_directory (file);
}
- nautilus_view_rename_dialog_new (view, file);
+ nautilus_view_rename_file_popover_new (view, file);
}
}
diff --git a/src/nautilus-view.h b/src/nautilus-view.h
index 93fbc894d..3cc87dab0 100644
--- a/src/nautilus-view.h
+++ b/src/nautilus-view.h
@@ -276,6 +276,8 @@ struct NautilusViewClass {
const char *uri);
NautilusWindow * (*get_window) (NautilusView *view);
+
+ GdkRectangle * (*compute_rename_popover_relative_to) (NautilusView *view);
};
/* GObject support */
diff --git a/src/nautilus.gresource.xml b/src/nautilus.gresource.xml
index acab5ff41..c80a529d4 100644
--- a/src/nautilus.gresource.xml
+++ b/src/nautilus.gresource.xml
@@ -8,7 +8,8 @@
<file>nautilus-toolbar-ui.xml</file>
<file>nautilus-toolbar-view-menu.xml</file>
<file>nautilus-toolbar-action-menu.xml</file>
- <file>nautilus-file-name-dialog.ui</file>
+ <file>nautilus-create-folder-dialog.ui</file>
+ <file>nautilus-rename-file-popover.ui</file>
<file>nautilus-view-context-menus.xml</file>
<file>nautilus-progress-info-widget.xml</file>
<file>nautilus-move-to-trash-shortcut-changed.ui</file>