2 * e-signature-script-dialog.c
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.
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.
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/>
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 #include "e-signature-script-dialog.h"
24 #include <glib/gi18n.h>
25 #include "e-util/e-binding.h"
27 #define E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE(obj) \
28 (G_TYPE_INSTANCE_GET_PRIVATE \
29 ((obj), E_TYPE_SIGNATURE_SCRIPT_DIALOG, ESignatureScriptDialogPrivate))
31 struct _ESignatureScriptDialogPrivate
{
33 GtkWidget
*file_chooser
;
43 static gpointer parent_class
;
46 signature_script_dialog_filter_cb (const GtkFileFilterInfo
*filter_info
)
48 const gchar
*filename
= filter_info
->filename
;
50 return g_file_test (filename
, G_FILE_TEST_IS_EXECUTABLE
);
54 signature_script_dialog_update_status (ESignatureScriptDialog
*dialog
)
57 const gchar
*script_name
;
61 script_file
= e_signature_script_dialog_get_script_file (dialog
);
62 script_name
= e_signature_script_dialog_get_script_name (dialog
);
64 sensitive
= (script_name
!= NULL
&& *script_name
!= '\0');
66 if (script_file
!= NULL
) {
70 filename
= g_file_get_path (script_file
);
71 executable
= g_file_test (filename
, G_FILE_TEST_IS_EXECUTABLE
);
74 show_alert
= !executable
;
75 sensitive
&= executable
;
77 g_object_unref (script_file
);
84 gtk_widget_show (dialog
->priv
->alert
);
86 gtk_widget_hide (dialog
->priv
->alert
);
88 gtk_dialog_set_response_sensitive (
89 GTK_DIALOG (dialog
), GTK_RESPONSE_OK
, sensitive
);
93 signature_script_dialog_set_property (GObject
*object
,
98 switch (property_id
) {
99 case PROP_SCRIPT_FILE
:
100 e_signature_script_dialog_set_script_file (
101 E_SIGNATURE_SCRIPT_DIALOG (object
),
102 g_value_get_object (value
));
105 case PROP_SCRIPT_NAME
:
106 e_signature_script_dialog_set_script_name (
107 E_SIGNATURE_SCRIPT_DIALOG (object
),
108 g_value_get_string (value
));
112 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
116 signature_script_dialog_get_property (GObject
*object
,
121 switch (property_id
) {
122 case PROP_SCRIPT_FILE
:
125 e_signature_script_dialog_get_script_file (
126 E_SIGNATURE_SCRIPT_DIALOG (object
)));
129 case PROP_SCRIPT_NAME
:
132 e_signature_script_dialog_get_script_name (
133 E_SIGNATURE_SCRIPT_DIALOG (object
)));
137 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
141 signature_script_dialog_dispose (GObject
*object
)
143 ESignatureScriptDialogPrivate
*priv
;
145 priv
= E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object
);
147 if (priv
->entry
!= NULL
) {
148 g_object_unref (priv
->entry
);
152 if (priv
->file_chooser
!= NULL
) {
153 g_object_unref (priv
->file_chooser
);
154 priv
->file_chooser
= NULL
;
157 if (priv
->alert
!= NULL
) {
158 g_object_unref (priv
->alert
);
162 /* Chain up to parent's dispose() method. */
163 G_OBJECT_CLASS (parent_class
)->dispose (object
);
167 signature_script_dialog_map (GtkWidget
*widget
)
169 GtkWidget
*action_area
;
170 GtkWidget
*content_area
;
172 /* Chain up to parent's map() method. */
173 GTK_WIDGET_CLASS (parent_class
)->map (widget
);
175 /* XXX Override GtkDialog's broken style property defaults. */
176 action_area
= gtk_dialog_get_action_area (GTK_DIALOG (widget
));
177 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (widget
));
179 gtk_box_set_spacing (GTK_BOX (content_area
), 12);
180 gtk_container_set_border_width (GTK_CONTAINER (action_area
), 0);
181 gtk_container_set_border_width (GTK_CONTAINER (content_area
), 12);
185 signature_script_dialog_class_init (ESignatureScriptDialogClass
*class)
187 GObjectClass
*object_class
;
188 GtkWidgetClass
*widget_class
;
190 parent_class
= g_type_class_peek_parent (class);
191 g_type_class_add_private (class, sizeof (ESignatureScriptDialogPrivate
));
193 object_class
= G_OBJECT_CLASS (class);
194 object_class
->set_property
= signature_script_dialog_set_property
;
195 object_class
->get_property
= signature_script_dialog_get_property
;
196 object_class
->dispose
= signature_script_dialog_dispose
;
198 widget_class
= GTK_WIDGET_CLASS (class);
199 widget_class
->map
= signature_script_dialog_map
;
201 g_object_class_install_property (
204 g_param_spec_object (
211 g_object_class_install_property (
214 g_param_spec_string (
224 signature_script_dialog_init (ESignatureScriptDialog
*dialog
)
226 GtkFileFilter
*filter
;
227 GtkWidget
*content_area
;
228 GtkWidget
*container
;
232 dialog
->priv
= E_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (dialog
);
234 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (dialog
));
236 gtk_dialog_add_button (
238 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
);
240 gtk_dialog_add_button (
242 GTK_STOCK_SAVE
, GTK_RESPONSE_OK
);
244 gtk_dialog_set_has_separator (GTK_DIALOG (dialog
), FALSE
);
245 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_OK
);
247 container
= content_area
;
249 widget
= gtk_table_new (4, 2, FALSE
);
250 gtk_table_set_col_spacings (GTK_TABLE (widget
), 6);
251 gtk_table_set_row_spacings (GTK_TABLE (widget
), 6);
252 gtk_table_set_row_spacing (GTK_TABLE (widget
), 0, 12);
253 gtk_box_pack_start (GTK_BOX (container
), widget
, FALSE
, FALSE
, 0);
254 gtk_widget_show (widget
);
258 widget
= gtk_image_new_from_stock (
259 GTK_STOCK_DIALOG_INFO
, GTK_ICON_SIZE_DIALOG
);
261 GTK_TABLE (container
), widget
,
262 0, 1, 0, 1, 0, 0, 0, 0);
263 gtk_widget_show (widget
);
265 widget
= gtk_label_new (_(
266 "The output of this script will be used as your\n"
267 "signature. The name you specify will be used\n"
268 "for display purposes only."));
270 GTK_TABLE (container
), widget
,
271 1, 2, 0, 1, GTK_FILL
| GTK_EXPAND
, 0, 0, 0);
272 gtk_widget_show (widget
);
274 widget
= gtk_entry_new ();
275 gtk_entry_set_activates_default (GTK_ENTRY (widget
), TRUE
);
277 GTK_TABLE (container
), widget
,
278 1, 2, 1, 2, GTK_FILL
| GTK_EXPAND
, 0, 0, 0);
279 dialog
->priv
->entry
= g_object_ref (widget
);
280 gtk_widget_show (widget
);
282 widget
= gtk_label_new_with_mnemonic (_("_Name:"));
283 gtk_label_set_mnemonic_widget (
284 GTK_LABEL (widget
), dialog
->priv
->entry
);
285 gtk_misc_set_alignment (GTK_MISC (widget
), 1.0, 0.5);
287 GTK_TABLE (container
), widget
,
288 0, 1, 1, 2, GTK_FILL
, 0, 0, 0);
289 gtk_widget_show (widget
);
291 widget
= gtk_file_chooser_button_new (
292 NULL
, GTK_FILE_CHOOSER_ACTION_OPEN
);
294 GTK_TABLE (container
), widget
,
295 1, 2, 2, 3, GTK_FILL
| GTK_EXPAND
, 0, 0, 0);
296 dialog
->priv
->file_chooser
= g_object_ref (widget
);
297 gtk_widget_show (widget
);
299 /* Restrict file selection to executable files. */
300 filter
= gtk_file_filter_new ();
301 gtk_file_filter_add_custom (
302 filter
, GTK_FILE_FILTER_FILENAME
,
303 (GtkFileFilterFunc
) signature_script_dialog_filter_cb
,
305 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget
), filter
);
307 /* XXX ESignature stores a filename instead of a URI,
308 * so we have to restrict it to local files only. */
309 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget
), TRUE
);
311 widget
= gtk_label_new_with_mnemonic (_("S_cript:"));
312 gtk_label_set_mnemonic_widget (
313 GTK_LABEL (widget
), dialog
->priv
->file_chooser
);
315 GTK_TABLE (container
), widget
,
316 0, 1, 2, 3, GTK_FILL
, 0, 0, 0);
317 gtk_widget_show (widget
);
319 /* This is just a placeholder. */
320 widget
= gtk_label_new (NULL
);
322 GTK_TABLE (container
), widget
,
323 0, 1, 3, 4, GTK_FILL
, 0, 0, 0);
324 gtk_widget_show (widget
);
326 widget
= gtk_hbox_new (FALSE
, 6);
328 GTK_TABLE (container
), widget
,
329 1, 2, 3, 4, 0, 0, 0, 0);
330 dialog
->priv
->alert
= g_object_ref (widget
);
331 gtk_widget_show (widget
);
335 widget
= gtk_image_new_from_stock (
336 GTK_STOCK_DIALOG_WARNING
, GTK_ICON_SIZE_MENU
);
337 gtk_box_pack_start (GTK_BOX (container
), widget
, FALSE
, FALSE
, 0);
338 gtk_widget_show (widget
);
340 markup
= g_markup_printf_escaped (
342 _("Script file must be executable."));
343 widget
= gtk_label_new (markup
);
344 gtk_label_set_use_markup (GTK_LABEL (widget
), TRUE
);
345 gtk_misc_set_alignment (GTK_MISC (widget
), 0.0, 0.5);
346 gtk_box_pack_start (GTK_BOX (container
), widget
, TRUE
, TRUE
, 0);
347 gtk_widget_show (widget
);
351 dialog
, "notify::script-file",
352 G_CALLBACK (signature_script_dialog_update_status
), NULL
);
355 dialog
, "notify::script-name",
356 G_CALLBACK (signature_script_dialog_update_status
), NULL
);
358 g_signal_connect_swapped (
359 dialog
->priv
->entry
, "changed",
360 G_CALLBACK (signature_script_dialog_update_status
), dialog
);
362 g_signal_connect_swapped (
363 dialog
->priv
->file_chooser
, "file-set",
364 G_CALLBACK (signature_script_dialog_update_status
), dialog
);
366 signature_script_dialog_update_status (dialog
);
370 e_signature_script_dialog_get_type (void)
372 static GType type
= 0;
374 if (G_UNLIKELY (type
== 0)) {
375 static const GTypeInfo type_info
= {
376 sizeof (ESignatureScriptDialogClass
),
377 (GBaseInitFunc
) NULL
,
378 (GBaseFinalizeFunc
) NULL
,
379 (GClassInitFunc
) signature_script_dialog_class_init
,
380 (GClassFinalizeFunc
) NULL
,
381 NULL
, /* class_data */
382 sizeof (ESignatureScriptDialog
),
384 (GInstanceInitFunc
) signature_script_dialog_init
,
385 NULL
/* value_table */
388 type
= g_type_register_static (
389 GTK_TYPE_DIALOG
, "ESignatureScriptDialog",
397 e_signature_script_dialog_new (GtkWindow
*parent
)
399 return g_object_new (
400 E_TYPE_SIGNATURE_SCRIPT_DIALOG
,
401 "transient-for", parent
, NULL
);
405 e_signature_script_dialog_get_script_file (ESignatureScriptDialog
*dialog
)
407 GtkFileChooser
*file_chooser
;
409 g_return_val_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog
), NULL
);
411 file_chooser
= GTK_FILE_CHOOSER (dialog
->priv
->file_chooser
);
413 return gtk_file_chooser_get_file (file_chooser
);
417 e_signature_script_dialog_set_script_file (ESignatureScriptDialog
*dialog
,
420 GtkFileChooser
*file_chooser
;
421 GError
*error
= NULL
;
423 g_return_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog
));
424 g_return_if_fail (G_IS_FILE (script_file
));
426 file_chooser
= GTK_FILE_CHOOSER (dialog
->priv
->file_chooser
);
428 if (gtk_file_chooser_set_file (file_chooser
, script_file
, &error
))
429 g_object_notify (G_OBJECT (dialog
), "script-file");
431 g_warning ("%s", error
->message
);
432 g_error_free (error
);
437 e_signature_script_dialog_get_script_name (ESignatureScriptDialog
*dialog
)
441 g_return_val_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog
), NULL
);
443 entry
= GTK_ENTRY (dialog
->priv
->entry
);
445 return gtk_entry_get_text (entry
);
449 e_signature_script_dialog_set_script_name (ESignatureScriptDialog
*dialog
,
450 const gchar
*script_name
)
454 g_return_if_fail (E_IS_SIGNATURE_SCRIPT_DIALOG (dialog
));
456 if (script_name
== NULL
)
459 entry
= GTK_ENTRY (dialog
->priv
->entry
);
460 gtk_entry_set_text (entry
, script_name
);
462 g_object_notify (G_OBJECT (dialog
), "script-name");