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
This commit is contained in:
Milan Crha
2020-11-06 12:12:29 +01:00
parent 3ae8f2d796
commit bb497cfd24
3 changed files with 133 additions and 4 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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