[gnome-flashback] desktop: add Rename... to icon menu
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] desktop: add Rename... to icon menu
- Date: Fri, 15 Nov 2019 21:26:06 +0000 (UTC)
commit 43c37cf7b2d9f356a67a3773ff3697cda7ac099f
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Fri Nov 15 23:24:30 2019 +0200
desktop: add Rename... to icon menu
gnome-flashback/libdesktop/Makefile.am | 2 +
.../libdesktop/gf-create-folder-dialog.c | 99 ++-----
.../libdesktop/gf-create-folder-dialog.h | 8 +-
gnome-flashback/libdesktop/gf-home-icon.c | 11 +
gnome-flashback/libdesktop/gf-icon-view.c | 130 +++++++--
gnome-flashback/libdesktop/gf-icon-view.h | 25 +-
gnome-flashback/libdesktop/gf-icon.c | 134 +++++++++
gnome-flashback/libdesktop/gf-icon.h | 2 +
gnome-flashback/libdesktop/gf-rename-popover.c | 312 +++++++++++++++++++++
gnome-flashback/libdesktop/gf-rename-popover.h | 41 +++
gnome-flashback/libdesktop/gf-trash-icon.c | 10 +
po/POTFILES.in | 1 +
12 files changed, 677 insertions(+), 98 deletions(-)
---
diff --git a/gnome-flashback/libdesktop/Makefile.am b/gnome-flashback/libdesktop/Makefile.am
index 82a8799..8667d0f 100644
--- a/gnome-flashback/libdesktop/Makefile.am
+++ b/gnome-flashback/libdesktop/Makefile.am
@@ -37,6 +37,8 @@ libdesktop_la_SOURCES = \
gf-icon.h \
gf-monitor-view.c \
gf-monitor-view.h \
+ gf-rename-popover.c \
+ gf-rename-popover.h \
gf-utils.c \
gf-utils.h \
$(BUILT_SOURCES) \
diff --git a/gnome-flashback/libdesktop/gf-create-folder-dialog.c
b/gnome-flashback/libdesktop/gf-create-folder-dialog.c
index 214af55..6584ec2 100644
--- a/gnome-flashback/libdesktop/gf-create-folder-dialog.c
+++ b/gnome-flashback/libdesktop/gf-create-folder-dialog.c
@@ -43,75 +43,13 @@ static guint dialog_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GfCreateFolderDialog, gf_create_folder_dialog, GTK_TYPE_DIALOG)
-static gboolean
-is_valid (GfCreateFolderDialog *self)
+static void
+validate (GfCreateFolderDialog *self)
{
- GtkRevealer *revealer;
const char *text;
- char *folder_name;
- char *validate_error;
- const char *error;
- gboolean valid;
- revealer = GTK_REVEALER (self->error_revealer);
text = gtk_entry_get_text (GTK_ENTRY (self->name_entry));
- folder_name = g_strdup (text);
- error = NULL;
- valid = TRUE;
-
- folder_name = g_strstrip (folder_name);
- validate_error = NULL;
-
- if (*folder_name == '\0')
- {
- error = NULL;
- valid = FALSE;
- }
- else if (g_strstr_len (folder_name, -1, "/") != NULL)
- {
- error = _("Folder names cannot contain “/”.");
- valid = FALSE;
- }
- else if (g_strcmp0 (folder_name, ".") == 0)
- {
- error = _("A folder cannot be called “.”.");
- valid = FALSE;
- }
- else if (g_strcmp0 (folder_name, "..") == 0)
- {
- error = _("A folder cannot be called “..”.");
- valid = FALSE;
- }
-
- if (valid)
- {
- g_assert_true (error == NULL);
-
- g_signal_emit (self, dialog_signals[VALIDATE], 0,
- folder_name, &validate_error);
-
- if (validate_error != NULL)
- {
- error = validate_error;
- valid = FALSE;
- }
- }
-
- if (error == NULL &&
- g_str_has_prefix (folder_name, "."))
- {
- error = _("Folders with “.” at the beginning of their name are hidden.");
- }
-
- gtk_label_set_text (GTK_LABEL (self->error_label), error);
- gtk_revealer_set_reveal_child (revealer, error != NULL);
-
- gtk_widget_set_sensitive (self->create_button, valid);
-
- g_free (validate_error);
- g_free (folder_name);
-
- return valid;
+ g_signal_emit (self, dialog_signals[VALIDATE], 0, text);
}
static void
@@ -125,7 +63,9 @@ static void
create_clicked_cb (GtkWidget *widget,
GfCreateFolderDialog *self)
{
- if (!is_valid (self))
+ validate (self);
+
+ if (!gtk_widget_get_sensitive (self->create_button))
return;
gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
@@ -135,15 +75,16 @@ static void
name_changed_cb (GtkEditable *editable,
GfCreateFolderDialog *self)
{
- is_valid (self);
+ validate (self);
}
static void
name_activate_cb (GtkWidget *widget,
GfCreateFolderDialog *self)
{
- if (!gtk_widget_get_sensitive (self->create_button) ||
- !is_valid (self))
+ validate (self);
+
+ if (!gtk_widget_get_sensitive (self->create_button))
return;
gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
@@ -229,9 +170,8 @@ install_signals (void)
dialog_signals[VALIDATE] =
g_signal_new ("validate", GF_TYPE_CREATE_FOLDER_DIALOG,
G_SIGNAL_RUN_LAST, 0,
- g_signal_accumulator_first_wins,
- NULL, NULL,
- G_TYPE_STRING, 1, G_TYPE_STRING);
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
}
static void
@@ -257,6 +197,21 @@ gf_create_folder_dialog_new (void)
NULL);
}
+void
+gf_create_folder_dialog_set_valid (GfCreateFolderDialog *self,
+ gboolean valid,
+ const char *message)
+{
+ GtkRevealer *revealer;
+
+ revealer = GTK_REVEALER (self->error_revealer);
+
+ gtk_label_set_text (GTK_LABEL (self->error_label), message);
+ gtk_revealer_set_reveal_child (revealer, message != NULL);
+
+ gtk_widget_set_sensitive (self->create_button, valid);
+}
+
char *
gf_create_folder_dialog_get_folder_name (GfCreateFolderDialog *self)
{
diff --git a/gnome-flashback/libdesktop/gf-create-folder-dialog.h
b/gnome-flashback/libdesktop/gf-create-folder-dialog.h
index ffc5669..d302a9e 100644
--- a/gnome-flashback/libdesktop/gf-create-folder-dialog.h
+++ b/gnome-flashback/libdesktop/gf-create-folder-dialog.h
@@ -26,9 +26,13 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GfCreateFolderDialog, gf_create_folder_dialog,
GF, CREATE_FOLDER_DIALOG, GtkDialog)
-GtkWidget *gf_create_folder_dialog_new (void);
+GtkWidget *gf_create_folder_dialog_new (void);
-char *gf_create_folder_dialog_get_folder_name (GfCreateFolderDialog *self);
+void gf_create_folder_dialog_set_valid (GfCreateFolderDialog *self,
+ gboolean valid,
+ const char *message);
+
+char *gf_create_folder_dialog_get_folder_name (GfCreateFolderDialog *self);
G_END_DECLS
diff --git a/gnome-flashback/libdesktop/gf-home-icon.c b/gnome-flashback/libdesktop/gf-home-icon.c
index f31b2aa..7e11bdb 100644
--- a/gnome-flashback/libdesktop/gf-home-icon.c
+++ b/gnome-flashback/libdesktop/gf-home-icon.c
@@ -25,9 +25,20 @@ struct _GfHomeIcon
G_DEFINE_TYPE (GfHomeIcon, gf_home_icon, GF_TYPE_ICON)
+static gboolean
+gf_home_icon_can_rename (GfIcon *icon)
+{
+ return FALSE;
+}
+
static void
gf_home_icon_class_init (GfHomeIconClass *self_class)
{
+ GfIconClass *icon_class;
+
+ icon_class = GF_ICON_CLASS (self_class);
+
+ icon_class->can_rename = gf_home_icon_can_rename;
}
static void
diff --git a/gnome-flashback/libdesktop/gf-icon-view.c b/gnome-flashback/libdesktop/gf-icon-view.c
index 8d455ba..d49f6e1 100644
--- a/gnome-flashback/libdesktop/gf-icon-view.c
+++ b/gnome-flashback/libdesktop/gf-icon-view.c
@@ -486,6 +486,25 @@ empty_trash_cb (GObject *object,
}
}
+static void
+rename_file_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error;
+
+ error = NULL;
+ gf_nautilus_gen_call_rename_file_finish (GF_NAUTILUS_GEN (object),
+ res, &error);
+
+ if (error != NULL)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Error renaming file: %s", error->message);
+ g_error_free (error);
+ }
+}
+
static GfIconInfo *
create_icon_info (GfIconView *self,
GtkWidget *icon)
@@ -683,28 +702,22 @@ desktop_changed_cb (GFileMonitor *monitor,
}
}
-static char *
+static void
create_folder_dialog_validate_cb (GfCreateFolderDialog *dialog,
const char *folder_name,
GfIconView *self)
{
- GList *l;
+ char *message;
+ gboolean valid;
- for (l = self->icons; l != NULL; l = l->next)
- {
- GfIconInfo *info;
- const char *name;
-
- info = l->data;
-
- name = gf_icon_get_name (GF_ICON (info->icon));
-
- if (g_strcmp0 (name, folder_name) == 0)
- return g_strdup (_("A folder with that name already exists."));
+ message = NULL;
+ valid = gf_icon_view_validate_new_name (self,
+ G_FILE_TYPE_DIRECTORY,
+ folder_name,
+ &message);
- }
-
- return NULL;
+ gf_create_folder_dialog_set_valid (dialog, valid, message);
+ g_free (message);
}
static void
@@ -2310,3 +2323,88 @@ gf_icon_view_empty_trash (GfIconView *self)
empty_trash_cb,
NULL);
}
+
+gboolean
+gf_icon_view_validate_new_name (GfIconView *self,
+ GFileType file_type,
+ const char *new_name,
+ char **message)
+{
+ gboolean is_dir;
+ char *text;
+ gboolean valid;
+ GList *l;
+
+ g_assert (message != NULL && *message == NULL);
+
+ is_dir = file_type == G_FILE_TYPE_DIRECTORY;
+ text = g_strstrip (g_strdup (new_name));
+ valid = TRUE;
+
+ if (*text == '\0')
+ {
+ valid = FALSE;
+ }
+ else if (g_strstr_len (text, -1, "/") != NULL)
+ {
+ valid = FALSE;
+ *message = g_strdup_printf (_("%s names cannot contain “/”."),
+ is_dir ? "Folder" : "File");
+ }
+ else if (g_strcmp0 (text, ".") == 0)
+ {
+ valid = FALSE;
+ *message = g_strdup_printf (_("A %s cannot be called “.”."),
+ is_dir ? "folder" : "file");
+ }
+ else if (g_strcmp0 (text, "..") == 0)
+ {
+ valid = FALSE;
+ *message = g_strdup_printf (_("A %s cannot be called “..”."),
+ is_dir ? "folder" : "file");
+ }
+
+ for (l = self->icons; l != NULL; l = l->next)
+ {
+ GfIconInfo *info;
+ const char *name;
+
+ info = l->data;
+
+ name = gf_icon_get_name (GF_ICON (info->icon));
+ if (g_strcmp0 (name, text) == 0)
+ {
+ valid = FALSE;
+ *message = g_strdup_printf (_("A %s with that name already exists."),
+ is_dir ? "folder" : "file");
+ break;
+ }
+ }
+
+ if (*message == NULL &&
+ g_str_has_prefix (text, "."))
+ {
+ *message = g_strdup_printf (_("%s with “.” at the beginning of their name are hidden."),
+ is_dir ? "Folders" : "Files");
+ }
+
+ g_free (text);
+
+ return valid;
+}
+
+void
+gf_icon_view_rename_file (GfIconView *self,
+ const char *uri,
+ const char *new_name)
+{
+ if (self->nautilus == NULL)
+ return;
+
+ gf_nautilus_gen_call_rename_file (self->nautilus,
+ uri,
+ new_name,
+ self->cancellable,
+ rename_file_cb,
+ NULL);
+}
diff --git a/gnome-flashback/libdesktop/gf-icon-view.h b/gnome-flashback/libdesktop/gf-icon-view.h
index b72a32e..b75bd9d 100644
--- a/gnome-flashback/libdesktop/gf-icon-view.h
+++ b/gnome-flashback/libdesktop/gf-icon-view.h
@@ -27,19 +27,28 @@ G_DECLARE_FINAL_TYPE (GfIconView, gf_icon_view, GF, ICON_VIEW, GtkEventBox)
GtkWidget *gf_icon_view_new (void);
-char *gf_icon_view_get_file_attributes (GfIconView *self);
+char *gf_icon_view_get_file_attributes (GfIconView *self);
-void gf_icon_view_set_representative_color (GfIconView *self,
- GdkRGBA *color);
+void gf_icon_view_set_representative_color (GfIconView *self,
+ GdkRGBA *color);
-void gf_icon_view_clear_selection (GfIconView *self);
+void gf_icon_view_clear_selection (GfIconView *self);
-GList *gf_icon_view_get_selected_icons (GfIconView *self);
+GList *gf_icon_view_get_selected_icons (GfIconView *self);
-void gf_icon_view_show_item_properties (GfIconView *self,
- const char * const *uris);
+void gf_icon_view_show_item_properties (GfIconView *self,
+ const char * const *uris);
-void gf_icon_view_empty_trash (GfIconView *self);
+void gf_icon_view_empty_trash (GfIconView *self);
+
+gboolean gf_icon_view_validate_new_name (GfIconView *self,
+ GFileType file_type,
+ const char *new_name,
+ char **message);
+
+void gf_icon_view_rename_file (GfIconView *self,
+ const char *uri,
+ const char *new_name);
G_END_DECLS
diff --git a/gnome-flashback/libdesktop/gf-icon.c b/gnome-flashback/libdesktop/gf-icon.c
index 41463ef..24ae67a 100644
--- a/gnome-flashback/libdesktop/gf-icon.c
+++ b/gnome-flashback/libdesktop/gf-icon.c
@@ -23,6 +23,7 @@
#include "gf-desktop-enums.h"
#include "gf-desktop-enum-types.h"
+#include "gf-rename-popover.h"
#include "gf-trash-icon.h"
#include "gf-utils.h"
@@ -48,7 +49,10 @@ typedef struct
GDesktopAppInfo *app_info;
+ char *name;
char *name_collated;
+
+ GtkWidget *popover;
} GfIconPrivate;
enum
@@ -127,6 +131,74 @@ icon_open (GfIcon *self)
g_free (uri);
}
+static void
+rename_validate_cb (GfRenamePopover *popover,
+ const char *new_name,
+ GfIcon *self)
+{
+ GfIconPrivate *priv;
+ char *message;
+ gboolean valid;
+
+ priv = gf_icon_get_instance_private (self);
+
+ if (g_strcmp0 (new_name, gf_icon_get_name (self)) == 0)
+ {
+ gf_rename_popover_set_valid (popover, TRUE, "");
+ return;
+ }
+
+ message = NULL;
+ valid = gf_icon_view_validate_new_name (priv->icon_view,
+ gf_icon_get_file_type (self),
+ new_name,
+ &message);
+
+ gf_rename_popover_set_valid (popover, valid, message);
+ g_free (message);
+}
+
+static void
+rename_do_rename_cb (GfRenamePopover *popover,
+ GfIcon *self)
+{
+ GfIconPrivate *priv;
+ char *new_name;
+
+ priv = gf_icon_get_instance_private (self);
+ new_name = gf_rename_popover_get_name (popover);
+
+ if (g_strcmp0 (new_name, priv->name) != 0)
+ {
+ char *uri;
+
+ uri = g_file_get_uri (priv->file);
+ gf_icon_view_rename_file (priv->icon_view, uri, new_name);
+ g_free (uri);
+ }
+
+ gtk_popover_popdown (GTK_POPOVER (popover));
+ g_free (new_name);
+}
+
+static void
+rename_closed_cb (GtkPopover *popover,
+ GfIcon *self)
+{
+ gtk_widget_destroy (GTK_WIDGET (popover));
+}
+
+static void
+rename_destroy_cb (GtkWidget *widget,
+ GfIcon *self)
+{
+ GfIconPrivate *priv;
+
+ priv = gf_icon_get_instance_private (self);
+
+ priv->popover = NULL;
+}
+
static void
open_cb (GtkMenuItem *item,
GfIcon *self)
@@ -134,6 +206,38 @@ open_cb (GtkMenuItem *item,
icon_open (self);
}
+static void
+rename_cb (GtkMenuItem *item,
+ GfIcon *self)
+{
+ GfIconPrivate *priv;
+
+ priv = gf_icon_get_instance_private (self);
+
+ g_assert (priv->popover == NULL);
+ priv->popover = gf_rename_popover_new (GTK_WIDGET (self),
+ gf_icon_get_file_type (self),
+ gf_icon_get_name (self));
+
+ g_signal_connect (priv->popover, "validate",
+ G_CALLBACK (rename_validate_cb),
+ self);
+
+ g_signal_connect (priv->popover, "do-rename",
+ G_CALLBACK (rename_do_rename_cb),
+ self);
+
+ g_signal_connect (priv->popover, "closed",
+ G_CALLBACK (rename_closed_cb),
+ self);
+
+ g_signal_connect (priv->popover, "destroy",
+ G_CALLBACK (rename_destroy_cb),
+ self);
+
+ gtk_popover_popup (GTK_POPOVER (priv->popover));
+}
+
static void
empty_trash_cb (GtkMenuItem *item,
GfIcon *self)
@@ -216,6 +320,21 @@ create_popup_menu (GfIcon *self)
G_CALLBACK (open_cb),
self);
+ if (GF_ICON_GET_CLASS (self)->can_rename (GF_ICON (self)))
+ {
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
+ gtk_widget_show (item);
+
+ item = gtk_menu_item_new_with_label (_("Rename..."));
+ gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item);
+ gtk_widget_show (item);
+
+ g_signal_connect (item, "activate",
+ G_CALLBACK (rename_cb),
+ self);
+ }
+
if (GF_IS_TRASH_ICON (self) &&
n_selected_icons == 1)
{
@@ -373,6 +492,7 @@ update_text (GfIcon *self)
if (name == NULL)
name = g_file_info_get_display_name (priv->info);
+ priv->name = g_strdup (name);
gtk_label_set_text (GTK_LABEL (priv->label), name);
g_clear_pointer (&priv->name_collated, g_free);
@@ -473,8 +593,12 @@ gf_icon_finalize (GObject *object)
priv = gf_icon_get_instance_private (self);
g_clear_pointer (&priv->css_class, g_free);
+
+ g_clear_pointer (&priv->name, g_free);
g_clear_pointer (&priv->name_collated, g_free);
+ g_clear_pointer (&priv->popover, gtk_widget_destroy);
+
G_OBJECT_CLASS (gf_icon_parent_class)->finalize (object);
}
@@ -570,6 +694,12 @@ gf_icon_get_preferred_width (GtkWidget *widget,
*natural_width += priv->extra_text_width;
}
+static gboolean
+gf_icon_can_rename (GfIcon *self)
+{
+ return TRUE;
+}
+
static void
install_properties (GObjectClass *object_class)
{
@@ -650,6 +780,8 @@ gf_icon_class_init (GfIconClass *self_class)
widget_class->get_preferred_width = gf_icon_get_preferred_width;
+ self_class->can_rename = gf_icon_can_rename;
+
install_properties (object_class);
install_signals ();
@@ -728,6 +860,8 @@ gf_icon_set_file (GfIcon *self,
priv = gf_icon_get_instance_private (self);
+ g_clear_pointer (&priv->popover, gtk_widget_destroy);
+
g_clear_object (&priv->file);
priv->file = g_object_ref (file);
diff --git a/gnome-flashback/libdesktop/gf-icon.h b/gnome-flashback/libdesktop/gf-icon.h
index 5c446c2..c416740 100644
--- a/gnome-flashback/libdesktop/gf-icon.h
+++ b/gnome-flashback/libdesktop/gf-icon.h
@@ -28,6 +28,8 @@ G_DECLARE_DERIVABLE_TYPE (GfIcon, gf_icon, GF, ICON, GtkButton)
struct _GfIconClass
{
GtkButtonClass parent_class;
+
+ gboolean (* can_rename) (GfIcon *self);
};
GtkWidget *gf_icon_new (GfIconView *icon_view,
diff --git a/gnome-flashback/libdesktop/gf-rename-popover.c b/gnome-flashback/libdesktop/gf-rename-popover.c
new file mode 100644
index 0000000..408c977
--- /dev/null
+++ b/gnome-flashback/libdesktop/gf-rename-popover.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2019 Alberts Muktupāvels
+ *
+ * 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 3 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/>.
+ */
+
+#include "config.h"
+#include "gf-rename-popover.h"
+
+#include <glib/gi18n.h>
+
+struct _GfRenamePopover
+{
+ GtkPopover parent;
+
+ GFileType file_type;
+ char *name;
+
+ GtkWidget *title_label;
+
+ GtkWidget *rename_button;
+
+ GtkWidget *name_entry;
+
+ GtkWidget *error_revealer;
+ GtkWidget *error_label;
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_FILE_TYPE,
+ PROP_NAME,
+
+ LAST_PROP
+};
+
+static GParamSpec *popover_properties[LAST_PROP] = { NULL };
+
+enum
+{
+ VALIDATE,
+
+ DO_RENAME,
+
+ LAST_SIGNAL
+};
+
+static guint popover_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GfRenamePopover, gf_rename_popover, GTK_TYPE_POPOVER)
+
+static void
+validate (GfRenamePopover *self)
+{
+ const char *text;
+
+ text = gtk_entry_get_text (GTK_ENTRY (self->name_entry));
+ g_signal_emit (self, popover_signals[VALIDATE], 0, text);
+}
+
+static void
+name_changed_cb (GtkEditable *editable,
+ GfRenamePopover *self)
+{
+ validate (self);
+}
+
+static void
+name_activate_cb (GtkWidget *widget,
+ GfRenamePopover *self)
+{
+ validate (self);
+
+ if (!gtk_widget_get_sensitive (self->rename_button))
+ return;
+
+ g_signal_emit (self, popover_signals[DO_RENAME], 0);
+}
+
+static void
+rename_clicked_cb (GtkWidget *widget,
+ GfRenamePopover *self)
+{
+ validate (self);
+
+ if (!gtk_widget_get_sensitive (self->rename_button))
+ return;
+
+ g_signal_emit (self, popover_signals[DO_RENAME], 0);
+}
+
+static void
+gf_rename_popover_constructed (GObject *object)
+{
+ GfRenamePopover *self;
+ gboolean is_dir;
+ const char *title;
+
+ self = GF_RENAME_POPOVER (object);
+
+ G_OBJECT_CLASS (gf_rename_popover_parent_class)->constructed (object);
+
+ is_dir = self->file_type == G_FILE_TYPE_DIRECTORY;
+ title = is_dir ? _("Folder name") : _("File name");
+
+ gtk_label_set_text (GTK_LABEL (self->title_label), title);
+ gtk_entry_set_text (GTK_ENTRY (self->name_entry), self->name);
+
+ g_signal_connect (self->name_entry, "changed",
+ G_CALLBACK (name_changed_cb),
+ self);
+}
+
+static void
+gf_rename_popover_finalize (GObject *object)
+{
+ GfRenamePopover *self;
+
+ self = GF_RENAME_POPOVER (object);
+
+ g_clear_pointer (&self->name, g_free);
+
+ G_OBJECT_CLASS (gf_rename_popover_parent_class)->finalize (object);
+}
+
+static void
+gf_rename_popover_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GfRenamePopover *self;
+
+ self = GF_RENAME_POPOVER (object);
+
+ switch (property_id)
+ {
+ case PROP_FILE_TYPE:
+ self->file_type = g_value_get_enum (value);
+ break;
+
+ case PROP_NAME:
+ g_assert (self->name == NULL);
+ self->name = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+install_properties (GObjectClass *object_class)
+{
+ popover_properties[PROP_FILE_TYPE] =
+ g_param_spec_enum ("file-type",
+ "file-type",
+ "file-type",
+ G_TYPE_FILE_TYPE,
+ G_FILE_TYPE_UNKNOWN,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_WRITABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ popover_properties[PROP_NAME] =
+ g_param_spec_string ("name",
+ "name",
+ "name",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_WRITABLE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP,
+ popover_properties);
+}
+
+static void
+install_signals (void)
+{
+ popover_signals[VALIDATE] =
+ g_signal_new ("validate", GF_TYPE_RENAME_POPOVER,
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ popover_signals[DO_RENAME] =
+ g_signal_new ("do-rename", GF_TYPE_RENAME_POPOVER,
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gf_rename_popover_class_init (GfRenamePopoverClass *self_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (self_class);
+
+ object_class->constructed = gf_rename_popover_constructed;
+ object_class->finalize = gf_rename_popover_finalize;
+ object_class->set_property = gf_rename_popover_set_property;
+
+ install_properties (object_class);
+ install_signals ();
+}
+
+static void
+gf_rename_popover_init (GfRenamePopover *self)
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkStyleContext *style;
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ g_object_set (vbox, "margin", 10, NULL);
+ gtk_container_add (GTK_CONTAINER (self), vbox);
+ gtk_widget_show (vbox);
+
+ self->title_label = gtk_label_new (NULL);
+ gtk_label_set_xalign (GTK_LABEL (self->title_label), 0.0);
+ gtk_container_add (GTK_CONTAINER (vbox), self->title_label);
+ gtk_widget_show (self->title_label);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_container_add (GTK_CONTAINER (vbox), hbox);
+ gtk_widget_show (hbox);
+
+ self->name_entry = gtk_entry_new ();
+ gtk_container_add (GTK_CONTAINER (hbox), self->name_entry);
+ gtk_widget_show (self->name_entry);
+
+ g_signal_connect (self->name_entry, "activate",
+ G_CALLBACK (name_activate_cb),
+ self);
+
+ self->rename_button = gtk_button_new_with_label (_("Rename"));
+ gtk_container_add (GTK_CONTAINER (hbox), self->rename_button);
+ gtk_widget_show (self->rename_button);
+
+ style = gtk_widget_get_style_context (self->rename_button);
+ gtk_style_context_add_class (style, GTK_STYLE_CLASS_SUGGESTED_ACTION);
+
+ g_signal_connect (self->rename_button, "clicked",
+ G_CALLBACK (rename_clicked_cb),
+ self);
+
+ self->error_revealer = gtk_revealer_new ();
+ gtk_container_add (GTK_CONTAINER (vbox), self->error_revealer);
+ gtk_widget_show (self->error_revealer);
+
+ self->error_label = gtk_label_new (NULL);
+ gtk_label_set_xalign (GTK_LABEL (self->error_label), 0.0);
+ gtk_container_add (GTK_CONTAINER (self->error_revealer), self->error_label);
+ gtk_widget_show (self->error_label);
+}
+
+GtkWidget *
+gf_rename_popover_new (GtkWidget *relative_to,
+ GFileType file_type,
+ const char *name)
+{
+ return g_object_new (GF_TYPE_RENAME_POPOVER,
+ "relative-to", relative_to,
+ "file-type", file_type,
+ "name", name,
+ NULL);
+}
+
+void
+gf_rename_popover_set_valid (GfRenamePopover *self,
+ gboolean valid,
+ const char *message)
+{
+ GtkRevealer *revealer;
+
+ revealer = GTK_REVEALER (self->error_revealer);
+
+ gtk_label_set_text (GTK_LABEL (self->error_label), message);
+ gtk_revealer_set_reveal_child (revealer, message != NULL);
+
+ gtk_widget_set_sensitive (self->rename_button, valid);
+}
+
+char *
+gf_rename_popover_get_name (GfRenamePopover *self)
+{
+ const char *text;
+ char *name;
+
+ text = gtk_entry_get_text (GTK_ENTRY (self->name_entry));
+ name = g_strdup (text);
+
+ return g_strstrip (name);
+}
diff --git a/gnome-flashback/libdesktop/gf-rename-popover.h b/gnome-flashback/libdesktop/gf-rename-popover.h
new file mode 100644
index 0000000..b7c0e63
--- /dev/null
+++ b/gnome-flashback/libdesktop/gf-rename-popover.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Alberts Muktupāvels
+ *
+ * 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 3 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/>.
+ */
+
+#ifndef GF_RENAME_POPOVER_H
+#define GF_RENAME_POPOVER_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GF_TYPE_RENAME_POPOVER (gf_rename_popover_get_type ())
+G_DECLARE_FINAL_TYPE (GfRenamePopover, gf_rename_popover,
+ GF, RENAME_POPOVER, GtkPopover)
+
+GtkWidget *gf_rename_popover_new (GtkWidget *relative_to,
+ GFileType file_type,
+ const char *name);
+
+void gf_rename_popover_set_valid (GfRenamePopover *self,
+ gboolean valid,
+ const char *message);
+
+char *gf_rename_popover_get_name (GfRenamePopover *self);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/libdesktop/gf-trash-icon.c b/gnome-flashback/libdesktop/gf-trash-icon.c
index 55b8bf6..93a725c 100644
--- a/gnome-flashback/libdesktop/gf-trash-icon.c
+++ b/gnome-flashback/libdesktop/gf-trash-icon.c
@@ -186,15 +186,25 @@ gf_trash_icon_dispose (GObject *object)
G_OBJECT_CLASS (gf_trash_icon_parent_class)->dispose (object);
}
+static gboolean
+gf_trash_icon_can_rename (GfIcon *icon)
+{
+ return FALSE;
+}
+
static void
gf_trash_icon_class_init (GfTrashIconClass *self_class)
{
GObjectClass *object_class;
+ GfIconClass *icon_class;
object_class = G_OBJECT_CLASS (self_class);
+ icon_class = GF_ICON_CLASS (self_class);
object_class->constructed = gf_trash_icon_constructed;
object_class->dispose = gf_trash_icon_dispose;
+
+ icon_class->can_rename = gf_trash_icon_can_rename;
}
static void
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 70b8628..ddeb8e3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -25,6 +25,7 @@ gnome-flashback/libdesktop/gf-create-folder-dialog.c
gnome-flashback/libdesktop/gf-desktop-window.c
gnome-flashback/libdesktop/gf-icon.c
gnome-flashback/libdesktop/gf-icon-view.c
+gnome-flashback/libdesktop/gf-rename-popover.c
gnome-flashback/libend-session-dialog/gf-inhibit-dialog.c
gnome-flashback/libend-session-dialog/gf-inhibit-dialog.ui
gnome-flashback/libinput-sources/gf-input-sources.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]