1 /*
2 * e-url-entry.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 #include "evolution-config.h"
19
20 #include "e-url-entry.h"
21
22 #include <gtk/gtk.h>
23 #include <glib/gi18n.h>
24
25 #include "e-misc-utils.h"
26
27 #define E_URL_ENTRY_GET_PRIVATE(obj) \
28 (G_TYPE_INSTANCE_GET_PRIVATE \
29 ((obj), E_TYPE_URL_ENTRY, EUrlEntryPrivate))
30
31 #define ICON_POSITION GTK_ENTRY_ICON_SECONDARY
32
33 enum {
34 PROP_0,
35 PROP_ICON_VISIBLE
36 };
37
G_DEFINE_TYPE(EUrlEntry,e_url_entry,GTK_TYPE_ENTRY)38 G_DEFINE_TYPE (
39 EUrlEntry,
40 e_url_entry,
41 GTK_TYPE_ENTRY)
42
43 static gboolean
44 url_entry_text_to_sensitive (GBinding *binding,
45 const GValue *source_value,
46 GValue *target_value,
47 gpointer user_data)
48 {
49 const gchar *text;
50 gboolean sensitive = FALSE;
51
52 text = g_value_get_string (source_value);
53
54 if (text != NULL) {
55 /* Skip leading whitespace. */
56 while (g_ascii_isspace (*text))
57 text++;
58
59 sensitive = *text != '\0';
60 }
61
62 g_value_set_boolean (target_value, sensitive);
63
64 return TRUE;
65 }
66
67 static void
url_entry_icon_release_cb(GtkEntry * entry,GtkEntryIconPosition icon_position,GdkEvent * event)68 url_entry_icon_release_cb (GtkEntry *entry,
69 GtkEntryIconPosition icon_position,
70 GdkEvent *event)
71 {
72 gpointer toplevel;
73
74 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (entry));
75 toplevel = gtk_widget_is_toplevel (toplevel) ? toplevel : NULL;
76
77 if (icon_position == ICON_POSITION) {
78 const gchar *text;
79
80 text = gtk_entry_get_text (entry);
81 g_return_if_fail (text != NULL);
82
83 /* Skip leading whitespace. */
84 while (g_ascii_isspace (*text))
85 text++;
86
87 e_show_uri (toplevel, text);
88 }
89 }
90
91 static void
e_url_entry_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)92 e_url_entry_set_property (GObject *object,
93 guint property_id,
94 const GValue *value,
95 GParamSpec *pspec)
96 {
97 switch (property_id) {
98 case PROP_ICON_VISIBLE:
99 e_url_entry_set_icon_visible (
100 E_URL_ENTRY (object),
101 g_value_get_boolean (value));
102 return;
103 }
104
105 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
106 }
107
108 static void
e_url_entry_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)109 e_url_entry_get_property (GObject *object,
110 guint property_id,
111 GValue *value,
112 GParamSpec *pspec)
113 {
114 switch (property_id) {
115 case PROP_ICON_VISIBLE:
116 g_value_set_boolean (
117 value,
118 e_url_entry_get_icon_visible (
119 E_URL_ENTRY (object)));
120 return;
121 }
122
123 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
124 }
125
126 static void
e_url_entry_class_init(EUrlEntryClass * class)127 e_url_entry_class_init (EUrlEntryClass *class)
128 {
129 GObjectClass *object_class;
130
131 object_class = G_OBJECT_CLASS (class);
132 object_class->set_property = e_url_entry_set_property;
133 object_class->get_property = e_url_entry_get_property;
134
135 g_object_class_install_property (
136 object_class,
137 PROP_ICON_VISIBLE,
138 g_param_spec_boolean (
139 "icon-visible",
140 NULL,
141 NULL,
142 FALSE,
143 G_PARAM_READWRITE |
144 G_PARAM_STATIC_STRINGS));
145 }
146
147 static void
e_url_entry_init(EUrlEntry * url_entry)148 e_url_entry_init (EUrlEntry *url_entry)
149 {
150 GtkEntry *entry;
151
152 entry = GTK_ENTRY (url_entry);
153
154 gtk_entry_set_icon_tooltip_text (
155 entry, ICON_POSITION, _("Click here to open the URL"));
156
157 e_url_entry_set_icon_visible (url_entry, TRUE);
158
159 /* XXX GtkEntryClass has no "icon_release" method pointer to
160 * override, so instead we have to connect to the signal. */
161 g_signal_connect (
162 url_entry, "icon-release",
163 G_CALLBACK (url_entry_icon_release_cb), NULL);
164
165 e_binding_bind_property_full (
166 url_entry, "text",
167 url_entry, "secondary-icon-sensitive",
168 G_BINDING_SYNC_CREATE,
169 url_entry_text_to_sensitive,
170 (GBindingTransformFunc) NULL,
171 NULL, (GDestroyNotify) NULL);
172 }
173
174 GtkWidget *
e_url_entry_new(void)175 e_url_entry_new (void)
176 {
177 return g_object_new (E_TYPE_URL_ENTRY, NULL);
178 }
179
180 void
e_url_entry_set_icon_visible(EUrlEntry * url_entry,gboolean visible)181 e_url_entry_set_icon_visible (EUrlEntry *url_entry,
182 gboolean visible)
183 {
184 GtkEntry *entry;
185
186 g_return_if_fail (E_IS_URL_ENTRY (url_entry));
187
188 entry = GTK_ENTRY (url_entry);
189
190 if (visible) {
191 gtk_entry_set_icon_from_icon_name (entry, ICON_POSITION, "go-jump");
192 gtk_entry_set_placeholder_text (entry, _("Enter a URL here"));
193 } else {
194 gtk_entry_set_icon_from_icon_name (entry, ICON_POSITION, NULL);
195 gtk_entry_set_placeholder_text (entry, NULL);
196 }
197 }
198
199 gboolean
e_url_entry_get_icon_visible(EUrlEntry * url_entry)200 e_url_entry_get_icon_visible (EUrlEntry *url_entry)
201 {
202 g_return_val_if_fail (E_IS_URL_ENTRY (url_entry), FALSE);
203
204 return gtk_entry_get_icon_name (GTK_ENTRY (url_entry), ICON_POSITION) != NULL;
205 }
206