#include "maemo/modest-osso-state-saving.h"
#endif /* MODEST_PLATFORM_MAEMO */
-
+#include "widgets/modest-ui-constants.h"
#include <widgets/modest-main-window.h>
#include <widgets/modest-msg-view-window.h>
#include <widgets/modest-account-view-window.h>
#include <widgets/modest-details-dialog.h>
-
+#include <widgets/modest-attachments-view.h>
+#include "widgets/modest-global-settings-dialog.h"
#include "modest-account-mgr-helpers.h"
#include "modest-mail-operation.h"
#include "modest-text-utils.h"
}
static void
+headers_action_mark_as_read (TnyHeader *header,
+ ModestWindow *win,
+ gpointer user_data)
+{
+ TnyHeaderFlags flags;
+
+ g_return_if_fail (TNY_IS_HEADER(header));
+
+ flags = tny_header_get_flags (header);
+ if (flags & TNY_HEADER_FLAG_SEEN) return;
+ tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
+}
+
+static void
+headers_action_mark_as_unread (TnyHeader *header,
+ ModestWindow *win,
+ gpointer user_data)
+{
+ TnyHeaderFlags flags;
+
+ g_return_if_fail (TNY_IS_HEADER(header));
+
+ flags = tny_header_get_flags (header);
+ if (flags & TNY_HEADER_FLAG_SEEN) {
+ tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
+ }
+}
+
+
+static void
headers_action_delete (TnyHeader *header,
ModestWindow *win,
gpointer user_data)
account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
/* Gets foldert type (OUTBOX headers will be opened in edit window */
-/* folder_type = modest_tny_folder_guess_folder_type (helper->folder); */
if (modest_tny_folder_is_local_folder (helper->folder))
folder_type = modest_tny_folder_get_local_folder_type (helper->folder);
else
win = modest_msg_view_window_new ((TnyMsg *) msg, account);
}
-
+
/* Register and show new window */
if (win != NULL) {
mgr = modest_runtime_get_window_mgr ();
return TRUE;
}
}
-
-static void
-do_send_receive_current_or_default (ModestWindow *win)
+
+/*
+ * This function performs the send & receive required actions. The
+ * window it's used to create the mail operation. Tipically it should
+ * be allways the main window, but we pass it as argument in order to
+ * be more flexible.
+ */
+void
+modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
{
- gchar *account_name;
+ gchar *acc_name = NULL;
- g_message ("%s: online? %s", __FUNCTION__,
- tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
-
- /* As per the UI spec, only the active account should be affected,
- * else the default folder if there is no active account: */
- account_name =
- g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
- if (!account_name)
- account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
+ /* If no account name was provided get the current account, if
+ there is none either then pick the default one */
if (!account_name) {
- g_printerr ("modest: cannot get default account\n");
- return;
+ acc_name = g_strdup (modest_window_get_active_account(win));
+ if (!acc_name)
+ acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
+ if (!acc_name) {
+ g_printerr ("modest: cannot get default account\n");
+ return;
+ }
+ } else {
+ acc_name = g_strdup (account_name);
}
-
- /* Do not continue if no suitable connection is open: */
- if (check_for_connection (account_name)) {
+
+ /* Send & receive. Do not continue if no suitable connection
+ is open */
+ if (check_for_connection (acc_name)) {
/* As per the UI spec,
* for POP accounts, we should receive,
* for IMAP we should synchronize everything, including receiving,
* for SMTP we should send,
* first receiving, then sending:
*/
- if (!action_receive(account_name, win))
+ if (!action_receive(acc_name, win))
g_printerr ("modest: failed to receive\n");
- if (!action_send(account_name))
+ if (!action_send(acc_name))
g_printerr ("modest: failed to send\n");
-
- g_free (account_name);
}
+ /* Free */
+ g_free (acc_name);
}
-
-static void
-do_send_receive_auto (ModestWindow *win)
+/*
+ * Refreshes all accounts. This function will be used by automatic
+ * updates
+ */
+void
+modest_ui_actions_do_send_receive_all (ModestWindow *win)
{
- g_message ("%s: online? %s", __FUNCTION__,
- tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
+ GSList *account_names, *iter;
- /* TODO: Delete the item->data strings as well as the list? */
- GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
- TRUE /* enabled accounts only */);
- GSList *iter = account_names;
+ account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
+ TRUE);
+
+ iter = account_names;
while (iter) {
- const gchar * account_name = (const char*) iter->data;
-
- /* Do not continue if no suitable connection is open: */
- if (account_name && check_for_connection (account_name)) {
- /* As per the UI spec,
- * for POP accounts, we should receive,
- * for IMAP we should synchronize everything, including receiving,
- * for SMTP we should send,
- * first receiving, then sending:
- */
- if (!action_receive(account_name, win))
- g_printerr ("modest: failed to receive for account %s\n", account_name);
- if (!action_send(account_name))
- g_printerr ("modest: failed to send for account %s\n", account_name);
- }
+ modest_ui_actions_do_send_receive ((const char*) iter->data, win);
+ iter = g_slist_next (iter);
}
-
+ g_slist_foreach (account_names, (GFunc) g_free, NULL);
g_slist_free (account_names);
}
-void
-do_send_receive (ModestWindow *win)
-{
- const gboolean auto_update = TRUE; /* TODO: Get gconf setting. */
- if (auto_update)
- do_send_receive_current_or_default (win);
- else
- do_send_receive_auto (win);
-}
-
+/*
+ * Handler of the click on Send&Receive button in the main toolbar
+ */
void
modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
{
g_slist_free (account_names);
/* If not, allow the user to create an account before trying to send/receive. */
- if (!accounts_exist) {
+ if (!accounts_exist)
modest_ui_actions_on_accounts (NULL, win);
- }
-
- do_send_receive (win);
+
+ /* Refresh the active account */
+ modest_ui_actions_do_send_receive (NULL, win);
}
-
-
void
modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
{
}
}
-
-
-/* void */
-/* modest_ui_actions_on_header_activated (ModestHeaderView *header_view, TnyHeader *header, */
-/* ModestMainWindow *main_window) */
-/* { */
-/* ModestWindow *win = NULL; */
-/* TnyFolder *folder = NULL; */
-/* TnyMsg *msg = NULL; */
-/* TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN; */
-/* ModestWindowMgr *mgr; */
-/* GtkTreeModel *model; */
-/* GtkTreeIter iter; */
-/* GtkTreeSelection *sel = NULL; */
-/* GList *sel_list = NULL; */
-
-/* g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); */
-
-/* if (!header) */
-/* return; */
-
-/* folder = tny_header_get_folder (header); */
-/* if (!folder) { */
-/* g_printerr ("modest: cannot get folder for header\n"); */
-/* return; */
-/* } */
-/* if (modest_tny_folder_is_local_folder (folder)) */
-/* folder_type = modest_tny_folder_get_local_folder_type (folder); */
-
-/* /\* FIXME: make async?; check error *\/ */
-/* msg = tny_folder_get_msg (folder, header, NULL); */
-/* if (!msg) { */
-/* g_printerr ("modest: cannot get msg for header\n"); */
-/* goto cleanup; */
-/* } */
-
-/* /\* Look if we already have a message view for that header *\/ */
-/* mgr = modest_runtime_get_window_mgr (); */
-/* win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header)); */
-
-/* /\* If not, create a new window *\/ */
-/* if (!win) { */
-/* gchar *account; */
-
-/* account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window))); */
-/* if (!account) */
-/* account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); */
-
-/* sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); */
-/* sel_list = gtk_tree_selection_get_selected_rows (sel, &model); */
-/* if (sel_list != NULL) { */
-/* gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) sel_list->data); */
-
-/* switch (folder_type) { */
-/* case TNY_FOLDER_TYPE_DRAFTS: */
-/* win = modest_msg_edit_window_new (msg, account); */
-/* break; */
-/* default: */
-/* win = modest_msg_view_window_new_with_header_model (msg, account, model, iter); */
-/* } */
-
-/* g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); */
-/* g_list_free (sel_list); */
-/* } else { */
-/* win = modest_msg_view_window_new (msg, account); */
-/* } */
-/* modest_window_mgr_register_window (mgr, win); */
-
-/* gtk_window_set_transient_for (GTK_WINDOW (win), */
-/* GTK_WINDOW (main_window)); */
-/* } */
-
-/* gtk_widget_show_all (GTK_WIDGET(win)); */
-
-/* g_object_unref (G_OBJECT (msg)); */
-
-/* cleanup: */
-/* g_object_unref (G_OBJECT (folder)); */
-/* } */
-
void
modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
TnyHeader *header,
GtkTreeIter iter;
GtkTreeSelection *sel = NULL;
GList *sel_list = NULL;
+ GList *tmp = NULL;
g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
helper->model = model;
helper->iter = iter;
+ /* Mark as read */
+ for (tmp=sel_list; tmp; tmp=g_list_next(tmp)) {
+ gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) tmp->data);
+ gtk_tree_model_get (model, &iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
+ &header, -1);
+
+ headers_action_mark_as_read (header, MODEST_WINDOW(main_window), NULL);
+
+ g_object_unref(header);
+ }
+
g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
g_list_free (sel_list);
}
if (TNY_IS_FOLDER (folder_store)) {
- modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
-
if (selected) {
+ modest_main_window_set_contents_style (main_window,
+ MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
TNY_FOLDER (folder_store));
modest_widget_memory_restore (conf, G_OBJECT(header_view),
modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
ModestWindow *win)
{
- g_message ("%s %s", __FUNCTION__, link);
+ /* g_message ("%s %s", __FUNCTION__, link); */
}
modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
ModestWindow *win)
{
- g_message (__FUNCTION__);
-
+ modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
}
void
const gchar *address,
ModestWindow *win)
{
- g_message ("%s %s", __FUNCTION__, address);
+ /* g_message ("%s %s", __FUNCTION__, address); */
}
void
modest_msg_edit_window_insert_image (window);
}
+void
+modest_ui_actions_on_attach_file (GtkAction *action,
+ ModestMsgEditWindow *window)
+{
+ g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ modest_msg_edit_window_attach_file (window);
+}
+
+void
+modest_ui_actions_on_remove_attachments (GtkAction *action,
+ ModestMsgEditWindow *window)
+{
+ g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ modest_msg_edit_window_remove_attachments (window, NULL);
+}
+
/*
* Shows a dialog with an entry that asks for some text. The returned
* value must be freed by the caller. The dialog window title will be
/* /\* suggested_name = X; *\/ */
/* /\* Show error to the user *\/ */
/* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
-/* MODEST_INFORMATION_CREATE_FOLDER); */
+/* _("mail_in_ui_folder_create_error")); */
/* } */
g_object_unref (mail_op);
}
/* Show error if happened */
if (modest_mail_operation_get_error (mail_op))
modest_platform_run_information_dialog (GTK_WINDOW (main_window),
- MODEST_INFORMATION_DELETE_FOLDER);
+ _("mail_in_ui_folder_delete_error"));
g_object_unref (G_OBJECT (mail_op));
}
void
modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
- const gchar* account_name,
+ const gchar* server_account_name,
+ gchar **username,
gchar **password,
gboolean *cancel,
gboolean *remember,
ModestMainWindow *main_window)
{
- gchar *txt;
- GtkWidget *dialog, *entry, *remember_pass_check;
-
- dialog = gtk_dialog_new_with_buttons (_("Password requested"),
+ g_return_if_fail(server_account_name);
+ /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
+
+#ifdef MODEST_PLATFORM_MAEMO
+ /* Maemo uses a different (awkward) button order,
+ * It should probably just use gtk_alternative_dialog_button_order ().
+ */
+ GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
+ NULL,
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_REJECT,
+ NULL);
+#else
+ GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
NULL,
GTK_DIALOG_MODAL,
GTK_STOCK_CANCEL,
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL);
+#endif /* MODEST_PLATFORM_MAEMO */
+
gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
- txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
+ gchar *server_name = modest_server_account_get_hostname (
+ modest_runtime_get_account_mgr(), server_account_name);
+
+ /* This causes a warning because the logical ID has no %s in it,
+ * though the translation does, but there is not much we can do about that: */
+ gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
FALSE, FALSE, 0);
g_free (txt);
-
- entry = gtk_entry_new_with_max_length (40);
- gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
- gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
+ g_free (server_name);
+ server_name = NULL;
+
+ /* username: */
+ gchar *initial_username = modest_server_account_get_username (
+ modest_runtime_get_account_mgr(), server_account_name);
+
+ GtkWidget *entry_username = gtk_entry_new ();
+ if (initial_username)
+ gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
+ /* Dim this if a connection has ever succeeded with this username,
+ * as per the UI spec: */
+ const gboolean username_known =
+ modest_server_account_get_username_has_succeeded(
+ modest_runtime_get_account_mgr(), server_account_name);
+ gtk_widget_set_sensitive (entry_username, !username_known);
- gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
- TRUE, FALSE, 0);
-
+#ifdef MODEST_PLATFORM_MAEMO
+ /* Auto-capitalization is the default, so let's turn it off: */
+ hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
+
+ /* Create a size group to be used by all captions.
+ * Note that HildonCaption does not create a default size group if we do not specify one.
+ * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+ GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+ GtkWidget *caption = hildon_caption_new (sizegroup,
+ _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
+ gtk_widget_show (entry_username);
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
+ FALSE, FALSE, MODEST_MARGIN_HALF);
+ gtk_widget_show (caption);
+#else
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
+ TRUE, FALSE, 0);
+#endif /* MODEST_PLATFORM_MAEMO */
+
+ /* password: */
+ GtkWidget *entry_password = gtk_entry_new ();
+ gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
+ /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
+
+#ifdef MODEST_PLATFORM_MAEMO
+ /* Auto-capitalization is the default, so let's turn it off: */
+ hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
+ HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
+
+ caption = hildon_caption_new (sizegroup,
+ _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
+ gtk_widget_show (entry_password);
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
+ FALSE, FALSE, MODEST_MARGIN_HALF);
+ gtk_widget_show (caption);
+ g_object_unref (sizegroup);
+#else
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
+ TRUE, FALSE, 0);
+#endif /* MODEST_PLATFORM_MAEMO */
+
+/* This is not in the Maemo UI spec:
remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
TRUE, FALSE, 0);
+*/
gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
- *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
- *cancel = FALSE;
+ if (username) {
+ *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
+
+ modest_server_account_set_username (
+ modest_runtime_get_account_mgr(), server_account_name,
+ *username);
+
+ const gboolean username_was_changed =
+ (strcmp (*username, initial_username) != 0);
+ if (username_was_changed) {
+ /* To actually use a changed username,
+ * we must reset the connection, according to pvanhoof.
+ * This _might_ be a sensible way to do that: */
+ TnyDevice *device = modest_runtime_get_device();
+ tny_device_force_offline (device);
+ tny_device_force_online (device);
+ }
+ }
+
+ if (password) {
+ *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
+
+ /* We do not save the password in the configuration,
+ * because this function is only called for passwords that should
+ * not be remembered:
+ modest_server_account_set_password (
+ modest_runtime_get_account_mgr(), server_account_name,
+ *password);
+ */
+ }
+
+ if (cancel)
+ *cancel = FALSE;
+
} else {
- *password = NULL;
- *cancel = TRUE;
+ if (username)
+ *username = NULL;
+
+ if (password)
+ *password = NULL;
+
+ if (cancel)
+ *cancel = TRUE;
}
+/* This is not in the Maemo UI spec:
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
*remember = TRUE;
else
*remember = FALSE;
+*/
gtk_widget_destroy (dialog);
}
GtkWidget *focused_widget;
focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
- if (GTK_IS_LABEL (focused_widget)) {
+ if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
+ modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
+ } else if (GTK_IS_LABEL (focused_widget)) {
gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
} else if (GTK_IS_EDITABLE (focused_widget)) {
gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
}
void
+modest_ui_actions_on_mark_as_read (GtkAction *action,
+ ModestWindow *window)
+{
+ g_return_if_fail (MODEST_IS_WINDOW(window));
+
+ /* Mark each header as read */
+ do_headers_action (window, headers_action_mark_as_read, NULL);
+}
+
+void
+modest_ui_actions_on_mark_as_unread (GtkAction *action,
+ ModestWindow *window)
+{
+ g_return_if_fail (MODEST_IS_WINDOW(window));
+
+ /* Mark each header as read */
+ do_headers_action (window, headers_action_mark_as_unread, NULL);
+}
+
+void
modest_ui_actions_on_change_zoom (GtkRadioAction *action,
GtkRadioAction *selected,
ModestWindow *window)
}
g_object_unref (iter);
}
+
+void
+modest_ui_actions_view_attachment (GtkAction *action,
+ ModestWindow *window)
+{
+ if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
+ modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
+ } else {
+ /* not supported window for this action */
+ g_return_if_reached ();
+ }
+}
+
+void
+modest_ui_actions_save_attachments (GtkAction *action,
+ ModestWindow *window)
+{
+ if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
+ modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
+ } else {
+ /* not supported window for this action */
+ g_return_if_reached ();
+ }
+}
+
+void
+modest_ui_actions_remove_attachments (GtkAction *action,
+ ModestWindow *window)
+{
+ if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
+ modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
+ } else {
+ /* not supported window for this action */
+ g_return_if_reached ();
+ }
+}
+
+void
+modest_ui_actions_on_settings (GtkAction *action,
+ ModestWindow *win)
+{
+ GtkWidget *dialog;
+ gint response;
+
+ dialog = modest_platform_get_global_settings_dialog ();
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
+ gtk_widget_show (dialog);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_ACCEPT) {
+ g_message ("YES");
+ }
+
+ gtk_widget_destroy (dialog);
+}