/* * e-mail-signature-manager.c * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with the program; if not, see * */ #include "e-mail-signature-manager.h" #include #include #include #include #include "e-mail-signature-preview.h" #include "e-mail-signature-tree-view.h" #include "e-mail-signature-script-dialog.h" #define E_MAIL_SIGNATURE_MANAGER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_MAIL_SIGNATURE_MANAGER, EMailSignatureManagerPrivate)) #define PREVIEW_HEIGHT 200 struct _EMailSignatureManagerPrivate { ESourceRegistry *registry; GtkWidget *tree_view; /* not referenced */ GtkWidget *add_button; /* not referenced */ GtkWidget *add_script_button; /* not referenced */ GtkWidget *edit_button; /* not referenced */ GtkWidget *remove_button; /* not referenced */ GtkWidget *preview; /* not referenced */ gboolean prefer_html; }; enum { PROP_0, PROP_PREFER_HTML, PROP_REGISTRY }; enum { ADD_SIGNATURE, ADD_SIGNATURE_SCRIPT, EDITOR_CREATED, EDIT_SIGNATURE, REMOVE_SIGNATURE, LAST_SIGNAL }; static guint signals[LAST_SIGNAL]; G_DEFINE_TYPE ( EMailSignatureManager, e_mail_signature_manager, GTK_TYPE_PANED) static void mail_signature_manager_emit_editor_created (EMailSignatureManager *manager, GtkWidget *editor) { g_return_if_fail (E_IS_MAIL_SIGNATURE_EDITOR (editor)); g_signal_emit (manager, signals[EDITOR_CREATED], 0, editor); } static gboolean mail_signature_manager_key_press_event_cb (EMailSignatureManager *manager, GdkEventKey *event) { if (event->keyval == GDK_KEY_Delete) { e_mail_signature_manager_remove_signature (manager); return TRUE; } return FALSE; } static void mail_signature_manager_run_script_dialog (EMailSignatureManager *manager, ESource *source, const gchar *title) { ESourceRegistry *registry; GtkWidget *dialog; gpointer parent; registry = e_mail_signature_manager_get_registry (manager); parent = gtk_widget_get_toplevel (GTK_WIDGET (manager)); parent = gtk_widget_is_toplevel (parent) ? parent : NULL; dialog = e_mail_signature_script_dialog_new (registry, parent, source); gtk_window_set_title (GTK_WINDOW (dialog), title); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { EAsyncClosure *closure; GAsyncResult *result; GError *error = NULL; closure = e_async_closure_new (); /* FIXME Make this cancellable. */ e_mail_signature_script_dialog_commit ( E_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL, e_async_closure_callback, closure); result = e_async_closure_wait (closure); e_mail_signature_script_dialog_commit_finish ( E_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), result, &error); e_async_closure_free (closure); /* FIXME Make this into an EAlert. */ if (error != NULL) { g_warning ("%s: %s", G_STRFUNC, error->message); g_error_free (error); } } gtk_widget_destroy (dialog); } static void mail_signature_manager_selection_changed_cb (EMailSignatureManager *manager, GtkTreeSelection *selection) { EMailSignaturePreview *preview; EMailSignatureTreeView *tree_view; ESource *source; GtkWidget *edit_button; GtkWidget *remove_button; gboolean sensitive; const gchar *uid = NULL; edit_button = manager->priv->edit_button; remove_button = manager->priv->remove_button; tree_view = E_MAIL_SIGNATURE_TREE_VIEW (manager->priv->tree_view); source = e_mail_signature_tree_view_ref_selected_source (tree_view); if (source != NULL) uid = e_source_get_uid (source); preview = E_MAIL_SIGNATURE_PREVIEW (manager->priv->preview); e_mail_signature_preview_set_source_uid (preview, uid); sensitive = (source != NULL); gtk_widget_set_sensitive (edit_button, sensitive); gtk_widget_set_sensitive (remove_button, sensitive); if (source != NULL) g_object_unref (source); } static void mail_signature_manager_set_registry (EMailSignatureManager *manager, ESourceRegistry *registry) { g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); g_return_if_fail (manager->priv->registry == NULL); manager->priv->registry = g_object_ref (registry); } static void mail_signature_manager_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { switch (property_id) { case PROP_PREFER_HTML: e_mail_signature_manager_set_prefer_html ( E_MAIL_SIGNATURE_MANAGER (object), g_value_get_boolean (value)); return; case PROP_REGISTRY: mail_signature_manager_set_registry ( E_MAIL_SIGNATURE_MANAGER (object), g_value_get_object (value)); return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void mail_signature_manager_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { case PROP_PREFER_HTML: g_value_set_boolean ( value, e_mail_signature_manager_get_prefer_html ( E_MAIL_SIGNATURE_MANAGER (object))); return; case PROP_REGISTRY: g_value_set_object ( value, e_mail_signature_manager_get_registry ( E_MAIL_SIGNATURE_MANAGER (object))); return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void mail_signature_manager_dispose (GObject *object) { EMailSignatureManagerPrivate *priv; priv = E_MAIL_SIGNATURE_MANAGER_GET_PRIVATE (object); if (priv->registry != NULL) { g_object_unref (priv->registry); priv->registry = NULL; } /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_mail_signature_manager_parent_class)-> dispose (object); } static void mail_signature_manager_constructed (GObject *object) { EMailSignatureManager *manager; GtkTreeSelection *selection; ESourceRegistry *registry; GSettings *settings; GtkWidget *container; GtkWidget *widget; GtkWidget *hbox; /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (e_mail_signature_manager_parent_class)-> constructed (object); manager = E_MAIL_SIGNATURE_MANAGER (object); registry = e_mail_signature_manager_get_registry (manager); gtk_orientable_set_orientation ( GTK_ORIENTABLE (manager), GTK_ORIENTATION_VERTICAL); container = GTK_WIDGET (manager); widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 12, 0, 0); gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE); gtk_widget_show (widget); container = widget; widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_container_add (GTK_CONTAINER (container), widget); gtk_widget_show (widget); container = hbox = widget; widget = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); gtk_widget_show (widget); container = widget; widget = e_mail_signature_tree_view_new (registry); gtk_container_add (GTK_CONTAINER (container), widget); manager->priv->tree_view = widget; /* not referenced */ gtk_widget_show (widget); g_signal_connect_swapped ( widget, "key-press-event", G_CALLBACK (mail_signature_manager_key_press_event_cb), manager); g_signal_connect_swapped ( widget, "row-activated", G_CALLBACK (e_mail_signature_manager_edit_signature), manager); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); g_signal_connect_swapped ( selection, "changed", G_CALLBACK (mail_signature_manager_selection_changed_cb), manager); container = hbox; widget = gtk_button_box_new (GTK_ORIENTATION_VERTICAL); gtk_button_box_set_layout ( GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START); gtk_box_set_spacing (GTK_BOX (widget), 6); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); gtk_widget_show (widget); container = widget; widget = gtk_button_new_from_stock (GTK_STOCK_ADD); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); manager->priv->add_button = widget; /* not referenced */ gtk_widget_show (widget); g_signal_connect_swapped ( widget, "clicked", G_CALLBACK (e_mail_signature_manager_add_signature), manager); widget = gtk_button_new_with_mnemonic (_("Add _Script")); gtk_button_set_image ( GTK_BUTTON (widget), gtk_image_new_from_stock ( GTK_STOCK_EXECUTE, GTK_ICON_SIZE_BUTTON)); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); manager->priv->add_script_button = widget; /* not referenced */ gtk_widget_show (widget); settings = g_settings_new ("org.gnome.desktop.lockdown"); g_settings_bind ( settings, "disable-command-line", widget, "visible", G_SETTINGS_BIND_GET | G_SETTINGS_BIND_INVERT_BOOLEAN); g_object_unref (settings); g_signal_connect_swapped ( widget, "clicked", G_CALLBACK (e_mail_signature_manager_add_signature_script), manager); widget = gtk_button_new_from_stock (GTK_STOCK_EDIT); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); manager->priv->edit_button = widget; /* not referenced */ gtk_widget_show (widget); g_signal_connect_swapped ( widget, "clicked", G_CALLBACK (e_mail_signature_manager_edit_signature), manager); widget = gtk_button_new_from_stock (GTK_STOCK_REMOVE); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); manager->priv->remove_button = widget; /* not referenced */ gtk_widget_show (widget); g_signal_connect_swapped ( widget, "clicked", G_CALLBACK (e_mail_signature_manager_remove_signature), manager); container = GTK_WIDGET (manager); widget = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, FALSE); gtk_widget_show (widget); container = widget; widget = e_mail_signature_preview_new (registry); gtk_container_add (GTK_CONTAINER (container), widget); manager->priv->preview = widget; /* not referenced */ gtk_widget_show (widget); gtk_paned_set_position (GTK_PANED (manager), PREVIEW_HEIGHT); } static void mail_signature_manager_add_signature (EMailSignatureManager *manager) { ESourceRegistry *registry; GtkWidget *editor; registry = e_mail_signature_manager_get_registry (manager); editor = e_mail_signature_editor_new (registry, NULL); gtkhtml_editor_set_html_mode ( GTKHTML_EDITOR (editor), manager->priv->prefer_html); mail_signature_manager_emit_editor_created (manager, editor); gtk_widget_grab_focus (manager->priv->tree_view); } static void mail_signature_manager_add_signature_script (EMailSignatureManager *manager) { const gchar *title; title = _("Add Signature Script"); mail_signature_manager_run_script_dialog (manager, NULL, title); gtk_widget_grab_focus (manager->priv->tree_view); } static void mail_signature_manager_editor_created (EMailSignatureManager *manager, EMailSignatureEditor *editor) { GtkWindowPosition position; gpointer parent; position = GTK_WIN_POS_CENTER_ON_PARENT; parent = gtk_widget_get_toplevel (GTK_WIDGET (manager)); parent = gtk_widget_is_toplevel (parent) ? parent : NULL; gtk_window_set_transient_for (GTK_WINDOW (editor), parent); gtk_window_set_position (GTK_WINDOW (editor), position); gtk_widget_show (GTK_WIDGET (editor)); } static void mail_signature_manager_edit_signature (EMailSignatureManager *manager) { EMailSignatureTreeView *tree_view; ESourceMailSignature *extension; ESourceRegistry *registry; GtkWidget *editor; ESource *source; GFileInfo *file_info; GFile *file; const gchar *attribute; const gchar *extension_name; const gchar *title; GError *error = NULL; registry = e_mail_signature_manager_get_registry (manager); tree_view = E_MAIL_SIGNATURE_TREE_VIEW (manager->priv->tree_view); source = e_mail_signature_tree_view_ref_selected_source (tree_view); g_return_if_fail (source != NULL); extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; extension = e_source_get_extension (source, extension_name); file = e_source_mail_signature_get_file (extension); attribute = G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE; /* XXX This blocks but it should just be a local file. */ file_info = g_file_query_info ( file, attribute, G_FILE_QUERY_INFO_NONE, NULL, &error); /* FIXME Make this into an EAlert. */ if (error != NULL) { g_warn_if_fail (file_info == NULL); g_warning ("%s: %s", G_STRFUNC, error->message); g_object_unref (source); g_error_free (error); return; } if (g_file_info_get_attribute_boolean (file_info, attribute)) goto script; editor = e_mail_signature_editor_new (registry, source); mail_signature_manager_emit_editor_created (manager, editor); goto exit; script: title = _("Edit Signature Script"); mail_signature_manager_run_script_dialog (manager, source, title); exit: gtk_widget_grab_focus (GTK_WIDGET (tree_view)); g_object_unref (file_info); g_object_unref (source); } static void mail_signature_manager_remove_signature (EMailSignatureManager *manager) { EMailSignatureTreeView *tree_view; ESourceMailSignature *extension; ESource *source; GFile *file; const gchar *extension_name; GError *error = NULL; tree_view = E_MAIL_SIGNATURE_TREE_VIEW (manager->priv->tree_view); source = e_mail_signature_tree_view_ref_selected_source (tree_view); if (source == NULL) return; extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE; extension = e_source_get_extension (source, extension_name); file = e_source_mail_signature_get_file (extension); /* XXX This blocks but it should just be a local file. */ if (!g_file_delete (file, NULL, &error)) { g_warning ("%s", error->message); g_clear_error (&error); } /* Remove the mail signature data source asynchronously. * XXX No callback function because there's not much we can do * if this fails. We should probably implement EAlertSink. */ e_source_remove (source, NULL, NULL, NULL); gtk_widget_grab_focus (GTK_WIDGET (tree_view)); g_object_unref (source); } static void e_mail_signature_manager_class_init (EMailSignatureManagerClass *class) { GObjectClass *object_class; g_type_class_add_private ( class, sizeof (EMailSignatureManagerPrivate)); object_class = G_OBJECT_CLASS (class); object_class->set_property = mail_signature_manager_set_property; object_class->get_property = mail_signature_manager_get_property; object_class->dispose = mail_signature_manager_dispose; object_class->constructed = mail_signature_manager_constructed; class->add_signature = mail_signature_manager_add_signature; class->add_signature_script = mail_signature_manager_add_signature_script; class->editor_created = mail_signature_manager_editor_created; class->edit_signature = mail_signature_manager_edit_signature; class->remove_signature = mail_signature_manager_remove_signature; g_object_class_install_property ( object_class, PROP_PREFER_HTML, g_param_spec_boolean ( "prefer-html", "Prefer HTML", NULL, TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); g_object_class_install_property ( object_class, PROP_REGISTRY, g_param_spec_object ( "registry", "Registry", NULL, E_TYPE_SOURCE_REGISTRY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); signals[ADD_SIGNATURE] = g_signal_new ( "add-signature", G_OBJECT_CLASS_TYPE (class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (EMailSignatureManagerClass, add_signature), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[ADD_SIGNATURE_SCRIPT] = g_signal_new ( "add-signature-script", G_OBJECT_CLASS_TYPE (class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET ( EMailSignatureManagerClass, add_signature_script), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[EDITOR_CREATED] = g_signal_new ( "editor-created", G_OBJECT_CLASS_TYPE (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (EMailSignatureManagerClass, editor_created), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, E_TYPE_MAIL_SIGNATURE_EDITOR); signals[EDIT_SIGNATURE] = g_signal_new ( "edit-signature", G_OBJECT_CLASS_TYPE (class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (EMailSignatureManagerClass, edit_signature), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[REMOVE_SIGNATURE] = g_signal_new ( "remove-signature", G_OBJECT_CLASS_TYPE (class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (EMailSignatureManagerClass, remove_signature), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void e_mail_signature_manager_init (EMailSignatureManager *manager) { manager->priv = E_MAIL_SIGNATURE_MANAGER_GET_PRIVATE (manager); } GtkWidget * e_mail_signature_manager_new (ESourceRegistry *registry) { g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); return g_object_new ( E_TYPE_MAIL_SIGNATURE_MANAGER, "registry", registry, NULL); } void e_mail_signature_manager_add_signature (EMailSignatureManager *manager) { g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); g_signal_emit (manager, signals[ADD_SIGNATURE], 0); } void e_mail_signature_manager_add_signature_script (EMailSignatureManager *manager) { g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); g_signal_emit (manager, signals[ADD_SIGNATURE_SCRIPT], 0); } void e_mail_signature_manager_edit_signature (EMailSignatureManager *manager) { g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); g_signal_emit (manager, signals[EDIT_SIGNATURE], 0); } void e_mail_signature_manager_remove_signature (EMailSignatureManager *manager) { g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); g_signal_emit (manager, signals[REMOVE_SIGNATURE], 0); } gboolean e_mail_signature_manager_get_prefer_html (EMailSignatureManager *manager) { g_return_val_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager), FALSE); return manager->priv->prefer_html; } void e_mail_signature_manager_set_prefer_html (EMailSignatureManager *manager, gboolean prefer_html) { g_return_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager)); if (manager->priv->prefer_html == prefer_html) return; manager->priv->prefer_html = prefer_html; g_object_notify (G_OBJECT (manager), "prefer-html"); } ESourceRegistry * e_mail_signature_manager_get_registry (EMailSignatureManager *manager) { g_return_val_if_fail (E_IS_MAIL_SIGNATURE_MANAGER (manager), NULL); return manager->priv->registry; }