X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmaemo%2Fmodest-msg-edit-window.c;h=3dfd3f64a3507a053d63ebe56c40615a94dc6ba9;hp=4ca1f4d1107e6b7c3a317570a4786748ab89ba23;hb=66a30e4f7f6a0a4357265f36e6698f877ef141a6;hpb=c23c9b6cc6be2bcdb5630e3855f2d9d518a49190 diff --git a/src/maemo/modest-msg-edit-window.c b/src/maemo/modest-msg-edit-window.c index 4ca1f4d..3dfd3f6 100644 --- a/src/maemo/modest-msg-edit-window.c +++ b/src/maemo/modest-msg-edit-window.c @@ -62,6 +62,7 @@ #include #include #include "modest-scroll-area.h" +#include "modest-msg-edit-window-ui-dimming.h" #include "modest-hildon-includes.h" #ifdef MODEST_HAVE_HILDON0_WIDGETS @@ -90,10 +91,8 @@ static void modest_msg_edit_window_init (ModestMsgEditWindow *obj); static void modest_msg_edit_window_finalize (GObject *obj); static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata); +static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor); static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor); -static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor); -static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor); -static void setup_insensitive_handlers (ModestMsgEditWindow *editor); static void reset_modified (ModestMsgEditWindow *editor); static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window); @@ -104,6 +103,11 @@ static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag, gpointer userdata); static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id); static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window); +static void subject_field_insert_text (GtkEditable *editable, + gchar *new_text, + gint new_text_length, + gint *position, + ModestMsgEditWindow *window); static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window, gpointer userdata); static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item, @@ -130,11 +134,12 @@ static void modest_msg_edit_window_show_toolbar (ModestWindow *window, static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard, GdkEvent *event, ModestMsgEditWindow *window); +static void subject_field_move_cursor (GtkEntry *entry, + GtkMovementStep step, + gint a1, + gboolean a2, + gpointer userdata); static void update_window_title (ModestMsgEditWindow *window); -static void update_dimmed (ModestMsgEditWindow *window); -static void update_paste_dimming (ModestMsgEditWindow *window); -static void update_select_all_dimming (ModestMsgEditWindow *window); -static void update_zoom_dimming (ModestMsgEditWindow *window); /* Find toolbar */ static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget, @@ -191,11 +196,6 @@ static void DEBUG_BUFFER (WPTextBuffer *buffer) /* GdkEventKey *event, */ /* gpointer user_data); */ -static void edit_menu_activated (GtkAction *action, - gpointer userdata); -static void view_menu_activated (GtkAction *action, - gpointer userdata); - /* list my signals */ enum { /* MY_SIGNAL_1, */ @@ -248,7 +248,10 @@ struct _ModestMsgEditWindowPrivate { gdouble zoom_level; + gboolean can_undo, can_redo; gulong clipboard_change_handler_id; + gulong default_clipboard_change_handler_id; + gchar *clipboard_text; TnyMsg *draft_msg; TnyMsg *outbox_msg; @@ -358,7 +361,12 @@ modest_msg_edit_window_init (ModestMsgEditWindow *obj) priv->draft_msg = NULL; priv->outbox_msg = NULL; priv->msg_uid = NULL; + + priv->can_undo = FALSE; + priv->can_redo = FALSE; priv->clipboard_change_handler_id = 0; + priv->default_clipboard_change_handler_id = 0; + priv->clipboard_text = NULL; priv->sent = FALSE; priv->last_vadj_upper = 0; @@ -536,6 +544,8 @@ init_window (ModestMsgEditWindow *obj) G_CALLBACK (text_buffer_can_undo), obj); g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo", G_CALLBACK (text_buffer_can_redo), obj); + g_signal_connect (G_OBJECT (priv->text_buffer), "changed", + G_CALLBACK (body_changed), obj); g_signal_connect (G_OBJECT (obj), "window-state-event", G_CALLBACK (modest_msg_edit_window_window_state_event), NULL); @@ -561,8 +571,9 @@ init_window (ModestMsgEditWindow *obj) "changed", G_CALLBACK (recpt_field_changed), obj); g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))), "changed", G_CALLBACK (recpt_field_changed), obj); - recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj)); g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj); + g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj); + g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj); g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj); g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj); @@ -594,6 +605,8 @@ init_window (ModestMsgEditWindow *obj) priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change", G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj); + priv->default_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change", + G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj); } @@ -602,10 +615,16 @@ modest_msg_edit_window_disconnect_signals (ModestWindow *window) { ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); - if (g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY), + if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) && + g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id)) g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id); + if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) && + g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + priv->default_clipboard_change_handler_id)) + g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + priv->default_clipboard_change_handler_id); } static void @@ -616,6 +635,11 @@ modest_msg_edit_window_finalize (GObject *obj) /* Sanity check: shouldn't be needed, the window mgr should call this function before */ modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj)); + + if (priv->clipboard_text != NULL) { + g_free (priv->clipboard_text); + priv->clipboard_text = NULL; + } if (priv->draft_msg != NULL) { TnyHeader *header = tny_msg_get_header (priv->draft_msg); @@ -727,7 +751,7 @@ replace_with_attachments (ModestMsgEditWindow *self, GList *attachments) g_object_unref (stream); if (pixbuf != NULL) { -/* wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf); */ + wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf); g_object_unref (pixbuf); } } @@ -818,6 +842,18 @@ set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich) wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer)); g_free (body); + /* Add attachments to the view */ + modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg); + priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)); + if (priv->attachments == NULL) { + gtk_widget_hide (priv->attachments_caption); + } else { + gtk_widget_set_no_show_all (priv->attachments_caption, FALSE); + gtk_widget_show_all (priv->attachments_caption); + replace_with_attachments (self, priv->attachments); + } + update_last_cid (self, priv->attachments); + if (preserve_is_rich && !is_html) { wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE); /* Get the default format required from configuration */ @@ -836,18 +872,6 @@ set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich) value that comes from msg <- not sure, should it be allowed? */ - /* Add attachments to the view */ - modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg); - priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)); - if (priv->attachments == NULL) { - gtk_widget_hide (priv->attachments_caption); - } else { - gtk_widget_set_no_show_all (priv->attachments_caption, FALSE); - gtk_widget_show_all (priv->attachments_caption); - replace_with_attachments (self, priv->attachments); - } - update_last_cid (self, priv->attachments); - DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer)); gtk_text_buffer_get_start_iter (priv->text_buffer, &iter); @@ -855,7 +879,7 @@ set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich) reset_modified (self); - update_dimmed (self); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self)); text_buffer_can_undo (priv->text_buffer, FALSE, self); text_buffer_can_redo (priv->text_buffer, FALSE, self); @@ -940,10 +964,6 @@ modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window) parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar"); hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar)); - /* should we hide the toolbar? */ - if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL)) - gtk_widget_hide (parent_priv->toolbar); - /* Font color placeholder */ placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor"); insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder)); @@ -957,7 +977,10 @@ modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window) gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE); gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE); gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index); - g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window); + g_signal_connect_swapped (G_OBJECT (priv->font_color_button), + "notify::color", + G_CALLBACK (modest_msg_edit_window_color_button_change), + window); /* Font size and face placeholder */ placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes"); @@ -1057,7 +1080,15 @@ modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window) gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE); gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE); + /* Explicitelly show all the toolbar (a normal gtk_widget_show + will not show the tool items added to the placeholders) */ + gtk_widget_show_all (parent_priv->toolbar); + /* Set the no show all *after* showing all items. We do not + want the toolbar to be shown with a show all because it + could go agains the gconf setting regarding showing or not + the toolbar of the editor window */ + gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE); } @@ -1073,9 +1104,10 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean pre GdkPixbuf *window_icon = NULL; GtkAction *action; ModestConf *conf; - gboolean prefer_formatted; - gint file_format; ModestPair *account_pair = NULL; + ModestDimmingRulesGroup *menu_rules_group = NULL; + ModestDimmingRulesGroup *toolbar_rules_group = NULL; + ModestDimmingRulesGroup *clipboard_rules_group = NULL; g_return_val_if_fail (msg, NULL); g_return_val_if_fail (account_name, NULL); @@ -1137,8 +1169,18 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean pre gtk_window_add_accel_group (GTK_WINDOW (obj), gtk_ui_manager_get_accel_group (parent_priv->ui_manager)); - /* Menubar */ + /* Menubar. Update the state of some toggles */ parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager); + conf = modest_runtime_get_conf (); + action = gtk_ui_manager_get_action (parent_priv->ui_manager, + "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu"); + modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), + modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR, NULL)); + action = gtk_ui_manager_get_action (parent_priv->ui_manager, + "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu"); + modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), + modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL)); + hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar)); /* Init window */ @@ -1151,12 +1193,45 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean pre modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj)); hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar)); - setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj)); - account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name); if (account_pair != NULL) modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first); + parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new (); + menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE); + toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE); + clipboard_rules_group = modest_dimming_rules_group_new ("ModestClipboardDimmingRules", FALSE); + /* Add common dimming rules */ + modest_dimming_rules_group_add_rules (menu_rules_group, + modest_msg_edit_window_menu_dimming_entries, + G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries), + MODEST_WINDOW (obj)); + modest_dimming_rules_group_add_rules (toolbar_rules_group, + modest_msg_edit_window_toolbar_dimming_entries, + G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries), + MODEST_WINDOW (obj)); + modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button, + G_CALLBACK (modest_ui_dimming_rules_on_set_style), + MODEST_WINDOW (obj)); + modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem, + G_CALLBACK (modest_ui_dimming_rules_on_set_style), + MODEST_WINDOW (obj)); + modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem, + G_CALLBACK (modest_ui_dimming_rules_on_set_style), + MODEST_WINDOW (obj)); + modest_dimming_rules_group_add_rules (clipboard_rules_group, + modest_msg_edit_window_clipboard_dimming_entries, + G_N_ELEMENTS (modest_msg_edit_window_clipboard_dimming_entries), + MODEST_WINDOW (obj)); + /* Insert dimming rules group for this window */ + modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group); + modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group); + modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group); + /* Checks the dimming rules */ + g_object_unref (menu_rules_group); + g_object_unref (toolbar_rules_group); + g_object_unref (clipboard_rules_group); + set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich); text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj)); @@ -1168,6 +1243,9 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean pre g_object_unref (window_icon); } + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj)); + modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), "ModestClipboardDimmingRules"); + /* Dim at start clipboard actions */ action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu"); gtk_action_set_sensitive (action, FALSE); @@ -1176,13 +1254,6 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean pre action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu"); gtk_action_set_sensitive (action, FALSE); - /* Update select all */ - update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj)); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu"); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu"); - g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj); - /* set initial state of cc and bcc */ action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu"); modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), @@ -1191,19 +1262,7 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean pre modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)); - /* Setup the file format */ - conf = modest_runtime_get_conf (); - prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error); - if (error) { - g_clear_error (&error); - file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT; - } else - file_format = (prefer_formatted) ? - MODEST_FILE_FORMAT_FORMATTED_TEXT : - MODEST_FILE_FORMAT_PLAIN_TEXT; - modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format); - - update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj)); + modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), "ModestClipboardDimmingRules"); priv->update_caption_visibility = TRUE; reset_modified (MODEST_MSG_EDIT_WINDOW (obj)); @@ -1264,8 +1323,7 @@ modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window) data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field))); if (priv->draft_msg) { data->draft_msg = g_object_ref (priv->draft_msg); - } - if (priv->outbox_msg) { + } else if (priv->outbox_msg) { data->draft_msg = g_object_ref (priv->outbox_msg); } else { data->draft_msg = NULL; @@ -1496,15 +1554,15 @@ text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *windo } wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE); - + action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold"); modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold); action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics"); modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); - modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); +/* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */ +/* modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */ g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button), G_CALLBACK (modest_msg_edit_window_color_button_change), @@ -2149,20 +2207,6 @@ modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowStat } void -modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window) -{ - ModestWindowPrivate *parent_priv; - GtkAction *fs_toggle_action; - gboolean active; - - parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - - fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu"); - active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active); -} - -void modest_msg_edit_window_show_cc (ModestMsgEditWindow *window, gboolean show) { @@ -2255,18 +2299,34 @@ modest_msg_edit_window_show_toolbar (ModestWindow *self, gboolean show_toolbar) { ModestWindowPrivate *parent_priv; + const gchar *action_name; + GtkAction *action; g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self)); parent_priv = MODEST_WINDOW_GET_PRIVATE(self); - /* FIXME: we can not just use the code of + /* We can not just use the code of modest_msg_edit_window_setup_toolbar because it has a mixture of both initialization and creation code. */ - if (show_toolbar) gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); else gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar)); + + /* Update also the actions (to update the toggles in the + menus), we have to do it manually because some other window + of the same time could have changed it (remember that the + toolbar fullscreen mode is shared by all the windows of the + same type */ + if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ())) + action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu"; + else + action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu"; + + action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name); + modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), + show_toolbar); + } void @@ -2348,7 +2408,7 @@ modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window, } break; } - update_dimmed (window); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window)); } } @@ -2494,7 +2554,7 @@ modest_msg_edit_window_undo (ModestMsgEditWindow *window) wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer)); - update_dimmed (window); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window)); } @@ -2508,91 +2568,47 @@ modest_msg_edit_window_redo (ModestMsgEditWindow *window) wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer)); - update_dimmed (window); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window)); } -static void -update_dimmed (ModestMsgEditWindow *window) +static void +text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window) { ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - GtkAction *action; - GtkWidget *widget; - gboolean rich_text; - gboolean editor_focused; - rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)); - editor_focused = gtk_widget_is_focus (priv->msg_body); - - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics"); - gtk_action_set_sensitive (action, rich_text && editor_focused); - widget = priv->font_color_button; - gtk_widget_set_sensitive (widget, rich_text && editor_focused); - widget = priv->font_size_toolitem; - gtk_widget_set_sensitive (widget, rich_text && editor_focused); - widget = priv->font_face_toolitem; - gtk_widget_set_sensitive (widget, rich_text && editor_focused); + priv->can_undo = can_undo; } -static void -setup_insensitive_handlers (ModestMsgEditWindow *window) +static void +text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window) { - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); - GtkWidget *widget; - - widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend"); - g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window); - widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold"); - g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window); - widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics"); - g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window); - widget = priv->font_color_button; - g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window); - widget = priv->font_size_toolitem; - g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window); - widget = priv->font_face_toolitem; - g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window); + priv->can_redo = can_redo; } -static void -text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window) +gboolean +modest_msg_edit_window_can_undo (ModestMsgEditWindow *window) { - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - GtkAction *action; + ModestMsgEditWindowPrivate *priv; + g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE); + priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu"); - gtk_action_set_sensitive (action, can_undo); + return priv->can_undo; } -static void -text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window) +gboolean +modest_msg_edit_window_can_redo (ModestMsgEditWindow *window) { - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - GtkAction *action; + ModestMsgEditWindowPrivate *priv; + g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE); + priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu"); - gtk_action_set_sensitive (action, can_redo); + return priv->can_redo; } + static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id) { @@ -2623,13 +2639,32 @@ text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id) } } +gboolean +message_is_empty (ModestMsgEditWindow *window) +{ + ModestMsgEditWindowPrivate *priv = NULL; + + g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE); + priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); + + /** TODO: Add wpeditor API to tell us if there is any _visible_ text, + * so we can ignore markup. + */ + GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)); + gint count = 0; + if (buf) + count = gtk_text_buffer_get_char_count (buf); + + return count == 0; +} + static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata) { - update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata)); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata)); return FALSE; } @@ -2637,45 +2672,13 @@ static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor) { - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor); - ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor); - GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer; - gboolean dim = FALSE; - GtkAction *action; - - to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)); - cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field)); - bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field)); - - dim = ((gtk_text_buffer_get_char_count (to_buffer) + - gtk_text_buffer_get_char_count (cc_buffer) + - gtk_text_buffer_get_char_count (bcc_buffer)) == 0); - - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend"); - gtk_action_set_sensitive (action, !dim); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu"); - gtk_action_set_sensitive (action, !dim); -} - -static void -send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor) -{ - hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first")); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor)); } static void -style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor) +body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor) { - gboolean rich_text, editor_focused; - - ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor); - rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)); - editor_focused = gtk_widget_is_focus (priv->msg_body); - - if (!rich_text) - hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext")); - else if (!editor_focused) - hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message")); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor)); } static void @@ -2714,6 +2717,9 @@ modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor) return FALSE; } + + + gboolean modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook) { @@ -2731,14 +2737,22 @@ modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to return FALSE; } - if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) + if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) { + modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field)); return FALSE; - if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) + } + if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) { + modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field)); return FALSE; - if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) + } + if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) { + modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field)); return FALSE; + } - modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field)); + if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) && + !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field))) + modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field)); return TRUE; @@ -2751,40 +2765,43 @@ modest_msg_edit_window_add_attachment_clicked (GtkButton *button, modest_msg_edit_window_offer_attach_file (window); } +const gchar * +modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win) +{ + ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win); + + return priv->clipboard_text; +} + static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard, GdkEvent *event, ModestMsgEditWindow *window) { - ModestWindowPrivate *parent_priv; - ModestMsgEditWindowPrivate *priv; - GtkAction *action; - gboolean has_selection; - GtkWidget *focused; - GList *selected_attachments = NULL; - gint n_att_selected = 0; - - priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); - parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - + ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); + GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); if (!GTK_WIDGET_VISIBLE (window)) return; - has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL); - focused = gtk_window_get_focus (GTK_WINDOW (window)); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu"); - gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused))); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu"); - gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused))); + if (priv->clipboard_text != NULL) { + g_free (priv->clipboard_text); + } - selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)); - n_att_selected = g_list_length (selected_attachments); - g_list_free (selected_attachments); + priv->clipboard_text = gtk_clipboard_wait_for_text (selection_clipboard); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu"); - gtk_action_set_sensitive (action, n_att_selected == 1); - - update_paste_dimming (window); + modest_window_check_dimming_rules_group (MODEST_WINDOW (window), "ModestClipboardDimmingRules"); +} +static void +subject_field_move_cursor (GtkEntry *entry, + GtkMovementStep step, + gint a1, + gboolean a2, + gpointer window) +{ + if (!GTK_WIDGET_VISIBLE (window)) + return; + + modest_window_check_dimming_rules_group (MODEST_WINDOW (window), "ModestClipboardDimmingRules"); } static void @@ -2809,27 +2826,48 @@ subject_field_changed (GtkEditable *editable, ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); update_window_title (window); gtk_text_buffer_set_modified (priv->text_buffer, TRUE); + modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window)); } -gboolean -message_is_empty (ModestMsgEditWindow *window) -{ - ModestMsgEditWindowPrivate *priv = NULL; +static void +subject_field_insert_text (GtkEditable *editable, + gchar *new_text, + gint new_text_length, + gint *position, + ModestMsgEditWindow *window) +{ + GString *result = g_string_new (""); + gchar *current; + gint result_len = 0; + + for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) { + gunichar c = g_utf8_get_char_validated (current, 8); + /* Invalid unichar, stop */ + if (c == -1) + break; + /* a bullet */ + if (c == 0x2022) + continue; + result = g_string_append_unichar (result, c); + result_len++; + } - g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE); - priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); + if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) { + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + if (result_len > 0) + { + /* Prevent endless recursion */ + g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window); + g_signal_emit_by_name (editable, "insert-text", + (gpointer) result->str, (gpointer) result->len, + (gpointer) position, (gpointer) window); + g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window); + } + } - /** TODO: Add wpeditor API to tell us if there is any _visible_ text, - * so we can ignore markup. - */ - GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)); - gint count = 0; - if (buf) - count = gtk_text_buffer_get_char_count (buf); - - return count == 0; + g_string_free (result, TRUE); } - + void modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window, gboolean show) @@ -2981,92 +3019,6 @@ modest_msg_edit_window_find_toolbar_close (GtkWidget *widget, gtk_toggle_action_set_active (toggle, FALSE); } - -static void -update_paste_dimming (ModestMsgEditWindow *window) -{ - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - GtkAction *action = NULL; - GtkClipboard *clipboard = NULL; - ModestEmailClipboard *e_clipboard; - GtkWidget *focused; - gboolean active; - - focused = gtk_window_get_focus (GTK_WINDOW (window)); - - e_clipboard = modest_runtime_get_email_clipboard (); - if (!modest_email_clipboard_cleared (e_clipboard)) { - active = TRUE; - } else { - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - active = gtk_clipboard_wait_is_text_available (clipboard); - } - - if (active) { - if (MODEST_IS_ATTACHMENTS_VIEW (focused)) - active = FALSE; - } - - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu"); - gtk_action_set_sensitive (action, active); - -} - -static void -update_select_all_dimming (ModestMsgEditWindow *window) -{ - GtkWidget *focused; - gboolean dimmed = FALSE; - GtkAction *action; - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - - focused = gtk_window_get_focus (GTK_WINDOW (window)); - if (GTK_IS_ENTRY (focused)) { - const gchar *current_text; - current_text = gtk_entry_get_text (GTK_ENTRY (focused)); - dimmed = ((current_text == NULL) || (current_text[0] == '\0')); - } else if (GTK_IS_TEXT_VIEW (focused)) { - GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused)); - dimmed = (gtk_text_buffer_get_char_count (buffer) < 1); - } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) { - dimmed = FALSE; - } - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu"); - gtk_action_set_sensitive (action, !dimmed); -} - -static void -update_zoom_dimming (ModestMsgEditWindow *window) -{ - GtkWidget *focused; - gboolean dimmed = FALSE; - GtkAction *action; - ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window); - - focused = gtk_window_get_focus (GTK_WINDOW (window)); - dimmed = ! WP_IS_TEXT_VIEW (focused); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu"); - gtk_action_set_sensitive (action, !dimmed); -} - -static void -edit_menu_activated (GtkAction *action, - gpointer userdata) -{ - ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata); - - update_select_all_dimming (window); - update_paste_dimming (window); -} -static void -view_menu_activated (GtkAction *action, - gpointer userdata) -{ - ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata); - - update_zoom_dimming (window); -} - gboolean modest_msg_edit_window_get_sent (ModestMsgEditWindow *window) { @@ -3164,3 +3116,37 @@ modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window) return priv->msg_uid; } + +GtkWidget * +modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win, + ModestMsgEditWindowWidgetType widget_type) +{ + ModestMsgEditWindowPrivate *priv; + + g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL); + priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win); + + switch (widget_type) { + case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY: + return priv->msg_body; + break; + case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO: + return priv->to_field; + break; + case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC: + return priv->cc_field; + break; + case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC: + return priv->bcc_field; + break; + case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT: + return priv->subject_field; + break; + case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS: + return priv->attachments_view; + break; + default: + return NULL; + } +} +