gboolean eex_ui_composer_actions (GtkUIManager *manager, EMsgComposer *composer) { static GtkActionEntry entries[] = { { "eex-send-options", NULL, N_("_Send Options"), NULL, N_("Insert Send options"), G_CALLBACK (action_send_options_cb) } }; GtkhtmlEditor *editor; EComposerHeaderTable *headers; EComposerHeader *header; editor = GTKHTML_EDITOR (composer); /* Add actions to the "composer" action group. */ e_action_group_add_actions_localized ( gtkhtml_editor_get_action_group (editor, "composer"), GETTEXT_PACKAGE, entries, G_N_ELEMENTS (entries), composer); headers = e_msg_composer_get_header_table (composer); header = e_composer_header_table_get_header (headers, E_COMPOSER_HEADER_FROM); from_changed_cb (E_COMPOSER_FROM_HEADER (header), composer); g_signal_connect (G_OBJECT (header), "changed", G_CALLBACK (from_changed_cb), composer); return TRUE; }
void e_composer_private_constructed (EMsgComposer *composer) { EMsgComposerPrivate *priv = composer->priv; EFocusTracker *focus_tracker; EComposerHeader *header; EShell *shell; EClientCache *client_cache; EHTMLEditor *editor; EHTMLEditorView *view; GtkUIManager *ui_manager; GtkAction *action; GtkWidget *container; GtkWidget *widget; GtkWidget *send_widget; GtkWindow *window; GSettings *settings; const gchar *path; gchar *filename, *gallery_path; gint ii; GError *error = NULL; editor = e_msg_composer_get_editor (composer); ui_manager = e_html_editor_get_ui_manager (editor); view = e_html_editor_get_view (editor); settings = e_util_ref_settings ("org.gnome.evolution.mail"); shell = e_msg_composer_get_shell (composer); client_cache = e_shell_get_client_cache (shell); /* Each composer window gets its own window group. */ window = GTK_WINDOW (composer); priv->window_group = gtk_window_group_new (); gtk_window_group_add_window (priv->window_group, window); priv->async_actions = gtk_action_group_new ("async"); priv->charset_actions = gtk_action_group_new ("charset"); priv->composer_actions = gtk_action_group_new ("composer"); priv->extra_hdr_names = g_ptr_array_new (); priv->extra_hdr_values = g_ptr_array_new (); priv->charset = e_composer_get_default_charset (); priv->is_from_new_message = FALSE; priv->set_signature_from_message = FALSE; priv->disable_signature = FALSE; priv->busy = FALSE; priv->saved_editable = FALSE; priv->drop_occured = FALSE; priv->dnd_is_uri = FALSE; priv->check_if_signature_is_changed = FALSE; priv->ignore_next_signature_change = FALSE; priv->dnd_history_saved = FALSE; priv->focused_entry = NULL; e_composer_actions_init (composer); filename = e_composer_find_data_file ("evolution-composer.ui"); gtk_ui_manager_add_ui_from_file (ui_manager, filename, &error); g_free (filename); /* We set the send button as important to have a label */ path = "/main-toolbar/pre-main-toolbar/send"; send_widget = gtk_ui_manager_get_widget (ui_manager, path); gtk_tool_item_set_is_important (GTK_TOOL_ITEM (send_widget), TRUE); composer_setup_charset_menu (composer); if (error != NULL) { /* Henceforth, bad things start happening. */ g_critical ("%s", error->message); g_clear_error (&error); } /* Configure an EFocusTracker to manage selection actions. */ focus_tracker = e_focus_tracker_new (GTK_WINDOW (composer)); action = e_html_editor_get_action (editor, "cut"); e_focus_tracker_set_cut_clipboard_action (focus_tracker, action); action = e_html_editor_get_action (editor, "copy"); e_focus_tracker_set_copy_clipboard_action (focus_tracker, action); action = e_html_editor_get_action (editor, "paste"); e_focus_tracker_set_paste_clipboard_action (focus_tracker, action); action = e_html_editor_get_action (editor, "select-all"); e_focus_tracker_set_select_all_action (focus_tracker, action); action = e_html_editor_get_action (editor, "undo"); e_focus_tracker_set_undo_action (focus_tracker, action); action = e_html_editor_get_action (editor, "redo"); e_focus_tracker_set_redo_action (focus_tracker, action); priv->focus_tracker = focus_tracker; widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add (GTK_CONTAINER (composer), widget); gtk_widget_show (widget); container = widget; /* Construct the main menu and toolbar. */ widget = e_html_editor_get_managed_widget (editor, "/main-menu"); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); gtk_widget_show (widget); widget = e_html_editor_get_managed_widget (editor, "/main-toolbar"); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); gtk_widget_show (widget); /* Construct the header table. */ widget = e_composer_header_table_new (client_cache); gtk_container_set_border_width (GTK_CONTAINER (widget), 6); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); priv->header_table = g_object_ref (widget); gtk_widget_show (widget); header = e_composer_header_table_get_header ( E_COMPOSER_HEADER_TABLE (widget), E_COMPOSER_HEADER_SUBJECT); e_binding_bind_property ( view, "spell-checker", header->input_widget, "spell-checker", G_BINDING_SYNC_CREATE); /* Construct the editing toolbars. We'll have to reparent * the embedded EHTMLEditorView a little further down. */ widget = GTK_WIDGET (editor); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); gtk_widget_show (widget); /* Construct the attachment paned. */ widget = e_attachment_paned_new (); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); priv->attachment_paned = g_object_ref_sink (widget); gtk_widget_show (widget); e_binding_bind_property ( view, "editable", widget, "sensitive", G_BINDING_SYNC_CREATE); container = e_attachment_paned_get_content_area ( E_ATTACHMENT_PANED (priv->attachment_paned)); widget = gtk_paned_new (GTK_ORIENTATION_VERTICAL); gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); gtk_widget_show (widget); container = widget; widget = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_size_request (widget, -1, GALLERY_INITIAL_HEIGHT); gtk_paned_pack1 (GTK_PANED (container), widget, FALSE, FALSE); priv->gallery_scrolled_window = g_object_ref (widget); gtk_widget_show (widget); /* Reparent the scrolled window containing the web view * widget into the content area of the top attachment pane. */ widget = GTK_WIDGET (view); widget = gtk_widget_get_parent (widget); gtk_widget_reparent (widget, container); /* Construct the picture gallery. */ container = priv->gallery_scrolled_window; /* FIXME This should be an EMsgComposer property. */ gallery_path = g_settings_get_string ( settings, "composer-gallery-path"); widget = e_picture_gallery_new (gallery_path); gtk_container_add (GTK_CONTAINER (container), widget); priv->gallery_icon_view = g_object_ref_sink (widget); g_free (gallery_path); e_signal_connect_notify_swapped ( view, "notify::mode", G_CALLBACK (composer_update_gallery_visibility), composer); g_signal_connect_swapped ( ACTION (PICTURE_GALLERY), "toggled", G_CALLBACK (composer_update_gallery_visibility), composer); /* Initial sync */ composer_update_gallery_visibility (composer); /* Bind headers to their corresponding actions. */ for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) { EComposerHeaderTable *table; EComposerHeader *header; GtkAction *action; table = E_COMPOSER_HEADER_TABLE (priv->header_table); header = e_composer_header_table_get_header (table, ii); switch (ii) { case E_COMPOSER_HEADER_FROM: e_widget_undo_attach ( GTK_WIDGET (e_composer_from_header_get_name_entry (E_COMPOSER_FROM_HEADER (header))), focus_tracker); e_widget_undo_attach ( GTK_WIDGET (e_composer_from_header_get_address_entry (E_COMPOSER_FROM_HEADER (header))), focus_tracker); action = ACTION (VIEW_FROM_OVERRIDE); e_binding_bind_property ( header, "override-visible", action, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); continue; case E_COMPOSER_HEADER_BCC: action = ACTION (VIEW_BCC); break; case E_COMPOSER_HEADER_CC: action = ACTION (VIEW_CC); break; case E_COMPOSER_HEADER_REPLY_TO: action = ACTION (VIEW_REPLY_TO); e_widget_undo_attach ( GTK_WIDGET (header->input_widget), focus_tracker); break; case E_COMPOSER_HEADER_SUBJECT: e_widget_undo_attach ( GTK_WIDGET (header->input_widget), focus_tracker); continue; default: continue; } e_binding_bind_property ( header, "sensitive", action, "sensitive", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); e_binding_bind_property ( header, "visible", action, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); } /* Disable actions that start asynchronous activities while an * asynchronous activity is in progress. We enforce this with * a simple inverted binding to EMsgComposer's "busy" property. */ e_binding_bind_property ( composer, "busy", priv->async_actions, "sensitive", G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); e_binding_bind_property ( composer, "busy", priv->header_table, "sensitive", G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); g_object_unref (settings); }