1 /*
2 * evolution-mailto-handler.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 <glib/gi18n-lib.h>
21 #include <libebackend/libebackend.h>
22
23 #include <shell/e-shell.h>
24
25 /* Standard GObject macros */
26 #define E_TYPE_MAILTO_HANDLER \
27 (e_mailto_handler_get_type ())
28 #define E_MAILTO_HANDLER(obj) \
29 (G_TYPE_CHECK_INSTANCE_CAST \
30 ((obj), E_TYPE_MAILTO_HANDLER, EMailtoHandler))
31
32 #define MAILTO_COMMAND \
33 "evolution --component=mail"
34
35 #define MAILTO_HANDLER "x-scheme-handler/mailto"
36
37 typedef struct _EMailtoHandler EMailtoHandler;
38 typedef struct _EMailtoHandlerClass EMailtoHandlerClass;
39
40 struct _EMailtoHandler {
41 EExtension parent;
42 };
43
44 struct _EMailtoHandlerClass {
45 EExtensionClass parent_class;
46 };
47
48 /* Module Entry Points */
49 void e_module_load (GTypeModule *type_module);
50 void e_module_unload (GTypeModule *type_module);
51
52 /* Forward Declarations */
53 GType e_mailto_handler_get_type (void);
54
G_DEFINE_DYNAMIC_TYPE(EMailtoHandler,e_mailto_handler,E_TYPE_EXTENSION)55 G_DEFINE_DYNAMIC_TYPE (EMailtoHandler, e_mailto_handler, E_TYPE_EXTENSION)
56
57 static EShell *
58 mailto_handler_get_shell (EMailtoHandler *extension)
59 {
60 EExtensible *extensible;
61
62 extensible = e_extension_get_extensible (E_EXTENSION (extension));
63
64 return E_SHELL (extensible);
65 }
66
67 static gboolean
mailto_handler_is_evolution(GAppInfo * app_info)68 mailto_handler_is_evolution (GAppInfo *app_info)
69 {
70 gint argc;
71 gchar **argv;
72 gchar *basename;
73 gboolean is_evolution;
74 const gchar *mailto_command;
75
76 if (app_info == NULL)
77 return FALSE;
78
79 mailto_command = g_app_info_get_commandline (app_info);
80 if (mailto_command == NULL)
81 return FALSE;
82
83 /* Tokenize the mailto command. */
84 if (!g_shell_parse_argv (mailto_command, &argc, &argv, NULL))
85 return FALSE;
86
87 g_return_val_if_fail (argc > 0, FALSE);
88
89 /* Check the basename of the first token. */
90 basename = g_path_get_basename (argv[0]);
91 is_evolution = g_str_has_prefix (basename, "evolution");
92 g_free (basename);
93
94 g_strfreev (argv);
95
96 return is_evolution;
97 }
98
99 static gboolean
mailto_handler_prompt(EMailtoHandler * extension)100 mailto_handler_prompt (EMailtoHandler *extension)
101 {
102 GSettings *settings;
103 GtkWidget *container;
104 GtkWidget *dialog;
105 GtkWidget *widget;
106 const gchar *text;
107 gchar *markup;
108 gint response;
109
110 dialog = gtk_dialog_new_with_buttons (
111 "", NULL, 0,
112 _("Do _not change settings"), GTK_RESPONSE_NO,
113 _("_Set as default email client"), GTK_RESPONSE_YES,
114 NULL);
115
116 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
117 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
118
119 container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
120
121 widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
122 gtk_container_set_border_width (GTK_CONTAINER (widget), 5);
123 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
124 gtk_widget_show (widget);
125
126 container = widget;
127
128 widget = gtk_image_new_from_icon_name ("dialog-question", GTK_ICON_SIZE_DIALOG);
129 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
130 gtk_widget_show (widget);
131
132 widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
133 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
134 gtk_widget_show (widget);
135
136 container = widget;
137
138 text = _("Do you want to make Evolution your default email client?");
139 markup = g_markup_printf_escaped ("<b>%s</b>", text);
140 widget = gtk_label_new (NULL);
141 gtk_label_set_markup (GTK_LABEL (widget), markup);
142 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
143 gtk_widget_show (widget);
144 g_free (markup);
145
146 text = _("_Do not show this message again");
147 widget = gtk_check_button_new_with_mnemonic (text);
148 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 12);
149 gtk_widget_show (widget);
150
151 settings = e_util_ref_settings ("org.gnome.evolution.mail");
152
153 g_settings_bind (
154 settings, "prompt-check-if-default-mailer",
155 widget, "active",
156 G_SETTINGS_BIND_GET |
157 G_SETTINGS_BIND_SET |
158 G_SETTINGS_BIND_INVERT_BOOLEAN);
159
160 g_object_unref (settings);
161
162 /* Direct input focus away from the checkbox. */
163 widget = gtk_dialog_get_widget_for_response (
164 GTK_DIALOG (dialog), GTK_RESPONSE_YES);
165 gtk_widget_grab_focus (widget);
166
167 response = gtk_dialog_run (GTK_DIALOG (dialog));
168
169 gtk_widget_destroy (dialog);
170
171 return (response == GTK_RESPONSE_YES);
172 }
173
174 static void
mailto_handler_check(EMailtoHandler * extension)175 mailto_handler_check (EMailtoHandler *extension)
176 {
177 GSettings *settings;
178 gboolean check_mailto_handler = TRUE;
179 GAppInfo *app_info = NULL;
180 GError *error = NULL;
181
182 settings = e_util_ref_settings ("org.gnome.evolution.mail");
183
184 check_mailto_handler = g_settings_get_boolean (
185 settings, "prompt-check-if-default-mailer");
186
187 g_object_unref (settings);
188
189 /* Should we check the "mailto" URI handler? */
190 if (!check_mailto_handler)
191 goto exit;
192
193 app_info = g_app_info_get_default_for_type (MAILTO_HANDLER, FALSE);
194
195 /* Is Evolution already handling "mailto" URIs? */
196 if (mailto_handler_is_evolution (app_info))
197 goto exit;
198
199 /* Does the user want Evolution to handle them? */
200 if (!mailto_handler_prompt (extension))
201 goto exit;
202
203 g_clear_object (&app_info);
204
205 /* Configure Evolution to be the "mailto" URI handler. */
206 app_info = g_app_info_create_from_commandline (
207 MAILTO_COMMAND,
208 _("Evolution"),
209 G_APP_INFO_CREATE_SUPPORTS_URIS,
210 &error);
211
212 /* Sanity check. */
213 g_return_if_fail (
214 ((app_info != NULL) && (error == NULL)) ||
215 ((app_info == NULL) && (error != NULL)));
216
217 if (app_info != NULL)
218 g_app_info_set_as_default_for_type (
219 app_info, MAILTO_HANDLER, &error);
220
221 exit:
222 g_clear_object (&app_info);
223
224 if (error != NULL) {
225 g_warning (
226 "Failed to register as default handler: %s",
227 error->message);
228 g_error_free (error);
229 }
230 }
231
232 static void
mailto_handler_constructed(GObject * object)233 mailto_handler_constructed (GObject *object)
234 {
235 EShell *shell;
236 EMailtoHandler *extension;
237
238 extension = E_MAILTO_HANDLER (object);
239
240 shell = mailto_handler_get_shell (extension);
241
242 g_signal_connect_swapped (
243 shell, "event::ready-to-start",
244 G_CALLBACK (mailto_handler_check), extension);
245
246 /* Chain up to parent's constructed() method. */
247 G_OBJECT_CLASS (e_mailto_handler_parent_class)->constructed (object);
248 }
249
250 static void
e_mailto_handler_class_init(EMailtoHandlerClass * class)251 e_mailto_handler_class_init (EMailtoHandlerClass *class)
252 {
253 GObjectClass *object_class;
254 EExtensionClass *extension_class;
255
256 object_class = G_OBJECT_CLASS (class);
257 object_class->constructed = mailto_handler_constructed;
258
259 extension_class = E_EXTENSION_CLASS (class);
260 extension_class->extensible_type = E_TYPE_SHELL;
261 }
262
263 static void
e_mailto_handler_class_finalize(EMailtoHandlerClass * class)264 e_mailto_handler_class_finalize (EMailtoHandlerClass *class)
265 {
266 }
267
268 static void
e_mailto_handler_init(EMailtoHandler * extension)269 e_mailto_handler_init (EMailtoHandler *extension)
270 {
271 }
272
273 G_MODULE_EXPORT void
e_module_load(GTypeModule * type_module)274 e_module_load (GTypeModule *type_module)
275 {
276 e_mailto_handler_register_type (type_module);
277 }
278
279 G_MODULE_EXPORT void
e_module_unload(GTypeModule * type_module)280 e_module_unload (GTypeModule *type_module)
281 {
282 }
283