[evolution/gnome-3-38] ECompEditor: Add easy way to open URLs in the Location field



commit 26bd8ed7c9e19b954707af767eb9f756ec8f3e81
Author: Milan Crha <mcrha redhat com>
Date:   Fri Nov 6 12:12:29 2020 +0100

    ECompEditor: Add easy way to open URLs in the Location field
    
    When the Location looks like a URL, let the user open the Location
    in the default application for that scheme by showing a button
    in the Location entry to open the URL.
    
    Related to https://gitlab.gnome.org/GNOME/evolution/-/issues/1184

 src/calendar/gui/e-comp-editor-property-parts.c | 47 +++++++++++++
 src/e-util/e-url-entry.c                        | 87 +++++++++++++++++++++++--
 src/e-util/e-url-entry.h                        |  3 +
 3 files changed, 133 insertions(+), 4 deletions(-)
---
diff --git a/src/calendar/gui/e-comp-editor-property-parts.c b/src/calendar/gui/e-comp-editor-property-parts.c
index bafb011d4d..9afcab6c4f 100644
--- a/src/calendar/gui/e-comp-editor-property-parts.c
+++ b/src/calendar/gui/e-comp-editor-property-parts.c
@@ -305,6 +305,45 @@ ecepp_location_save_list (GtkEntry *entry)
        g_free (filename);
 }
 
+static gboolean
+ecepp_location_text_to_icon_visible (GBinding *binding,
+                                    const GValue *source_value,
+                                    GValue *target_value,
+                                    gpointer user_data)
+{
+       const gchar *text;
+       gboolean icon_visible = FALSE;
+
+       text = g_value_get_string (source_value);
+
+       if (text && *text) {
+               struct _schemas {
+                       const gchar *schema;
+                       gint len;
+               } schemas[] = {
+                       { "http:", 5 },
+                       { "https:", 6 },
+                       { "www.", 4 },
+                       { "ftp:", 4 },
+                       { "sip:", 4 },
+                       { "tel:", 4 },
+                       { "xmpp:", 5 }
+               };
+               gint ii;
+
+               for (ii = 0; ii < G_N_ELEMENTS (schemas); ii++) {
+                       if (g_ascii_strncasecmp (text, schemas[ii].schema, schemas[ii].len) == 0) {
+                               icon_visible = TRUE;
+                               break;
+                       }
+               }
+       }
+
+       g_value_set_boolean (target_value, icon_visible);
+
+       return TRUE;
+}
+
 static void
 ecepp_location_create_widgets (ECompEditorPropertyPart *property_part,
                               GtkWidget **out_label_widget,
@@ -338,6 +377,13 @@ ecepp_location_create_widgets (ECompEditorPropertyPart *property_part,
        gtk_entry_set_completion (GTK_ENTRY (*out_edit_widget), completion);
        g_object_unref (completion);
 
+       e_binding_bind_property_full (
+               *out_edit_widget, "text",
+               *out_edit_widget, "icon-visible",
+               G_BINDING_SYNC_CREATE,
+               ecepp_location_text_to_icon_visible,
+               NULL, NULL, NULL);
+
        *out_label_widget = gtk_label_new_with_mnemonic (C_("ECompEditor", "_Location:"));
        gtk_label_set_mnemonic_widget (GTK_LABEL (*out_label_widget), *out_edit_widget);
 
@@ -386,6 +432,7 @@ e_comp_editor_property_part_location_class_init (ECompEditorPropertyPartLocation
        ECompEditorPropertyPartClass *part_class;
 
        part_string_class = E_COMP_EDITOR_PROPERTY_PART_STRING_CLASS (klass);
+       part_string_class->entry_type = E_TYPE_URL_ENTRY;
        part_string_class->prop_kind = I_CAL_LOCATION_PROPERTY;
        part_string_class->i_cal_new_func = i_cal_property_new_location;
        part_string_class->i_cal_set_func = i_cal_property_set_location;
diff --git a/src/e-util/e-url-entry.c b/src/e-util/e-url-entry.c
index a38e108e9b..f5638c872e 100644
--- a/src/e-util/e-url-entry.c
+++ b/src/e-util/e-url-entry.c
@@ -30,6 +30,11 @@
 
 #define ICON_POSITION GTK_ENTRY_ICON_SECONDARY
 
+enum {
+       PROP_0,
+       PROP_ICON_VISIBLE
+};
+
 G_DEFINE_TYPE (
        EUrlEntry,
        e_url_entry,
@@ -83,9 +88,60 @@ url_entry_icon_release_cb (GtkEntry *entry,
        }
 }
 
+static void
+e_url_entry_set_property (GObject *object,
+                         guint property_id,
+                         const GValue *value,
+                         GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_ICON_VISIBLE:
+                       e_url_entry_set_icon_visible (
+                               E_URL_ENTRY (object),
+                               g_value_get_boolean (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+e_url_entry_get_property (GObject *object,
+                         guint property_id,
+                         GValue *value,
+                         GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_ICON_VISIBLE:
+                       g_value_set_boolean (
+                               value,
+                               e_url_entry_get_icon_visible (
+                               E_URL_ENTRY (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
 static void
 e_url_entry_class_init (EUrlEntryClass *class)
 {
+       GObjectClass *object_class;
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = e_url_entry_set_property;
+       object_class->get_property = e_url_entry_get_property;
+
+       g_object_class_install_property (
+               object_class,
+               PROP_ICON_VISIBLE,
+               g_param_spec_boolean (
+                       "icon-visible",
+                       NULL,
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE |
+                       G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -95,13 +151,10 @@ e_url_entry_init (EUrlEntry *url_entry)
 
        entry = GTK_ENTRY (url_entry);
 
-       gtk_entry_set_icon_from_icon_name (
-               entry, ICON_POSITION, "go-jump");
-
        gtk_entry_set_icon_tooltip_text (
                entry, ICON_POSITION, _("Click here to open the URL"));
 
-       gtk_entry_set_placeholder_text (entry, _("Enter a URL here"));
+       e_url_entry_set_icon_visible (url_entry, TRUE);
 
        /* XXX GtkEntryClass has no "icon_release" method pointer to
         *     override, so instead we have to connect to the signal. */
@@ -124,3 +177,29 @@ e_url_entry_new (void)
        return g_object_new (E_TYPE_URL_ENTRY, NULL);
 }
 
+void
+e_url_entry_set_icon_visible (EUrlEntry *url_entry,
+                             gboolean visible)
+{
+       GtkEntry *entry;
+
+       g_return_if_fail (E_IS_URL_ENTRY (url_entry));
+
+       entry = GTK_ENTRY (url_entry);
+
+       if (visible) {
+               gtk_entry_set_icon_from_icon_name (entry, ICON_POSITION, "go-jump");
+               gtk_entry_set_placeholder_text (entry, _("Enter a URL here"));
+       } else {
+               gtk_entry_set_icon_from_icon_name (entry, ICON_POSITION, NULL);
+               gtk_entry_set_placeholder_text (entry, NULL);
+       }
+}
+
+gboolean
+e_url_entry_get_icon_visible (EUrlEntry *url_entry)
+{
+       g_return_val_if_fail (E_IS_URL_ENTRY (url_entry), FALSE);
+
+       return gtk_entry_get_icon_name (GTK_ENTRY (url_entry), ICON_POSITION) != NULL;
+}
diff --git a/src/e-util/e-url-entry.h b/src/e-util/e-url-entry.h
index a59944d5a3..77f56cbd43 100644
--- a/src/e-util/e-url-entry.h
+++ b/src/e-util/e-url-entry.h
@@ -60,6 +60,9 @@ struct _EUrlEntryClass {
 
 GType          e_url_entry_get_type            (void) G_GNUC_CONST;
 GtkWidget *    e_url_entry_new                 (void);
+void           e_url_entry_set_icon_visible    (EUrlEntry *url_entry,
+                                                gboolean visible);
+gboolean       e_url_entry_get_icon_visible    (EUrlEntry *url_entry);
 
 G_END_DECLS
 


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