diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index e2353d818a..73b8b9252d 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -463,6 +463,7 @@ gtk_private_h_sources = \
gtkfilechooserprivate.h \
gtkfilechoosernativeprivate.h \
gtkfilechooserwidgetprivate.h \
+ gtkfilechoosererrorstackprivate.h \
gtkfilechooserutils.h \
gtkfilefilterprivate.h \
gtkfilesystem.h \
@@ -943,7 +944,8 @@ gtk_base_c_sources = \
gtkwin32theme.c \
gdkpixbufutils.c \
gtkgizmo.c \
- gtkcenterbox.c
+ gtkcenterbox.c \
+ gtkfilechoosererrorstack.c
if USE_QUARTZ
gtk_base_c_sources += \
diff --git a/gtk/gtkfilechoosererrorstack.c b/gtk/gtkfilechoosererrorstack.c
new file mode 100644
index 0000000000..03d9c0c768
--- /dev/null
+++ b/gtk/gtkfilechoosererrorstack.c
@@ -0,0 +1,136 @@
+/* This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ */
+#include "config.h"
+#include "gtkfilechoosererrorstackprivate.h"
+#include "gtkstack.h"
+#include "gtklabel.h"
+#include "gtkintl.h"
+
+G_DEFINE_TYPE (GtkFileChooserErrorStack, gtk_file_chooser_error_stack, GTK_TYPE_STACK)
+
+static void
+gtk_file_chooser_error_stack_class_init (GtkFileChooserErrorStackClass *class)
+{
+
+}
+
+static void
+gtk_file_chooser_error_stack_init (GtkFileChooserErrorStack *self)
+{
+ GtkWidget *label;
+ GtkStack *stack = GTK_STACK (self);
+
+ gtk_stack_set_transition_type (stack, GTK_STACK_TRANSITION_TYPE_CROSSFADE);
+ gtk_stack_set_transition_duration (stack, 50);
+
+ label = gtk_label_new ("");
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "no-error");
+
+ label = gtk_label_new ("");
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "custom");
+
+ label = gtk_label_new (_("A folder cannot be called “.”"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "folder-cannot-be-called-dot");
+
+ label = gtk_label_new (_("A file cannot be called “.”"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "file-cannot-be-called-dot");
+
+ label = gtk_label_new (_("A folder cannot be called “..”"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "folder-cannot-be-called-dot-dot");
+
+ label = gtk_label_new (_("A file cannot be called “..”"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "file-cannot-be-called-dot-dot");
+
+ label = gtk_label_new (_("Folder names cannot contain “/”"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "folder-name-cannot-contain-slash");
+
+ label = gtk_label_new (_("File names cannot contain “/”"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "file-name-cannot-contain-slash");
+
+ label = gtk_label_new (_("Folder names should not begin with a space"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "folder-name-should-not-begin-with-space");
+
+ label = gtk_label_new (_("File names should not begin with a space"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "file-name-should-not-begin-with-space");
+
+ label = gtk_label_new (_("Folder names should not end with a space"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "folder-name-should-not-end-with-space");
+
+ label = gtk_label_new (_("File names should not end with a space"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "file-name-should-not-end-with-space");
+
+ label = gtk_label_new (_("Folder names starting with a “.” are hidden"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "folder-name-with-dot-is-hidden");
+
+ label = gtk_label_new (_("File names starting with a “.” are hidden"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "file-name-with-dot-is-hidden");
+
+ label = gtk_label_new (_("A folder with that name already exists"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "folder-name-already-exists");
+
+ label = gtk_label_new (_("A file with that name already exists"));
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_stack_add_named (stack, label, "file-name-already-exists");
+
+ gtk_stack_set_visible_child_name (stack, "no-error");
+}
+
+void
+gtk_file_chooser_error_stack_set_error (GtkFileChooserErrorStack *self,
+ gboolean is_folder,
+ const char *label_name)
+{
+ char *child_name;
+
+ if (g_strcmp0 (label_name, "no-error") == 0)
+ {
+ gtk_stack_set_visible_child_name (GTK_STACK (self), "no-error");
+ return;
+ }
+
+ child_name = g_strdup_printf ("%s-%s",
+ is_folder ? "folder" : "file",
+ label_name);
+
+ gtk_stack_set_visible_child_name (GTK_STACK (self), child_name);
+
+ g_free (child_name);
+}
+
+
+void
+gtk_file_chooser_error_stack_set_custom_error (GtkFileChooserErrorStack *self,
+ const char *label_text)
+{
+ GtkWidget *label = gtk_stack_get_child_by_name (GTK_STACK (self), "cutsom");
+
+ gtk_label_set_text (GTK_LABEL (label), label_text);
+
+ gtk_stack_set_visible_child_name (GTK_STACK (self), "custom");
+}
diff --git a/gtk/gtkfilechoosererrorstackprivate.h b/gtk/gtkfilechoosererrorstackprivate.h
new file mode 100644
index 0000000000..7f222c65f8
--- /dev/null
+++ b/gtk/gtkfilechoosererrorstackprivate.h
@@ -0,0 +1,58 @@
+/* This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ */
+
+#ifndef __GTK_FILE_CHOOSER_ERROR_STACK_H__
+#define __GTK_FILE_CHOOSER_ERROR_STACK_H__
+
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include "gtkstack.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_FILE_CHOOSER_ERROR_STACK (gtk_file_chooser_error_stack_get_type ())
+#define GTK_FILE_CHOOSER_ERROR_STACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER_ERROR_STACK, GtkFileChooserErrorStack))
+#define GTK_FILE_CHOOSER_ERROR_STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_CHOOSER_ERROR_STACK, GtkFileChooserErrorStackClass))
+#define GTK_IS_FILE_CHOOSER_ERROR_STACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_CHOOSER_ERROR_STACK))
+#define GTK_IS_FILE_CHOOSER_ERROR_STACK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_CHOOSER_ERROR_STACK))
+#define GTK_FILE_CHOOSER_ERROR_STACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_ERROR_STACK, GtkFileChooserErrorStackClass))
+
+typedef struct _GtkFileChooserErrorStack GtkFileChooserErrorStack;
+typedef struct _GtkFileChooserErrorStackClass GtkFileChooserErrorStackClass;
+
+struct _GtkFileChooserErrorStack
+{
+ GtkStack parent_instance;
+};
+
+struct _GtkFileChooserErrorStackClass
+{
+ GtkStackClass parent_class;
+};
+
+GType gtk_file_chooser_error_stack_get_type (void) G_GNUC_CONST;
+
+void gtk_file_chooser_error_stack_set_error (GtkFileChooserErrorStack *self,
+ gboolean is_folder,
+ const char *label_name);
+
+void gtk_file_chooser_error_stack_set_custom_error (GtkFileChooserErrorStack *self,
+ const char *label_text);
+
+G_END_DECLS
+
+#endif
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index ec51668609..08c96bb1db 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -81,6 +81,7 @@
#include "gtkmodelbutton.h"
#include "gtkgesturelongpress.h"
#include "gtkdebug.h"
+#include "gtkfilechoosererrorstackprivate.h"
#include
@@ -248,11 +249,11 @@ struct _GtkFileChooserWidgetPrivate {
GtkWidget *browse_path_bar;
GtkWidget *new_folder_name_entry;
GtkWidget *new_folder_create_button;
- GtkWidget *new_folder_error_label;
+ GtkWidget *new_folder_error_stack;
GtkWidget *new_folder_popover;
GtkWidget *rename_file_name_entry;
GtkWidget *rename_file_rename_button;
- GtkWidget *rename_file_error_label;
+ GtkWidget *rename_file_error_stack;
GtkWidget *rename_file_popover;
GFile *rename_file_source_file;
@@ -985,7 +986,9 @@ new_folder_popover_active (GtkWidget *button,
gtk_entry_set_text (GTK_ENTRY (priv->new_folder_name_entry), "");
gtk_widget_set_sensitive (priv->new_folder_create_button, FALSE);
- gtk_label_set_text (GTK_LABEL (priv->new_folder_error_label), "");
+ gtk_file_chooser_error_stack_set_error (GTK_FILE_CHOOSER_ERROR_STACK (priv->new_folder_error_stack),
+ FALSE,
+ "no-error");
}
struct FileExistsData
@@ -994,7 +997,7 @@ struct FileExistsData
gboolean file_exists_and_is_not_folder;
GFile *parent_file;
GFile *file;
- GtkWidget *error_label;
+ GtkWidget *error_stack;
GtkWidget *button;
};
@@ -1018,15 +1021,10 @@ name_exists_get_info_cb (GCancellable *cancellable,
if (info != NULL)
{
- const gchar *msg;
-
- if (_gtk_file_info_consider_as_directory (info))
- msg = _("A folder with that name already exists");
- else
- msg = _("A file with that name already exists");
-
gtk_widget_set_sensitive (data->button, FALSE);
- gtk_label_set_text (GTK_LABEL (data->error_label), msg);
+ gtk_file_chooser_error_stack_set_error (GTK_FILE_CHOOSER_ERROR_STACK (data->error_stack),
+ _gtk_file_info_consider_as_directory (info),
+ "name-already-exists");
}
else
{
@@ -1047,38 +1045,31 @@ check_valid_child_name (GtkFileChooserWidget *impl,
const gchar *name,
gboolean is_folder,
GFile *original,
- GtkWidget *error_label,
+ GtkWidget *error_stack,
GtkWidget *button)
{
GtkFileChooserWidgetPrivate *priv = impl->priv;
+ GtkFileChooserErrorStack *stack = GTK_FILE_CHOOSER_ERROR_STACK (error_stack);
gtk_widget_set_sensitive (button, FALSE);
if (name[0] == '\0')
- gtk_label_set_text (GTK_LABEL (error_label), "");
+ gtk_file_chooser_error_stack_set_error (stack, FALSE, "no-error");
else if (strcmp (name, ".") == 0)
- gtk_label_set_text (GTK_LABEL (error_label),
- is_folder ? _("A folder cannot be called “.”")
- : _("A file cannot be called “.”"));
+ gtk_file_chooser_error_stack_set_error (stack, is_folder, "cannot-be-called-dot");
else if (strcmp (name, "..") == 0)
- gtk_label_set_text (GTK_LABEL (error_label),
- is_folder ? _("A folder cannot be called “..”")
- : _("A file cannot be called “..”"));
+ gtk_file_chooser_error_stack_set_error (stack, is_folder, "cannot-be-called-dot-dot");
else if (strchr (name, '/') != NULL)
- gtk_label_set_text (GTK_LABEL (error_label),
- is_folder ? _("Folder names cannot contain “/”")
- : _("File names cannot contain “/”"));
+ gtk_file_chooser_error_stack_set_error (stack, is_folder, "name-cannot-contain-slash");
else
{
GFile *file;
GError *error = NULL;
- gtk_label_set_text (GTK_LABEL (error_label), "");
-
file = g_file_get_child_for_display_name (parent, name, &error);
if (file == NULL)
{
- gtk_label_set_text (GTK_LABEL (error_label), error->message);
+ gtk_file_chooser_error_stack_set_custom_error (stack, error->message);
g_error_free (error);
}
else if (original && g_file_equal (original, file))
@@ -1092,23 +1083,18 @@ check_valid_child_name (GtkFileChooserWidget *impl,
/* Warn the user about questionable names that are technically valid */
if (g_ascii_isspace (name[0]))
- gtk_label_set_text (GTK_LABEL (error_label),
- is_folder ? _("Folder names should not begin with a space")
- : _("File names should not begin with a space"));
-
+ gtk_file_chooser_error_stack_set_error (stack, is_folder, "name-should-not-begin-with-space");
else if (g_ascii_isspace (name[strlen (name) - 1]))
- gtk_label_set_text (GTK_LABEL (error_label),
- is_folder ? _("Folder names should not end with a space")
- : _("File names should not end with a space"));
+ gtk_file_chooser_error_stack_set_error (stack, is_folder, "name-should-not-end-with-space");
else if (name[0] == '.')
- gtk_label_set_text (GTK_LABEL (error_label),
- is_folder ? _("Folder names starting with a “.” are hidden")
- : _("File names starting with a “.” are hidden"));
+ gtk_file_chooser_error_stack_set_error (stack, is_folder, "name-with-dot-is-hidden");
+ else
+ gtk_file_chooser_error_stack_set_error (stack, FALSE, "no-error");
data = g_new0 (struct FileExistsData, 1);
data->impl = g_object_ref (impl);
data->file = g_object_ref (file);
- data->error_label = error_label;
+ data->error_stack = error_stack;
data->button = button;
if (priv->file_exists_get_info_cancellable)
@@ -1137,7 +1123,7 @@ new_folder_name_changed (GtkEntry *entry,
gtk_entry_get_text (entry),
TRUE,
NULL,
- priv->new_folder_error_label,
+ priv->new_folder_error_stack,
priv->new_folder_create_button);
}
@@ -1570,7 +1556,7 @@ rename_file_name_changed (GtkEntry *entry,
gtk_entry_get_text (entry),
file_type == G_FILE_TYPE_DIRECTORY,
priv->rename_file_source_file,
- priv->rename_file_error_label,
+ priv->rename_file_error_stack,
priv->rename_file_rename_button);
}
@@ -8499,11 +8485,11 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_location_renderer);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_name_entry);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_create_button);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_error_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_error_stack);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_popover);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_name_entry);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_rename_button);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_error_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_error_stack);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_popover);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, remote_warning_bar);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, box);
@@ -8661,6 +8647,7 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
*/
g_type_ensure (GTK_TYPE_PATH_BAR);
g_type_ensure (GTK_TYPE_PLACES_VIEW);
+ g_type_ensure (GTK_TYPE_FILE_CHOOSER_ERROR_STACK);
gtk_widget_init_template (GTK_WIDGET (impl));
gtk_widget_set_size_request (priv->browse_files_tree_view, 280, -1);
diff --git a/gtk/ui/gtkfilechooserwidget.ui b/gtk/ui/gtkfilechooserwidget.ui
index 40e688ba28..bf678809dc 100644
--- a/gtk/ui/gtkfilechooserwidget.ui
+++ b/gtk/ui/gtkfilechooserwidget.ui
@@ -427,8 +427,7 @@
-
-
- start
+
0