No issues found
1 /*
2 * e-shell-utils.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 /**
23 * SECTION: e-shell-utils
24 * @short_description: high-level utilities with shell integration
25 * @include: shell/e-shell-utils.h
26 **/
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include "e-shell-utils.h"
33
34 #include <glib/gi18n-lib.h>
35
36 #include <libedataserver/libedataserver.h>
37
38 #include "widgets/misc/e-import-assistant.h"
39
40 /**
41 * e_shell_configure_ui_manager:
42 * @shell: an #EShell
43 * @ui_manager: an #EUIManager
44 *
45 * Adds shell integration to @ui_manager. In particular, it keeps
46 * @ui_manager's EUIManager:express-mode property synchronized with
47 * @shell's EShell:express-mode property.
48 **/
49 void
50 e_shell_configure_ui_manager (EShell *shell,
51 EUIManager *ui_manager)
52 {
53 g_return_if_fail (E_IS_SHELL (shell));
54 g_return_if_fail (E_IS_UI_MANAGER (ui_manager));
55
56 g_object_bind_property (
57 shell, "express-mode",
58 ui_manager, "express-mode",
59 G_BINDING_SYNC_CREATE);
60 }
61
62 /**
63 * e_shell_run_open_dialog:
64 * @shell: an #EShell
65 * @title: file chooser dialog title
66 * @customize_func: optional dialog customization function
67 * @customize_data: optional data to pass to @customize_func
68 *
69 * Runs a #GtkFileChooserDialog in open mode with the given title and
70 * returns the selected #GFile. If @customize_func is provided, the
71 * function is called just prior to running the dialog (the file chooser
72 * is the first argument, @customize data is the second). If the user
73 * cancels the dialog the function will return %NULL.
74 *
75 * Returns: the #GFile to open, or %NULL
76 **/
77 GFile *
78 e_shell_run_open_dialog (EShell *shell,
79 const gchar *title,
80 GtkCallback customize_func,
81 gpointer customize_data)
82 {
83 GtkFileChooser *file_chooser;
84 GFile *chosen_file = NULL;
85 GtkWidget *dialog;
86 GtkWindow *parent;
87
88 g_return_val_if_fail (E_IS_SHELL (shell), NULL);
89
90 parent = e_shell_get_active_window (shell);
91
92 dialog = gtk_file_chooser_dialog_new (
93 title, parent,
94 GTK_FILE_CHOOSER_ACTION_OPEN,
95 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
96 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
97
98 file_chooser = GTK_FILE_CHOOSER (dialog);
99
100 gtk_dialog_set_default_response (
101 GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
102
103 gtk_file_chooser_set_local_only (file_chooser, FALSE);
104
105 /* Allow further customizations before running the dialog. */
106 if (customize_func != NULL)
107 customize_func (dialog, customize_data);
108
109 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
110 chosen_file = gtk_file_chooser_get_file (file_chooser);
111
112 gtk_widget_destroy (dialog);
113
114 return chosen_file;
115 }
116
117 /**
118 * e_shell_run_save_dialog:
119 * @shell: an #EShell
120 * @title: file chooser dialog title
121 * @suggestion: file name suggestion, or %NULL
122 * @filters: Possible filters for dialog, or %NULL
123 * @customize_func: optional dialog customization function
124 * @customize_data: optional data to pass to @customize_func
125 *
126 * Runs a #GtkFileChooserDialog in save mode with the given title and
127 * returns the selected #GFile. If @customize_func is provided, the
128 * function is called just prior to running the dialog (the file chooser
129 * is the first argument, @customize_data is the second). If the user
130 * cancels the dialog the function will return %NULL.
131 *
132 * With non-%NULL @filters will be added also file filters to the dialog.
133 * The string format is "pat1:mt1;pat2:mt2:...", where 'pat' is a pattern
134 * and 'mt' is a MIME type for the pattern to be used. There can be more
135 * than one MIME type, those are separated by comma.
136 *
137 * Returns: the #GFile to save to, or %NULL
138 **/
139 GFile *
140 e_shell_run_save_dialog (EShell *shell,
141 const gchar *title,
142 const gchar *suggestion,
143 const gchar *filters,
144 GtkCallback customize_func,
145 gpointer customize_data)
146 {
147 GtkFileChooser *file_chooser;
148 GFile *chosen_file = NULL;
149 GtkWidget *dialog;
150 GtkWindow *parent;
151
152 g_return_val_if_fail (E_IS_SHELL (shell), NULL);
153
154 parent = e_shell_get_active_window (shell);
155
156 dialog = gtk_file_chooser_dialog_new (
157 title, parent,
158 GTK_FILE_CHOOSER_ACTION_SAVE,
159 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
160 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
161
162 file_chooser = GTK_FILE_CHOOSER (dialog);
163
164 gtk_dialog_set_default_response (
165 GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
166
167 gtk_file_chooser_set_local_only (file_chooser, FALSE);
168 gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE);
169
170 if (suggestion != NULL) {
171 gchar *current_name;
172
173 current_name = g_strdup (suggestion);
174 e_filename_make_safe (current_name);
175 gtk_file_chooser_set_current_name (file_chooser, current_name);
176 g_free (current_name);
177 }
178
179 if (filters != NULL) {
180 gchar **flts = g_strsplit (filters, ";", -1);
181 gint i;
182
183 for (i = 0; flts[i]; i++) {
184 GtkFileFilter *filter = gtk_file_filter_new ();
185 gchar *flt = flts[i];
186 gchar *delim = strchr (flt, ':'), *next = NULL;
187
188 if (delim) {
189 *delim = 0;
190 next = strchr (delim + 1, ',');
191 }
192
193 gtk_file_filter_add_pattern (filter, flt);
194 if (g_ascii_strcasecmp (flt, "*.mbox") == 0)
195 gtk_file_filter_set_name (filter, _("Berkeley Mailbox (mbox)"));
196 else if (g_ascii_strcasecmp (flt, "*.vcf") == 0)
197 gtk_file_filter_set_name (filter, _("vCard (.vcf)"));
198 else if (g_ascii_strcasecmp (flt, "*.ics") == 0)
199 gtk_file_filter_set_name (filter, _("iCalendar (.ics)"));
200
201 while (delim) {
202 delim++;
203 if (next)
204 *next = 0;
205
206 gtk_file_filter_add_mime_type (filter, delim);
207
208 delim = next;
209 if (next)
210 next = strchr (next + 1, ',');
211 }
212
213 gtk_file_chooser_add_filter (file_chooser, filter);
214 }
215
216 if (flts && flts[0]) {
217 GtkFileFilter *filter = gtk_file_filter_new ();
218
219 gtk_file_filter_add_pattern (filter, "*");
220 gtk_file_filter_set_name (filter, _("All Files (*)"));
221 gtk_file_chooser_add_filter (file_chooser, filter);
222 }
223
224 g_strfreev (flts);
225 }
226
227 /* Allow further customizations before running the dialog. */
228 if (customize_func != NULL)
229 customize_func (dialog, customize_data);
230
231 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
232 chosen_file = gtk_file_chooser_get_file (file_chooser);
233
234 gtk_widget_destroy (dialog);
235
236 return chosen_file;
237 }
238
239 /**
240 * e_shell_utils_import_uris:
241 * @shell: The #EShell instance
242 * @uris: %NULL-terminated list of URIs to import
243 *
244 * Imports given URIs to Evolution, giving user a choice what to import
245 * if more than one importer can be applied, and where to import it, if
246 * the importer itself is configurable.
247 *
248 * URIs should be either a filename or URI of form file://.
249 * All others are skipped.
250 *
251 * Returns: the number of URIs successfully handled
252 **/
253 guint
254 e_shell_utils_import_uris (EShell *shell,
255 const gchar * const *uris)
256 {
257 GtkWindow *parent;
258 GtkWidget *assistant;
259
260 g_return_val_if_fail (shell != NULL, 0);
261 g_return_val_if_fail (uris != NULL, 0);
262
263 parent = e_shell_get_active_window (shell);
264 assistant = e_import_assistant_new_simple (parent, uris);
265
266 if (assistant) {
267 g_signal_connect_after (
268 assistant, "cancel",
269 G_CALLBACK (gtk_widget_destroy), NULL);
270
271 g_signal_connect_after (
272 assistant, "finished",
273 G_CALLBACK (gtk_widget_destroy), NULL);
274
275 gtk_application_add_window (
276 GTK_APPLICATION (shell),
277 GTK_WINDOW (assistant));
278
279 gtk_widget_show (assistant);
280 } else
281 g_warning ("Cannot import any of the given URIs");
282
283 return g_strv_length ((gchar **) uris);
284 }
285
286 /**
287 * e_shell_hide_widgets_for_express_mode:
288 * @shell: an #EShell
289 * @builder: a #GtkBuilder
290 * @widget_name: NULL-terminated list of strings
291 *
292 * If Evolution is running in Express mode (i.e. if the specified @shell is
293 * in Express mode), then this function will hide a list of widgets, based
294 * on their specified names. The list of names must be NULL-terminated,
295 * and each element of that list must be the name of a widget present in
296 * @builder. Those widgets will then get hidden.
297 *
298 * This can be used to simplify preference dialogs and such in an easy
299 * fashion, for use in Express mode.
300 *
301 * If Evolution is not running in Express mode, this function does nothing.
302 */
303 void
304 e_shell_hide_widgets_for_express_mode (EShell *shell,
305 GtkBuilder *builder,
306 const gchar *widget_name,
307 ...)
308 {
309 va_list args;
310
311 g_return_if_fail (E_IS_SHELL (shell));
312 g_return_if_fail (GTK_IS_BUILDER (builder));
313 g_return_if_fail (widget_name != NULL);
314
315 if (!e_shell_get_express_mode (shell))
316 return;
317
318 va_start (args, widget_name);
319
320 while (widget_name != NULL) {
321 GObject *object;
322
323 object = gtk_builder_get_object (builder, widget_name);
324 if (!GTK_IS_WIDGET (object)) {
325 g_error (
326 "Object '%s' was not found in the builder "
327 "file, or it is not a GtkWidget", widget_name);
328 g_assert_not_reached ();
329 }
330
331 gtk_widget_hide (GTK_WIDGET (object));
332
333 widget_name = va_arg (args, const gchar *);
334 }
335
336 va_end (args);
337 }