From 1e269a39bd6e1c33e72e98b72f59f810d8f64e8a Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Wed, 11 Apr 2007 07:59:55 +0000 Subject: [PATCH] * src/maemo/modest-msg-edit-window.c: * Commented call to gtk_text_buffer_set_can_paste_rich_text as it does not exist in gtk 2.10. * src/maemo/modest-main-window-ui.h: * Added zoom menu. * Added callback for message details action. * Added next/prev message menu actions. * Added callback for "close window" menu action. * Added next message, prev message, find in message and move to actions to toolbar. * Added toggle action for toggling fullscreen view. * src/maemo/modest-platform.c: * Added support for n800 and osso 1.1 implementation switching of URI handling (n800 uses osso-uri and osso 1.1 uses hildon-uri). * Added implementation of modest_platform_activate_uri and modest_platform_show_uri_popup (both for n800 and osso 1.1). * Added warning banners for trying to show a popup of an URI we don't support. * src/maemo/modest-icon-names.h: * Added "move to..." icon. * src/maemo/modest-msg-view-window.c, src/widgets/modest-msg-view-window.h: * Added support for adding key accelerators from ui manager. * Added support for zooming (actions for zoom levels, key accelerators for hw keys, integration in menu). It uses the magnification support in gtkhtml. * Added support for fullscreen (actions for toggling fullscreen, key accelerator for hw key, integration in menu). It uses the standard ui action for toggling fullscreen in GtkWindow. * Added ..._new_with_header_model. This function is used to add a reference to a header list model. It's used for implementing next/prev message actions. * Added support for browsing next/prev messages of the header model inside (the one the view was opened from). Added also dimming support of next/prev message actions. * Refactored toolbar setup to the new get_toolbar function. * Now toolbar buttons get the whole space with homogeneous spacing and expandable properties. * Contextual menu for toolbar button "reply". It shows a menu with different kinds of reply actions (forward, reply and reply to all). * Added "find in message" implementation. It uses HildonFindToolbar and gtkhtml engine search. It's working partially, as automatic scroll to the words found is not working yet. * Now it sets the priority of the message shown in the message view, getting the information from the headers list. * Added support for translation of ui manager actions. * Added handler for contextual links in message view. * Dimming support of reply button depending on the folder the message is opened from. * src/maemo/ui/modest-msg-view-window-ui.xml: * Renamed some action names to be the same of main window. * Added zoom level menu. * Added fullscreen toggle menu option * Added next/prev message menu options. * Added "close all windows" menu option. * Completed the toolbar layout: - Added new, move to, find in message, prev message and next message actions. - Removed forward and reply to all toolbar buttons, and added contextual menu for reply (including these actions). * Added keyboard accelerators for zoom, fullscreen, and scroll. * src/maemo/ui/modest-main-window-ui.xml: * Renamed action names * src/modest-ui-actions.[ch]: * ..._on_delete closes the window after deletion when used from ModestMsgView. * ..._on_quit now calls gtk_main_quit () to really close the application. * ..._on_close_window added to implement specific window close. It's partially implemented now (does not close properly the main window). * ..._on_next and ..._on_prev: added support for prev and next operations in ModestMsgViewWindow (not implemented yet in Maemo client). It passes a reference to the modesl of the header list, that the ModestMsgViewWindow should hold to implement next/prev on the specific model. * ..._on_header_activate: now it passes the reference of the header list model to the constructor of ModestMsgViewWindow (used in implementation of on_next and on_prev). * ..._on_msg_link_clicked: calls to the new platform function modest_platform_activate_uri (currently only implemented in maemo platform). * Added ..._on_msg_link_contextual action, that's run on requesting the contextual menu of a link. It calls to the new modest_platform_show_uri_popup (). * Added ..._on_change_zoom. This calls to the newly implemented zoom support in ModestWindow (implemented at least for ModestMsgViewWindow in maemo). * Added ..._on_toggle_fullscreen. This toggles fullscreen status of the window it's called from. * Added ..._on_message_details. This opens the new message details dialog. * src/modest-platform.h: * Added new function ..._activate_uri for implementing default uri action handler. * Added new function ..._show_uri_popup for implementing contextual menu of an uri. * src/gnome/modest-platform.c: * Added skel implementations for ..._activate_uri and ..._show_uri_popup. * src/gnome/modest-msg-view-window.c: * Added skel implementations of ..._new_with_header_model, ..._select_next_message and ..._select_previous_message. * src/widgets/modest-mail-header-view.c: * Added support for showing the priority of the message. It does not use the priority in the TnyHeader, but there are methods for setting it externally. * Removed bolding of field names. * Now it get's and expanded parameter in constructor to specify if it should be expanded on startup. * src/widgets/modest-msg-view.[ch]: * Added support for searching in gtkhtml view. * Added support for showing contextual menus using tap and hold (only in MAEMO). * Added support for zooming (using gtkhtml magnification). * Now it constructs the mail header view expanded. * Added separator * Added support for showing priority of messages (it simply sets the priority of the mail header view). * src/widgets/modest-window.[ch]: * Added abstract methods for setting/getting zoom level. * Added src/widgets/modest-msg-view-details-dialog.[ch]: * Dialog to show some message properties. Now it's used only from ModestMsgViewWindow details action. pmo-trunk-r1539 --- autogen.sh | 2 +- debian/rules | 2 +- src/gnome/modest-msg-view-window.c | 29 ++ src/gnome/modest-platform.c | 12 +- src/maemo/modest-icon-names.h | 1 + src/maemo/modest-main-window-ui.h | 15 +- src/maemo/modest-msg-edit-window.c | 4 +- src/maemo/modest-msg-view-window.c | 658 +++++++++++++++++++++++++- src/maemo/modest-platform.c | 137 +++++- src/maemo/ui/modest-main-window-ui.xml | 6 +- src/maemo/ui/modest-msg-view-window-ui.xml | 54 ++- src/modest-platform.h | 22 +- src/modest-ui-actions.c | 168 ++++++- src/modest-ui-actions.h | 19 +- src/widgets/Makefile.am | 2 + src/widgets/modest-mail-header-view.c | 94 ++-- src/widgets/modest-mail-header-view.h | 6 +- src/widgets/modest-msg-view-details-dialog.c | 290 ++++++++++++ src/widgets/modest-msg-view-details-dialog.h | 77 +++ src/widgets/modest-msg-view-window.h | 41 +- src/widgets/modest-msg-view.c | 153 +++++- src/widgets/modest-msg-view.h | 10 + src/widgets/modest-window.c | 36 ++ src/widgets/modest-window.h | 23 + 24 files changed, 1772 insertions(+), 89 deletions(-) create mode 100644 src/widgets/modest-msg-view-details-dialog.c create mode 100644 src/widgets/modest-msg-view-details-dialog.h diff --git a/autogen.sh b/autogen.sh index 18fa2a7..095bb92 100755 --- a/autogen.sh +++ b/autogen.sh @@ -18,5 +18,5 @@ which gnome-autogen.sh || { exit 1 } -USE_GNOME2_MACROS=1 . gnome-autogen.sh +USE_GNOME2_MACROS=1 . gnome-autogen.sh $@ diff --git a/debian/rules b/debian/rules index a08b90f..c08d3ba 100755 --- a/debian/rules +++ b/debian/rules @@ -16,7 +16,7 @@ make-orig-source: make-orig-source-internal: echo -e "Source: modest\nBuild-Depends: subversion, autoconf, automake1.9, autotools-dev, libtool, gtk-doc-tools (>= 1.0), libglib2.0-dev (>= 2.6), gnome-common, devscripts, fakeroot\n\nPackage: modest\n" | dpkg-checkbuilddeps - svn export . $(TMPNAME)/modest-$(UPSTREAMVER) - cd $(TMPNAME)/modest-$(UPSTREAMVER) && NOCONFIGURE=0 ./autogen.sh + cd $(TMPNAME)/modest-$(UPSTREAMVER) && NOCONFIGURE=0 ./autogen.sh --enable-debug cd $(TMPNAME) && tar czf modest_$(UPSTREAMVER).orig.tar.gz --exclude modest-$(UPSTREAMVER)/debian modest-$(UPSTREAMVER) cd $(TMPNAME)/modest-$(UPSTREAMVER) && dch -bv $(UPSTREAMVER)-1 "Exported from SVN on $(DATE)" cd $(TMPNAME)/modest-$(UPSTREAMVER) && dpkg-buildpackage -rfakeroot -S -uc -us && \ diff --git a/src/gnome/modest-msg-view-window.c b/src/gnome/modest-msg-view-window.c index 4b9f610..2b5c155 100644 --- a/src/gnome/modest-msg-view-window.c +++ b/src/gnome/modest-msg-view-window.c @@ -290,3 +290,32 @@ modest_msg_view_window_get_message (ModestMsgViewWindow *self) return modest_msg_view_get_message (MODEST_MSG_VIEW(msg_view)); } + +ModestWindow* +modest_msg_view_window_new_with_header_model (TnyMsg *msg, + const gchar *account, + GtkTreeModel *model, + GtkTreeIter iter) +{ + /* Currently we simply redirect to new constructor. It should store a + reference to the header list model, to enable next/prev message + actions */ + g_message ("partially implemented %s", __FUNCTION__); + + return modest_msg_view_window_new (msg, account); +} + + +gboolean +modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) +{ + g_message ("not implemented %s", __FUNCTION__); + return FALSE; +} + +gboolean +modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) +{ + g_message ("not implemented %s", __FUNCTION__); + return FALSE; +} diff --git a/src/gnome/modest-platform.c b/src/gnome/modest-platform.c index de8ae08..685d458 100644 --- a/src/gnome/modest-platform.c +++ b/src/gnome/modest-platform.c @@ -78,6 +78,17 @@ modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type, return icon_name; } +gboolean +modest_platform_activate_uri (const gchar *uri) +{ + g_message ("not implemented %s", __FUNCTION__); +} + +gboolean +modest_platform_show_uri_popup (const gchar *uri) +{ + g_message ("not implemented %s", __FUNCTION__); +} GdkPixbuf* modest_platform_get_icon (const gchar *name) @@ -97,4 +108,3 @@ modest_platform_get_icon (const gchar *name) return pixbuf; } - diff --git a/src/maemo/modest-icon-names.h b/src/maemo/modest-icon-names.h index 71a80ca..6f5cc99 100644 --- a/src/maemo/modest-icon-names.h +++ b/src/maemo/modest-icon-names.h @@ -73,6 +73,7 @@ #define MODEST_TOOLBAR_ICON_SPLIT_VIEW "qgn_toolb_rss_fldonoff" #define MODEST_TOOLBAR_ICON_SORT "qgn_list_sort" #define MODEST_TOOLBAR_ICON_REFRESH "qgn_toolb_gene_refresh" +#define MODEST_TOOLBAR_ICON_MOVE_TO_FOLDER "qgn_toolb_gene_movetofldr" /* Stock icon names */ #define MODEST_STOCK_MAIL_SEND "modest-stock-mail-send" diff --git a/src/maemo/modest-main-window-ui.h b/src/maemo/modest-main-window-ui.h index 243b5cd..9af67ee 100644 --- a/src/maemo/modest-main-window-ui.h +++ b/src/maemo/modest-main-window-ui.h @@ -46,6 +46,7 @@ static const GtkActionEntry modest_action_entries [] = { { "View", NULL, N_("mcen_me_inbox_view") }, { "Tools", NULL, N_("mcen_me_inbox_tools") }, { "Close", NULL, N_("mcen_me_inbox_close") }, + { "Zoom", NULL, N_("Zoom") }, /* Email */ { "EmailNew", NULL, N_("mcen_me_inbox_new") }, /* submenu */ @@ -57,7 +58,7 @@ static const GtkActionEntry modest_action_entries [] = { { "EmailForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) }, { "EmailDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) }, { "EmailContents", NULL, N_("mcen_me_inbox_retrieve_contents"), NULL, NULL, NULL }, - { "EmailDetails", NULL, N_("mcen_me_inbox_messagedetails"), NULL, NULL, NULL }, + { "EmailDetails", NULL, N_("mcen_me_inbox_messagedetails"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_message_details) }, { "EmailPurgeAttachments", NULL, N_("FIXME: Purge attachments"), NULL, NULL, NULL }, @@ -78,6 +79,8 @@ static const GtkActionEntry modest_action_entries [] = { { "ViewShowToolbar", NULL, N_("mcen_me_inbox_toolbar") }, /* submenu */ { "ViewShowToolbarNormalScreen", NULL, N_("mcen_me_inbox_normalview"), NULL, NULL, NULL }, { "ViewShowToolbarFullScreen", NULL, N_("mcen_me_inbox_optimizedview"), NULL, NULL, NULL }, + { "ViewPreviousMessage", NULL, N_("qgn_toolb_gene_back"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_prev) }, + { "ViewNextMessage", NULL, N_("qgn_toolb_gene_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_next) }, /* Tools */ { "ToolsSettings", NULL, N_("mcen_me_inbox_options"), NULL, NULL, NULL }, @@ -91,7 +94,7 @@ static const GtkActionEntry modest_action_entries [] = { { "ToolsHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, NULL }, /* Close */ - { "CloseWindow", NULL, N_("mcen_me_inbox_close_window"), NULL, NULL, NULL }, + { "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) }, @@ -107,6 +110,14 @@ static const GtkActionEntry modest_action_entries [] = { { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "t", NULL, G_CALLBACK (modest_ui_actions_toggle_view) }, { "ToolbarDeleteMessage", MODEST_STOCK_DELETE, N_("qgn_toolb_gene_deletebutton"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) }, { "ToolbarSort", MODEST_STOCK_SORT, N_("qgn_list_sort"), NULL, NULL, NULL }, + { "ToolbarFindInMessage", GTK_STOCK_FIND, N_("qgn_toolb_gene_find"), NULL, NULL, NULL }, + { "ToolbarMessageBack", GTK_STOCK_GO_BACK, N_("qgn_toolb_gene_back"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_prev) }, + { "ToolbarMessageForward", GTK_STOCK_GO_FORWARD, N_("qgn_toolb_gene_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_next) }, + { "ToolbarMessageMoveTo", MODEST_TOOLBAR_ICON_MOVE_TO_FOLDER, N_("qgn_toolb_gene_movetofldr"), NULL, NULL, NULL }, +}; + +static const GtkToggleActionEntry modest_toggle_action_entries [] = { + { "ShowToggleFullscreen", GTK_STOCK_FULLSCREEN, N_("Full screen"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_toggle_fullscreen), FALSE }, }; diff --git a/src/maemo/modest-msg-edit-window.c b/src/maemo/modest-msg-edit-window.c index 6e74091..7910a87 100644 --- a/src/maemo/modest-msg-edit-window.c +++ b/src/maemo/modest-msg-edit-window.c @@ -266,7 +266,7 @@ init_window (ModestMsgEditWindow *obj) priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)); g_object_set (priv->text_buffer, "font_scale", 1.0, NULL); wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE); - gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); +/* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */ wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE); g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes", G_CALLBACK (text_buffer_refresh_attributes), obj); @@ -361,7 +361,7 @@ set_msg (ModestMsgEditWindow *self, TnyMsg *msg) if (subject) gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject); - gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); +/* 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')) { diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index 8097d01..212fd2d 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -30,16 +30,49 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include +#include +#include +#include +#include static void modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass); static void modest_msg_view_window_init (ModestMsgViewWindow *obj); static void modest_msg_view_window_finalize (GObject *obj); +static void modest_msg_view_window_toggle_find_toolbar (GtkToggleAction *obj, + gpointer data); +static void modest_msg_view_window_find_toolbar_close (GtkWidget *widget, + ModestMsgViewWindow *obj); +static void modest_msg_view_window_find_toolbar_search (GtkWidget *widget, + ModestMsgViewWindow *obj); + +static void modest_msg_view_window_set_zoom (ModestWindow *window, + gdouble zoom); +static gdouble modest_msg_view_window_get_zoom (ModestWindow *window); +static void modest_msg_view_window_zoom_minus (GtkAction *action, ModestWindow *window); +static void modest_msg_view_window_zoom_plus (GtkAction *action, ModestWindow *window); +static gboolean modest_msg_view_window_key_release_event (GtkWidget *window, + GdkEventKey *event, + gpointer userdata); +static void modest_msg_view_window_scroll_up (ModestWindow *window); +static void modest_msg_view_window_scroll_down (ModestWindow *window); +static void modest_msg_view_window_toggle_fullscreen (GtkAction *action, ModestWindow *window); +static gboolean modest_msg_view_window_is_last_message (ModestMsgViewWindow *window); +static gboolean modest_msg_view_window_is_first_message (ModestMsgViewWindow *window); +static TnyFolderType modest_msg_view_window_get_folder_type (ModestMsgViewWindow *window); +static void modest_msg_view_window_update_dimmed (ModestMsgViewWindow *window); +static void modest_msg_view_window_update_priority (ModestMsgViewWindow *window); + + + /* list my signals */ enum { @@ -48,12 +81,37 @@ enum { LAST_SIGNAL }; +static const GtkToggleActionEntry msg_view_toggle_action_entries [] = { + { "FindInMessage", GTK_STOCK_FIND, N_("qgn_toolb_gene_find"), NULL, NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE }, +}; + +static const GtkRadioActionEntry msg_view_zoom_action_entries [] = { + { "Zoom50", NULL, N_("mcen_me_viewer_50"), NULL, NULL, 50 }, + { "Zoom80", NULL, N_("mcen_me_viewer_80"), NULL, NULL, 80 }, + { "Zoom100", NULL, N_("mcen_me_viewer_100"), NULL, NULL, 100 }, + { "Zoom120", NULL, N_("mcen_me_viewer_120"), NULL, NULL, 120 }, + { "Zoom150", NULL, N_("mcen_me_viewer_150"), NULL, NULL, 150 }, + { "Zoom200", NULL, N_("mcen_me_viewer_200"), NULL, NULL, 200 } +}; + +static const GtkActionEntry modest_msg_view_action_entries [] = { + { "ZoomPlus", NULL, N_("Zoom +"), "F7", NULL, G_CALLBACK (modest_msg_view_window_zoom_plus) }, + { "ZoomMinus", NULL, N_("Zoom -"), "F8", NULL, G_CALLBACK (modest_msg_view_window_zoom_minus) }, + { "ToggleFullscreen", NULL, N_("Toggle fullscreen"), "F6", NULL, G_CALLBACK (modest_msg_view_window_toggle_fullscreen) }, +}; + typedef struct _ModestMsgViewWindowPrivate ModestMsgViewWindowPrivate; struct _ModestMsgViewWindowPrivate { GtkWidget *toolbar; GtkWidget *menubar; GtkWidget *msg_view; + GtkWidget *main_scroll; + GtkWidget *find_toolbar; + gchar *last_search; + + GtkTreeModel *header_model; + GtkTreeIter iter; }; #define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ @@ -93,11 +151,16 @@ static void modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass) { GObjectClass *gobject_class; + ModestWindowClass *modest_window_class; gobject_class = (GObjectClass*) klass; + modest_window_class = (ModestWindowClass *) klass; parent_class = g_type_class_peek_parent (klass); gobject_class->finalize = modest_msg_view_window_finalize; + modest_window_class->set_zoom_func = modest_msg_view_window_set_zoom; + modest_window_class->get_zoom_func = modest_msg_view_window_get_zoom; + g_type_class_add_private (gobject_class, sizeof(ModestMsgViewWindowPrivate)); } @@ -110,6 +173,8 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj) priv->toolbar = NULL; priv->menubar = NULL; priv->msg_view = NULL; + + priv->header_model = NULL; } static void @@ -154,6 +219,51 @@ menubar_to_menu (GtkUIManager *ui_manager) return main_menu; } +static GtkWidget* +get_toolbar (ModestMsgViewWindow *self) +{ + GtkWidget *toolbar, *reply_button, *menu; + ModestWindowPrivate *parent_priv; + GtkWidget *button; + + parent_priv = MODEST_WINDOW_GET_PRIVATE (self); + toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar"); + reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); + + menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolbarReplyCSM"); + gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0); + + button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew"); + gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE); + gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (button), TRUE); + + button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); + gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE); + gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (button), TRUE); + + button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo"); + gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE); + gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (button), TRUE); + + button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage"); + gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE); + gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (button), TRUE); + + button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageBack"); + gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE); + gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (button), TRUE); + + button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageForward"); + gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE); + gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (button), TRUE); + + button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FindInMessage"); + gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE); + gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (button), TRUE); + + return toolbar; +} + static void init_window (ModestMsgViewWindow *obj, TnyMsg *msg) @@ -161,7 +271,7 @@ init_window (ModestMsgViewWindow *obj, TnyMsg *msg) GtkWidget *main_vbox; ModestMsgViewWindowPrivate *priv; ModestWindowPrivate *parent_priv; - GtkWidget *scrolled_window; + GtkAccelGroup *accel_group; priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj); parent_priv = MODEST_WINDOW_GET_PRIVATE(obj); @@ -176,25 +286,42 @@ init_window (ModestMsgViewWindow *obj, TnyMsg *msg) gtk_widget_show_all (GTK_WIDGET(parent_priv->menubar)); hildon_window_set_menu (HILDON_WINDOW(obj), GTK_MENU(parent_priv->menubar)); - parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar"); + parent_priv->toolbar = get_toolbar (obj); gtk_widget_show_all (GTK_WIDGET(parent_priv->toolbar)); hildon_window_add_toolbar (HILDON_WINDOW(obj), GTK_TOOLBAR(parent_priv->toolbar)); - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_NONE); + accel_group = gtk_ui_manager_get_accel_group (parent_priv->ui_manager); + gtk_window_add_accel_group (GTK_WINDOW (obj), accel_group); + + priv->main_scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->main_scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->main_scroll), GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (scrolled_window), priv->msg_view); - gtk_box_pack_start (GTK_BOX(main_vbox), scrolled_window, TRUE, TRUE, 6); + gtk_container_add (GTK_CONTAINER (priv->main_scroll), priv->msg_view); + gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_scroll, TRUE, TRUE, 0); gtk_container_add (GTK_CONTAINER(obj), main_vbox); + + priv->find_toolbar = hildon_find_toolbar_new (NULL); + gtk_widget_set_no_show_all (priv->find_toolbar, TRUE); + g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_view_window_find_toolbar_close), obj); + g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj); gtk_widget_show_all (GTK_WIDGET(main_vbox)); + gtk_box_pack_end (GTK_BOX (main_vbox), priv->find_toolbar, FALSE, FALSE, 0); } static void modest_msg_view_window_finalize (GObject *obj) { + ModestMsgViewWindowPrivate *priv; + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (obj); + if (priv->header_model != NULL) { + g_object_unref (priv->header_model); + priv->header_model = NULL; + } + G_OBJECT_CLASS(parent_class)->finalize (obj); } @@ -207,6 +334,28 @@ on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgViewWindow *self) return FALSE; } +ModestWindow * +modest_msg_view_window_new_with_header_model (TnyMsg *msg, const gchar *account_name, + GtkTreeModel *model, GtkTreeIter iter) +{ + ModestMsgViewWindow *window = NULL; + ModestMsgViewWindowPrivate *priv = NULL; + + window = MODEST_MSG_VIEW_WINDOW(modest_msg_view_window_new (msg, account_name)); + g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL); + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + g_object_ref (model); + priv->header_model = model; + priv->iter = iter; + + modest_msg_view_window_update_priority (window); + + modest_msg_view_window_update_dimmed (window); + + return MODEST_WINDOW(window); +} ModestWindow * @@ -226,12 +375,32 @@ modest_msg_view_window_new (TnyMsg *msg, const gchar *account_name) parent_priv->ui_manager = gtk_ui_manager_new(); action_group = gtk_action_group_new ("ModestMsgViewWindowActions"); + gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); /* Add common actions */ gtk_action_group_add_actions (action_group, modest_action_entries, G_N_ELEMENTS (modest_action_entries), obj); + gtk_action_group_add_actions (action_group, + modest_msg_view_action_entries, + G_N_ELEMENTS (modest_msg_view_action_entries), + obj); + gtk_action_group_add_toggle_actions (action_group, + modest_toggle_action_entries, + G_N_ELEMENTS (modest_toggle_action_entries), + obj); + gtk_action_group_add_toggle_actions (action_group, + msg_view_toggle_action_entries, + G_N_ELEMENTS (msg_view_toggle_action_entries), + obj); + gtk_action_group_add_radio_actions (action_group, + msg_view_zoom_action_entries, + G_N_ELEMENTS (msg_view_zoom_action_entries), + 100, + G_CALLBACK (modest_ui_actions_on_change_zoom), + obj); + gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0); g_object_unref (action_group); @@ -266,8 +435,21 @@ modest_msg_view_window_new (TnyMsg *msg, const gchar *account_name) G_CALLBACK (modest_ui_actions_on_msg_attachment_clicked), obj); g_signal_connect (G_OBJECT(priv->msg_view), "recpt_activated", G_CALLBACK (modest_ui_actions_on_msg_recpt_activated), obj); + g_signal_connect (G_OBJECT(priv->msg_view), "link_contextual", + G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj); + + g_signal_connect (G_OBJECT (obj), "key-release-event", + G_CALLBACK (modest_msg_view_window_key_release_event), + NULL); modest_window_set_active_account (MODEST_WINDOW(obj), account_name); + + priv->last_search = NULL; + + modest_msg_view_window_update_dimmed (MODEST_MSG_VIEW_WINDOW (obj)); + + gtk_widget_grab_focus (priv->msg_view); + return MODEST_WINDOW(obj); } @@ -287,3 +469,465 @@ modest_msg_view_window_get_message (ModestMsgViewWindow *self) return modest_msg_view_get_message (msg_view); } + +static void +modest_msg_view_window_toggle_find_toolbar (GtkToggleAction *toggle, + gpointer data) +{ + ModestMsgViewWindow *window = MODEST_MSG_VIEW_WINDOW (data); + ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + if (gtk_toggle_action_get_active (toggle)) { + gtk_widget_show (priv->find_toolbar); + } else { + gtk_widget_hide (priv->find_toolbar); + } + + +} + +static void +modest_msg_view_window_find_toolbar_close (GtkWidget *widget, + ModestMsgViewWindow *obj) +{ + GtkToggleAction *toggle; + ModestWindowPrivate *parent_priv; + parent_priv = MODEST_WINDOW_GET_PRIVATE (obj); + + toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage")); + gtk_toggle_action_set_active (toggle, FALSE); +} + +static void +modest_msg_view_window_find_toolbar_search (GtkWidget *widget, + ModestMsgViewWindow *obj) +{ + gchar *current_search; + ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (obj); + + g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL); + + if ((current_search == NULL) && (strcmp (current_search, "") == 0)) { + g_free (current_search); + return; + } + + if ((priv->last_search == NULL) || (strcmp (priv->last_search, current_search) != 0)) { + gboolean result; + g_free (priv->last_search); + priv->last_search = g_strdup (current_search); + result = modest_msg_view_search (MODEST_MSG_VIEW (priv->msg_view), + priv->last_search); + } else { + modest_msg_view_search_next (MODEST_MSG_VIEW (priv->msg_view)); + } + + g_free (current_search); + +} + +static void +modest_msg_view_window_set_zoom (ModestWindow *window, + gdouble zoom) +{ + ModestMsgViewWindowPrivate *priv; + + g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window)); + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + modest_msg_view_set_zoom (MODEST_MSG_VIEW (priv->msg_view), zoom); +} + +static gdouble +modest_msg_view_window_get_zoom (ModestWindow *window) +{ + ModestMsgViewWindowPrivate *priv; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), 1.0); + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + return modest_msg_view_get_zoom (MODEST_MSG_VIEW (priv->msg_view)); +} + +static void +modest_msg_view_window_zoom_plus (GtkAction *action, ModestWindow *window) +{ + ModestWindowPrivate *parent_priv; + GtkRadioAction *zoom_radio_action; + GSList *group, *node; + + parent_priv = MODEST_WINDOW_GET_PRIVATE (window); + zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, + "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu")); + + group = gtk_radio_action_get_group (zoom_radio_action); + + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) { + hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level")); + return; + } + + for (node = group; node != NULL; node = g_slist_next (node)) { + if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) { + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE); + return; + } + } +} + +static void +modest_msg_view_window_zoom_minus (GtkAction *action, ModestWindow *window) +{ + ModestWindowPrivate *parent_priv; + GtkRadioAction *zoom_radio_action; + GSList *group, *node; + + parent_priv = MODEST_WINDOW_GET_PRIVATE (window); + zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, + "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu")); + + group = gtk_radio_action_get_group (zoom_radio_action); + + for (node = group; node != NULL; node = g_slist_next (node)) { + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) { + if (node->next != NULL) + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE); + else + hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level")); + break; + } + } +} + +static gboolean +modest_msg_view_window_key_release_event (GtkWidget *window, + GdkEventKey *event, + gpointer userdata) +{ + if (event->type == GDK_KEY_RELEASE) { + switch (event->keyval) { + case GDK_Up: + modest_msg_view_window_scroll_up (MODEST_WINDOW (window)); + return TRUE; + break; + case GDK_Down: + modest_msg_view_window_scroll_down (MODEST_WINDOW (window)); + return TRUE; + break; + default: + return FALSE; + break; + }; + } else { + return FALSE; + } +} + +static void +modest_msg_view_window_scroll_up (ModestWindow *window) +{ + ModestMsgViewWindowPrivate *priv; + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", GTK_SCROLL_STEP_UP, FALSE); +} + +static void +modest_msg_view_window_scroll_down (ModestWindow *window) +{ + ModestMsgViewWindowPrivate *priv; + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", GTK_SCROLL_STEP_DOWN, FALSE); +} + +static gboolean +modest_msg_view_window_is_last_message (ModestMsgViewWindow *window) +{ + GtkTreePath *path; + ModestMsgViewWindowPrivate *priv; + GtkTreeIter tmp_iter; + gboolean has_next = FALSE; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), TRUE); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + if (priv->header_model) { + path = gtk_tree_model_get_path (priv->header_model, &priv->iter); + if (!path) + return TRUE; + while (!has_next) { + TnyHeader *header; + gtk_tree_path_next (path); + if (!gtk_tree_model_get_iter (priv->header_model, &tmp_iter, path)) + break; + gtk_tree_model_get (priv->header_model, &tmp_iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + &header, -1); + if (!(tny_header_get_flags(header)&TNY_HEADER_FLAG_DELETED)) { + has_next = TRUE; + break; + } + + } + gtk_tree_path_free (path); + return !has_next; + } else { + return TRUE; + } + +} + +static gboolean +modest_msg_view_window_is_first_message (ModestMsgViewWindow *window) +{ + GtkTreePath *path; + ModestMsgViewWindowPrivate *priv; + gboolean result; + GtkTreeIter tmp_iter; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), TRUE); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + if (priv->header_model) { + gchar * path_string; + path = gtk_tree_model_get_path (priv->header_model, &priv->iter); + if (!path) + return TRUE; + + path_string = gtk_tree_path_to_string (path); + result = (strcmp (path_string, "0")==0); + if (result) { + g_free (path_string); + gtk_tree_path_free (path); + return result; + } + + while (result) { + TnyHeader *header; + + gtk_tree_path_prev (path); + + if (!gtk_tree_model_get_iter (priv->header_model, &tmp_iter, path)) + break; + gtk_tree_model_get (priv->header_model, &tmp_iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + &header, -1); + if (!(tny_header_get_flags(header)&TNY_HEADER_FLAG_DELETED)) { + result = FALSE; + break; + } + + path_string = gtk_tree_path_to_string (path); + if (strcmp(path_string, "0")==0) { + g_free (path_string); + break; + } + g_free (path_string); + } + gtk_tree_path_free (path); + return result; + } else { + return TRUE; + } + +} + +gboolean +modest_msg_view_window_select_next_message (ModestMsgViewWindow *window) +{ + ModestMsgViewWindowPrivate *priv; + GtkTreeIter tmp_iter; + gboolean has_next = FALSE; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + if (priv->header_model) { + tmp_iter = priv->iter; + while (gtk_tree_model_iter_next (priv->header_model, &tmp_iter)) { + TnyHeader *header; + TnyFolder *folder; + TnyMsg *msg; + + priv->iter = tmp_iter; + gtk_tree_model_get (priv->header_model, &(priv->iter), TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + &header, -1); + if (!header) + break; + if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) + continue; + + folder = tny_header_get_folder (header); + if (!folder) + break; + msg = tny_folder_get_msg (folder, header, NULL); + if (!msg) { + g_object_unref (folder); + break; + } + has_next = TRUE; + modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), msg); + modest_msg_view_window_update_dimmed (window); + modest_msg_view_window_update_priority (window); + gtk_widget_grab_focus (priv->msg_view); + + g_object_unref (msg); + break; + } + + return has_next; + } else { + return FALSE; + } +} + +gboolean +modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) +{ + ModestMsgViewWindowPrivate *priv; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + if (priv->header_model) { + GtkTreePath *path; + gboolean has_prev = FALSE; + + path = gtk_tree_model_get_path (priv->header_model, &(priv->iter)); + while (gtk_tree_path_prev (path)) { + TnyHeader *header; + TnyFolder *folder; + TnyMsg *msg; + + gtk_tree_model_get_iter (priv->header_model, &(priv->iter), path); + gtk_tree_model_get (priv->header_model, &(priv->iter), TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + &header, -1); + if (!header) + break; + if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) + continue; + folder = tny_header_get_folder (header); + if (!folder) + break; + msg = tny_folder_get_msg (folder, header, NULL); + if (!msg) { + g_object_unref (folder); + break; + } + has_prev = TRUE; + modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), msg); + modest_msg_view_window_update_dimmed (window); + modest_msg_view_window_update_priority (window); + gtk_widget_grab_focus (priv->msg_view); + + g_object_unref (msg); + break; + } + gtk_tree_path_free (path); + return has_prev; + } else { + return FALSE; + } +} + +static TnyFolderType +modest_msg_view_window_get_folder_type (ModestMsgViewWindow *window) +{ + ModestMsgViewWindowPrivate *priv; + TnyMsg *msg; + TnyFolderType folder_type; + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + folder_type = TNY_FOLDER_TYPE_UNKNOWN; + + msg = modest_msg_view_get_message (MODEST_MSG_VIEW (priv->msg_view)); + if (msg) { + TnyFolder *folder; + + folder = tny_msg_get_folder (msg); + + if (folder) { + folder_type = tny_folder_get_folder_type (folder); + + if (folder_type == TNY_FOLDER_TYPE_NORMAL || folder_type == TNY_FOLDER_TYPE_UNKNOWN) { + const gchar *fname = tny_folder_get_name (folder); + folder_type = modest_tny_folder_guess_folder_type_from_name (fname); + } + + g_object_unref (folder); + } + } + + return folder_type; +} + +static void +modest_msg_view_window_update_dimmed (ModestMsgViewWindow *window) +{ + ModestWindowPrivate *parent_priv; + GtkAction *widget; + gboolean is_first, is_last; + TnyFolderType folder_type; + gboolean is_not_sent; + + parent_priv = MODEST_WINDOW_GET_PRIVATE (window); + + is_first = modest_msg_view_window_is_first_message (window); + is_last = modest_msg_view_window_is_last_message (window); + + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageBack"); + gtk_action_set_sensitive (widget, !is_first); + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewPreviousMessageMenu"); + gtk_action_set_sensitive (widget, !is_first); + + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageForward"); + gtk_action_set_sensitive (widget, !is_last); + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewNextMessageMenu"); + gtk_action_set_sensitive (widget, !is_last); + + folder_type = modest_msg_view_window_get_folder_type (MODEST_MSG_VIEW_WINDOW (window)); + is_not_sent = ((folder_type == TNY_FOLDER_TYPE_DRAFTS)||(folder_type == TNY_FOLDER_TYPE_OUTBOX)); + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); + gtk_action_set_sensitive (widget, !is_not_sent); + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/MessageMenu/MessageReplyMenu"); + gtk_action_set_sensitive (widget, !is_not_sent); + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/MessageMenu/MessageReplyAllMenu"); + gtk_action_set_sensitive (widget, !is_not_sent); + widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/MessageMenu/MessageForwardMenu"); + gtk_action_set_sensitive (widget, !is_not_sent); + +} + +static void +modest_msg_view_window_update_priority (ModestMsgViewWindow *window) +{ + ModestMsgViewWindowPrivate *priv; + TnyHeaderFlags flags = 0; + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + + if (priv->header_model) { + TnyHeader *header; + + gtk_tree_model_get (priv->header_model, &(priv->iter), TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, + &header, -1); + flags = tny_header_get_flags (header); + } + + modest_msg_view_set_priority (MODEST_MSG_VIEW(priv->msg_view), flags); + +} + +static void +modest_msg_view_window_toggle_fullscreen (GtkAction *action, ModestWindow *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/ShowToggleFullscreenMenu"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active); +} diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index 0456da6..6b5a227 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -28,17 +28,24 @@ */ #include +#include #include #include #ifdef MODEST_HILDON_VERSION_0 #include +#include #else #include +#include #endif /*MODEST_HILDON_VERSION_0*/ #include #include +#include +#include +#include +#include gboolean modest_platform_init (void) @@ -130,6 +137,135 @@ modest_platform_get_file_icon_name (const gchar* name, const gchar* mime_type, return icon_name; } +gboolean +modest_platform_activate_uri (const gchar *uri) +{ + gboolean result; + +#ifdef MODEST_HILDON_VERSION_0 + result = osso_uri_open (uri, NULL, NULL); +#else + result = hildon_uri_open (uri, NULL, NULL); +#endif + + if (!result) + hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link")); + return result; +} + +typedef struct { + GSList * actions; + gchar *uri; +} ModestPlatformPopupInfo; + +static gboolean +delete_uri_popup (GtkWidget *menu, + GdkEvent *event, + gpointer userdata) +{ + ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata; + + g_free (popup_info->uri); +#ifdef MODEST_HILDON_VERSION_0 + osso_uri_free_actions (popup_info->actions); +#else + hildon_uri_free_actions (popup_info->actions); +#endif + return FALSE; +} + +static void +activate_uri_popup_item (GtkMenuItem *menu_item, + gpointer userdata) +{ + GSList *node; + ModestPlatformPopupInfo *popup_info = (ModestPlatformPopupInfo *) userdata; + GtkWidget *label; + + label = gtk_bin_get_child (GTK_BIN (menu_item)); + + for (node = popup_info->actions; node != NULL; node = g_slist_next (node)) { +#ifdef MODEST_HILDON_VERSION_0 + OssoURIAction *action = (OssoURIAction *) node->data; + if (strcmp (gtk_label_get_text (GTK_LABEL(label)), osso_uri_action_get_name (action))==0) { + osso_uri_open (popup_info->uri, action, NULL); + break; + } +#else + HildonURIAction *action = (HildonURIAction *) node->data; + if (strcmp (gtk_label_get_text (GTK_LABEL(label)), hildon_uri_action_get_name (action))==0) { + hildon_uri_open (popup_info->uri, action, NULL); + break; + } +#endif + } +} + +gboolean +modest_platform_show_uri_popup (const gchar *uri) +{ + gchar *scheme; + GSList *actions_list; + + if (uri == NULL) + return FALSE; +#ifdef MODEST_HILDON_VERSION_0 + scheme = osso_uri_get_scheme_from_uri (uri, NULL); + actions_list = osso_uri_get_actions (scheme, NULL); +#else + scheme = hildon_uri_get_scheme_from_uri (uri, NULL); + actions_list = hildon_uri_get_actions (scheme, NULL); +#endif + if (actions_list != NULL) { + GSList *node; + GtkWidget *menu = gtk_menu_new (); + ModestPlatformPopupInfo *popup_info = g_new0 (ModestPlatformPopupInfo, 1); + + popup_info->actions = actions_list; + popup_info->uri = g_strdup (uri); + + for (node = actions_list; node != NULL; node = g_slist_next (node)) { + GtkWidget *menu_item; + +#ifdef MODEST_HILDON_VERSION_0 + OssoURIAction *action; + + action = (OssoURIAction *) node->data; + menu_item = gtk_menu_item_new_with_label (osso_uri_action_get_name (action)); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item), popup_info); + + if (osso_uri_is_default_action (action, NULL)) { + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + } else { + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + } +#else + HildonURIAction *action; + + action = (HildonURIAction *) node->data; + menu_item = gtk_menu_item_new_with_label (hildon_uri_action_get_name (action)); + g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (activate_uri_popup_item), popup_info); + + if (hildon_uri_is_default_action (action, NULL)) { + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + } else { + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + } +#endif + + gtk_widget_show (menu_item); + } + g_signal_connect (G_OBJECT (menu), "delete-event", G_CALLBACK (delete_uri_popup), popup_info); + gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time ()); + + } else { + hildon_banner_show_information (NULL, NULL, _("mcen_ib_unsupported_link")); + } + + g_free (scheme); + return TRUE; +} + GdkPixbuf* modest_platform_get_icon (const gchar *name) @@ -152,4 +288,3 @@ modest_platform_get_icon (const gchar *name) return pixbuf; } - diff --git a/src/maemo/ui/modest-main-window-ui.xml b/src/maemo/ui/modest-main-window-ui.xml index 7581443..461adda 100644 --- a/src/maemo/ui/modest-main-window-ui.xml +++ b/src/maemo/ui/modest-main-window-ui.xml @@ -111,12 +111,12 @@ - - + + - + diff --git a/src/maemo/ui/modest-msg-view-window-ui.xml b/src/maemo/ui/modest-msg-view-window-ui.xml index dd9a7cf..7d916c5 100644 --- a/src/maemo/ui/modest-msg-view-window-ui.xml +++ b/src/maemo/ui/modest-msg-view-window-ui.xml @@ -32,16 +32,16 @@ - - - - + + + + - + - + - + @@ -53,6 +53,22 @@ + + + + + + + + + + + + + + + + @@ -60,13 +76,33 @@ + + - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/modest-platform.h b/src/modest-platform.h index f839513..a309314 100644 --- a/src/modest-platform.h +++ b/src/modest-platform.h @@ -74,6 +74,26 @@ gchar* modest_platform_get_file_icon_name (const gchar* name, const gchar* mime gchar **effective_mime_type); /** + * modest_platform_activate_uri: + * @uri: the uri to activate + * + * This function activates an URI + * + * Returns: %TRUE if successful, %FALSE if not. + **/ +gboolean modest_platform_activate_uri (const gchar *uri); + +/** + * modest_platform_show_uri_popup: + * @uri: an URI with the string + * + * This function show the popup of actions for an URI + * + * Returns: %TRUE if successful, %FALSE if not. + **/ +gboolean modest_platform_show_uri_popup (const gchar *uri); + +/** * modest_platform_get_icon: * @name: the name of the icon * @@ -81,6 +101,4 @@ gchar* modest_platform_get_file_icon_name (const gchar* name, const gchar* mime */ GdkPixbuf* modest_platform_get_icon (const gchar *name); - - #endif /* __MODEST_PLATFORM_UTILS_H__ */ diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index d1e3baa..665c510 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -41,10 +41,12 @@ #include "modest-ui-actions.h" #include "modest-tny-platform-factory.h" +#include "modest-platform.h" #include #include #include +#include #include "modest-account-mgr-helpers.h" #include "modest-mail-operation.h" @@ -85,6 +87,8 @@ static void read_msg_func (gpointer data, gpointer user_data); static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data); static void reply_forward (ReplyForwardAction action, ModestWindow *win); +static void modest_ui_actions_message_details_cb (gpointer msg_data, + gpointer helper_data); static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title); @@ -182,6 +186,10 @@ modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win) /* Free iter */ g_object_unref (G_OBJECT (iter)); } + + if (MODEST_IS_MSG_VIEW_WINDOW (win)) { + gtk_widget_destroy (GTK_WIDGET(win)); + } } @@ -190,7 +198,20 @@ modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win) { /* FIXME: save size of main window */ /* save_sizes (main_window); */ - gtk_widget_destroy (GTK_WIDGET (win)); +/* gtk_widget_destroy (GTK_WIDGET (win)); */ + gtk_main_quit (); +} + +void +modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win) +{ + if (MODEST_IS_MSG_VIEW_WINDOW (win)) { + gtk_widget_destroy (GTK_WIDGET (win)); + } else if (MODEST_IS_WINDOW (win)) { + gtk_widget_destroy (GTK_WIDGET (win)); + } else { + g_return_if_reached (); + } } void @@ -520,32 +541,43 @@ modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win) void modest_ui_actions_on_next (GtkAction *action, - ModestMainWindow *main_window) + ModestWindow *window) { - GtkWidget *header_view; - g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); + if (MODEST_IS_MAIN_WINDOW (window)) { + GtkWidget *header_view; - header_view = modest_main_window_get_child_widget (main_window, - MODEST_WIDGET_TYPE_HEADER_VIEW); - if (!header_view) - return; + header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window), + MODEST_WIDGET_TYPE_HEADER_VIEW); + if (!header_view) + return; - modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); + modest_header_view_select_next (MODEST_HEADER_VIEW(header_view)); + } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window)); + } else { + g_return_if_reached (); + } } void modest_ui_actions_on_prev (GtkAction *action, - ModestMainWindow *main_window) + ModestWindow *window) { - GtkWidget *header_view; - g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); + g_return_if_fail (MODEST_IS_WINDOW(window)); - header_view = modest_main_window_get_child_widget (main_window, - MODEST_WIDGET_TYPE_HEADER_VIEW); - if (!header_view) - return; - - modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); + if (MODEST_IS_MAIN_WINDOW (window)) { + GtkWidget *header_view; + header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window), + MODEST_WIDGET_TYPE_HEADER_VIEW); + if (!header_view) + return; + + modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view)); + } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window)); + } else { + g_return_if_reached (); + } } @@ -766,6 +798,9 @@ modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader TnyFolder *folder = NULL; TnyMsg *msg = NULL; gchar *account = NULL; + GtkTreeModel *model = NULL; + GtkTreeSelection *sel = NULL; + GtkTreeIter iter; ModestWindowMgr *mgr; g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); @@ -791,7 +826,12 @@ modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); /* Create and register message view window */ - win = modest_msg_view_window_new (msg, account); + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view)); + if (gtk_tree_selection_get_selected (sel, &model, &iter)) { + win = modest_msg_view_window_new_with_header_model (msg, account, model, iter); + } else { + win = modest_msg_view_window_new (msg, account); + } mgr = modest_runtime_get_window_mgr (); modest_window_mgr_register_window (mgr, win); @@ -910,7 +950,7 @@ void modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link, ModestWindow *win) { - g_message (__FUNCTION__); + g_message ("%s %s", __FUNCTION__, link); } @@ -918,7 +958,14 @@ void modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link, ModestWindow *win) { - g_message (__FUNCTION__); + modest_platform_activate_uri (link); +} + +void +modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link, + ModestWindow *win) +{ + modest_platform_show_uri_popup (link); } void @@ -1423,3 +1470,82 @@ modest_ui_actions_on_select_all (GtkAction *action, gtk_text_buffer_select_range (buffer, &start, &end); } } + +void +modest_ui_actions_on_change_zoom (GtkRadioAction *action, + GtkRadioAction *selected, + ModestWindow *window) +{ + gint value; + + value = gtk_radio_action_get_current_value (selected); + if (MODEST_IS_WINDOW (window)) { + modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100); + } +} + +void +modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW (window)); + + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle))) { + gtk_window_fullscreen (GTK_WINDOW (window)); + } else { + gtk_window_unfullscreen (GTK_WINDOW (window)); + } +} + +static void +modest_ui_actions_message_details_cb (gpointer msg_data, + gpointer helper_data) +{ + GtkWidget *dialog; + TnyMsg *msg = (TnyMsg *) msg_data; + TnyHeader *header; + GetMsgAsyncHelper *helper = (GetMsgAsyncHelper *) helper_data; + + header = tny_msg_get_header (msg); + + dialog = modest_msg_view_details_dialog_new (GTK_WINDOW (helper->window), header); + g_object_unref (header); + gtk_widget_show_all (dialog); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); +} + +void +modest_ui_actions_on_message_details (GtkAction *action, + ModestWindow *win) +{ + TnyList * headers_list; + GetMsgAsyncHelper *helper; + + headers_list = get_selected_headers (win); + if (!headers_list) + return; + + helper = g_slice_new0 (GetMsgAsyncHelper); + helper->window = win; + helper->func = modest_ui_actions_message_details_cb; + helper->iter = tny_list_create_iterator (headers_list); + helper->user_data = NULL; + + if (MODEST_IS_MSG_VIEW_WINDOW (win)) { + TnyMsg *msg; + + msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win)); + if (!msg) + return; + else { + modest_ui_actions_message_details_cb (msg, helper); + } + } else { + /* here we should add an implementation to run the message details dialog + from the main window */ + g_return_if_reached (); + } +} diff --git a/src/modest-ui-actions.h b/src/modest-ui-actions.h index cd5c1d2..4756fe0 100644 --- a/src/modest-ui-actions.h +++ b/src/modest-ui-actions.h @@ -43,6 +43,8 @@ void modest_ui_actions_on_delete (GtkAction *action, ModestWindow *wi void modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win); +void modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win); + void modest_ui_actions_on_new_account (GtkAction *action, ModestWindow *win); void modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win); @@ -59,9 +61,11 @@ void modest_ui_actions_on_forward (GtkAction *action, ModestWindow *wi void modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win); -void modest_ui_actions_on_next (GtkAction *action, ModestMainWindow *main_window); +void modest_ui_actions_on_next (GtkAction *action, ModestWindow *main_window); + +void modest_ui_actions_on_prev (GtkAction *action, ModestWindow *main_window); -void modest_ui_actions_on_prev (GtkAction *action, ModestMainWindow *main_window); +void modest_ui_actions_on_message_details (GtkAction *action, ModestWindow *win); void modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window); @@ -91,6 +95,9 @@ void modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, void modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link, ModestWindow *win); +void modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link, + ModestWindow *win); + void modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part, ModestWindow *win); @@ -153,5 +160,13 @@ void modest_ui_actions_on_paste (GtkAction *action, void modest_ui_actions_on_select_all (GtkAction *action, ModestWindow *window); +void modest_ui_actions_on_change_zoom (GtkRadioAction *action, + GtkRadioAction *selected, + ModestWindow *window); + +void modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle, + ModestWindow *window); + + G_END_DECLS #endif /* __MODEST_UI_ACTIONS_H__ */ diff --git a/src/widgets/Makefile.am b/src/widgets/Makefile.am index ff67a8b..afa6f15 100644 --- a/src/widgets/Makefile.am +++ b/src/widgets/Makefile.am @@ -39,6 +39,8 @@ libmodest_widgets_la_SOURCES= \ modest-msg-view-window.h \ modest-msg-view.c \ modest-msg-view.h \ + modest-msg-view-details-dialog.c \ + modest-msg-view-details-dialog.h \ modest-recpt-view.c \ modest-recpt-view.h \ modest-scroll-text.c \ diff --git a/src/widgets/modest-mail-header-view.c b/src/widgets/modest-mail-header-view.c index edcf7b5..629feba 100644 --- a/src/widgets/modest-mail-header-view.c +++ b/src/widgets/modest-mail-header-view.c @@ -53,10 +53,13 @@ struct _ModestMailHeaderViewPriv GtkWidget *main_vbox; GtkWidget *expander; GtkWidget *headers_vbox; + GtkWidget *subject_box; + GtkWidget *priority_icon; GtkSizeGroup *labels_size_group; gboolean is_outgoing; gboolean is_draft; TnyHeader *header; + TnyHeaderFlags priority_flags; }; #define MODEST_MAIL_HEADER_VIEW_GET_PRIVATE(o) \ @@ -74,7 +77,6 @@ add_date_time_header (ModestMailHeaderView *mail_header, const gchar *name, time ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (mail_header); GtkWidget *hbox, *date_hbox, *time_hbox; GtkWidget *label; - gchar *bolded_field = NULL; modest_text_utils_strftime (date_buf, BUF_SIZE, "%x", date); modest_text_utils_strftime (time_buf, BUF_SIZE, "%X", date); @@ -84,9 +86,7 @@ add_date_time_header (ModestMailHeaderView *mail_header, const gchar *name, time time_hbox = gtk_hbox_new (FALSE, 12); label = gtk_label_new (NULL); - bolded_field = g_strconcat ("", name, "", NULL); - gtk_label_set_markup (GTK_LABEL (label), bolded_field); - g_free (bolded_field); + gtk_label_set_markup (GTK_LABEL (label), name); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0); gtk_box_pack_start (GTK_BOX (date_hbox), label, FALSE, FALSE, 0); gtk_size_group_add_widget (priv->labels_size_group, label); @@ -99,9 +99,7 @@ add_date_time_header (ModestMailHeaderView *mail_header, const gchar *name, time label = gtk_label_new(NULL); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0); - bolded_field = g_strconcat ("", _("mail_va_time"), "", NULL); - gtk_label_set_markup (GTK_LABEL (label), bolded_field); - g_free (bolded_field); + gtk_label_set_markup (GTK_LABEL (label), _("mail_va_time")); gtk_box_pack_start (GTK_BOX (time_hbox), label, FALSE, FALSE, 0); label = gtk_label_new(time_buf); @@ -131,14 +129,10 @@ add_header (ModestMailHeaderView *widget, const gchar *field, const gchar *value GtkWidget *label_field, *label_value; GtkWidget *scroll_text; GtkTextBuffer *text_buffer; - gchar *bolded_field = NULL; hbox = gtk_hbox_new (FALSE, 12); label_field = gtk_label_new (NULL); - if (field) - bolded_field = g_strconcat ("", field, "", NULL); - gtk_label_set_markup (GTK_LABEL (label_field), bolded_field); - g_free (bolded_field); + gtk_label_set_markup (GTK_LABEL (label_field), field); gtk_misc_set_alignment (GTK_MISC (label_field), 0.0, 0.0); scroll_text = modest_scroll_text_new (NULL, 2); label_value = (GtkWidget *) modest_scroll_text_get_text_view (MODEST_SCROLL_TEXT (scroll_text)); @@ -162,14 +156,10 @@ add_recpt_header (ModestMailHeaderView *widget, const gchar *field, const gchar ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (widget); GtkWidget *hbox; GtkWidget *label_field, *label_value; - gchar *bolded_field = NULL; hbox = gtk_hbox_new (FALSE, 12); label_field = gtk_label_new (NULL); - if (field != NULL) - bolded_field = g_strconcat ("", field, "", NULL); - gtk_label_set_markup (GTK_LABEL (label_field), bolded_field); - g_free (bolded_field); + gtk_label_set_markup (GTK_LABEL (label_field), field); gtk_misc_set_alignment (GTK_MISC (label_field), 0.0, 0.0); label_value = modest_recpt_view_new (); modest_recpt_view_set_recipients (MODEST_RECPT_VIEW(label_value), value); @@ -256,7 +246,7 @@ modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *head if (header && G_IS_OBJECT (header)) { const gchar *to, *from, *subject, *bcc, *cc; - GtkWidget *subject_box, *subject_label; + GtkWidget *subject_label; g_object_ref (G_OBJECT (header)); priv->header = header; @@ -270,7 +260,7 @@ modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *head cc = tny_header_get_cc (header); bcc = tny_header_get_bcc (header); - subject_box = gtk_hbox_new (FALSE, 12); + priv->subject_box = gtk_hbox_new (FALSE, 0); subject_label = gtk_label_new (NULL); if (subject) gtk_label_set_text (GTK_LABEL (subject_label), subject); @@ -286,11 +276,10 @@ modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *head /* GtkWidget *priority_icon = gtk_image_new_from_icon_name ("qgn_list_messaging_high", GTK_ICON_SIZE_MENU); */ /* gtk_box_pack_start (GTK_BOX (subject_box), priority_icon, FALSE, FALSE, 0); */ /* } */ - gtk_box_pack_start (GTK_BOX (subject_box), subject_label, TRUE, TRUE, 0); + priv->priority_icon = NULL; + gtk_box_pack_end (GTK_BOX (priv->subject_box), subject_label, TRUE, TRUE, 0); if (priv->is_outgoing) { - gchar *bolded_label = g_strconcat ("", _("mail_va_to"), "", NULL); - gtk_label_set_markup (GTK_LABEL (priv->fromto_label), bolded_label); - g_free (bolded_label); + gtk_label_set_markup (GTK_LABEL (priv->fromto_label), _("mail_va_to")); if (to) modest_recpt_view_set_recipients (MODEST_RECPT_VIEW (priv->fromto_contents), to); if (cc) @@ -299,15 +288,13 @@ modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *head add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_hotfix1"), bcc); if (priv->is_draft&& from) add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_from"), from); - modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_subject"), subject_box, TRUE, TRUE); + modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_subject"), priv->subject_box, TRUE, TRUE); if (priv->is_draft) add_date_time_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Last saved:"), tny_header_get_date_sent (header)); else add_date_time_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Sent:"), tny_header_get_date_sent (header)); } else { - gchar *bolded_label = g_strconcat ("", _("mail_va_from"), "", NULL); - gtk_label_set_markup (GTK_LABEL (priv->fromto_label), bolded_label); - g_free (bolded_label); + gtk_label_set_markup (GTK_LABEL (priv->fromto_label), _("mail_va_from")); if (from) modest_recpt_view_set_recipients (MODEST_RECPT_VIEW (priv->fromto_contents), from); if (cc) @@ -316,7 +303,7 @@ modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *head add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_hotfix1"), bcc); if (to) add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_to"), to); - modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_subject"), subject_box, TRUE, TRUE); + modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_subject"), priv->subject_box, TRUE, TRUE); add_date_time_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Received:"), tny_header_get_date_received (header)); } } @@ -385,15 +372,11 @@ modest_mail_header_view_add_custom_header (ModestMailHeaderView *header_view, g_return_val_if_fail (MODEST_IS_MAIL_HEADER_VIEW (header_view), NULL); GtkWidget *hbox; GtkWidget *label_field; - gchar *bolded_field = NULL; priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (header_view); hbox = gtk_hbox_new (FALSE, 12); label_field = gtk_label_new (NULL); - if (label != NULL) - bolded_field = g_strconcat ("", label, "", NULL); - gtk_label_set_markup (GTK_LABEL (label_field), bolded_field); - g_free (bolded_field); + gtk_label_set_markup (GTK_LABEL (label_field), label); gtk_misc_set_alignment (GTK_MISC (label_field), 0.0, 0.0); gtk_box_pack_start (GTK_BOX (hbox), label_field, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), custom_widget, TRUE, TRUE, 0); @@ -420,10 +403,15 @@ modest_mail_header_view_add_custom_header (ModestMailHeaderView *header_view, * Return value: a new #ModestHeaderView instance implemented for Gtk+ **/ TnyHeaderView* -modest_mail_header_view_new (void) +modest_mail_header_view_new (gboolean expanded) { + ModestMailHeaderViewPriv *priv; ModestMailHeaderView *self = g_object_new (MODEST_TYPE_MAIL_HEADER_VIEW, NULL); + priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (self); + gtk_expander_set_expanded (GTK_EXPANDER (priv->expander), expanded); + expander_activate (priv->expander, self); + return TNY_HEADER_VIEW (self); } @@ -574,3 +562,41 @@ modest_mail_header_view_get_type (void) return type; } + +TnyHeaderFlags +modest_mail_header_view_get_priority (ModestMailHeaderView *headers_view) +{ + ModestMailHeaderViewPriv *priv; + + g_return_val_if_fail (MODEST_IS_MAIL_HEADER_VIEW (headers_view), 0); + priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (headers_view); + + return priv->priority_flags; +} + +void +modest_mail_header_view_set_priority (ModestMailHeaderView *headers_view, + TnyHeaderFlags flags) +{ + ModestMailHeaderViewPriv *priv; + + g_return_if_fail (MODEST_IS_MAIL_HEADER_VIEW (headers_view)); + priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (headers_view); + + priv->priority_flags = flags & (TNY_HEADER_FLAG_HIGH_PRIORITY); + + if (priv->priority_flags == 0) { + if (priv->priority_icon != NULL) { + gtk_widget_destroy (priv->priority_icon); + priv->priority_icon = NULL; + } + } else if (priv->priority_flags == TNY_HEADER_FLAG_HIGH_PRIORITY) { + priv->priority_icon = gtk_image_new_from_icon_name ("qgn_list_messaging_high", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->priority_icon, FALSE, FALSE, 0); + gtk_widget_show (priv->priority_icon); + } else if (priv->priority_flags == TNY_HEADER_FLAG_LOW_PRIORITY) { + priv->priority_icon = gtk_image_new_from_icon_name ("qgn_list_messaging_low", GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->priority_icon, FALSE, FALSE, 0); + gtk_widget_show (priv->priority_icon); + } +} diff --git a/src/widgets/modest-mail-header-view.h b/src/widgets/modest-mail-header-view.h index ff2a3a5..b7051c3 100644 --- a/src/widgets/modest-mail-header-view.h +++ b/src/widgets/modest-mail-header-view.h @@ -67,7 +67,7 @@ struct _ModestMailHeaderViewClass }; GType modest_mail_header_view_get_type (void); -TnyHeaderView* modest_mail_header_view_new (void); +TnyHeaderView* modest_mail_header_view_new (gboolean expanded); const GtkWidget *modest_mail_header_view_add_custom_header (ModestMailHeaderView *header_view, const gchar *label, @@ -75,6 +75,10 @@ const GtkWidget *modest_mail_header_view_add_custom_header (ModestMailHeaderView gboolean with_expander, gboolean start); +TnyHeaderFlags modest_mail_header_view_get_priority (ModestMailHeaderView *header_view); +void modest_mail_header_view_set_priority (ModestMailHeaderView *header_view, TnyHeaderFlags flags); + + G_END_DECLS #endif diff --git a/src/widgets/modest-msg-view-details-dialog.c b/src/widgets/modest-msg-view-details-dialog.c new file mode 100644 index 0000000..0100f0b --- /dev/null +++ b/src/widgets/modest-msg-view-details-dialog.c @@ -0,0 +1,290 @@ +/* connection-specific-smtp-window.c */ + +#include "modest-msg-view-details-dialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void modest_msg_view_details_dialog_add_row (ModestMsgViewDetailsDialog *self, const gchar *label, const gchar *value); +static void modest_msg_view_details_dialog_set_header (TnyHeaderView *self, TnyHeader *header); +static void modest_msg_view_details_dialog_clear (TnyHeaderView *self); +static void modest_msg_view_details_dialog_tny_header_view_init (gpointer g_iface, gpointer iface_data); +static TnyFolderType modest_msg_view_details_dialog_get_folder_type (ModestMsgViewDetailsDialog *window); + +G_DEFINE_TYPE_WITH_CODE (ModestMsgViewDetailsDialog, modest_msg_view_details_dialog, GTK_TYPE_DIALOG, G_IMPLEMENT_INTERFACE ( TNY_TYPE_HEADER_VIEW, modest_msg_view_details_dialog_tny_header_view_init)); + +#define MODEST_MSG_VIEW_DETAILS_DIALOG_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG, ModestMsgViewDetailsDialogPrivate)) + + +typedef struct _ModestMsgViewDetailsDialogPrivate ModestMsgViewDetailsDialogPrivate; + +struct _ModestMsgViewDetailsDialogPrivate +{ + TnyHeader *header; + GtkWidget *props_table; +}; + +static void +modest_msg_view_details_dialog_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +modest_msg_view_details_dialog_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +modest_msg_view_details_dialog_dispose (GObject *object) +{ + if (G_OBJECT_CLASS (modest_msg_view_details_dialog_parent_class)->dispose) + G_OBJECT_CLASS (modest_msg_view_details_dialog_parent_class)->dispose (object); +} + +static void +modest_msg_view_details_dialog_finalize (GObject *object) +{ + ModestMsgViewDetailsDialogPrivate *priv = MODEST_MSG_VIEW_DETAILS_DIALOG_GET_PRIVATE (object); + + if (priv->header) { + g_object_unref (priv->header); + priv->header = NULL; + } + G_OBJECT_CLASS (modest_msg_view_details_dialog_parent_class)->finalize (object); +} + +static void +modest_msg_view_details_dialog_class_init (ModestMsgViewDetailsDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ModestMsgViewDetailsDialogPrivate)); + + object_class->get_property = modest_msg_view_details_dialog_get_property; + object_class->set_property = modest_msg_view_details_dialog_set_property; + object_class->dispose = modest_msg_view_details_dialog_dispose; + object_class->finalize = modest_msg_view_details_dialog_finalize; +} + +static void +modest_msg_view_details_dialog_init (ModestMsgViewDetailsDialog *self) +{ + ModestMsgViewDetailsDialogPrivate *priv = MODEST_MSG_VIEW_DETAILS_DIALOG_GET_PRIVATE (self); + GtkWidget *scrollbar; + + priv->header = NULL; + scrollbar = gtk_scrolled_window_new (NULL, NULL); + + gtk_window_set_default_size (GTK_WINDOW (self), 400, 220); + gtk_window_set_title (GTK_WINDOW (self), _("mcen_ti_message_properties")); + + priv->props_table = gtk_table_new (0, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (priv->props_table), 12); + gtk_table_set_row_spacings (GTK_TABLE (priv->props_table), 1); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollbar), priv->props_table); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (self)->vbox), scrollbar); + + gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE); + gtk_dialog_add_button (GTK_DIALOG (self), _("mcen_bd_close"), GTK_RESPONSE_CLOSE); +} + +static void +modest_msg_view_details_dialog_tny_header_view_init (gpointer g_iface, gpointer iface_data) +{ + TnyHeaderViewIface *iface = (TnyHeaderViewIface *) g_iface; + + iface->set_header_func = modest_msg_view_details_dialog_set_header; + iface->clear_func = modest_msg_view_details_dialog_clear; +} + +GtkWidget* +modest_msg_view_details_dialog_new (GtkWindow *parent, TnyHeader *header) +{ + GtkWidget *dialog; + dialog = GTK_WIDGET (g_object_new (MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG, "transient-for", parent, NULL)); + + if (header != NULL) + modest_msg_view_details_dialog_set_header (TNY_HEADER_VIEW (dialog), header); + + return dialog; +} + +static void +modest_msg_view_details_dialog_add_row (ModestMsgViewDetailsDialog *self, + const gchar *label, + const gchar *value) +{ + ModestMsgViewDetailsDialogPrivate *priv; + guint n_rows = 0; + GtkWidget *label_w, *value_w; + + priv = MODEST_MSG_VIEW_DETAILS_DIALOG_GET_PRIVATE (self); + + g_object_get (G_OBJECT (priv->props_table), "n-rows", &n_rows,NULL); + label_w = gtk_label_new (label); + gtk_misc_set_alignment (GTK_MISC (label_w), 1.0, 0.0); + gtk_label_set_justify (GTK_LABEL (label_w), GTK_JUSTIFY_RIGHT); + value_w = gtk_label_new (value); + gtk_label_set_line_wrap (GTK_LABEL (value_w), TRUE); + gtk_misc_set_alignment (GTK_MISC (value_w), 0.0, 0.0); + gtk_label_set_justify (GTK_LABEL (value_w), GTK_JUSTIFY_LEFT); + + gtk_table_attach (GTK_TABLE (priv->props_table), label_w, 0, 1, n_rows, n_rows + 1, GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0, 0); + gtk_table_attach (GTK_TABLE (priv->props_table), value_w, 1, 2, n_rows, n_rows + 1, GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0, 0); + +} + +static TnyFolderType +modest_msg_view_details_dialog_get_folder_type (ModestMsgViewDetailsDialog *window) +{ + ModestMsgViewDetailsDialogPrivate *priv; + TnyFolderType folder_type; + + priv = MODEST_MSG_VIEW_DETAILS_DIALOG_GET_PRIVATE (window); + + folder_type = TNY_FOLDER_TYPE_UNKNOWN; + + if (priv->header) { + TnyFolder *folder; + + folder = tny_header_get_folder (priv->header); + + if (folder) { + folder_type = tny_folder_get_folder_type (folder); + + if (folder_type == TNY_FOLDER_TYPE_NORMAL || folder_type == TNY_FOLDER_TYPE_UNKNOWN) { + const gchar *fname = tny_folder_get_name (folder); + folder_type = modest_tny_folder_guess_folder_type_from_name (fname); + } + + g_object_unref (folder); + } + } + + return folder_type; +} + + +static void +modest_msg_view_details_dialog_set_header (TnyHeaderView *self, + TnyHeader *header) +{ + ModestMsgViewDetailsDialogPrivate *priv; + gchar *from, *subject, *to, *cc; + time_t received, sent; + guint size; + gchar *size_s; + + g_return_if_fail (MODEST_IS_MSG_VIEW_DETAILS_DIALOG (self)); + priv = MODEST_MSG_VIEW_DETAILS_DIALOG_GET_PRIVATE (self); + + modest_msg_view_details_dialog_clear (self); + + priv->header = header; + + if (header != NULL) { + TnyFolderType folder_type; + g_object_ref (header); + + folder_type = modest_msg_view_details_dialog_get_folder_type (MODEST_MSG_VIEW_DETAILS_DIALOG (self)); + + from = g_strdup (tny_header_get_from (header)); + to = g_strdup (tny_header_get_to (header)); + subject = g_strdup (tny_header_get_subject (header)); + cc = g_strdup (tny_header_get_cc (header)); + received = tny_header_get_date_received (header); + sent = tny_header_get_date_sent (header); + size = tny_header_get_message_size (header); + + if (from == NULL) + from = g_strdup (""); + if (to == NULL) + to = g_strdup (""); + if (subject == NULL) + subject = g_strdup (""); + if (cc == NULL) + cc = g_strdup (""); + + modest_msg_view_details_dialog_add_row (MODEST_MSG_VIEW_DETAILS_DIALOG (self), _("mcen_fi_message_properties_from"), from); + modest_msg_view_details_dialog_add_row (MODEST_MSG_VIEW_DETAILS_DIALOG (self), _("mcen_fi_message_properties_subject"), subject); + if ((folder_type != TNY_FOLDER_TYPE_SENT)&& + (folder_type != TNY_FOLDER_TYPE_DRAFTS)&& + (folder_type != TNY_FOLDER_TYPE_OUTBOX)) { + gchar *received_s; + + received_s = modest_text_utils_get_display_date (received); + if (received_s == NULL) + received_s = g_strdup (received_s); + modest_msg_view_details_dialog_add_row (MODEST_MSG_VIEW_DETAILS_DIALOG (self), _("mcen_fi_message_properties_received"), received_s); + g_free (received_s); + } + + if ((folder_type != TNY_FOLDER_TYPE_DRAFTS)&& + (folder_type != TNY_FOLDER_TYPE_OUTBOX)) { + gchar *sent_s; + + sent_s = modest_text_utils_get_display_date (sent); + if (sent_s == NULL) + sent_s = g_strdup (sent_s); + modest_msg_view_details_dialog_add_row (MODEST_MSG_VIEW_DETAILS_DIALOG (self), _("mcen_fi_message_properties_sent"), sent_s); + g_free (sent_s); + } + + modest_msg_view_details_dialog_add_row (MODEST_MSG_VIEW_DETAILS_DIALOG (self), _("mcen_fi_message_properties_to"), to); + modest_msg_view_details_dialog_add_row (MODEST_MSG_VIEW_DETAILS_DIALOG (self), _("mcen_fi_message_properties_cc"), cc); + + if (size <= 0) + size_s = g_strdup (_("mcen_va_message_properties_size_noinfo")); + else + size_s = modest_text_utils_get_display_size (size); + modest_msg_view_details_dialog_add_row (MODEST_MSG_VIEW_DETAILS_DIALOG (self), _("mcen_fi_message_properties_size"), size_s); + g_free (size_s); + + g_free (to); + g_free (from); + g_free (subject); + g_free (cc); + } + +} + +static void +modest_msg_view_details_dialog_clear (TnyHeaderView *self) +{ + ModestMsgViewDetailsDialogPrivate *priv; + GList *children, *node; + + g_return_if_fail (MODEST_IS_MSG_VIEW_DETAILS_DIALOG (self)); + priv = MODEST_MSG_VIEW_DETAILS_DIALOG_GET_PRIVATE (self); + + if (priv->header != NULL) { + g_object_unref (priv->header); + priv->header = NULL; + } + + children = gtk_container_get_children (GTK_CONTAINER (priv->props_table)); + for (node = children; node != NULL; node = g_list_next (node)) + gtk_widget_destroy (GTK_WIDGET (node->data)); + +} diff --git a/src/widgets/modest-msg-view-details-dialog.h b/src/widgets/modest-msg-view-details-dialog.h new file mode 100644 index 0000000..1930e9b --- /dev/null +++ b/src/widgets/modest-msg-view-details-dialog.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MODEST_MSG_VIEW_DETAILS_DIALOG +#define __MODEST_MSG_VIEW_DETAILS_DIALOG + +#include +#include +#include + + +G_BEGIN_DECLS + +#define MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG modest_msg_view_details_dialog_get_type() + +#define MODEST_MSG_VIEW_DETAILS_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG, ModestMsgViewDetailsDialog)) + +#define MODEST_MSG_VIEW_DETAILS_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG, ModestMsgViewDetailsDialogClass)) + +#define MODEST_IS_MSG_VIEW_DETAILS_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG)) + +#define MODEST_IS_MSG_VIEW_DETAILS_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG)) + +#define MODEST_MSG_VIEW_DETAILS_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + MODEST_TYPE_MSG_VIEW_DETAILS_DIALOG, ModestMsgViewDetailsDialogClass)) + +typedef struct { + GtkDialog parent; + +} ModestMsgViewDetailsDialog; + +typedef struct { + GtkDialogClass parent_class; +} ModestMsgViewDetailsDialogClass; + +GType modest_msg_view_details_dialog_get_type (void); + +GtkWidget* modest_msg_view_details_dialog_new (GtkWindow *parent, TnyHeader *header); + +G_END_DECLS + +#endif /* __MODEST_MSG_VIEW_DETAILS_DIALOG */ diff --git a/src/widgets/modest-msg-view-window.h b/src/widgets/modest-msg-view-window.h index e607e0b..8a8877a 100644 --- a/src/widgets/modest-msg-view-window.h +++ b/src/widgets/modest-msg-view-window.h @@ -32,6 +32,7 @@ #include #include +#include G_BEGIN_DECLS @@ -76,10 +77,26 @@ GType modest_msg_view_window_get_type (void) G_GNUC_CONST; */ ModestWindow* modest_msg_view_window_new (TnyMsg *msg, const gchar *account); +/** + * modest_msg_view_window_new_with_header_model: + * @msg: an #TnyMsg instance + * @account: the account name + * @model: a #GtkTreeModel, with the format used by #ModestHeaderView + * @iter: a #GtkTreeIter, pointing to the position of @msg in @model. + * + * instantiates a new #ModestMsgViewWindow widget. The account name is used to + * set the proper account when choosing reply/forward from the msg view window. + * This constructor also passes a reference to the @model of the header view + * to allow selecting previous/next messages. + * + * Returns: a new #ModestMsgViewWindow, or NULL in case of error + */ +ModestWindow* modest_msg_view_window_new_with_header_model (TnyMsg *msg, const gchar *account, GtkTreeModel *model, GtkTreeIter iter); + /** * modest_msg_view_window_get_message: - * @msg: an #ModestMsgViewWindow instance + * @window: an #ModestMsgViewWindow instance * * get the message in this msg view * @@ -87,6 +104,28 @@ ModestWindow* modest_msg_view_window_new (TnyMsg *msg, const gchar *ac */ TnyMsg* modest_msg_view_window_get_message (ModestMsgViewWindow *window); +/** + * modest_msg_view_window_select_next_message: + * @window: a #ModestMsgViewWindow instance + * + * select the next message obtained from the header view this view + * was called from + * + * Returns: %TRUE if a new message is shown. + */ +gboolean modest_msg_view_window_select_next_message (ModestMsgViewWindow *window); + +/** + * modest_msg_view_window_select_previous_message: + * @window: a #ModestMsgViewWindow instance + * + * select the previous message obtained from the header view this view + * was called from + * + * Returns: %TRUE if a new message is shown. + */ +gboolean modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window); + G_END_DECLS #endif /* __MODEST_MSG_VIEW_WINDOW_H__ */ diff --git a/src/widgets/modest-msg-view.c b/src/widgets/modest-msg-view.c index ae6112b..685b7d2 100644 --- a/src/widgets/modest-msg-view.c +++ b/src/widgets/modest-msg-view.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include @@ -64,6 +66,7 @@ static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgV static gboolean on_url_requested (GtkWidget *widget, const gchar *uri, GtkHTMLStream *stream, ModestMsgView *msg_view); static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view); +static void on_tap_and_hold (GtkWidget *widget, gpointer userdata); /* size allocation and drawing handlers */ static void get_view_allocation (ModestMsgView *msg_view, GtkAllocation *allocation); @@ -91,6 +94,7 @@ enum { LINK_HOVER_SIGNAL, ATTACHMENT_CLICKED_SIGNAL, RECPT_ACTIVATED_SIGNAL, + LINK_CONTEXTUAL_SIGNAL, LAST_SIGNAL }; @@ -125,6 +129,14 @@ struct _ModestMsgViewPrivate { GdkWindow *headers_window; GdkWindow *html_window; + /* zoom */ + gdouble current_zoom; + + /* link click management */ + gchar *last_url; + + TnyHeaderFlags priority_flags; + gulong sig1, sig2, sig3; }; #define MODEST_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ @@ -252,6 +264,15 @@ modest_msg_view_class_init (ModestMsgViewClass *klass) g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + signals[LINK_CONTEXTUAL_SIGNAL] = + g_signal_new ("link_contextual", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(ModestMsgViewClass, link_contextual), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + widget_class->set_scroll_adjustments_signal = g_signal_new ("set_scroll_adjustments", G_OBJECT_CLASS_TYPE (gobject_class), @@ -438,8 +459,11 @@ set_scroll_adjustments (ModestMsgView *msg_view, GtkAdjustment *hadj, GtkAdjustment *vadj) { + ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view); modest_msg_view_set_hadjustment (msg_view, hadj); modest_msg_view_set_vadjustment (msg_view, vadj); + + gtk_container_set_focus_vadjustment (GTK_CONTAINER (priv->gtkhtml), vadj); } static void @@ -831,6 +855,9 @@ modest_msg_view_init (ModestMsgView *obj) priv = MODEST_MSG_VIEW_GET_PRIVATE(obj); + priv->current_zoom = 1.0; + priv->priority_flags = 0; + priv->hadj = NULL; priv->vadj = NULL; priv->shadow_type = GTK_SHADOW_IN; @@ -854,7 +881,7 @@ modest_msg_view_init (ModestMsgView *obj) gtk_html_set_blocking (GTK_HTML(priv->gtkhtml), FALSE); gtk_html_set_images_blocking (GTK_HTML(priv->gtkhtml), FALSE); - priv->mail_header_view = GTK_WIDGET(modest_mail_header_view_new ()); + priv->mail_header_view = GTK_WIDGET(modest_mail_header_view_new (TRUE)); gtk_widget_set_no_show_all (priv->mail_header_view, TRUE); priv->attachments_view = GTK_WIDGET(modest_attachments_view_new (NULL)); @@ -1045,6 +1072,7 @@ modest_msg_view_new (TnyMsg *msg) GObject *obj; ModestMsgView* self; ModestMsgViewPrivate *priv; + GtkWidget *separator; obj = G_OBJECT(g_object_new(MODEST_TYPE_MSG_VIEW, NULL)); self = MODEST_MSG_VIEW(obj); @@ -1066,11 +1094,18 @@ modest_msg_view_new (TnyMsg *msg) /* gtk_widget_set_no_show_all (priv->attachments_box, TRUE); */ } + separator = gtk_hseparator_new (); + gtk_box_pack_start (GTK_BOX(priv->headers_box), separator, FALSE, FALSE, 0); + gtk_widget_set_parent (priv->headers_box, GTK_WIDGET (self)); if (priv->gtkhtml) { gtk_container_add (GTK_CONTAINER (priv->html_scroll), priv->gtkhtml); gtk_widget_set_parent (priv->html_scroll, GTK_WIDGET(self)); +#ifdef MAEMO_CHANGES + gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->gtkhtml), NULL, NULL, 0); + g_signal_connect (G_OBJECT (priv->gtkhtml), "tap-and-hold", G_CALLBACK (on_tap_and_hold), obj); +#endif } modest_msg_view_set_message (self, msg); @@ -1078,6 +1113,19 @@ modest_msg_view_new (TnyMsg *msg) return GTK_WIDGET(self); } +#ifdef MAEMO_CHANGES +static void +on_tap_and_hold (GtkWidget *widget, + gpointer data) +{ + ModestMsgView *msg_view = (ModestMsgView *) data; + ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view); + + g_signal_emit (G_OBJECT (msg_view), signals[LINK_CONTEXTUAL_SIGNAL], + 0, priv->last_url); +} +#endif + static void on_recpt_activated (ModestMailHeaderView *header_view, const gchar *address, @@ -1109,6 +1157,11 @@ on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view) static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view) { + ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view); + + g_free (priv->last_url); + priv->last_url = g_strdup (uri); + g_signal_emit (G_OBJECT(msg_view), signals[LINK_HOVER_SIGNAL], 0, uri); @@ -1355,3 +1408,101 @@ modest_msg_view_get_message (ModestMsgView *self) return MODEST_MSG_VIEW_GET_PRIVATE(self)->msg; } +gboolean +modest_msg_view_search (ModestMsgView *self, const gchar *search) +{ + ModestMsgViewPrivate *priv; + gboolean result; + GtkAdjustment *vadj, *tmp_vadj; + gdouble y_offset; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW (self), FALSE); + + priv = MODEST_MSG_VIEW_GET_PRIVATE (self); + vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (priv->gtkhtml)); + g_object_ref (vadj); + tmp_vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, vadj->lower, vadj->upper, vadj->step_increment, 32.0, 32.0)); + gtk_layout_set_vadjustment (GTK_LAYOUT (priv->gtkhtml), tmp_vadj); + result = gtk_html_engine_search (GTK_HTML (priv->gtkhtml), + search, + FALSE, TRUE, TRUE); + y_offset = tmp_vadj->value; + g_message ("VALUE %f", y_offset); + gtk_layout_set_vadjustment (GTK_LAYOUT (priv->gtkhtml), vadj); + g_object_unref (vadj); + + return result; +} + +gboolean +modest_msg_view_search_next (ModestMsgView *self) +{ + ModestMsgViewPrivate *priv; + gboolean result; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW (self), FALSE); + + priv = MODEST_MSG_VIEW_GET_PRIVATE (self); + result = gtk_html_engine_search_next (GTK_HTML (priv->gtkhtml)); + + { + GtkAdjustment *adj; + + adj = gtk_container_get_focus_vadjustment (GTK_CONTAINER (priv->gtkhtml)); + g_message ("ADJ value %f", adj->value); + } + + return result; +} + +void +modest_msg_view_set_zoom (ModestMsgView *self, gdouble zoom) +{ + ModestMsgViewPrivate *priv; + + g_return_if_fail (MODEST_IS_MSG_VIEW (self)); + + priv = MODEST_MSG_VIEW_GET_PRIVATE (self); + priv->current_zoom = zoom; + gtk_html_set_magnification (GTK_HTML(priv->gtkhtml), zoom); + + gtk_widget_queue_resize (priv->gtkhtml); +} + +gdouble +modest_msg_view_get_zoom (ModestMsgView *self) +{ + ModestMsgViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW (self), 1.0); + + priv = MODEST_MSG_VIEW_GET_PRIVATE (self); + + return priv->current_zoom; +} + +TnyHeaderFlags +modest_msg_view_get_priority (ModestMsgView *self) +{ + ModestMsgViewPrivate *priv; + + g_return_val_if_fail (MODEST_IS_MSG_VIEW (self), 0); + + priv = MODEST_MSG_VIEW_GET_PRIVATE (self); + + return priv->priority_flags; +} + +void +modest_msg_view_set_priority (ModestMsgView *self, TnyHeaderFlags flags) +{ + ModestMsgViewPrivate *priv; + + g_return_if_fail (MODEST_IS_MSG_VIEW (self)); + + priv = MODEST_MSG_VIEW_GET_PRIVATE (self); + + priv->priority_flags = flags & (TNY_HEADER_FLAG_HIGH_PRIORITY); + + modest_mail_header_view_set_priority (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view), flags); +} diff --git a/src/widgets/modest-msg-view.h b/src/widgets/modest-msg-view.h index 8e34f4f..8432a4e 100644 --- a/src/widgets/modest-msg-view.h +++ b/src/widgets/modest-msg-view.h @@ -64,6 +64,8 @@ struct _ModestMsgViewClass { gpointer user_data); void (*link_clicked) (ModestMsgView *msgview, const gchar* link, gpointer user_data); + void (*link_contextual) (ModestMsgView *msgview, const gchar* link, + gpointer user_data); void (*attachment_clicked) (ModestMsgView *msgview, TnyMimePart *mime_part, gpointer user_data); void (*recpt_activated) (ModestMsgView *msgview, const gchar *address, @@ -124,6 +126,14 @@ void modest_msg_view_set_hadjustment (ModestMsgView *self, GtkAdjustment *hadj); void modest_msg_view_set_shadow_type (ModestMsgView *self, GtkShadowType type); GtkShadowType modest_msg_view_get_shadow_type (ModestMsgView *self); +gboolean modest_msg_view_search (ModestMsgView *self, const gchar *search); +gboolean modest_msg_view_search_next (ModestMsgView *self); +void modest_msg_view_set_zoom (ModestMsgView *self, gdouble zoom); +gdouble modest_msg_view_get_zoom (ModestMsgView *self); +TnyHeaderFlags modest_msg_view_get_priority (ModestMsgView *self); +void modest_msg_view_set_priority (ModestMsgView *self, TnyHeaderFlags flags); + + G_END_DECLS #endif /* __MODEST_MSG_VIEW_H__ */ diff --git a/src/widgets/modest-window.c b/src/widgets/modest-window.c index a5a667d..0e93b07 100644 --- a/src/widgets/modest-window.c +++ b/src/widgets/modest-window.c @@ -35,6 +35,12 @@ static void modest_window_class_init (ModestWindowClass *klass); static void modest_window_init (ModestWindow *obj); static void modest_window_finalize (GObject *obj); + +static void modest_window_set_zoom_default (ModestWindow *window, + gdouble zoom); +gdouble modest_window_get_zoom_default (ModestWindow *window); + + /* list my signals */ enum { LAST_SIGNAL @@ -86,6 +92,9 @@ modest_window_class_init (ModestWindowClass *klass) parent_class = g_type_class_peek_parent (klass); gobject_class->finalize = modest_window_finalize; + klass->set_zoom_func = modest_window_set_zoom_default; + klass->get_zoom_func = modest_window_get_zoom_default; + g_type_class_add_private (gobject_class, sizeof(ModestWindowPrivate)); } @@ -144,3 +153,30 @@ modest_window_set_active_account (ModestWindow *self, const gchar *active_accoun priv->active_account = g_strdup (active_account); } } + +void +modest_window_set_zoom (ModestWindow *window, + gdouble zoom) +{ + MODEST_WINDOW_GET_CLASS (window)->set_zoom_func (window, zoom); + return; +} + +gdouble +modest_window_get_zoom (ModestWindow *window) +{ + return MODEST_WINDOW_GET_CLASS (window)->get_zoom_func (window); +} + +static void +modest_window_set_zoom_default (ModestWindow *window, + gdouble zoom) +{ + return; +} + +gdouble +modest_window_get_zoom_default (ModestWindow *window) +{ + return 1.0; +} diff --git a/src/widgets/modest-window.h b/src/widgets/modest-window.h index 8902355..8706f41 100644 --- a/src/widgets/modest-window.h +++ b/src/widgets/modest-window.h @@ -72,6 +72,10 @@ struct _ModestWindow { struct _ModestWindowClass { ModestWindowParentClass parent_class; + + /* virtual methods */ + void (*set_zoom_func) (ModestWindow *self, gdouble zoom); + gdouble (*get_zoom_func) (ModestWindow *self); }; /** @@ -106,6 +110,25 @@ const gchar* modest_window_get_active_account (ModestWindow *self); */ void modest_window_set_active_account (ModestWindow *self, const gchar *active_account); +/** + * modest_window_set_zoom: + * @window: a #ModestWindow instance + * @zoom: the zoom level (1.0 is no zoom) + * + * sets the zoom level of the window + */ +void modest_window_set_zoom (ModestWindow *window, + gdouble value); + +/** + * modest_window_get_zoom: + * @window: a #ModestWindow instance + * + * gets the zoom of the window + * + * Returns: the current zoom value (1.0 is no zoom) + */ +gdouble modest_window_get_zoom (ModestWindow *window); G_END_DECLS -- 1.7.9.5