[evolution/wip/webkit2] Visualize incorrect values in account/source editors



commit ff6e361e501c62787332d9abc1e99084fdcfb58f
Author: Milan Crha <mcrha redhat com>
Date:   Wed Mar 2 19:14:04 2016 +0100

    Visualize incorrect values in account/source editors

 .../evolution-util/evolution-util-sections.txt     |    1 +
 e-util/e-misc-utils.c                              |   29 +++++++++
 e-util/e-misc-utils.h                              |    2 +
 e-util/e-source-config.c                           |   16 +++--
 e-util/e-source-config.h                           |    2 +-
 mail/e-mail-config-identity-page.c                 |   67 +++++++++++++++----
 mail/e-mail-config-summary-page.c                  |    3 +
 .../evolution-book-config-google.c                 |   15 ++++-
 .../book-config-ldap/evolution-book-config-ldap.c  |   43 +++++++++++--
 .../evolution-book-config-webdav.c                 |    2 +
 .../evolution-cal-config-caldav.c                  |    2 +
 modules/cal-config-google/e-cal-config-google.c    |   15 ++++-
 modules/cal-config-google/e-cal-config-gtasks.c    |   34 +++++++++-
 .../evolution-cal-config-weather.c                 |   11 +++-
 .../evolution-cal-config-webcal.c                  |    2 +
 modules/mail-config/e-mail-config-local-accounts.c |   29 ++++++++-
 .../mail-config/e-mail-config-remote-accounts.c    |   36 +++++++++--
 .../mail-config/e-mail-config-sendmail-backend.c   |   16 +++++
 modules/mail-config/e-mail-config-smtp-backend.c   |   36 ++++++++---
 po/POTFILES.in                                     |    1 +
 20 files changed, 313 insertions(+), 49 deletions(-)
---
diff --git a/doc/reference/evolution-util/evolution-util-sections.txt 
b/doc/reference/evolution-util/evolution-util-sections.txt
index 11116d2..0ab4883 100644
--- a/doc/reference/evolution-util/evolution-util-sections.txt
+++ b/doc/reference/evolution-util/evolution-util-sections.txt
@@ -3228,6 +3228,7 @@ e_file_lock_exists
 e_util_guess_mime_type
 e_util_get_category_filter_options
 e_util_dup_searchable_categories
+e_util_set_entry_issue_hint
 e_binding_transform_color_to_string
 e_binding_transform_string_to_color
 e_binding_transform_source_to_uid
diff --git a/e-util/e-misc-utils.c b/e-util/e-misc-utils.c
index d6b3a05..e9bbcfe 100644
--- a/e-util/e-misc-utils.c
+++ b/e-util/e-misc-utils.c
@@ -3297,3 +3297,32 @@ e_util_is_running_gnome (void)
        return runs_gnome != 0;
 #endif
 }
+
+/**
+ * e_util_set_entry_issue_hint:
+ * @entry: a #GtkEntry
+ * @hint: (allow none): a hint to set, or %NULL to unset
+ *
+ * Sets a @hint on the secondary @entry icon about an entered value issue,
+ * or unsets it, when the @hint is %NULL.
+ *
+ * Since: 3.20
+ **/
+void
+e_util_set_entry_issue_hint (GtkWidget *entry,
+                            const gchar *hint)
+{
+       GtkEntry *eentry;
+
+       g_return_if_fail (GTK_IS_ENTRY (entry));
+
+       eentry = GTK_ENTRY (entry);
+
+       if (hint) {
+               gtk_entry_set_icon_from_icon_name (eentry, GTK_ENTRY_ICON_SECONDARY, "dialog-warning");
+               gtk_entry_set_icon_tooltip_text (eentry, GTK_ENTRY_ICON_SECONDARY, hint);
+       } else {
+               gtk_entry_set_icon_from_icon_name (eentry, GTK_ENTRY_ICON_SECONDARY, NULL);
+               gtk_entry_set_icon_tooltip_text (eentry, GTK_ENTRY_ICON_SECONDARY, NULL);
+       }
+}
diff --git a/e-util/e-misc-utils.h b/e-util/e-misc-utils.h
index f40a4c1..931fa37 100644
--- a/e-util/e-misc-utils.h
+++ b/e-util/e-misc-utils.h
@@ -282,6 +282,8 @@ void                e_util_run_simple_async_result_in_thread
                                                 GSimpleAsyncThreadFunc func,
                                                 GCancellable *cancellable);
 gboolean       e_util_is_running_gnome         (void);
+void           e_util_set_entry_issue_hint     (GtkWidget *entry,
+                                                const gchar *hint);
 
 guint          e_util_normalize_font_size      (GtkWidget *widget,
                                                 gdouble font_size);
diff --git a/e-util/e-source-config.c b/e-util/e-source-config.c
index 8802283..4182164 100644
--- a/e-util/e-source-config.c
+++ b/e-util/e-source-config.c
@@ -798,6 +798,7 @@ source_config_check_complete (ESourceConfig *config,
        GtkEntry *name_entry;
        GtkComboBox *type_combo;
        const gchar *text;
+       gboolean correct;
 
        /* Make sure the Type: combo box has a valid item. */
        type_combo = GTK_COMBO_BOX (config->priv->type_combo);
@@ -807,10 +808,11 @@ source_config_check_complete (ESourceConfig *config,
        /* Make sure the Name: entry field is not empty. */
        name_entry = GTK_ENTRY (config->priv->name_entry);
        text = gtk_entry_get_text (name_entry);
-       if (text == NULL || *text == '\0')
-               return FALSE;
+       correct = text != NULL && *text != '\0';
 
-       return TRUE;
+       e_util_set_entry_issue_hint (config->priv->name_entry, correct ? NULL : _("Name cannot be empty"));
+
+       return correct;
 }
 
 static void
@@ -1451,7 +1453,7 @@ e_source_config_add_secure_connection_for_webdav (ESourceConfig *config,
                G_CALLBACK (webdav_unset_ssl_trust_clicked_cb), extension);
 }
 
-void
+GtkWidget *
 e_source_config_add_user_entry (ESourceConfig *config,
                                 ESource *scratch_source)
 {
@@ -1460,8 +1462,8 @@ e_source_config_add_user_entry (ESourceConfig *config,
        ESourceExtension *extension;
        const gchar *extension_name;
 
-       g_return_if_fail (E_IS_SOURCE_CONFIG (config));
-       g_return_if_fail (E_IS_SOURCE (scratch_source));
+       g_return_val_if_fail (E_IS_SOURCE_CONFIG (config), NULL);
+       g_return_val_if_fail (E_IS_SOURCE (scratch_source), NULL);
 
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
        extension = e_source_get_extension (scratch_source, extension_name);
@@ -1483,5 +1485,7 @@ e_source_config_add_user_entry (ESourceConfig *config,
         * GtkEntry to the user name of the current user. */
        if (original_source == NULL)
                gtk_entry_set_text (GTK_ENTRY (widget), g_get_user_name ());
+
+       return widget;
 }
 
diff --git a/e-util/e-source-config.h b/e-util/e-source-config.h
index 26eb064..93bb4e1 100644
--- a/e-util/e-source-config.h
+++ b/e-util/e-source-config.h
@@ -113,7 +113,7 @@ void                e_source_config_add_secure_connection
 void           e_source_config_add_secure_connection_for_webdav
                                                (ESourceConfig *config,
                                                 ESource *scratch_source);
-void           e_source_config_add_user_entry  (ESourceConfig *config,
+GtkWidget *    e_source_config_add_user_entry  (ESourceConfig *config,
                                                 ESource *scratch_source);
 
 #endif /* E_SOURCE_CONFIG_H */
diff --git a/mail/e-mail-config-identity-page.c b/mail/e-mail-config-identity-page.c
index ed44d48..96c6d93 100644
--- a/mail/e-mail-config-identity-page.c
+++ b/mail/e-mail-config-identity-page.c
@@ -36,7 +36,11 @@ struct _EMailConfigIdentityPagePrivate {
        gboolean show_instructions;
        gboolean show_signatures;
        gboolean show_autodiscover_check;
-       GtkWidget *autodiscover_check; /* not referenced */
+       GtkWidget *autodiscover_check;  /* not referenced */
+       GtkWidget *display_name_entry;  /* not referenced */
+       GtkWidget *name_entry;          /* not referenced */
+       GtkWidget *address_entry;       /* not referenced */
+       GtkWidget *reply_to_entry;      /* not referenced */
 };
 
 enum {
@@ -332,6 +336,8 @@ mail_config_identity_page_constructed (GObject *object)
        gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
        gtk_widget_show (widget);
 
+       page->priv->display_name_entry = widget;
+
        e_binding_bind_object_text_property (
                source, "display-name",
                widget, "text",
@@ -385,6 +391,8 @@ mail_config_identity_page_constructed (GObject *object)
        gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
        gtk_widget_show (widget);
 
+       page->priv->name_entry = widget;
+
        e_binding_bind_object_text_property (
                extension, "name",
                widget, "text",
@@ -417,6 +425,8 @@ mail_config_identity_page_constructed (GObject *object)
        gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
        gtk_widget_show (widget);
 
+       page->priv->address_entry = widget;
+
        e_binding_bind_object_text_property (
                extension, "address",
                widget, "text",
@@ -468,6 +478,8 @@ mail_config_identity_page_constructed (GObject *object)
        gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 2, 1);
        gtk_widget_show (widget);
 
+       page->priv->reply_to_entry = widget;
+
        e_binding_bind_object_text_property (
                extension, "reply-to",
                widget, "text",
@@ -580,6 +592,7 @@ mail_config_identity_page_check_complete (EMailConfigPage *page)
        const gchar *address;
        const gchar *reply_to;
        const gchar *display_name;
+       gboolean correct, complete = TRUE;
 
        id_page = E_MAIL_CONFIG_IDENTITY_PAGE (page);
        extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
@@ -592,28 +605,54 @@ mail_config_identity_page_check_complete (EMailConfigPage *page)
 
        display_name = e_source_get_display_name (source);
 
-       if (name == NULL)
-               return FALSE;
+       correct = name != NULL;
+       complete = complete && correct;
+
+       e_util_set_entry_issue_hint (id_page->priv->name_entry, correct ? NULL : _("Full Name cannot be 
empty"));
+
+       correct = TRUE;
 
        /* Only enforce when the email address is visible. */
        if (e_mail_config_identity_page_get_show_email_address (id_page)) {
-               if (address == NULL)
-                       return FALSE;
-
-               if (!mail_config_identity_page_is_email (address))
-                       return FALSE;
+               if (address == NULL) {
+                       e_util_set_entry_issue_hint (id_page->priv->address_entry, _("Email Address cannot be 
empty"));
+                       correct = FALSE;
+               }
+
+               if (correct && !mail_config_identity_page_is_email (address)) {
+                       e_util_set_entry_issue_hint (id_page->priv->address_entry, _("Email Address is not a 
valid email"));
+                       correct = FALSE;
+               }
        }
 
+       complete = complete && correct;
+
+       if (correct)
+               e_util_set_entry_issue_hint (id_page->priv->address_entry, NULL);
+
        /* A NULL reply_to string is allowed. */
-       if (reply_to != NULL && !mail_config_identity_page_is_email (reply_to))
-               return FALSE;
+       if (reply_to != NULL && !mail_config_identity_page_is_email (reply_to)) {
+               e_util_set_entry_issue_hint (id_page->priv->reply_to_entry, _("Reply To is not a valid 
email"));
+               complete = FALSE;
+       } else {
+               e_util_set_entry_issue_hint (id_page->priv->reply_to_entry, NULL);
+       }
+
+       correct = TRUE;
 
        /* Only enforce when account information is visible. */
-       if (e_mail_config_identity_page_get_show_account_info (id_page))
-               if (display_name == NULL || *display_name == '\0')
-                       return FALSE;
+       if (e_mail_config_identity_page_get_show_account_info (id_page)) {
+               if (display_name == NULL || *display_name == '\0') {
+                       e_util_set_entry_issue_hint (id_page->priv->display_name_entry, _("Account Name 
cannot be empty"));
+                       correct = FALSE;
+               }
+       }
+
+       complete = complete && correct;
+       if (correct)
+               e_util_set_entry_issue_hint (id_page->priv->display_name_entry, NULL);
 
-       return TRUE;
+       return complete;
 }
 
 static void
diff --git a/mail/e-mail-config-summary-page.c b/mail/e-mail-config-summary-page.c
index 91f9698..f9b3426 100644
--- a/mail/e-mail-config-summary-page.c
+++ b/mail/e-mail-config-summary-page.c
@@ -22,6 +22,7 @@
 
 #include <camel/camel.h>
 #include <libebackend/libebackend.h>
+#include <e-util/e-util.h>
 
 #define E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE(obj) \
        (G_TYPE_INSTANCE_GET_PRIVATE \
@@ -628,6 +629,8 @@ mail_config_summary_page_check_complete (EMailConfigPage *page)
        complete = (*stripped_text != '\0');
        g_free (stripped_text);
 
+       e_util_set_entry_issue_hint (GTK_WIDGET (priv->account_name_entry), complete ? NULL : _("Account Name 
cannot be empty"));
+
        return complete;
 }
 
diff --git a/modules/book-config-google/evolution-book-config-google.c 
b/modules/book-config-google/evolution-book-config-google.c
index 864e3b1..91eeb8c 100644
--- a/modules/book-config-google/evolution-book-config-google.c
+++ b/modules/book-config-google/evolution-book-config-google.c
@@ -28,7 +28,7 @@ typedef ESourceConfigBackendClass EBookConfigGoogleClass;
 typedef struct _Context Context;
 
 struct _Context {
-       gint placeholder;
+       GtkWidget *user_entry; /* not referenced */
 };
 
 /* Module Entry Points */
@@ -65,7 +65,7 @@ book_config_google_insert_widgets (ESourceConfigBackend *backend,
                G_OBJECT (backend), uid, context,
                (GDestroyNotify) book_config_google_context_free);
 
-       e_source_config_add_user_entry (config, scratch_source);
+       context->user_entry = e_source_config_add_user_entry (config, scratch_source);
 
        e_source_config_add_refresh_interval (config, scratch_source);
 }
@@ -75,14 +75,23 @@ book_config_google_check_complete (ESourceConfigBackend *backend,
                                    ESource *scratch_source)
 {
        ESourceAuthentication *extension;
+       Context *context;
+       gboolean correct;
        const gchar *extension_name;
        const gchar *user;
 
+       context = g_object_get_data (G_OBJECT (backend), e_source_get_uid (scratch_source));
+       g_return_val_if_fail (context != NULL, FALSE);
+
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
        extension = e_source_get_extension (scratch_source, extension_name);
        user = e_source_authentication_get_user (extension);
 
-       return (user != NULL && *user != '\0');
+       correct = user != NULL && *user != '\0';
+
+       e_util_set_entry_issue_hint (context->user_entry, correct ? NULL : _("User name cannot be empty"));
+
+       return correct;
 }
 
 static void
diff --git a/modules/book-config-ldap/evolution-book-config-ldap.c 
b/modules/book-config-ldap/evolution-book-config-ldap.c
index f67fd82..c3a77cf 100644
--- a/modules/book-config-ldap/evolution-book-config-ldap.c
+++ b/modules/book-config-ldap/evolution-book-config-ldap.c
@@ -51,6 +51,7 @@ struct _Context {
        GtkWidget *auth_entry;
        GtkWidget *host_entry;
        GtkWidget *port_combo;
+       GtkWidget *port_error_image;
        GtkWidget *security_combo;
        GtkWidget *search_base_combo;
        GtkWidget *search_base_button;
@@ -101,6 +102,7 @@ book_config_ldap_context_free (Context *context)
        g_object_unref (context->auth_entry);
        g_object_unref (context->host_entry);
        g_object_unref (context->port_combo);
+       g_object_unref (context->port_error_image);
        g_object_unref (context->security_combo);
        g_object_unref (context->search_base_combo);
        g_object_unref (context->search_base_button);
@@ -481,7 +483,7 @@ book_config_build_port_combo (void)
        return widget;
 }
 
-static void
+static GtkWidget *
 book_config_ldap_insert_notebook_widget (GtkWidget *vbox,
                                          GtkSizeGroup *size_group,
                                          const gchar *caption,
@@ -504,6 +506,8 @@ book_config_ldap_insert_notebook_widget (GtkWidget *vbox,
        gtk_widget_show (label);
 
        gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+
+       return hbox;
 }
 
 static void
@@ -603,11 +607,20 @@ book_config_ldap_insert_widgets (ESourceConfigBackend *backend,
        gtk_widget_show (widget);
 
        widget = book_config_build_port_combo ();
-       book_config_ldap_insert_notebook_widget (
+       hbox = book_config_ldap_insert_notebook_widget (
                container, size_group, _("Port:"), widget);
        context->port_combo = g_object_ref (widget);
        gtk_widget_show (widget);
 
+       widget = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_BUTTON);
+       g_object_set (G_OBJECT (widget),
+               "visible", FALSE,
+               "has-tooltip", TRUE,
+               "tooltip-text", _("Port number is not valid"),
+               NULL);
+       gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+       context->port_error_image = g_object_ref (widget);
+
        /* This must follow the order of ESourceLDAPSecurity. */
        widget = gtk_combo_box_text_new ();
        gtk_combo_box_text_append_text (
@@ -938,6 +951,11 @@ book_config_ldap_check_complete (ESourceConfigBackend *backend,
        const gchar *host;
        const gchar *user;
        guint16 port;
+       Context *context;
+       gboolean correct, complete = TRUE;
+
+       context = g_object_get_data (G_OBJECT (backend), e_source_get_uid (scratch_source));
+       g_return_val_if_fail (context != NULL, FALSE);
 
        extension_name = E_SOURCE_EXTENSION_LDAP_BACKEND;
        extension = e_source_get_extension (scratch_source, extension_name);
@@ -954,14 +972,27 @@ book_config_ldap_check_complete (ESourceConfigBackend *backend,
        user = e_source_authentication_get_user (
                E_SOURCE_AUTHENTICATION (extension));
 
-       if (host == NULL || *host == '\0' || port == 0)
-               return FALSE;
+       correct = host != NULL && *host != '\0';
+       complete = complete && correct;
+
+       e_util_set_entry_issue_hint (context->host_entry, correct ? NULL : _("Server address cannot be 
empty"));
+
+       correct = port != 0;
+       complete = complete && correct;
+
+       gtk_widget_set_visible (context->port_error_image, !correct);
+
+       correct = TRUE;
 
        if (auth != E_SOURCE_LDAP_AUTHENTICATION_NONE)
                if (user == NULL || *user == '\0')
-                       return FALSE;
+                       correct = FALSE;
 
-       return TRUE;
+       complete = complete && correct;
+
+       e_util_set_entry_issue_hint (context->auth_entry, correct ? NULL : _("User name cannot be empty"));
+
+       return complete;
 }
 
 static void
diff --git a/modules/book-config-webdav/evolution-book-config-webdav.c 
b/modules/book-config-webdav/evolution-book-config-webdav.c
index 15d0c02..06a5d05 100644
--- a/modules/book-config-webdav/evolution-book-config-webdav.c
+++ b/modules/book-config-webdav/evolution-book-config-webdav.c
@@ -191,6 +191,8 @@ book_config_webdav_check_complete (ESourceConfigBackend *backend,
        if (soup_uri != NULL)
                soup_uri_free (soup_uri);
 
+       e_util_set_entry_issue_hint (context->url_entry, complete ? NULL : _("URL is not a valid http:// nor 
https:// URL"));
+
        return complete;
 }
 
diff --git a/modules/cal-config-caldav/evolution-cal-config-caldav.c 
b/modules/cal-config-caldav/evolution-cal-config-caldav.c
index 20738a9..e468e6d 100644
--- a/modules/cal-config-caldav/evolution-cal-config-caldav.c
+++ b/modules/cal-config-caldav/evolution-cal-config-caldav.c
@@ -412,6 +412,8 @@ cal_config_caldav_check_complete (ESourceConfigBackend *backend,
 
        gtk_widget_set_sensitive (context->find_button, complete);
 
+       e_util_set_entry_issue_hint (context->url_entry, complete ? NULL : _("URL is not a valid http:// nor 
https:// URL"));
+
        return complete;
 }
 
diff --git a/modules/cal-config-google/e-cal-config-google.c b/modules/cal-config-google/e-cal-config-google.c
index dce7c17..c7dd42d 100644
--- a/modules/cal-config-google/e-cal-config-google.c
+++ b/modules/cal-config-google/e-cal-config-google.c
@@ -32,6 +32,7 @@ typedef struct _Context Context;
 
 struct _Context {
        GtkWidget *google_button;
+       GtkWidget *user_entry;
 };
 
 /* Forward Declarations */
@@ -46,6 +47,7 @@ static void
 cal_config_google_context_free (Context *context)
 {
        g_object_unref (context->google_button);
+       g_object_unref (context->user_entry);
 
        g_slice_free (Context, context);
 }
@@ -85,7 +87,7 @@ cal_config_google_insert_widgets (ESourceConfigBackend *backend,
        e_cal_source_config_add_offline_toggle (
                E_CAL_SOURCE_CONFIG (config), scratch_source);
 
-       e_source_config_add_user_entry (config, scratch_source);
+       context->user_entry = g_object_ref (e_source_config_add_user_entry (config, scratch_source));
 
        widget = e_google_chooser_button_new (scratch_source, config);
        e_source_config_insert_widget (
@@ -158,14 +160,23 @@ cal_config_google_check_complete (ESourceConfigBackend *backend,
                                   ESource *scratch_source)
 {
        ESourceAuthentication *extension;
+       Context *context;
+       gboolean correct;
        const gchar *extension_name;
        const gchar *user;
 
+       context = g_object_get_data (G_OBJECT (backend), e_source_get_uid (scratch_source));
+       g_return_val_if_fail (context != NULL, FALSE);
+
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
        extension = e_source_get_extension (scratch_source, extension_name);
        user = e_source_authentication_get_user (extension);
 
-       return (user != NULL);
+       correct = (user != NULL);
+
+       e_util_set_entry_issue_hint (context->user_entry, correct ? NULL : _("User name cannot be empty"));
+
+       return correct;
 }
 
 static void
diff --git a/modules/cal-config-google/e-cal-config-gtasks.c b/modules/cal-config-google/e-cal-config-gtasks.c
index 49e3717..bb21a14 100644
--- a/modules/cal-config-google/e-cal-config-gtasks.c
+++ b/modules/cal-config-google/e-cal-config-gtasks.c
@@ -18,6 +18,7 @@
 #endif
 
 #include <string.h>
+#include <glib/gi18n-lib.h>
 
 #include <libebackend/libebackend.h>
 
@@ -28,6 +29,12 @@
 typedef ESourceConfigBackend ECalConfigGTasks;
 typedef ESourceConfigBackendClass ECalConfigGTasksClass;
 
+typedef struct _Context Context;
+
+struct _Context {
+       GtkWidget *user_entry;
+};
+
 /* Forward Declarations */
 GType e_cal_config_gtasks_get_type (void);
 
@@ -36,6 +43,14 @@ G_DEFINE_DYNAMIC_TYPE (
        e_cal_config_gtasks,
        E_TYPE_SOURCE_CONFIG_BACKEND)
 
+static void
+cal_config_gtasks_context_free (Context *context)
+{
+       g_object_unref (context->user_entry);
+
+       g_slice_free (Context, context);
+}
+
 static gboolean
 cal_config_gtasks_allow_creation (ESourceConfigBackend *backend)
 {
@@ -67,10 +82,16 @@ cal_config_gtasks_insert_widgets (ESourceConfigBackend *backend,
                                   ESource *scratch_source)
 {
        ESourceConfig *config;
+       Context *context;
 
        config = e_source_config_backend_get_config (backend);
+       context = g_slice_new0 (Context);
+
+       g_object_set_data_full (
+               G_OBJECT (backend), e_source_get_uid (scratch_source), context,
+               (GDestroyNotify) cal_config_gtasks_context_free);
 
-       e_source_config_add_user_entry (config, scratch_source);
+       context->user_entry = g_object_ref (e_source_config_add_user_entry (config, scratch_source));
        e_source_config_add_refresh_interval (config, scratch_source);
 }
 
@@ -79,14 +100,23 @@ cal_config_gtasks_check_complete (ESourceConfigBackend *backend,
                                   ESource *scratch_source)
 {
        ESourceAuthentication *extension;
+       Context *context;
+       gboolean correct;
        const gchar *extension_name;
        const gchar *user;
 
+       context = g_object_get_data (G_OBJECT (backend), e_source_get_uid (scratch_source));
+       g_return_val_if_fail (context != NULL, FALSE);
+
        extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
        extension = e_source_get_extension (scratch_source, extension_name);
        user = e_source_authentication_get_user (extension);
 
-       return user && *user;
+       correct = user && *user;
+
+       e_util_set_entry_issue_hint (context->user_entry, correct ? NULL : _("User name cannot be empty"));
+
+       return correct;
 }
 
 static void
diff --git a/modules/cal-config-weather/evolution-cal-config-weather.c 
b/modules/cal-config-weather/evolution-cal-config-weather.c
index 216e0e4..e02b2d6 100644
--- a/modules/cal-config-weather/evolution-cal-config-weather.c
+++ b/modules/cal-config-weather/evolution-cal-config-weather.c
@@ -301,9 +301,14 @@ cal_config_weather_check_complete (ESourceConfigBackend *backend,
                                    ESource *scratch_source)
 {
        ESourceWeather *extension;
+       Context *context;
+       gboolean correct;
        const gchar *extension_name;
        const gchar *location;
 
+       context = g_object_get_data (G_OBJECT (backend), e_source_get_uid (scratch_source));
+       g_return_val_if_fail (context != NULL, FALSE);
+
        extension_name = E_SOURCE_EXTENSION_WEATHER_BACKEND;
        extension = e_source_get_extension (scratch_source, extension_name);
 
@@ -311,7 +316,11 @@ cal_config_weather_check_complete (ESourceConfigBackend *backend,
 
        g_debug ("Location: [%s]", location);
 
-       return (location != NULL) && (*location != '\0');
+       correct = (location != NULL) && (*location != '\0');
+
+       e_util_set_entry_issue_hint (context->location_entry, correct ? NULL : _("Location cannot be empty"));
+
+       return correct;
 }
 
 static void
diff --git a/modules/cal-config-webcal/evolution-cal-config-webcal.c 
b/modules/cal-config-webcal/evolution-cal-config-webcal.c
index 2b84455..e6b933e 100644
--- a/modules/cal-config-webcal/evolution-cal-config-webcal.c
+++ b/modules/cal-config-webcal/evolution-cal-config-webcal.c
@@ -181,6 +181,8 @@ cal_config_webcal_check_complete (ESourceConfigBackend *backend,
        if (soup_uri != NULL)
                soup_uri_free (soup_uri);
 
+       e_util_set_entry_issue_hint (context->url_entry, complete ? NULL : _("URL is not a valid http:// nor 
https:// URL"));
+
        return complete;
 }
 
diff --git a/modules/mail-config/e-mail-config-local-accounts.c 
b/modules/mail-config/e-mail-config-local-accounts.c
index bce5131..15d36a9 100644
--- a/modules/mail-config/e-mail-config-local-accounts.c
+++ b/modules/mail-config/e-mail-config-local-accounts.c
@@ -66,6 +66,8 @@ typedef EMailConfigServiceBackendClass EMailConfigNoneBackendClass;
 
 struct _EMailConfigLocalBackend {
        EMailConfigServiceBackend parent;
+
+       GtkWidget *path_error_image;
 };
 
 struct _EMailConfigLocalBackendClass {
@@ -74,6 +76,8 @@ struct _EMailConfigLocalBackendClass {
        const gchar *file_chooser_label;
        const gchar *file_chooser_title;
        GtkFileChooserAction file_chooser_action;
+       const gchar *file_error_message;
+
 };
 
 /* Forward Declarations */
@@ -151,6 +155,7 @@ mail_config_local_backend_insert_widgets (EMailConfigServiceBackend *backend,
                                           GtkBox *parent)
 {
        CamelSettings *settings;
+       EMailConfigLocalBackend *local_backend;
        EMailConfigLocalBackendClass *class;
        GtkLabel *label;
        GtkWidget *widget;
@@ -158,6 +163,7 @@ mail_config_local_backend_insert_widgets (EMailConfigServiceBackend *backend,
        const gchar *path;
 
        class = E_MAIL_CONFIG_LOCAL_BACKEND_GET_CLASS (backend);
+       local_backend = E_MAIL_CONFIG_LOCAL_BACKEND (backend);
        settings = e_mail_config_service_backend_get_settings (backend);
 
        widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
@@ -188,21 +194,37 @@ mail_config_local_backend_insert_widgets (EMailConfigServiceBackend *backend,
        if (path != NULL)
                gtk_file_chooser_set_filename (
                        GTK_FILE_CHOOSER (widget), path);
+
+       widget = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_BUTTON);
+       g_object_set (G_OBJECT (widget),
+               "visible", FALSE,
+               "has-tooltip", TRUE,
+               "tooltip-text", class->file_error_message,
+               NULL);
+       gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+       local_backend->path_error_image = widget;  /* do not reference */
 }
 
 static gboolean
 mail_config_local_backend_check_complete (EMailConfigServiceBackend *backend)
 {
+       EMailConfigLocalBackend *local_backend;
        CamelSettings *settings;
        CamelLocalSettings *local_settings;
        const gchar *path;
+       gboolean complete;
 
+       local_backend = E_MAIL_CONFIG_LOCAL_BACKEND (backend);
        settings = e_mail_config_service_backend_get_settings (backend);
 
        local_settings = CAMEL_LOCAL_SETTINGS (settings);
        path = camel_local_settings_get_path (local_settings);
 
-       return (path != NULL && *path != '\0');
+       complete = (path != NULL && *path != '\0');
+
+       gtk_widget_set_visible (local_backend->path_error_image, !complete);
+
+       return complete;
 }
 
 static void
@@ -245,6 +267,7 @@ e_mail_config_mh_backend_class_init (EMailConfigLocalBackendClass *class)
        class->file_chooser_label = _("Mail _Directory:");
        class->file_chooser_title = _("Choose a MH mail directory");
        class->file_chooser_action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
+       class->file_error_message = _("MH mail directory cannot be empty");
 }
 
 static void
@@ -268,6 +291,7 @@ e_mail_config_mbox_backend_class_init (EMailConfigLocalBackendClass *class)
        class->file_chooser_label = _("Local Delivery _File:");
        class->file_chooser_title = _("Choose a local delivery file");
        class->file_chooser_action = GTK_FILE_CHOOSER_ACTION_OPEN;
+       class->file_error_message = _("Local delivery file cannot be empty");
 }
 
 static void
@@ -291,6 +315,7 @@ e_mail_config_maildir_backend_class_init (EMailConfigLocalBackendClass *class)
        class->file_chooser_label = _("Mail _Directory:");
        class->file_chooser_title = _("Choose a Maildir mail directory");
        class->file_chooser_action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
+       class->file_error_message = _("Maildir mail directory cannot be empty");
 }
 
 static void
@@ -314,6 +339,7 @@ e_mail_config_spool_dir_backend_class_init (EMailConfigLocalBackendClass *class)
        class->file_chooser_label = _("Spool _File:");
        class->file_chooser_title = _("Choose a mbox spool file");
        class->file_chooser_action = GTK_FILE_CHOOSER_ACTION_OPEN;
+       class->file_error_message = _("Mbox spool file cannot be empty");
 }
 
 static void
@@ -337,6 +363,7 @@ e_mail_config_spool_file_backend_class_init (EMailConfigLocalBackendClass *class
        class->file_chooser_label = _("Spool _Directory:");
        class->file_chooser_title = _("Choose a mbox spool directory");
        class->file_chooser_action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
+       class->file_error_message = _("Mbox spool directory cannot be empty");
 }
 
 static void
diff --git a/modules/mail-config/e-mail-config-remote-accounts.c 
b/modules/mail-config/e-mail-config-remote-accounts.c
index 45fdd60..b2d4da7 100644
--- a/modules/mail-config/e-mail-config-remote-accounts.c
+++ b/modules/mail-config/e-mail-config-remote-accounts.c
@@ -60,6 +60,7 @@ struct _EMailConfigRemoteBackend {
 
        GtkWidget *host_entry;          /* not referenced */
        GtkWidget *port_entry;          /* not referenced */
+       GtkWidget *port_error_image;    /* not referenced */
        GtkWidget *user_entry;          /* not referenced */
        GtkWidget *security_combo_box;  /* not referenced */
        GtkWidget *auth_check;          /* not referenced */
@@ -177,6 +178,15 @@ mail_config_remote_backend_insert_widgets (EMailConfigServiceBackend *backend,
        remote_backend->port_entry = widget;  /* do not reference */
        gtk_widget_show (widget);
 
+       widget = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_BUTTON);
+       g_object_set (G_OBJECT (widget),
+               "visible", FALSE,
+               "has-tooltip", TRUE,
+               "tooltip-text", _("Port number is not valid"),
+               NULL);
+       gtk_grid_attach (GTK_GRID (container), widget, 4, 0, 1, 1);
+       remote_backend->port_error_image = widget;  /* do not reference */
+
        widget = gtk_label_new_with_mnemonic (_("User_name:"));
        gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
        gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
@@ -187,7 +197,7 @@ mail_config_remote_backend_insert_widgets (EMailConfigServiceBackend *backend,
        widget = gtk_entry_new ();
        gtk_widget_set_hexpand (widget, TRUE);
        gtk_label_set_mnemonic_widget (label, widget);
-       gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 3, 1);
+       gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 4, 1);
        remote_backend->user_entry = widget;  /* do not reference */
        gtk_widget_show (widget);
 
@@ -309,6 +319,7 @@ mail_config_remote_backend_check_complete (EMailConfigServiceBackend *backend)
        EPortEntry *port_entry;
        const gchar *host;
        const gchar *user;
+       gboolean correct, complete = TRUE;
 
        remote_backend = E_MAIL_CONFIG_REMOTE_BACKEND (backend);
 
@@ -321,20 +332,35 @@ mail_config_remote_backend_check_complete (EMailConfigServiceBackend *backend)
        host = camel_network_settings_get_host (network_settings);
        user = camel_network_settings_get_user (network_settings);
 
+       correct = TRUE;
+
        if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_HOST) &&
            (host == NULL || *host == '\0'))
-               return FALSE;
+               correct = FALSE;
+
+       complete = complete && correct;
+       e_util_set_entry_issue_hint (remote_backend->host_entry, correct ? NULL : _("Server address cannot be 
empty"));
+
+       correct = TRUE;
 
        port_entry = E_PORT_ENTRY (remote_backend->port_entry);
        if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_PORT) &&
            !e_port_entry_is_valid (port_entry))
-               return FALSE;
+               correct = FALSE;
+
+       complete = complete && correct;
+       gtk_widget_set_visible (remote_backend->port_error_image, !correct);
+
+       correct = TRUE;
 
        if (CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_USER) &&
            (user == NULL || *user == '\0'))
-               return FALSE;
+               correct = FALSE;
+
+       complete = complete && correct;
+       e_util_set_entry_issue_hint (remote_backend->user_entry, correct ? NULL : _("User name cannot be 
empty"));
 
-       return TRUE;
+       return complete;
 }
 
 static void
diff --git a/modules/mail-config/e-mail-config-sendmail-backend.c 
b/modules/mail-config/e-mail-config-sendmail-backend.c
index dbba920..1b0a003 100644
--- a/modules/mail-config/e-mail-config-sendmail-backend.c
+++ b/modules/mail-config/e-mail-config-sendmail-backend.c
@@ -27,6 +27,11 @@
 
 #include "e-mail-config-sendmail-backend.h"
 
+struct _EMailConfigSendmailBackendPrivate
+{
+       GtkWidget *custom_binary_entry; /* not referenced */
+};
+
 G_DEFINE_DYNAMIC_TYPE (
        EMailConfigSendmailBackend,
        e_mail_config_sendmail_backend,
@@ -36,6 +41,7 @@ static void
 mail_config_sendmail_backend_insert_widgets (EMailConfigServiceBackend *backend,
                                              GtkBox *parent)
 {
+       EMailConfigSendmailBackend *sendmail_backend;
        CamelSettings *settings;
        GtkLabel *label;
        GtkWidget *widget;
@@ -49,6 +55,7 @@ mail_config_sendmail_backend_insert_widgets (EMailConfigServiceBackend *backend,
        PangoAttribute *attr;
        PangoAttrList *attr_list;
 
+       sendmail_backend = E_MAIL_CONFIG_SENDMAIL_BACKEND (backend);
        settings = e_mail_config_service_backend_get_settings (backend);
 
        markup = g_markup_printf_escaped ("<b>%s</b>", _("Configuration"));
@@ -83,6 +90,8 @@ mail_config_sendmail_backend_insert_widgets (EMailConfigServiceBackend *backend,
        gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
        custom_binary_entry = widget;
 
+       sendmail_backend->priv->custom_binary_entry = widget;
+
        e_binding_bind_property (
                use_custom_binary_check, "active",
                label, "sensitive",
@@ -175,11 +184,13 @@ mail_config_sendmail_backend_insert_widgets (EMailConfigServiceBackend *backend,
 static gboolean
 mail_config_sendmail_backend_check_complete (EMailConfigServiceBackend *backend)
 {
+       EMailConfigSendmailBackend *sendmail_backend;
        CamelSettings *settings;
        gboolean use_custom_binary = FALSE;
        gchar *custom_binary = NULL;
        gboolean res = TRUE;
 
+       sendmail_backend = E_MAIL_CONFIG_SENDMAIL_BACKEND (backend);
        settings = e_mail_config_service_backend_get_settings (backend);
 
        g_object_get (
@@ -196,6 +207,8 @@ mail_config_sendmail_backend_check_complete (EMailConfigServiceBackend *backend)
 
        g_free (custom_binary);
 
+       e_util_set_entry_issue_hint (sendmail_backend->priv->custom_binary_entry, res ? NULL : _("Custom 
binary cannot be empty"));
+
        return res;
 }
 
@@ -204,6 +217,8 @@ e_mail_config_sendmail_backend_class_init (EMailConfigSendmailBackendClass *clas
 {
        EMailConfigServiceBackendClass *backend_class;
 
+       g_type_class_add_private (class, sizeof (EMailConfigSendmailBackendPrivate));
+
        backend_class = E_MAIL_CONFIG_SERVICE_BACKEND_CLASS (class);
        backend_class->backend_name = "sendmail";
        backend_class->insert_widgets = mail_config_sendmail_backend_insert_widgets;
@@ -218,6 +233,7 @@ e_mail_config_sendmail_backend_class_finalize (EMailConfigSendmailBackendClass *
 static void
 e_mail_config_sendmail_backend_init (EMailConfigSendmailBackend *backend)
 {
+       backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend, E_TYPE_MAIL_CONFIG_SENDMAIL_BACKEND, 
EMailConfigSendmailBackendPrivate);
 }
 
 void
diff --git a/modules/mail-config/e-mail-config-smtp-backend.c 
b/modules/mail-config/e-mail-config-smtp-backend.c
index 1f1d0cd..043b4d1 100644
--- a/modules/mail-config/e-mail-config-smtp-backend.c
+++ b/modules/mail-config/e-mail-config-smtp-backend.c
@@ -34,6 +34,7 @@
 struct _EMailConfigSmtpBackendPrivate {
        GtkWidget *host_entry;                  /* not referenced */
        GtkWidget *port_entry;                  /* not referenced */
+       GtkWidget *port_error_image;            /* not referenced */
        GtkWidget *user_entry;                  /* not referenced */
        GtkWidget *security_combo_box;          /* not referenced */
        GtkWidget *auth_required_toggle;        /* not referenced */
@@ -132,9 +133,18 @@ mail_config_smtp_backend_insert_widgets (EMailConfigServiceBackend *backend,
        priv->port_entry = widget;  /* do not reference */
        gtk_widget_show (widget);
 
+       widget = gtk_image_new_from_icon_name ("dialog-warning", GTK_ICON_SIZE_BUTTON);
+       g_object_set (G_OBJECT (widget),
+               "visible", FALSE,
+               "has-tooltip", TRUE,
+               "tooltip-text", _("Port number is not valid"),
+               NULL);
+       gtk_grid_attach (GTK_GRID (container), widget, 4, 0, 1, 1);
+       priv->port_error_image = widget;  /* do not reference */
+
        text = _("Ser_ver requires authentication");
        widget = gtk_check_button_new_with_mnemonic (text);
-       gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 3, 1);
+       gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 4, 1);
        priv->auth_required_toggle = widget;  /* do not reference */
        gtk_widget_show (widget);
 
@@ -249,7 +259,7 @@ mail_config_smtp_backend_insert_widgets (EMailConfigServiceBackend *backend,
        widget = gtk_entry_new ();
        gtk_widget_set_hexpand (widget, TRUE);
        gtk_label_set_mnemonic_widget (label, widget);
-       gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 2, 1);
+       gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 3, 1);
        priv->user_entry = widget;  /* do not reference */
        gtk_widget_show (widget);
 
@@ -352,6 +362,7 @@ mail_config_smtp_backend_check_complete (EMailConfigServiceBackend *backend)
        EPortEntry *port_entry;
        const gchar *host;
        const gchar *user;
+       gboolean correct, complete = TRUE;
 
        priv = E_MAIL_CONFIG_SMTP_BACKEND_GET_PRIVATE (backend);
 
@@ -361,21 +372,30 @@ mail_config_smtp_backend_check_complete (EMailConfigServiceBackend *backend)
        host = camel_network_settings_get_host (network_settings);
        user = camel_network_settings_get_user (network_settings);
 
-       if (host == NULL || *host == '\0')
-               return FALSE;
+       correct = (host != NULL && *host != '\0');
+       complete = complete && correct;
+
+       e_util_set_entry_issue_hint (priv->host_entry, correct ? NULL : _("Server address cannot be empty"));
 
        port_entry = E_PORT_ENTRY (priv->port_entry);
 
-       if (!e_port_entry_is_valid (port_entry))
-               return FALSE;
+       correct = e_port_entry_is_valid (port_entry);
+       complete = complete && correct;
+
+       gtk_widget_set_visible (priv->port_error_image, !correct);
 
        toggle_button = GTK_TOGGLE_BUTTON (priv->auth_required_toggle);
 
+       correct = TRUE;
+
        if (gtk_toggle_button_get_active (toggle_button))
                if (user == NULL || *user == '\0')
-                       return FALSE;
+                       correct = FALSE;
 
-       return TRUE;
+       complete = complete && correct;
+       e_util_set_entry_issue_hint (priv->user_entry, correct ? NULL : _("User name cannot be empty"));
+
+       return complete;
 }
 
 static void
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 70364dc..60d1a5c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -396,6 +396,7 @@ modules/book-config-webdav/evolution-book-config-webdav.c
 modules/cal-config-caldav/evolution-cal-config-caldav.c
 modules/cal-config-contacts/evolution-cal-config-contacts.c
 modules/cal-config-google/e-cal-config-google.c
+modules/cal-config-google/e-cal-config-gtasks.c
 modules/cal-config-google/e-google-chooser-button.c
 modules/cal-config-local/evolution-cal-config-local.c
 modules/cal-config-weather/evolution-cal-config-weather.c



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]