[nautilus/gnome-3-28] rename-file-popover-controller: Make popover recyclable
- From: Carlos Soriano <csoriano src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/gnome-3-28] rename-file-popover-controller: Make popover recyclable
- Date: Mon, 9 Apr 2018 19:59:22 +0000 (UTC)
commit e950794a6253f06741a350501b966a32d64e4039
Author: Ernestas Kulik <ernestask gnome org>
Date: Thu Mar 15 21:28:54 2018 +0200
rename-file-popover-controller: Make popover recyclable
Creating and destroying the controller each time we want to rename
something results in not being able to pop down the popover, which leads
to an inconsistent look.
The “containing-directory” in the file name widget controller parent
class needed to be made non-construct-only, as otherwise it would be
impossible to reuse the same controller.
Fixes https://gitlab.gnome.org/GNOME/nautilus/issues/260
src/nautilus-file-name-widget-controller.c | 24 +++-
src/nautilus-file-name-widget-controller.h | 3 +-
src/nautilus-files-view.c | 63 ++++++---
src/nautilus-rename-file-popover-controller.c | 191 ++++++++++++++++----------
src/nautilus-rename-file-popover-controller.h | 8 +-
5 files changed, 187 insertions(+), 102 deletions(-)
---
diff --git a/src/nautilus-file-name-widget-controller.c b/src/nautilus-file-name-widget-controller.c
index 0deff902b..9b49b0f4c 100644
--- a/src/nautilus-file-name-widget-controller.c
+++ b/src/nautilus-file-name-widget-controller.c
@@ -63,6 +63,15 @@ nautilus_file_name_widget_controller_get_new_name (NautilusFileNameWidgetControl
return NAUTILUS_FILE_NAME_WIDGET_CONTROLLER_GET_CLASS (self)->get_new_name (self);
}
+void
+nautilus_file_name_widget_controller_set_containing_directory (NautilusFileNameWidgetController *self,
+ NautilusDirectory *directory)
+{
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+
+ g_object_set (self, "containing-directory", directory, NULL);
+}
+
static gboolean
nautilus_file_name_widget_controller_name_is_valid (NautilusFileNameWidgetController *self,
gchar *name,
@@ -160,6 +169,8 @@ file_name_widget_controller_process_new_name (NautilusFileNameWidgetController *
NautilusFile *existing_file;
priv = nautilus_file_name_widget_controller_get_instance_private (controller);
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (priv->containing_directory));
+
name = nautilus_file_name_widget_controller_get_new_name (controller);
*valid_name = nautilus_file_name_widget_controller_name_is_valid (controller,
name,
@@ -289,6 +300,11 @@ file_name_widget_controller_on_activate (gpointer user_data)
static void
nautilus_file_name_widget_controller_init (NautilusFileNameWidgetController *self)
{
+ NautilusFileNameWidgetControllerPrivate *priv;
+
+ priv = nautilus_file_name_widget_controller_get_instance_private (self);
+
+ priv->containing_directory = NULL;
}
static void
@@ -345,8 +361,9 @@ nautilus_file_name_widget_controller_set_property (GObject *object,
case PROP_CONTAINING_DIRECTORY:
{
- priv->containing_directory = NAUTILUS_DIRECTORY (g_value_get_object (value));
- nautilus_directory_ref (priv->containing_directory);
+ g_clear_object (&priv->containing_directory);
+
+ priv->containing_directory = NAUTILUS_DIRECTORY (g_value_dup_object (value));
}
break;
@@ -460,6 +477,5 @@ nautilus_file_name_widget_controller_class_init (NautilusFileNameWidgetControlle
"Containing Directory",
"The directory used to check for duplicate names",
NAUTILUS_TYPE_DIRECTORY,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_WRITABLE));
}
diff --git a/src/nautilus-file-name-widget-controller.h b/src/nautilus-file-name-widget-controller.h
index 1331c5644..ae1c9c26a 100644
--- a/src/nautilus-file-name-widget-controller.h
+++ b/src/nautilus-file-name-widget-controller.h
@@ -47,5 +47,6 @@ struct _NautilusFileNameWidgetControllerClass
gchar * nautilus_file_name_widget_controller_get_new_name (NautilusFileNameWidgetController *controller);
-
+void nautilus_file_name_widget_controller_set_containing_directory (NautilusFileNameWidgetController
*controller,
+ NautilusDirectory
*directory);
#endif /* NAUTILUS_FILE_NAME_WIDGET_CONTROLLER_H */
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index a18cd8cf8..0c7380ae9 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -269,6 +269,9 @@ typedef struct
GCancellable *starred_cancellable;
NautilusTagManager *tag_manager;
+
+ gint name_accepted_handler_id;
+ gint cancelled_handler_id;
} NautilusFilesViewPrivate;
typedef struct
@@ -1884,6 +1887,29 @@ nautilus_files_view_compute_rename_popover_pointing_to (NautilusFilesView *view)
return NAUTILUS_FILES_VIEW_CLASS (G_OBJECT_GET_CLASS (view))->compute_rename_popover_pointing_to (view);
}
+static void
+disconnect_rename_controller_signals (NautilusFilesView *self)
+{
+ NautilusFilesViewPrivate *priv;
+
+ g_assert (NAUTILUS_IS_FILES_VIEW (self));
+
+ priv = nautilus_files_view_get_instance_private (self);
+
+ if (priv->name_accepted_handler_id != 0)
+ {
+ g_signal_handler_disconnect (priv->rename_file_controller, priv->name_accepted_handler_id);
+ priv->name_accepted_handler_id = 0;
+ }
+
+ if (priv->cancelled_handler_id != 0)
+ {
+ g_signal_handler_disconnect (priv->rename_file_controller,
+ priv->cancelled_handler_id);
+ priv->cancelled_handler_id = 0;
+ }
+}
+
static void
rename_file_popover_controller_on_name_accepted (NautilusFileNameWidgetController *controller,
gpointer user_data)
@@ -1908,7 +1934,7 @@ rename_file_popover_controller_on_name_accepted (NautilusFileNameWidgetControlle
nautilus_rename_file (target_file, name, NULL, NULL);
- g_clear_object (&priv->rename_file_controller);
+ disconnect_rename_controller_signals (view);
}
static void
@@ -1916,12 +1942,10 @@ rename_file_popover_controller_on_cancelled (NautilusFileNameWidgetController *c
gpointer user_data)
{
NautilusFilesView *view;
- NautilusFilesViewPrivate *priv;
view = NAUTILUS_FILES_VIEW (user_data);
- priv = nautilus_files_view_get_instance_private (view);
- g_clear_object (&priv->rename_file_controller);
+ disconnect_rename_controller_signals (view);
}
static void
@@ -1933,11 +1957,6 @@ nautilus_files_view_rename_file_popover_new (NautilusFilesView *view,
priv = nautilus_files_view_get_instance_private (view);
- if (priv->rename_file_controller != NULL)
- {
- return;
- }
-
/* Make sure the whole item is visible. The selection is a single item, the
* one to rename with the popover, so we can use reveal_selection() for this.
*/
@@ -1945,19 +1964,19 @@ nautilus_files_view_rename_file_popover_new (NautilusFilesView *view,
pointing_to = nautilus_files_view_compute_rename_popover_pointing_to (view);
- priv->rename_file_controller =
- nautilus_rename_file_popover_controller_new (target_file,
- pointing_to,
- GTK_WIDGET (view));
+ nautilus_rename_file_popover_controller_show_for_file (priv->rename_file_controller,
+ target_file,
+ pointing_to,
+ GTK_WIDGET (view));
- g_signal_connect (priv->rename_file_controller,
- "name-accepted",
- (GCallback) rename_file_popover_controller_on_name_accepted,
- view);
- g_signal_connect (priv->rename_file_controller,
- "cancelled",
- (GCallback) rename_file_popover_controller_on_cancelled,
- view);
+ priv->name_accepted_handler_id = g_signal_connect (priv->rename_file_controller,
+ "name-accepted",
+ G_CALLBACK
(rename_file_popover_controller_on_name_accepted),
+ view);
+ priv->cancelled_handler_id = g_signal_connect (priv->rename_file_controller,
+ "cancelled",
+ G_CALLBACK (rename_file_popover_controller_on_cancelled),
+ view);
}
static void
@@ -9662,6 +9681,8 @@ nautilus_files_view_init (NautilusFilesView *view)
priv->starred_cancellable = g_cancellable_new ();
priv->tag_manager = nautilus_tag_manager_get ();
+ priv->rename_file_controller = nautilus_rename_file_popover_controller_new ();
+
nautilus_profile_end (NULL);
}
diff --git a/src/nautilus-rename-file-popover-controller.c b/src/nautilus-rename-file-popover-controller.c
index 5806315fb..2c10e07e2 100644
--- a/src/nautilus-rename-file-popover-controller.c
+++ b/src/nautilus-rename-file-popover-controller.c
@@ -38,13 +38,52 @@ struct _NautilusRenameFilePopoverController
gboolean target_is_folder;
GtkWidget *rename_file_popover;
+ GtkWidget *name_entry;
+ GtkWidget *name_label;
gint closed_handler_id;
gint file_changed_handler_id;
+ gint key_press_event_handler_id;
};
G_DEFINE_TYPE (NautilusRenameFilePopoverController, nautilus_rename_file_popover_controller,
NAUTILUS_TYPE_FILE_NAME_WIDGET_CONTROLLER)
+static void
+disconnect_signal_handlers (NautilusRenameFilePopoverController *self)
+{
+ g_assert (NAUTILUS_IS_RENAME_FILE_POPOVER_CONTROLLER (self));
+
+ if (self->closed_handler_id != 0)
+ {
+ g_signal_handler_disconnect (self->rename_file_popover, self->closed_handler_id);
+ self->closed_handler_id = 0;
+ }
+
+ if (self->file_changed_handler_id != 0)
+ {
+ g_signal_handler_disconnect (self->target_file, self->file_changed_handler_id);
+ self->file_changed_handler_id = 0;
+ }
+
+ if (self->key_press_event_handler_id != 0)
+ {
+ g_signal_handler_disconnect (self->name_entry, self->key_press_event_handler_id);
+ self->key_press_event_handler_id = 0;
+ }
+}
+
+static void
+reset_state (NautilusRenameFilePopoverController *self)
+{
+ g_assert (NAUTILUS_IS_RENAME_FILE_POPOVER_CONTROLLER (self));
+
+ disconnect_signal_handlers (self);
+
+ g_clear_object (&self->target_file);
+
+ gtk_popover_popdown (GTK_POPOVER (self->rename_file_popover));
+}
+
static void
rename_file_popover_controller_on_closed (GtkPopover *popover,
gpointer user_data)
@@ -53,9 +92,7 @@ rename_file_popover_controller_on_closed (GtkPopover *popover,
controller = NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER (user_data);
- g_signal_handler_disconnect (controller->rename_file_popover,
- controller->closed_handler_id);
- controller->closed_handler_id = 0;
+ reset_state (controller);
g_signal_emit_by_name (controller, "cancelled");
}
@@ -137,7 +174,7 @@ name_entry_on_f2_pressed (GtkWidget *widget,
text_length = (guint) gtk_entry_get_text_length (GTK_ENTRY (widget));
if (text_length == 0)
{
- return GDK_EVENT_PROPAGATE;
+ return GDK_EVENT_STOP;
}
gtk_editable_get_selection_bounds (GTK_EDITABLE (widget),
@@ -160,7 +197,7 @@ name_entry_on_f2_pressed (GtkWidget *widget,
start_offset, end_offset);
}
- return GDK_EVENT_PROPAGATE;
+ return GDK_EVENT_STOP;
}
static gboolean
@@ -212,18 +249,14 @@ target_file_on_changed (NautilusFile *file,
if (nautilus_file_is_gone (file))
{
- g_signal_handler_disconnect (controller->target_file,
- controller->file_changed_handler_id);
- controller->file_changed_handler_id = 0;
+ reset_state (controller);
g_signal_emit_by_name (controller, "cancelled");
}
}
NautilusRenameFilePopoverController *
-nautilus_rename_file_popover_controller_new (NautilusFile *target_file,
- GdkRectangle *pointing_to,
- GtkWidget *relative_to)
+nautilus_rename_file_popover_controller_new (void)
{
NautilusRenameFilePopoverController *self;
g_autoptr (GtkBuilder) builder = NULL;
@@ -233,9 +266,6 @@ nautilus_rename_file_popover_controller_new (NautilusFile *target_file,
GtkWidget *name_entry;
GtkWidget *activate_button;
GtkWidget *name_label;
- NautilusDirectory *containing_directory;
- g_autofree char *display_name = NULL;
- gint n_chars;
builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-rename-file-popover.ui");
rename_file_popover = GTK_WIDGET (gtk_builder_get_object (builder, "rename_file_popover"));
@@ -245,35 +275,67 @@ nautilus_rename_file_popover_controller_new (NautilusFile *target_file,
activate_button = GTK_WIDGET (gtk_builder_get_object (builder, "rename_button"));
name_label = GTK_WIDGET (gtk_builder_get_object (builder, "name_label"));
- if (!nautilus_file_is_self_owned (target_file))
- {
- NautilusFile *parent_location;
+ self = g_object_new (NAUTILUS_TYPE_RENAME_FILE_POPOVER_CONTROLLER,
+ "error-revealer", error_revealer,
+ "error-label", error_label,
+ "name-entry", name_entry,
+ "activate-button", activate_button,
+ NULL);
+
+ self->rename_file_popover = g_object_ref_sink (rename_file_popover);
+ self->name_entry = name_entry;
+ self->name_label = name_label;
+
+ gtk_popover_set_default_widget (GTK_POPOVER (rename_file_popover), name_entry);
+
+ return self;
+}
+
+NautilusFile *
+nautilus_rename_file_popover_controller_get_target_file (NautilusRenameFilePopoverController *self)
+{
+ g_return_val_if_fail (NAUTILUS_IS_RENAME_FILE_POPOVER_CONTROLLER (self), NULL);
+
+ return self->target_file;
+}
+
+void
+nautilus_rename_file_popover_controller_show_for_file (NautilusRenameFilePopoverController *self,
+ NautilusFile *target_file,
+ GdkRectangle *pointing_to,
+ GtkWidget *relative_to)
+{
+ g_autoptr (NautilusDirectory) containing_directory = NULL;
+ g_autofree gchar *display_name = NULL;
+ gint n_chars;
+
+ g_assert (NAUTILUS_IS_RENAME_FILE_POPOVER_CONTROLLER (self));
+ g_assert (NAUTILUS_IS_FILE (target_file));
- parent_location = nautilus_file_get_parent (target_file);
- containing_directory = nautilus_directory_get_for_file (parent_location);
+ reset_state (self);
- nautilus_file_unref (parent_location);
+ self->target_file = g_object_ref (target_file);
+
+ if (!nautilus_file_is_self_owned (self->target_file))
+ {
+ g_autoptr (NautilusFile) parent = NULL;
+
+ parent = nautilus_file_get_parent (self->target_file);
+ containing_directory = nautilus_directory_get_for_file (parent);
}
else
{
- containing_directory = nautilus_directory_get_for_file (target_file);
+ containing_directory = nautilus_directory_get_for_file (self->target_file);
}
- self = g_object_new (NAUTILUS_TYPE_RENAME_FILE_POPOVER_CONTROLLER,
- "error-revealer", error_revealer,
- "error-label", error_label,
- "name-entry", name_entry,
- "activate-button", activate_button,
- "containing-directory", containing_directory, NULL);
-
- self->target_is_folder = nautilus_file_is_directory (target_file);
- self->target_file = nautilus_file_ref (target_file);
+ nautilus_file_name_widget_controller_set_containing_directory (NAUTILUS_FILE_NAME_WIDGET_CONTROLLER
(self),
+ containing_directory);
- self->rename_file_popover = rename_file_popover;
+ self->target_is_folder = nautilus_file_is_directory (self->target_file);
- self->closed_handler_id = g_signal_connect (rename_file_popover,
+ self->closed_handler_id = g_signal_connect (self->rename_file_popover,
"closed",
- (GCallback) rename_file_popover_controller_on_closed,
+ G_CALLBACK (rename_file_popover_controller_on_closed),
self);
self->file_changed_handler_id = g_signal_connect (self->target_file,
@@ -281,26 +343,25 @@ nautilus_rename_file_popover_controller_new (NautilusFile *target_file,
G_CALLBACK (target_file_on_changed),
self);
- g_signal_connect (name_entry,
- "key-press-event",
- G_CALLBACK (name_entry_on_key_pressed),
- self);
+ self->key_press_event_handler_id = g_signal_connect (self->name_entry,
+ "key-press-event",
+ G_CALLBACK (name_entry_on_key_pressed),
+ self);
- gtk_label_set_text (GTK_LABEL (name_label),
+ gtk_label_set_text (GTK_LABEL (self->name_label),
self->target_is_folder ? _("Folder name") :
_("File name"));
- display_name = nautilus_file_get_display_name (target_file);
+ display_name = nautilus_file_get_display_name (self->target_file);
- gtk_entry_set_text (GTK_ENTRY (name_entry), display_name);
+ gtk_entry_set_text (GTK_ENTRY (self->name_entry), display_name);
- gtk_popover_set_default_widget (GTK_POPOVER (rename_file_popover), name_entry);
- gtk_popover_set_pointing_to (GTK_POPOVER (rename_file_popover), pointing_to);
- gtk_popover_set_relative_to (GTK_POPOVER (rename_file_popover), relative_to);
+ gtk_popover_set_pointing_to (GTK_POPOVER (self->rename_file_popover), pointing_to);
+ gtk_popover_set_relative_to (GTK_POPOVER (self->rename_file_popover), relative_to);
- gtk_popover_popup (GTK_POPOVER (rename_file_popover));
+ gtk_popover_popup (GTK_POPOVER (self->rename_file_popover));
- if (nautilus_file_is_regular_file (target_file))
+ if (nautilus_file_is_regular_file (self->target_file))
{
gint start_offset;
gint end_offset;
@@ -308,31 +369,30 @@ nautilus_rename_file_popover_controller_new (NautilusFile *target_file,
/* Select the name part without the file extension */
eel_filename_get_rename_region (display_name,
&start_offset, &end_offset);
- gtk_editable_select_region (GTK_EDITABLE (name_entry),
+ gtk_editable_select_region (GTK_EDITABLE (self->name_entry),
start_offset, end_offset);
}
n_chars = g_utf8_strlen (display_name, -1);
- gtk_entry_set_width_chars (GTK_ENTRY (name_entry),
+ gtk_entry_set_width_chars (GTK_ENTRY (self->name_entry),
MIN (MAX (n_chars, RENAME_ENTRY_MIN_CHARS),
RENAME_ENTRY_MAX_CHARS));
-
- nautilus_directory_unref (containing_directory);
-
- return self;
}
-NautilusFile *
-nautilus_rename_file_popover_controller_get_target_file (NautilusRenameFilePopoverController *self)
+static void
+on_name_accepted (NautilusFileNameWidgetController *controller)
{
- g_return_val_if_fail (NAUTILUS_IS_RENAME_FILE_POPOVER_CONTROLLER (self), NULL);
+ NautilusRenameFilePopoverController *self;
- return self->target_file;
+ self = NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER (controller);
+
+ reset_state (self);
}
static void
nautilus_rename_file_popover_controller_init (NautilusRenameFilePopoverController *self)
{
+ g_signal_connect_after (self, "name-accepted", G_CALLBACK (on_name_accepted), self);
}
static void
@@ -342,25 +402,10 @@ nautilus_rename_file_popover_controller_finalize (GObject *object)
self = NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER (object);
- if (self->rename_file_popover)
- {
- if (self->closed_handler_id)
- {
- g_signal_handler_disconnect (self->rename_file_popover,
- self->closed_handler_id);
- self->closed_handler_id = 0;
- }
- gtk_popover_popdown (GTK_POPOVER (self->rename_file_popover));
- g_clear_pointer (&self->rename_file_popover, gtk_widget_destroy);
- }
+ reset_state (self);
- if (self->file_changed_handler_id != 0)
- {
- g_signal_handler_disconnect (self->target_file,
- self->file_changed_handler_id);
- self->file_changed_handler_id = 0;
- }
- nautilus_file_unref (self->target_file);
+ gtk_widget_destroy (self->rename_file_popover);
+ g_clear_object (&self->rename_file_popover);
G_OBJECT_CLASS (nautilus_rename_file_popover_controller_parent_class)->finalize (object);
}
diff --git a/src/nautilus-rename-file-popover-controller.h b/src/nautilus-rename-file-popover-controller.h
index 2445ae341..8aff060c9 100644
--- a/src/nautilus-rename-file-popover-controller.h
+++ b/src/nautilus-rename-file-popover-controller.h
@@ -29,10 +29,12 @@
#define NAUTILUS_TYPE_RENAME_FILE_POPOVER_CONTROLLER nautilus_rename_file_popover_controller_get_type ()
G_DECLARE_FINAL_TYPE (NautilusRenameFilePopoverController, nautilus_rename_file_popover_controller,
NAUTILUS, RENAME_FILE_POPOVER_CONTROLLER, NautilusFileNameWidgetController)
-NautilusRenameFilePopoverController * nautilus_rename_file_popover_controller_new (NautilusFile *target_file,
- GdkRectangle *pointing_to,
- GtkWidget
*relative_to);
+NautilusRenameFilePopoverController * nautilus_rename_file_popover_controller_new (void);
NautilusFile * nautilus_rename_file_popover_controller_get_target_file (NautilusRenameFilePopoverController
*controller);
+void nautilus_rename_file_popover_controller_show_for_file (NautilusRenameFilePopoverController
*controller,
+ NautilusFile
*target_file,
+ GdkRectangle
*pointing_to,
+ GtkWidget
*relative_to);
#endif /* NAUTILUS_RENAME_FILE_POPOVER_CONTROLLER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]