/* #include <hildon-widgets/hildon-wizard-dialog.h> */
#include "modest-wizard-dialog.h" /* We use a copied-and-improved HildonWizardDialog. */
#include "modest-account-mgr.h"
+#include <config.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
* widget provided by users contains the actual wizard pages.
*/
+#include <config.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtkimage.h>
gtk_dialog_set_has_separator (dialog, FALSE);
wizard_dialog->priv = priv;
priv->box = GTK_BOX (gtk_hbox_new (FALSE, 0));
-#ifdef MODEST_HILDON_VERSION_0
+#ifdef MODEST_HILDON_VERSION_0
priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard",
- HILDON_ICON_SIZE_WIDG_WIZARD);
+ HILDON_ICON_SIZE_WIDG_WIZARD);
#else
priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard",
- HILDON_ICON_SIZE_WIZARD);
+ HILDON_ICON_SIZE_WIZARD);
#endif /*MODEST_HILDON_VERSION_0*/
/* Default values for user provided properties */
priv->notebook = NULL;
GtkWidget *contact_dialog;
GSList *email_addrs_per_contact = NULL;
gchar *econtact_id;
+ gboolean focus_recpt_editor = FALSE;
+ GtkWidget *toplevel;
g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (recpt_editor));
+
contact_model = osso_abook_contact_model_new ();
if (!open_addressbook ()) {
if (contact_model) {
g_slist_foreach (email_addrs_per_contact, (GFunc) g_free, NULL);
g_slist_free (email_addrs_per_contact);
email_addrs_per_contact = NULL;
+ focus_recpt_editor = TRUE;
}
}
g_list_free (contacts_list);
gtk_widget_destroy (contact_dialog);
+ if (focus_recpt_editor)
+ modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (recpt_editor));
+
}
/**
gtk_list_store_set(list_store, &iter, 0, email_addr, -1);
g_free(email_addr);
}
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter);
+ gtk_tree_selection_select_iter (selection, &iter);
gtk_widget_show_all(select_email_addr_dlg);
result = gtk_dialog_run(GTK_DIALOG(select_email_addr_dlg));
/* Email */
{ "EmailNew", NULL, N_("mcen_me_inbox_new") }, /* submenu */
{ "EmailNewMessage", NULL, N_("mcen_me_inbox_message"), "<CTRL>N", NULL, G_CALLBACK (modest_ui_actions_on_new_msg) },
+ { "EmailNewDefault", NULL, N_("mcen_me_inbox_new"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_msg) },
{ "EmailNewFolder", NULL, N_("mcen_me_inbox_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
{ "EmailOpen", NULL, N_("mcen_me_inbox_open"), "<CTRL>O", NULL, NULL },
{ "EmailReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
#include "modest-tny-platform-factory.h"
#include "modest-tny-msg.h"
#include "modest-address-book.h"
+#include "modest-text-utils.h"
#include <tny-simple-list.h>
#include <wptextview.h>
#include <wptextbuffer.h>
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 to_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 gboolean is_modified (ModestMsgEditWindow *editor);
+
static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
static void text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *location, GtkTextMark *mark, gpointer userdata);
static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
TnyHeaderFlags priority_flags;
gdouble zoom_level;
+
+ TnyMsg *draft_msg;
};
#define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
priv->bcc_caption = NULL;
priv->priority_flags = 0;
+
+ priv->draft_msg = NULL;
}
g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
+ g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
+ G_CALLBACK (msg_body_focus), obj);
+ g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
+ G_CALLBACK (msg_body_focus), obj);
+ g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
+ "changed", G_CALLBACK (to_field_changed), obj);
+ to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
+
priv->scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
static gboolean
on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
{
+ GtkWidget *close_dialog;
+ ModestMsgEditWindowPrivate *priv;
+ gint response;
+
+ priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
save_settings (self);
- return FALSE;
+ if (is_modified (self)) {
+ close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
+ response = gtk_dialog_run (GTK_DIALOG (close_dialog));
+ gtk_widget_destroy (close_dialog);
+
+ if (response != GTK_RESPONSE_CANCEL) {
+ modest_ui_actions_on_save_to_drafts (NULL, self);
+ }
+ }
+/* /\* remove old message from drafts *\/ */
+/* if (priv->draft_msg) { */
+/* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
+/* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
+/* account_name, */
+/* TNY_ACCOUNT_TYPE_STORE); */
+/* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
+/* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
+/* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
+/* tny_folder_remove_msg (folder, header, NULL); */
+/* g_object_unref (folder); */
+/* g_object_unref (header); */
+/* g_object_unref (priv->draft_msg); */
+/* priv->draft_msg = NULL; */
+/* } */
+ gtk_widget_destroy (GTK_WIDGET (self));
+
+ return TRUE;
}
static GtkWidget *
set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
{
TnyHeader *header;
- const gchar *to, *cc, *bcc, *subject, *body;
+ const gchar *to, *cc, *bcc, *subject;
+ gchar *body;
ModestMsgEditWindowPrivate *priv;
+ GtkTextIter iter;
g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
g_return_if_fail (TNY_IS_MSG (msg));
/* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
body = modest_tny_msg_get_body (msg, FALSE);
- if ((body!=NULL) && (body[0] != '\0')) {
- wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
- wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
- (gchar *) body,
- -1);
- wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
- } else {
- WPTextBufferFormat fmt = {0};
-
- fmt.font_size = DEFAULT_FONT_SIZE;
- fmt.font = DEFAULT_FONT;
- fmt.rich_text = 1;
- fmt.text_position = TEXT_POSITION_NORMAL;
- fmt.justification = 0;
- fmt.cs.font_size = 1;
- fmt.cs.font = 1;
- fmt.cs.text_position = 1;
- fmt.cs.justification = 1;
- wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &fmt);
+
+ if ((body == NULL)||(body[0] == '\0')) {
+ g_free (body);
+ body = modest_text_utils_convert_to_html ("");
+ }
+ wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
+ wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
+ (gchar *) body,
+ strlen (body));
+ wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
+ g_free (body);
+
+ /* Get the default format required from configuration */
+ if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
+ wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
}
/* Set the default focus depending on having already a To: field or not */
if ((!to)||(*to == '\0')) {
- gtk_widget_grab_focus (priv->to_field);
+ modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
} else {
gtk_widget_grab_focus (priv->msg_body);
}
if (priv->attachments == NULL)
gtk_widget_hide_all (priv->attachments_caption);
+ gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
+ gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
+
+ reset_modified (self);
+
update_dimmed (self);
text_buffer_can_undo (priv->text_buffer, FALSE, self);
+
+ priv->draft_msg = msg;
}
static void
gtk_action_group_add_radio_actions (action_group,
modest_msg_edit_file_format_action_entries,
G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
- MODEST_FILE_FORMAT_FORMATTED_TEXT,
+ modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
obj);
gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
+ setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
+
set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
GtkWidget *view_focus;
view_focus = gtk_window_get_focus (GTK_WINDOW (window));
- if (gtk_widget_get_parent (view_focus) &&
- MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (view_focus))) {
- editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (view_focus));
- } else {
- editor = MODEST_RECPT_EDITOR (priv->to_field);
+ /* This code should be kept in sync with ModestRecptEditor. The
+ textview inside the recpt editor is the one that really gets the
+ focus. As it's inside a scrolled window, and this one inside the
+ hbox recpt editor inherits from, we'll need to go up in the
+ hierarchy to know if the text view is part of the recpt editor
+ or if it's a different text entry */
+
+ if (gtk_widget_get_parent (view_focus)) {
+ GtkWidget *first_parent;
+
+ first_parent = gtk_widget_get_parent (view_focus);
+ if (gtk_widget_get_parent (first_parent) &&
+ MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
+ editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
+ }
}
+
+ if (editor == NULL)
+ editor = MODEST_RECPT_EDITOR (priv->to_field);
+
}
modest_address_book_select_addresses (editor);
void
modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
{
- GtkWidget *focused;
- ModestMsgEditWindowPrivate *priv;
-
g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
- priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
- focused = gtk_window_get_focus (GTK_WINDOW (window));
- if (MODEST_IS_RECPT_EDITOR (focused)) {
- modest_msg_edit_window_open_addressbook (window, MODEST_RECPT_EDITOR (focused));
- } else {
- modest_msg_edit_window_open_addressbook (window, MODEST_RECPT_EDITOR (priv->to_field));
- }
-
+ modest_msg_edit_window_open_addressbook (window, NULL);
}
+
static void
modest_msg_edit_window_show_toolbar (ModestWindow *self,
gboolean show_toolbar)
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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+}
+
+static void
+setup_insensitive_handlers (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, "/MenuBar/EmailMenu/SendMenu");
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
+
+ widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
+ widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
+ widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
+ widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
+ widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
+ widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
+ widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
+ 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/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;
- gtk_widget_set_sensitive (widget, rich_text);
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
widget = priv->font_size_toolitem;
- gtk_widget_set_sensitive (widget, rich_text);
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
widget = priv->font_face_toolitem;
- gtk_widget_set_sensitive (widget, rich_text);
+ g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
+
}
static void
action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
gtk_action_set_sensitive (action, can_undo);
}
+
+static gboolean
+msg_body_focus (GtkWidget *focus,
+ GdkEventFocus *event,
+ gpointer userdata)
+{
+ update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
+ return FALSE;
+}
+
+static void
+to_field_changed (GtkTextBuffer *buffer,
+ ModestMsgEditWindow *editor)
+{
+ ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
+ GtkAction *action;
+
+ action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
+ gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
+ action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
+ gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
+}
+
+static void
+send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
+{
+ hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
+}
+
+static void
+style_insensitive_press (GtkWidget *widget, 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"));
+}
+
+static void
+reset_modified (ModestMsgEditWindow *editor)
+{
+ ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
+ GtkTextBuffer *buffer;
+
+ buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
+ gtk_text_buffer_set_modified (buffer, FALSE);
+ buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
+ gtk_text_buffer_set_modified (buffer, FALSE);
+ buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
+ gtk_text_buffer_set_modified (buffer, FALSE);
+ gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
+}
+
+static gboolean
+is_modified (ModestMsgEditWindow *editor)
+{
+ ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
+ GtkTextBuffer *buffer;
+
+ buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
+ if (gtk_text_buffer_get_modified (buffer))
+ return TRUE;
+ buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
+ if (gtk_text_buffer_get_modified (buffer))
+ return TRUE;
+ buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
+ if (gtk_text_buffer_get_modified (buffer))
+ return TRUE;
+ if (gtk_text_buffer_get_modified (priv->text_buffer))
+ return TRUE;
+
+ return FALSE;
+}
+
<menubar name="MenuBar">
<menu name="EmailMenu" action="Email">
+ <menuitem name="SendMenu" action="ActionsSend"/>
+ <menuitem name="SaveToDraftsMenu" action="ActionsSaveToDrafts"/>
+ <separator/>
<menuitem name="SelectContactsMenu" action="SelectContacts"/>
+ <separator/>
+ <menuitem name="NewMessageMenu" action="ActionsNewMessage"/>
+ <separator/>
+ <menuitem name="DeleteMenu" action="ActionsDelete"/>
</menu>
<menu name="EditMenu" action="Edit">
</menu>
</menu>
+ <menu name="CloseMenu" action="Close">
+ <menuitem name="CloseWindowMenu" action="CloseWindow"/>
+ <menuitem name="CloseAllWindowsMenu" action="CloseAllWindows"/>
+ </menu>
+
</menubar>
<toolbar name="ToolBar">
<menuitem name="MessageReplyAllMenu" action="EmailReplyAll"/>
<menuitem name="MessageForwardMenu" action="EmailForward"/>
<separator/>
- <menuitem name="MessageNewMenu" action="EmailNew"/>
+ <menuitem name="MessageNewMenu" action="EmailNewDefault"/>
<separator/>
<menuitem name="MessageDeleteMenu" action="EmailDelete"/>
<separator/>
#define MODEST_CONF_REPLY_TYPE MODEST_CONF_NAMESPACE "/reply_type" /* int */
#define MODEST_CONF_FORWARD_TYPE MODEST_CONF_NAMESPACE "/forward_type" /* int */
+#define MODEST_CONF_PREFER_FORMATTED_TEXT MODEST_CONF_NAMESPACE "/prefer_formatted_text"
+
#define MODEST_CONF_CONNECT_AT_STARTUP MODEST_CONF_NAMESPACE "/connect_at_startup"
#define MODEST_CONF_SHOW_CC MODEST_CONF_NAMESPACE "/show_cc"
#define MODEST_ACCOUNT_DISPLAY_NAME "display_name" /* string */
#define MODEST_ACCOUNT_STORE_ACCOUNT "store_account" /* string */
#define MODEST_ACCOUNT_TRANSPORT_ACCOUNT "transport_account" /* string */
-#define MODEST_ACCOUNT_FULLNAME "fullname"
-#define MODEST_ACCOUNT_EMAIL "email"
+#define MODEST_ACCOUNT_FULLNAME "fullname" /* string */
+#define MODEST_ACCOUNT_EMAIL "email" /* string */
/* This is a list of strings, with each strings,
* alernating between a connection name, followed by a corresponding server account name.
typedef struct _ModestFormatterPrivate ModestFormatterPrivate;
struct _ModestFormatterPrivate {
gchar *content_type;
+ gchar *signature;
};
#define MODEST_FORMATTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
MODEST_TYPE_FORMATTER, \
}
ModestFormatter*
-modest_formatter_new (const gchar *content_type)
+modest_formatter_new (const gchar *content_type, const gchar *signature)
{
ModestFormatter *formatter;
ModestFormatterPrivate *priv;
formatter = g_object_new (MODEST_TYPE_FORMATTER, NULL);
priv = MODEST_FORMATTER_GET_PRIVATE (formatter);
priv->content_type = g_strdup (content_type);
+ priv->signature = g_strdup (signature);
return formatter;
}
if (priv->content_type)
g_free (priv->content_type);
+ if (priv->signature)
+ g_free (priv->signature);
+
(*parent_class->finalize) (object);
}
return modest_text_utils_cite (text,
priv->content_type,
+ priv->signature,
tny_header_get_from (header),
tny_header_get_date_sent (header));
}
return modest_text_utils_inline (text,
priv->content_type,
+ priv->signature,
tny_header_get_from (header),
tny_header_get_date_sent (header),
tny_header_get_to (header),
/* TODO: get 80 from the configuration */
return modest_text_utils_quote (text,
priv->content_type,
+ priv->signature,
tny_header_get_from (header),
tny_header_get_date_sent (header),
80);
GType modest_formatter_get_type (void);
-ModestFormatter* modest_formatter_new (const gchar *content_type);
+ModestFormatter* modest_formatter_new (const gchar *content_type, const gchar *signature);
/**
* modest_formatter_cite:
g_object_unref (G_OBJECT (new_msg));
}
+void
+modest_mail_operation_save_to_drafts (ModestMailOperation *self,
+ TnyTransportAccount *transport_account,
+ const gchar *from, const gchar *to,
+ const gchar *cc, const gchar *bcc,
+ const gchar *subject, const gchar *plain_body,
+ const gchar *html_body,
+ const GList *attachments_list,
+ TnyHeaderFlags priority_flags)
+{
+ TnyMsg *msg = NULL;
+ TnyFolder *folder = NULL;
+ ModestMailOperationPrivate *priv = NULL;
+ GError *err = NULL;
+
+ /* GList *node = NULL; */
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
+
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
+ if (html_body == NULL) {
+ msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
+ } else {
+ msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
+ }
+ if (!msg) {
+ g_printerr ("modest: failed to create a new msg\n");
+ goto cleanup;
+ }
+
+ folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
+ if (!folder) {
+ g_printerr ("modest: failed to find Drafts folder\n");
+ goto cleanup;
+ }
+
+ tny_folder_add_msg (folder, msg, &err);
+ if (err) {
+ g_printerr ("modest: error adding msg to Drafts folder: %s",
+ err->message);
+ g_error_free (err);
+ goto cleanup;
+ }
+
+ modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
+
+ /* Free */
+cleanup:
+ if (msg)
+ g_object_unref (G_OBJECT(msg));
+ if (folder)
+ g_object_unref (G_OBJECT(folder));
+}
+
static void
recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
{
const GList *attachments_list,
TnyHeaderFlags priority_flags);
+
+/**
+ * modest_mail_operation_save_to_drafts:
+ * @self: a #ModestMailOperation
+ * @transport_account: a non-NULL #TnyTransportAccount
+ * @from: the email address of the mail sender
+ * @to: a non-NULL email address of the mail receiver
+ * @cc: a comma-separated list of email addresses where to send a carbon copy
+ * @bcc: a comma-separated list of email addresses where to send a blind carbon copy
+ * @subject: the subject of the new mail
+ * @plain_body: the plain text body of the new mail.
+ * @html_body: the html version of the body of the new mail. If NULL, the mail will
+ * be sent with the plain body only.
+ * @attachments_list: a #GList of attachments, each attachment must be a #TnyMimePart
+ *
+ * Save a mail message to drafts using the provided
+ * #TnyTransportAccount. This operation is synchronous, so the
+ * #ModestMailOperation should not be added to any
+ * #ModestMailOperationQueue
+ **/
+void modest_mail_operation_save_to_drafts (ModestMailOperation *self,
+ TnyTransportAccount *transport_account,
+ const gchar *from,
+ const gchar *to,
+ const gchar *cc,
+ const gchar *bcc,
+ const gchar *subject,
+ const gchar *plain_body,
+ const gchar *html_body,
+ const GList *attachments_list,
+ TnyHeaderFlags priority_flags);
/**
* modest_mail_operation_update_account:
* @self: a #ModestMailOperation
gchar *
modest_text_utils_quote (const gchar *text,
const gchar *content_type,
+ const gchar *signature,
const gchar *from,
const time_t sent_date,
int limit)
gchar *
modest_text_utils_cite (const gchar *text,
const gchar *content_type,
+ const gchar *signature,
const gchar *from,
time_t sent_date)
{
gchar *tmp, *retval;
+ gchar *tmp_sig;
g_return_val_if_fail (text, NULL);
g_return_val_if_fail (content_type, NULL);
+ if (!signature)
+ tmp_sig = g_strdup ("");
+ else if (!strcmp(content_type, "text/html")) {
+ tmp_sig = modest_text_utils_convert_to_html_body(signature);
+ } else {
+ tmp_sig = g_strdup (signature);
+ }
+
tmp = cite (sent_date, from);
- retval = g_strdup_printf ("%s%s\n", tmp, text);
+ retval = g_strdup_printf ("%s%s%s\n", tmp_sig, tmp, text);
+ g_free (tmp_sig);
g_free (tmp);
return retval;
gchar *
modest_text_utils_inline (const gchar *text,
const gchar *content_type,
+ const gchar *signature,
const gchar *from,
time_t sent_date,
const gchar *to,
const gchar *subject)
{
gchar sent_str[101];
- const gchar *plain_format = "%s\n%s %s\n%s %s\n%s %s\n%s %s\n\n%s";
+ gchar *formatted_signature;
+ const gchar *plain_format = "%s%s\n%s %s\n%s %s\n%s %s\n%s %s\n\n%s";
const gchar *html_format = \
- "%s<br>\n<table width=\"100%\" border=\"0\" cellspacing=\"2\" cellpadding=\"2\">\n" \
+ "%s%s<br>\n<table width=\"100%\" border=\"0\" cellspacing=\"2\" cellpadding=\"2\">\n" \
"<tr><td>%s</td><td>%s</td></tr>\n" \
"<tr><td>%s</td><td>%s</td></tr>\n" \
"<tr><td>%s</td><td>%s</td></tr>\n" \
else
format = plain_format;
- return g_strdup_printf (format,
+ if (signature != NULL) {
+ if (!strcmp (content_type, "text/html")) {
+ formatted_signature = g_strconcat (signature, "<br/>", NULL);
+ } else {
+ formatted_signature = g_strconcat (signature, "\n");
+ }
+ } else {
+ formatted_signature = "";
+ }
+
+ return g_strdup_printf (format, formatted_signature,
FORWARD_STRING,
FROM_STRING, (from) ? from : EMPTY_STRING,
SENT_STRING, sent_str,
return result;
}
-
-gchar*
-modest_text_utils_convert_to_html (const gchar *data)
+static void
+modest_text_utils_convert_buffer_to_html (GString *html, const gchar *data)
{
guint i;
gboolean space_seen = FALSE;
- GString *html;
gsize len;
-
- if (!data)
- return NULL;
len = strlen (data);
- html = g_string_sized_new (1.5 * len); /* just a guess... */
- g_string_append_printf (html,
- "<html><head>"
- "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf8\">"
- "</head>"
- "<body><tt>");
-
/* replace with special html chars where needed*/
for (i = 0; i != len; ++i) {
char kar = data[i];
g_string_append_c (html, kar);
}
}
+}
+
+gchar*
+modest_text_utils_convert_to_html (const gchar *data)
+{
+ GString *html;
+ gsize len;
- g_string_append (html, "</tt></body></html>");
+ if (!data)
+ return NULL;
+
+ len = strlen (data);
+ html = g_string_sized_new (1.5 * len); /* just a guess... */
+
+ g_string_append_printf (html,
+ "<html><head>"
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf8\">"
+ "</head>"
+ "<body>");
+
+ modest_text_utils_convert_buffer_to_html (html, data);
+
+ g_string_append (html, "</body></html>");
+ hyperlinkify_plain_text (html);
+
+ return g_string_free (html, FALSE);
+}
+
+gchar *
+modest_text_utils_convert_to_html_body (const gchar *data)
+{
+ GString *html;
+ gsize len;
+
+ if (!data)
+ return NULL;
+
+ len = strlen (data);
+ html = g_string_sized_new (1.5 * len); /* just a guess... */
+
+ modest_text_utils_convert_buffer_to_html (html, data);
+
hyperlinkify_plain_text (html);
return g_string_free (html, FALSE);
* @text: a non-NULL string which contains the message to quote
* @from: a non-NULL sender of the original message
* @content_type: the non-NULL content type for the quoting, e.g. "text/html"
+ * @signature: NULL or the signature to add
* @sent_date: sent date/time of the original message
* @limit: specifies the maximum characters per line in the quoted text
*
*/
gchar* modest_text_utils_quote (const gchar *text,
const gchar *content_type,
+ const gchar *signature,
const gchar *from,
const time_t sent_date,
int limit);
*/
gchar* modest_text_utils_cite (const gchar *text,
const gchar *content_type,
+ const gchar *signature,
const gchar *from,
time_t sent_date);
*/
gchar* modest_text_utils_inline (const gchar *text,
const gchar *content_type,
+ const gchar *signature,
const gchar *from,
time_t sent_date,
const gchar *to,
*/
gchar* modest_text_utils_convert_to_html (const gchar *txt);
+/**
+ * modest_text_utils_convert_to_html_body:
+ * @txt: a string
+ *
+ * convert plain text (utf8) into html without adding html headers.
+ *
+ * Returns: a newly allocated string containing the html
+ */
+gchar* modest_text_utils_convert_to_html_body (const gchar *data);
+
/**
* modest_text_utils_strftime:
gtk_text_buffer_get_bounds (buf, &start, &end);
to_quote = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
+ if (tny_mime_part_content_type_is (body, "text/plain")) {
+ gchar *to_quote_converted = modest_text_utils_convert_to_html (to_quote);
+ g_free (to_quote);
+ to_quote = to_quote_converted;
+ }
g_object_unref (buf);
return to_quote;
static TnyMsg *
-create_reply_forward_mail (TnyMsg *msg, const gchar *from, gboolean is_reply, guint type)
+create_reply_forward_mail (TnyMsg *msg, const gchar *from, const gchar *signature, gboolean is_reply, guint type)
{
TnyMsg *new_msg;
TnyHeader *new_header, *header;
gchar *new_subject;
TnyMimePart *body;
ModestFormatter *formatter;
+ gchar *subject_prefix;
/* Get body from original msg. Always look for the text/plain
part of the message to create the reply/forwarded mail */
body = modest_tny_msg_find_body_part (msg, FALSE);
/* TODO: select the formatter from account prefs */
- formatter = modest_formatter_new ("text/plain");
+ if (modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL))
+ formatter = modest_formatter_new ("text/html", signature);
+ else
+ formatter = modest_formatter_new ("text/plain", signature);
/* Format message body */
if (is_reply) {
tny_header_set_replyto (new_header, from);
/* Change the subject */
+ if (is_reply)
+ subject_prefix = g_strconcat (_("mail_va_re"), ":", NULL);
+ else
+ subject_prefix = g_strconcat (_("mail_va_fw"), ":", NULL);
new_subject =
(gchar *) modest_text_utils_derived_subject (tny_header_get_subject(header),
- (is_reply) ? _("Re:") : _("Fwd:"));
+ subject_prefix);
+ g_free (subject_prefix);
tny_header_set_subject (new_header, (const gchar *) new_subject);
g_free (new_subject);
TnyMsg*
modest_tny_msg_create_forward_msg (TnyMsg *msg,
const gchar *from,
+ const gchar *signature,
ModestTnyMsgForwardType forward_type)
{
TnyMsg *new_msg;
TnyList *parts = NULL;
GList *attachments_list = NULL;
- new_msg = create_reply_forward_mail (msg, from, FALSE, forward_type);
+ new_msg = create_reply_forward_mail (msg, from, signature, FALSE, forward_type);
/* Add attachments */
parts = TNY_LIST (tny_simple_list_new());
TnyMsg*
modest_tny_msg_create_reply_msg (TnyMsg *msg,
const gchar *from,
+ const gchar *signature,
ModestTnyMsgReplyType reply_type,
ModestTnyMsgReplyMode reply_mode)
{
const gchar *cc = NULL, *bcc = NULL;
GString *tmp = NULL;
- new_msg = create_reply_forward_mail (msg, from, TRUE, reply_type);
+ new_msg = create_reply_forward_mail (msg, from, signature, TRUE, reply_type);
/* Fill the header */
header = tny_msg_get_header (msg);
* modest_tny_msg_create_forward_msg:
* @msg: a valid #TnyMsg instance
* @from: the sender of the forwarded mail
+ * @signature: signature to attach to the reply
* @forward_type: the type of formatting used to create the forwarded message
*
* Creates a forwarded message from an existing one
**/
TnyMsg* modest_tny_msg_create_forward_msg (TnyMsg *msg,
const gchar *from,
+ const gchar *signature,
ModestTnyMsgForwardType forward_type);
/**
* modest_tny_msg_create_reply_msg:
* @msg: a valid #TnyMsg instance
* @from: the sender of the forwarded mail
+ * @signature: signature to add to the reply message
* @reply_type: the type of formatting used to create the reply message
* @reply_mode: the mode of reply: to the sender only, to a mail list or to all
*
**/
TnyMsg* modest_tny_msg_create_reply_msg (TnyMsg *msg,
const gchar *from,
+ const gchar *signature,
ModestTnyMsgReplyType reply_type,
ModestTnyMsgReplyMode reply_mode);
TnyIterator *iter;
g_return_if_fail (MODEST_IS_WINDOW(win));
+
+ if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
+ gboolean ret_value;
+ g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
+ return;
+ }
header_list = get_selected_headers (win);
{
if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
gtk_widget_destroy (GTK_WIDGET (win));
+ } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
+ gboolean ret_value;
+ g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
} else if (MODEST_IS_WINDOW (win)) {
gtk_widget_destroy (GTK_WIDGET (win));
} else {
TnyFolder *folder = NULL;
gchar *account_name = NULL;
gchar *from_str = NULL;
- GError *err = NULL;
+/* GError *err = NULL; */
TnyAccount *account = NULL;
ModestWindowMgr *mgr;
+ gchar *signature = NULL;
account_name = g_strdup(modest_window_get_active_account (win));
if (!account_name)
goto cleanup;
}
- msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
+ if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
+ MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
+ signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
+ MODEST_ACCOUNT_SIGNATURE, FALSE);
+ } else {
+ signature = g_strdup ("");
+ }
+
+ msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
if (!msg) {
g_printerr ("modest: failed to create new msg\n");
goto cleanup;
goto cleanup;
}
- tny_folder_add_msg (folder, msg, &err);
- if (err) {
- g_printerr ("modest: error adding msg to Drafts folder: %s",
- err->message);
- g_error_free (err);
- goto cleanup;
- }
+/* tny_folder_add_msg (folder, msg, &err); */
+/* if (err) { */
+/* g_printerr ("modest: error adding msg to Drafts folder: %s", */
+/* err->message); */
+/* g_error_free (err); */
+/* goto cleanup; */
+/* } */
/* Create and register edit window */
msg_win = modest_msg_edit_window_new (msg, account_name);
cleanup:
g_free (account_name);
g_free (from_str);
+ g_free (signature);
if (account)
g_object_unref (G_OBJECT(account));
if (msg)
TnyFolder *folder = NULL;
TnyAccount *account = NULL;
ModestWindowMgr *mgr;
+ gchar *signature = NULL;
msg = TNY_MSG (data);
helper = (GetMsgAsyncHelper *) user_data;
from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
rf_helper->account_name);
+ if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
+ rf_helper->account_name,
+ MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
+ signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
+ rf_helper->account_name,
+ MODEST_ACCOUNT_SIGNATURE, FALSE);
+ }
/* Create reply mail */
switch (rf_helper->action) {
case ACTION_REPLY:
new_msg =
- modest_tny_msg_create_reply_msg (msg, from,
+ modest_tny_msg_create_reply_msg (msg, from, signature,
rf_helper->reply_forward_type,
MODEST_TNY_MSG_REPLY_MODE_SENDER);
break;
case ACTION_REPLY_TO_ALL:
new_msg =
- modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
+ modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
MODEST_TNY_MSG_REPLY_MODE_ALL);
edit_type = MODEST_EDIT_TYPE_REPLY;
break;
case ACTION_FORWARD:
new_msg =
- modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
+ modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
edit_type = MODEST_EDIT_TYPE_FORWARD;
break;
default:
return;
}
+ g_free (signature);
+
if (!new_msg) {
g_printerr ("modest: failed to create message\n");
goto cleanup;
}
void
+modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
+{
+ TnyTransportAccount *transport_account;
+ ModestMailOperation *mail_operation;
+ MsgData *data;
+ gchar *account_name, *from;
+ ModestAccountMgr *account_mgr;
+
+ g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
+
+ data = modest_msg_edit_window_get_msg_data (edit_window);
+
+ account_mgr = modest_runtime_get_account_mgr();
+ account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
+ if (!account_name)
+ account_name = modest_account_mgr_get_default_account (account_mgr);
+ if (!account_name) {
+ g_printerr ("modest: no account found\n");
+ modest_msg_edit_window_free_msg_data (edit_window, data);
+ return;
+ }
+ transport_account =
+ TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
+ (modest_runtime_get_account_store(),
+ account_name,
+ TNY_ACCOUNT_TYPE_TRANSPORT));
+ if (!transport_account) {
+ g_printerr ("modest: no transport account found for '%s'\n", account_name);
+ g_free (account_name);
+ modest_msg_edit_window_free_msg_data (edit_window, data);
+ return;
+ }
+ from = modest_account_mgr_get_from_string (account_mgr, account_name);
+
+ /* Create the mail operation */
+ mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO);
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
+
+ modest_mail_operation_save_to_drafts (mail_operation,
+ transport_account,
+ from,
+ data->to,
+ data->cc,
+ data->bcc,
+ data->subject,
+ data->plain_body,
+ data->html_body,
+ data->attachments,
+ data->priority_flags);
+ /* Frees */
+ g_free (from);
+ g_free (account_name);
+ g_object_unref (G_OBJECT (transport_account));
+ g_object_unref (G_OBJECT (mail_operation));
+
+ modest_msg_edit_window_free_msg_data (edit_window, data);
+
+ /* Save settings and close the window */
+ gtk_widget_destroy (GTK_WIDGET (edit_window));
+}
+void
modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
{
TnyTransportAccount *transport_account;
void modest_ui_actions_on_send (GtkWidget *widget,
ModestMsgEditWindow *edit_window);
+void modest_ui_actions_on_save_to_drafts (GtkWidget *widget,
+ ModestMsgEditWindow *edit_window);
+
void modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
ModestMsgEditWindow *window);
{ "FileFormat", NULL, N_("mcen_me_editor_file_format") },
{ "Tools", NULL, N_("mcen_me_inbox_tools") },
{ "ShowToolbar", NULL, N_("mcen_me_inbox_toolbar") },
+ { "Close", NULL, N_("mcen_me_inbox_close") },
/* ACTIONS */
+ { "ActionsNewMessage", NULL, N_("mcen_me_viewer_newemail"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_msg) },
+ { "ActionsSaveToDrafts", NULL, N_("mcen_me_editor_save_as_draft"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_save_to_drafts) },
+ { "ActionsDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) },
{ "ActionsSend", NULL, N_("mcen_me_editor_send"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_send) },
/* { "ActionsFontColor", GTK_STOCK_SELECT_COLOR, N_("Color"), NULL, N_("Change text color"), G_CALLBACK (modest_ui_actions_on_select_editor_color)}, */
/* { "BackgroundColor", GTK_STOCK_SELECT_COLOR, N_("Background color"), NULL, N_("Change background color"), G_CALLBACK (modest_ui_actions_on_select_editor_background_color)}, */
{ "SelectAll", NULL, N_("mcen_me_viewer_selectall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_select_all)},
{ "SelectFont", NULL, N_("mcen_me_editor_font"), NULL, NULL, G_CALLBACK (modest_ui_actions_msg_edit_on_select_font)},
{ "SelectContacts", NULL, N_("mcen_me_editor_selectrecipients"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_select_contacts)},
+ { "CloseWindow", NULL, N_("mcen_me_inbox_close_window"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_close_window)},
+ { "CloseAllWindows", NULL, N_("mcen_me_inbox_close_windows"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_quit) },
/* KEY ACCELERATOR ACTIONS */
{ "ZoomPlus", NULL, N_("Zoom +"), "F7", NULL, G_CALLBACK (modest_ui_actions_on_zoom_plus) },
#include <modest-scroll-text.h>
#include <pango/pango-attributes.h>
#include <string.h>
+#include <gdk/gdkkeysyms.h>
static GObjectClass *parent_class = NULL;
GtkWidget *abook_button;
GtkWidget *scrolled_window;
gchar *recipients;
+
};
#define MODEST_RECPT_EDITOR_GET_PRIVATE(o) \
/* widget events */
static void modest_recpt_editor_on_abook_clicked (GtkButton *button,
ModestRecptEditor *editor);
+static gboolean modest_recpt_editor_on_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ ModestRecptEditor *editor);
+static void modest_recpt_editor_move_cursor_to_end (ModestRecptEditor *editor);
+static void modest_recpt_editor_on_focus_in (GtkTextView *text_view,
+ GdkEventFocus *event,
+ ModestRecptEditor *editor);
+static void modest_recpt_editor_on_insert_text (GtkTextBuffer *buffer,
+ GtkTextIter *location,
+ gchar *text,
+ gint len,
+ ModestRecptEditor *editor);
+static gboolean modest_recpt_editor_on_key_press_event (GtkTextView *text_view,
+ GdkEventKey *key,
+ ModestRecptEditor *editor);
+static GtkTextTag *iter_has_recipient (GtkTextIter *iter);
+static gunichar iter_previous_char (GtkTextIter *iter);
+/* static gunichar iter_next_char (GtkTextIter *iter); */
+static GtkTextTag *prev_iter_has_recipient (GtkTextIter *iter);
+/* static GtkTextTag *next_iter_has_recipient (GtkTextIter *iter); */
+static void select_tag_of_iter (GtkTextIter *iter, GtkTextTag *tag);
+
/**
* modest_recpt_editor_new:
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
+ g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor);
gtk_text_buffer_set_text (buffer, recipients, -1);
if (GTK_WIDGET_REALIZED (recpt_editor))
gtk_widget_queue_resize (GTK_WIDGET (recpt_editor));
+ g_signal_handlers_unblock_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor);
}
gtk_text_buffer_get_end_iter (buffer, &iter);
+ g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor);
+
gtk_text_buffer_insert (buffer, &iter, recipients, -1);
+
+ g_signal_handlers_unblock_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor);
+
if (GTK_WIDGET_REALIZED (recpt_editor))
gtk_widget_queue_resize (GTK_WIDGET (recpt_editor));
GtkTextBuffer *buffer = NULL;
GtkTextIter start, end, iter;
GtkTextTag *tag = NULL;
- gboolean is_first_recipient = TRUE;
GSList *node;
+ gboolean is_first_recipient = TRUE;
g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
+ g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor);
gtk_text_buffer_get_bounds (buffer, &start, &end);
- if (!gtk_text_iter_equal (&start, &end))
- gtk_text_buffer_insert (buffer, &end, ";\n", -1);
+ if (gtk_text_buffer_get_char_count (buffer) > 0) {
+ gchar * buffer_contents;
+
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ buffer_contents = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+ if (!g_str_has_suffix (buffer_contents, "\n")) {
+ if (g_str_has_suffix (buffer_contents, ";")||(g_str_has_suffix (buffer_contents, ",")))
+ gtk_text_buffer_insert (buffer, &end, "\n", -1);
+ else
+ gtk_text_buffer_insert (buffer, &end, ";\n", -1);
+ }
+ g_free (buffer_contents);
+ }
gtk_text_buffer_get_end_iter (buffer, &iter);
g_object_set_data_full (G_OBJECT (tag), "recipient-id", g_strdup (recipient_id), (GDestroyNotify) g_free);
for (node = email_list; node != NULL; node = g_slist_next (node)) {
- gchar *recipient = (gchar *) email_list->data;
+ gchar *recipient = (gchar *) node->data;
if ((recipient) && (strlen (recipient) != 0)) {
- if (!is_first_recipient) {
- gtk_text_buffer_insert (buffer, &iter, ";\n", -1);
- } else {
- is_first_recipient = FALSE;
- }
+ if (!is_first_recipient)
+ gtk_text_buffer_insert (buffer, &iter, "\n", -1);
gtk_text_buffer_insert_with_tags (buffer, &iter, recipient, -1, tag, NULL);
+ gtk_text_buffer_insert (buffer, &iter, ";", -1);
+ is_first_recipient = FALSE;
}
}
+ g_signal_handlers_unblock_by_func (buffer, modest_recpt_editor_on_insert_text, recpt_editor);
+
+ modest_recpt_editor_move_cursor_to_end (recpt_editor);
}
{
ModestRecptEditorPrivate *priv;
GtkWidget *abook_icon;
+ GtkTextBuffer *buffer;
priv = MODEST_RECPT_EDITOR_GET_PRIVATE (instance);
gtk_widget_set_size_request (priv->text_view, 75, -1);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
g_signal_connect (G_OBJECT (priv->abook_button), "clicked", G_CALLBACK (modest_recpt_editor_on_abook_clicked), instance);
+ g_signal_connect (G_OBJECT (priv->text_view), "button-release-event", G_CALLBACK (modest_recpt_editor_on_button_release_event), instance);
+ g_signal_connect (G_OBJECT (priv->text_view), "key-press-event", G_CALLBACK (modest_recpt_editor_on_key_press_event), instance);
+ g_signal_connect (G_OBJECT (priv->text_view), "focus-in-event", G_CALLBACK (modest_recpt_editor_on_focus_in), instance);
+ g_signal_connect (G_OBJECT (buffer), "insert-text", G_CALLBACK (modest_recpt_editor_on_insert_text), instance);
- GTK_WIDGET_SET_FLAGS (GTK_WIDGET (instance), GTK_CAN_FOCUS);
- gtk_container_set_focus_child (GTK_CONTAINER (instance), priv->text_view);
+/* gtk_container_set_focus_child (GTK_CONTAINER (instance), priv->text_view); */
return;
}
gtk_size_group_add_widget (size_group, priv->scrolled_window);
}
+GtkTextBuffer *
+modest_recpt_editor_get_buffer (ModestRecptEditor *recpt_editor)
+{
+ ModestRecptEditorPrivate *priv;
+
+ g_return_val_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor), NULL);
+ priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
+
+ return gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
+}
+
static void
modest_recpt_editor_on_abook_clicked (GtkButton *button, ModestRecptEditor *editor)
{
g_signal_emit_by_name (G_OBJECT (editor), "open-addressbook");
}
+static gboolean
+modest_recpt_editor_on_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ ModestRecptEditor *recpt_editor)
+{
+ ModestRecptEditorPrivate *priv;
+ GtkTextIter location, start, end;
+ GtkTextMark *mark;
+ GtkTextBuffer *buffer;
+ GtkTextTag *tag;
+ gboolean selection_changed = FALSE;
+
+ priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
+
+ buffer = modest_recpt_editor_get_buffer (recpt_editor);
+ mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &location, mark);
+ g_message ("RELEASE OFFSET %d", gtk_text_iter_get_offset (&location));
+
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+
+ tag = iter_has_recipient (&start);
+ if (tag != NULL)
+ if (!gtk_text_iter_begins_tag (&start, tag)) {
+ gtk_text_iter_backward_to_tag_toggle (&start, tag);
+ selection_changed = TRUE;
+ }
+
+ tag = iter_has_recipient (&end);
+ if (tag != NULL)
+ if (!gtk_text_iter_ends_tag (&end, tag)) {
+ gtk_text_iter_forward_to_tag_toggle (&end, tag);
+ selection_changed = TRUE;
+ }
+
+ gtk_text_buffer_select_range (buffer, &start, &end);
+
+ return FALSE;
+}
+
+static void
+modest_recpt_editor_on_focus_in (GtkTextView *text_view,
+ GdkEventFocus *event,
+ ModestRecptEditor *editor)
+{
+ ModestRecptEditorPrivate *priv = MODEST_RECPT_EDITOR_GET_PRIVATE (editor);
+ modest_recpt_editor_move_cursor_to_end (editor);
+ gtk_text_view_place_cursor_onscreen (GTK_TEXT_VIEW (priv->text_view));
+}
+
+static void
+modest_recpt_editor_on_insert_text (GtkTextBuffer *buffer,
+ GtkTextIter *location,
+ gchar *text,
+ gint len,
+ ModestRecptEditor *editor)
+{
+ GtkTextIter prev;
+ gunichar prev_char;
+ ModestRecptEditorPrivate *priv = MODEST_RECPT_EDITOR_GET_PRIVATE (editor);
+
+ if (iter_has_recipient (location)) {
+ gtk_text_buffer_get_end_iter (buffer, location);
+ gtk_text_buffer_place_cursor (buffer, location);
+ }
+
+ if (gtk_text_iter_is_start (location))
+ return;
+
+ if (gtk_text_iter_is_end (location)) {
+ prev = *location;
+ if (!gtk_text_iter_backward_char (&prev))
+ return;
+ prev_char = gtk_text_iter_get_char (&prev);
+ g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, editor);
+ if (prev_char == ';'||prev_char == ',') {
+ GtkTextMark *insert;
+ gtk_text_buffer_insert (buffer, location, "\n",-1);
+ insert = gtk_text_buffer_get_insert (buffer);
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->text_view), location, 0.0,TRUE, 0.0, 1.0);
+ }
+ g_signal_handlers_unblock_by_func (buffer, modest_recpt_editor_on_insert_text, editor);
+
+ }
+
+}
+
+static GtkTextTag *
+iter_has_recipient (GtkTextIter *iter)
+{
+ GSList *tags, *node;
+ GtkTextTag *result = NULL;
+
+ tags = gtk_text_iter_get_tags (iter);
+
+ for (node = tags; node != NULL; node = g_slist_next (node)) {
+ GtkTextTag *tag = GTK_TEXT_TAG (node->data);
+
+ if (g_object_get_data (G_OBJECT (tag), "recipient-tag-id")) {
+ result = tag;
+ break;
+ }
+ }
+ g_slist_free (tags);
+ return result;
+}
+
+static GtkTextTag *
+prev_iter_has_recipient (GtkTextIter *iter)
+{
+ GtkTextIter prev;
+
+ prev = *iter;
+ gtk_text_iter_backward_char (&prev);
+ return iter_has_recipient (&prev);
+}
+
+/* static GtkTextTag * */
+/* next_iter_has_recipient (GtkTextIter *iter) */
+/* { */
+/* GtkTextIter next; */
+
+/* next = *iter; */
+/* return iter_has_recipient (&next); */
+/* } */
+
+static gunichar
+iter_previous_char (GtkTextIter *iter)
+{
+ GtkTextIter prev;
+
+ prev = *iter;
+ gtk_text_iter_backward_char (&prev);
+ return gtk_text_iter_get_char (&prev);
+}
+
+/* static gunichar */
+/* iter_next_char (GtkTextIter *iter) */
+/* { */
+/* GtkTextIter next; */
+
+/* next = *iter; */
+/* gtk_text_iter_forward_char (&next); */
+/* return gtk_text_iter_get_char (&next); */
+/* } */
+
+static void
+select_tag_of_iter (GtkTextIter *iter, GtkTextTag *tag)
+{
+ GtkTextIter start, end;
+
+ start = *iter;
+ if (!gtk_text_iter_begins_tag (&start, tag))
+ gtk_text_iter_backward_to_tag_toggle (&start, tag);
+ end = *iter;
+ if (!gtk_text_iter_ends_tag (&end, tag))
+ gtk_text_iter_forward_to_tag_toggle (&end, tag);
+ gtk_text_buffer_select_range (gtk_text_iter_get_buffer (iter), &start, &end);
+}
+
+static gboolean
+modest_recpt_editor_on_key_press_event (GtkTextView *text_view,
+ GdkEventKey *key,
+ ModestRecptEditor *editor)
+{
+ GtkTextMark *insert;
+ GtkTextBuffer * buffer;
+ GtkTextIter location;
+ GtkTextTag *tag;
+
+ buffer = gtk_text_view_get_buffer (text_view);
+ insert = gtk_text_buffer_get_insert (buffer);
+
+ /* cases to cover:
+ * * cursor is on resolved recipient:
+ * - right should go to first character after the recipient (usually ; or ,)
+ * - left should fo to the first character before the recipient
+ * - return should run check names on the recipient.
+ * * cursor is just after a recipient:
+ * - right should go to the next character. If it's a recipient, should select
+ * it
+ * - left should go to the previous character. If it's a recipient, should go
+ * to the first character of the recipient, and select it.
+ * * cursor is on arbitrary text:
+ * - return should add a ; and go to the next line
+ * - left or right standard ones.
+ * * cursor is after a \n:
+ * - left should go to the character before the \n (as if \n was not a character)
+ * * cursor is before a \n:
+ * - right should go to the character after the \n
+ */
+
+ gtk_text_buffer_get_iter_at_mark (buffer, &location, insert);
+
+ switch (key->keyval) {
+ case GDK_Left:
+ case GDK_KP_Left:
+ {
+ gboolean cursor_ready = FALSE;
+ while (!cursor_ready) {
+ if (iter_previous_char (&location) == '\n') {
+ g_message ("INTRO FOUND");
+ gtk_text_iter_backward_char (&location);
+ } else {
+ cursor_ready = TRUE;
+ }
+ }
+ tag = iter_has_recipient (&location);
+ if ((tag != NULL)&& (gtk_text_iter_is_start (&location) || !(gtk_text_iter_begins_tag (&location, tag)))) {
+ select_tag_of_iter (&location, tag);
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0);
+ return TRUE;
+ }
+ gtk_text_iter_backward_char (&location);
+ tag = iter_has_recipient (&location);
+ if (tag != NULL)
+ select_tag_of_iter (&location, tag);
+ else {
+ gtk_text_buffer_place_cursor (buffer, &location);
+ }
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0);
+
+ return TRUE;
+ }
+ break;
+ case GDK_Right:
+ case GDK_KP_Right:
+ {
+ gboolean cursor_moved = FALSE;
+
+ tag = iter_has_recipient (&location);
+ if ((tag != NULL)&&(!gtk_text_iter_ends_tag (&location, tag))) {
+ gtk_text_iter_forward_to_tag_toggle (&location, tag);
+ while (gtk_text_iter_get_char (&location) == '\n')
+ gtk_text_iter_forward_char (&location);
+ gtk_text_buffer_place_cursor (buffer, &location);
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0);
+ return TRUE;
+ }
+
+ while (gtk_text_iter_get_char (&location) == '\n') {
+ gtk_text_iter_forward_char (&location);
+ cursor_moved = TRUE;
+ }
+ if (!cursor_moved)
+ gtk_text_iter_forward_char (&location);
+ while (gtk_text_iter_get_char (&location) == '\n') {
+ gtk_text_iter_forward_char (&location);
+ cursor_moved = TRUE;
+ }
+
+ tag = iter_has_recipient (&location);
+ if (tag != NULL)
+ select_tag_of_iter (&location, tag);
+ else
+ gtk_text_buffer_place_cursor (buffer, &location);
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), insert, 0.0, FALSE, 0.0, 1.0);
+ return TRUE;
+ }
+ break;
+ case GDK_Return:
+ case GDK_KP_Enter:
+ {
+ g_signal_handlers_block_by_func (buffer, modest_recpt_editor_on_insert_text, editor);
+ tag = iter_has_recipient (&location);
+ if (tag != NULL) {
+ gtk_text_buffer_get_end_iter (buffer, &location);
+ gtk_text_buffer_place_cursor (buffer, &location);
+ if ((iter_previous_char (&location) != ';')&&(iter_previous_char (&location) != ','))
+ gtk_text_buffer_insert_at_cursor (buffer, ";", -1);
+ gtk_text_buffer_insert_at_cursor (buffer, "\n", -1);
+ } else {
+ gunichar prev_char = iter_previous_char (&location);
+ if ((gtk_text_iter_is_start (&location))||(prev_char == '\n')
+ ||(prev_char == ';')||(prev_char == ','))
+ g_signal_emit_by_name (G_OBJECT (editor), "open-addressbook");
+ else {
+ if ((prev_char != ';') && (prev_char != ','))
+ gtk_text_buffer_insert_at_cursor (buffer, ";", -1);
+ gtk_text_buffer_insert_at_cursor (buffer, "\n", -1);
+ }
+ }
+ g_signal_handlers_unblock_by_func (buffer, modest_recpt_editor_on_insert_text, editor);
+ return TRUE;
+ }
+ break;
+ case GDK_BackSpace:
+ {
+ if (gtk_text_buffer_get_has_selection (buffer)) {
+ gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
+ return TRUE;
+ }
+ tag = prev_iter_has_recipient (&location);
+ if (tag != NULL) {
+ GtkTextIter iter_in_tag;
+ iter_in_tag = location;
+ g_message ("DELETE PREV SELECTION");
+ gtk_text_iter_backward_char (&iter_in_tag);
+ select_tag_of_iter (&iter_in_tag, tag);
+ gtk_text_buffer_delete_selection (buffer, TRUE, TRUE);
+ return TRUE;
+ }
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+}
+
+static void
+modest_recpt_editor_move_cursor_to_end (ModestRecptEditor *editor)
+{
+ ModestRecptEditorPrivate *priv = MODEST_RECPT_EDITOR_GET_PRIVATE (editor);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
+ GtkTextIter start, end;
+
+ gtk_text_buffer_get_end_iter (buffer, &start);
+ end = start;
+ gtk_text_buffer_select_range (buffer, &start, &end);
+
+
+}
+
+void
+modest_recpt_editor_grab_focus (ModestRecptEditor *recpt_editor)
+{
+ ModestRecptEditorPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
+ priv = MODEST_RECPT_EDITOR_GET_PRIVATE (recpt_editor);
+
+ gtk_widget_grab_focus (priv->text_view);
+}
+
static void
modest_recpt_editor_finalize (GObject *object)
{
#include <glib-object.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtksizegroup.h>
+#include <gtk/gtktextbuffer.h>
G_BEGIN_DECLS
void modest_recpt_editor_add_resolved_recipient (ModestRecptEditor *recpt_editor, GSList *email_list, const gchar * recipient_id);
void modest_recpt_editor_set_field_size_group (ModestRecptEditor *recpt_editor, GtkSizeGroup *size_group);
+GtkTextBuffer *modest_recpt_editor_get_buffer (ModestRecptEditor *recpt_editor);
+void modest_recpt_editor_grab_focus (ModestRecptEditor *recpt_editor);
G_END_DECLS
text_view = GTK_TEXT_VIEW(modest_scroll_text_get_text_view (MODEST_SCROLL_TEXT (instance)));
g_signal_connect (G_OBJECT (text_view), "button-press-event", G_CALLBACK (button_press_event), instance);
- g_signal_connect (G_OBJECT (text_view), "button-release-event", G_CALLBACK (button_release_event), instance);
+ g_signal_connect_after (G_OBJECT (text_view), "button-release-event", G_CALLBACK (button_release_event), instance);
return;
}
/* Count lines in text view */
for (line = 0; line < line_limit; line++) {
- if (!gtk_text_view_forward_display_line (GTK_TEXT_VIEW (text_view), &iter))
+ if (!gtk_text_view_forward_display_line_end (GTK_TEXT_VIEW (text_view), &iter))
break;
+ else
+ gtk_text_view_forward_display_line (GTK_TEXT_VIEW (text_view), &iter);
}
- /* Put again the cursor in the first character. Also scroll to first line */
- gtk_text_buffer_place_cursor (buffer, &insert_iter);
- gtk_text_view_place_cursor_onscreen (GTK_TEXT_VIEW (text_view));
-
/* Change the adjustment properties for one line per step behavior */
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (widget));
if (adj != NULL) {
priv->line_height = iter_rectangle.height;
+ /* Put again the cursor in the first character. Also scroll to first line */
+ gtk_text_buffer_place_cursor (buffer, &insert_iter);
+ gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (text_view), insert_mark);
+
}
static void