+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.
docs
EXTRA_DIST=\
- autogen.sh
+ autogen.sh TODO COPYING
CFLAGS=\
-Wall
dnl configure.ac for modest
-dnl Time-stamp: <2006-07-20 17:01:42 (djcb)>
+dnl Time-stamp: <2006-07-21 09:30:11 (djcb)>
dnl written by Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>
AC_INIT([modest],[0.0.1],[http://maemo.org])
src/hildon/Makefile
src/hildon/com.nokia.modest.service
src/hildon/modest.desktop.in
+src/widgets/Makefile
docs/Makefile
docs/reference/Makefile
])
#
# Makefile.am
-# Time-stamp: <2006-07-19 18:21:49 (djcb)>
+# Time-stamp: <2006-07-21 09:29:41 (djcb)>
SUBDIRS=$(MODEST_PLATFORM_DIR)
DIST_SUBDIRS = gtk gtk2 hildon
modest-account-keys.h\
modest-account-mgr.h\
modest-account-mgr.c\
- modest-account-view.h\
- modest-account-view.c\
modest-window-mgr.h\
modest-window-mgr.c\
modest-icon-factory.c\
modest-icon-factory.h\
modest-tny-account-store.h\
modest-tny-account-store.c\
- modest-tny-folder-tree-view.h\
- modest-tny-folder-tree-view.c\
- modest-tny-header-tree-view.h\
- modest-tny-header-tree-view.c\
- modest-tny-msg-view.h\
- modest-tny-msg-view.c\
modest-tny-msg-actions.h\
modest-tny-msg-actions.c\
modest-proto.h\
$(MODEST_GSTUFF_LIBS) \
$(MODEST_LIBTINYMAIL_GNOME_DESKTOP_LIBS) \
$(MODEST_LIBTINYMAIL_MAEMO_LIBS) \
- $(MODEST_PLATFORM_DIR)/libmodest-ui.la
+ $(MODEST_PLATFORM_DIR)/libmodest-ui.la \
+ widgets/libmodest-widgets.la
+
EXTRA_DIST=modest-marshal.list
#
# Makefile.am
-# Time-stamp: <2006-06-06 14:27:48 (djcb)>
+# Time-stamp: <2006-07-21 10:45:41 (djcb)>
#
#
# use Automake 'trick' ==> convenience static libraries, which
INCLUDES=\
$(MODEST_GSTUFF_CFLAGS) \
$(MODEST_LIBTINYMAIL_GNOME_DESKTOP_CFLAGS) \
+ -I ${top_srcdir}/src \
-DPREFIX=\"@prefix@\" \
-Wall
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
static GtkWidget* modest_main_window_header_tree (TnyMsgFolderIface *folder);
-static void on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
+static void on_folder_clicked (ModestFolderView *folder_tree,
TnyMsgFolderIface *folder,
gpointer data);
-static void on_message_clicked (ModestTnyFolderTreeView *folder_tree,
+static void on_message_clicked (ModestFolderView *folder_tree,
TnyMsgIface *message,
gpointer data);
static void on_headers_status_update (GtkWidget *header_view, const gchar *msg, gint status,
gpointer user_data);
-static void on_status_cleanup (gpointer user_data);
-
static void register_toolbar_callbacks (ModestUI *modest_ui);
g_signal_connect (G_OBJECT(folder_view), "folder_selected",
G_CALLBACK(on_folder_clicked), modest_ui);
- message_view = GTK_WIDGET(modest_tny_msg_view_new (NULL));
+ message_view = GTK_WIDGET(modest_msg_view_new (NULL));
priv->message_view = message_view;
if (!message_view) {
g_warning ("failed to create message view");
static void
-on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
+on_folder_clicked (ModestFolderView *folder_tree,
TnyMsgFolderIface *folder,
gpointer data)
{
GtkWidget *win;
GtkWidget *button;
- ModestTnyHeaderTreeView *tree_view;
- ModestTnyMsgView *msg_view;
+ ModestHeaderView *tree_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
GtkWidget *scrollview;
priv = MODEST_UI_GET_PRIVATE(data);
scrollview = glade_xml_get_widget (priv->glade_xml,"mail_list");
- tree_view = MODEST_TNY_HEADER_TREE_VIEW (priv->header_view);
+ tree_view = MODEST_HEADER_VIEW (priv->header_view);
win = glade_xml_get_widget (priv->glade_xml, "main");
gtk_window_set_title (GTK_WINDOW(win),
tny_msg_folder_iface_get_name(folder));
- modest_tny_header_tree_view_set_folder (tree_view, folder);
+ modest_header_view_set_folder (tree_view, folder);
priv->current_folder = folder;
button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
gtk_widget_set_sensitive(button, FALSE);
}
- msg_view = MODEST_TNY_MSG_VIEW (priv->message_view);
+ msg_view = MODEST_MSG_VIEW (priv->message_view);
g_return_if_fail (msg_view);
- modest_tny_msg_view_set_message (msg_view, NULL);
+ modest_msg_view_set_message (msg_view, NULL);
}
static void
-on_message_clicked (ModestTnyFolderTreeView *folder_tree,
- TnyMsgIface *message,
- gpointer data)
+on_message_clicked (ModestFolderView *folder_tree,
+ TnyMsgIface *message,
+ gpointer data)
{
GtkWidget *button;
- ModestTnyMsgView *msg_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
g_return_if_fail (data);
priv = MODEST_UI_GET_PRIVATE (data);
- msg_view = MODEST_TNY_MSG_VIEW (priv->message_view);
+ msg_view = MODEST_MSG_VIEW (priv->message_view);
- modest_tny_msg_view_set_message (msg_view, message);
+ modest_msg_view_set_message (msg_view, message);
button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
if (button) {
int i;
GSList *columns = NULL;
GtkWidget *header_tree;
- ModestTnyHeaderTreeViewColumn cols[] = {
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE
+ ModestHeaderViewColumn cols[] = {
+ MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
+ MODEST_HEADER_VIEW_COLUMN_ATTACH,
+ MODEST_HEADER_VIEW_COLUMN_FROM,
+ MODEST_HEADER_VIEW_COLUMN_SUBJECT,
+ MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE
};
- for (i = 0 ; i != sizeof(cols) / sizeof(ModestTnyHeaderTreeViewColumn); ++i)
+ for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
- header_tree = GTK_WIDGET(modest_tny_header_tree_view_new(folder, columns,
- MODEST_TNY_HEADER_TREE_VIEW_STYLE_NORMAL));
+ header_tree = GTK_WIDGET(modest_header_view_new(folder, columns,
+ MODEST_HEADER_VIEW_STYLE_NORMAL));
g_slist_free (columns);
if (!header_tree) {
{
GtkWidget *folder_tree;
- folder_tree = GTK_WIDGET (modest_tny_folder_tree_view_new (account_store));
+ folder_tree = GTK_WIDGET (modest_folder_view_new (account_store));
if (!folder_tree) {
g_warning ("could not create folder list");
return NULL;
GtkTreeIter iter;
GtkTreeModel *mymodel;
- ModestTnyHeaderTreeView *header_view;
- ModestTnyMsgView *msg_view;
+ ModestHeaderView *header_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
g_return_if_fail (modest_ui);
priv = MODEST_UI_GET_PRIVATE(modest_ui);
- msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
+ msg_view = MODEST_MSG_VIEW(priv->message_view);
g_return_if_fail (msg_view);
- header_view = MODEST_TNY_HEADER_TREE_VIEW(priv->header_view);
+ header_view = MODEST_HEADER_VIEW(priv->header_view);
g_return_if_fail (header_view);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
if (priv->header_view && priv->current_folder) {
- modest_tny_header_tree_view_set_folder (MODEST_TNY_HEADER_TREE_VIEW(priv->header_view),
- priv->current_folder);
+ modest_header_view_set_folder (MODEST_HEADER_VIEW(priv->header_view),
+ priv->current_folder);
gtk_widget_queue_draw (priv->header_view);
}
}
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
TnyMsgHeaderIface *header;
- ModestTnyHeaderTreeView *header_view;
- ModestTnyMsgView *msg_view;
+ ModestHeaderView *header_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
const TnyMsgIface *msg;
priv = MODEST_UI_GET_PRIVATE(modest_ui);
- msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
+ msg_view = MODEST_MSG_VIEW(priv->message_view);
g_return_if_fail (msg_view);
- header_view = MODEST_TNY_HEADER_TREE_VIEW(priv->header_view);
+ header_view = MODEST_HEADER_VIEW(priv->header_view);
g_return_if_fail (header_view);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
from = tny_msg_header_iface_get_from(header);
sent_date = tny_msg_header_iface_get_date_sent(header);
- unquoted = modest_tny_msg_view_get_selected_text(msg_view);
+ unquoted = modest_msg_view_get_selected_text(msg_view);
quoted = modest_tny_msg_actions_quote(msg, from, sent_date, line_limit, unquoted);
switch (qstype) {
case QUOTED_SEND_REPLY:
g_string_prepend(re_sub, _("Re: "));
- new_editor_with_presets(modest_ui, from, /* cc */ "", /* bcc */ "", re_sub->str, quoted, attachments);
+ new_editor_with_presets(modest_ui, from, /* cc */ "", /* bcc */ "",
+ re_sub->str, quoted, attachments);
break;
case QUOTED_SEND_FORWARD:
attachments = modest_tny_attachment_new_list_from_msg(msg, FALSE);
g_string_prepend(re_sub, _("Fwd: "));
- new_editor_with_presets(modest_ui, /* from */ "", /* cc */ "", /* bcc */ "", re_sub->str, quoted, attachments);
+ new_editor_with_presets(modest_ui, /* from */ "", /* cc */ "",
+ /* bcc */ "", re_sub->str, quoted, attachments);
break;
case QUOTED_SEND_FORWARD_ATTACHED:
attachments = modest_tny_attachment_new_list_from_msg(msg, TRUE);
g_string_prepend(re_sub, _("Fwd: "));
- new_editor_with_presets(modest_ui, /* from */ "", /* cc */ "", /* bcc */ "", re_sub->str, "", attachments);
+ new_editor_with_presets(modest_ui, /* from */ "", /* cc */ "",
+ /* bcc */ "", re_sub->str, "", attachments);
break;
default:
break;
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
GtkTreeModel *model;
GtkTreeIter iter;
GtkScrolledWindow *scroll;
- ModestTnyHeaderTreeView *header_view;
+ ModestHeaderView *header_view;
TnyMsgHeaderIface *header;
const TnyMsgFolderIface *folder;
TnyMsgIface *msg;
scroll = GTK_SCROLLED_WINDOW(gtk_paned_get_child1 (GTK_PANED(paned)));
g_return_if_fail (scroll);
- header_view = MODEST_TNY_HEADER_TREE_VIEW(gtk_bin_get_child (GTK_BIN(scroll)));
+ header_view = MODEST_HEADER_VIEW(gtk_bin_get_child (GTK_BIN(scroll)));
g_return_if_fail (header_view);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
static void modest_ui_class_init (ModestUIClass *klass);
static void modest_ui_init (ModestUI *obj);
static void modest_ui_finalize (GObject *obj);
-
-static void modest_ui_window_destroy (GtkWidget *win, GdkEvent *event, gpointer data);
static void modest_ui_last_window_closed (GObject *obj, gpointer data);
gchar *on_password_requested (TnyAccountIface *, const gchar *, gboolean *);
{
ModestUIPrivate *priv = user_data;
- g_return_if_fail (MODEST_IS_TNY_FOLDER_TREE_VIEW (priv->folder_view));
- g_return_if_fail (MODEST_IS_TNY_HEADER_TREE_VIEW (priv->header_view));
+ g_return_if_fail (MODEST_IS_FOLDER_VIEW (priv->folder_view));
+ g_return_if_fail (MODEST_IS_HEADER_VIEW (priv->header_view));
- modest_tny_header_tree_view_set_folder (MODEST_TNY_HEADER_TREE_VIEW(priv->header_view),
+ modest_header_view_set_folder (MODEST_HEADER_VIEW(priv->header_view),
NULL);
- modest_tny_folder_tree_view_update_model(MODEST_TNY_FOLDER_TREE_VIEW(priv->folder_view),
- TNY_ACCOUNT_STORE_IFACE(account_store));
+ modest_folder_view_update_model(MODEST_FOLDER_VIEW(priv->folder_view),
+ TNY_ACCOUNT_STORE_IFACE(account_store));
}
INCLUDES=\
$(MODEST_GSTUFF_CFLAGS) \
$(MODEST_LIBTINYMAIL_GNOME_DESKTOP_CFLAGS) \
- -I ${top_srcdir}/src
+ -I ${top_srcdir}/src \
-DPREFIX=\"@prefix@\" \
-Wall
{
GtkWidget *button_box;
- GtkWidget *add_button, *remove_button, *edit_button, *close_button;
+ GtkWidget *add_button, *remove_button, *edit_button;
ModestAccountViewWindowPrivate *priv;
priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self);
main_vbox = gtk_vbox_new (FALSE, 6);
main_hbox = gtk_hbox_new (FALSE, 6);
- account_view = modest_widget_factory_get_account_view_widget (priv->widget_factory);
+ account_view = modest_widget_factory_get_account_view (priv->widget_factory);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(account_view));
g_signal_connect (G_OBJECT(sel), "changed", G_CALLBACK(on_selection_changed),
ModestWidgetFactory *widget_factory;
ModestConf *conf;
- ModestTnyHeaderTreeView *header_view;
- ModestTnyFolderTreeView *folder_view;
- ModestTnyMsgView *msg_preview;
+ ModestHeaderView *header_view;
+ ModestFolderView *folder_view;
+ ModestMsgView *msg_preview;
};
{
GtkWidget *account_win;
ModestMainWindowPrivate *priv;
- ModestAccountMgr *account_mgr;
g_return_if_fail (widget);
g_return_if_fail (self);
-static ModestTnyHeaderTreeView*
+static ModestHeaderView*
header_view_new (ModestMainWindow *self)
{
int i;
GSList *columns = NULL;
- ModestTnyHeaderTreeView *header_view;
+ ModestHeaderView *header_view;
ModestMainWindowPrivate *priv;
- ModestTnyHeaderTreeViewColumn cols[] = {
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE
+ ModestHeaderViewColumn cols[] = {
+ MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
+ MODEST_HEADER_VIEW_COLUMN_ATTACH,
+ MODEST_HEADER_VIEW_COLUMN_FROM,
+ MODEST_HEADER_VIEW_COLUMN_SUBJECT,
+ MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE
};
priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
- for (i = 0 ; i != sizeof(cols) / sizeof(ModestTnyHeaderTreeViewColumn); ++i)
+ for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
- header_view = modest_widget_factory_get_header_tree_widget (priv->widget_factory);
- modest_tny_header_tree_view_set_columns (header_view, columns);
+ header_view = modest_widget_factory_get_header_view (priv->widget_factory);
+ modest_header_view_set_columns (header_view, columns);
g_slist_free (columns);
return header_view;
-static void
-save_sizes (ModestMainWindow *self, ModestConf *conf)
-{
- ModestMainWindowPrivate *priv;
-
- int x,y;
-
- priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
-
-
-}
-
-
-
static GtkWidget*
wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
{
priv->conf = conf;
/* widgets from factory */
- priv->folder_view = modest_widget_factory_get_folder_tree_widget (factory);
+ priv->folder_view = modest_widget_factory_get_folder_view (factory);
priv->header_view = header_view_new (MODEST_MAIN_WINDOW(obj));
- priv->msg_preview = modest_widget_factory_get_msg_preview_widget (factory);
+ priv->msg_preview = modest_widget_factory_get_msg_preview (factory);
folder_win = wrapped_in_scrolled_window (GTK_WIDGET(priv->folder_view),
FALSE);
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <modest-tny-msg-view.h>
+#include <widgets/modest-msg-view.h>
#include "modest-msg-window.h"
/* 'private'/'protected' functions */
gtk_table_attach_defaults (GTK_TABLE(header_table), bcc_field, 1,2,2,3);
gtk_table_attach_defaults (GTK_TABLE(header_table), subject_field, 1,2,3,4);
- msg_field = modest_tny_msg_view_new (NULL);
+ msg_field = modest_msg_view_new (NULL);
main_vbox = gtk_vbox_new (FALSE, 6);
#
# Makefile.am
-# Time-stamp: <2006-06-06 14:27:48 (djcb)>
+# Time-stamp: <2006-07-21 11:12:44 (djcb)>
#
#
# use Automake 'trick' ==> convenience static libraries, which
$(MODEST_GSTUFF_CFLAGS) \
$(MODEST_LIBTINYMAIL_GNOME_DESKTOP_CFLAGS) \
$(MODEST_LIBTINYMAIL_MAEMO_CFLAGS) \
+ -I ${top_srcdir}/src \
-DPREFIX=\"@prefix@\" \
-Wall
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
static GtkWidget* modest_main_window_header_tree (TnyMsgFolderIface *folder);
-static void on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
+static void on_folder_clicked (ModestFolderView *folder_tree,
TnyMsgFolderIface *folder,
gpointer data);
-static void on_message_clicked (ModestTnyFolderTreeView *folder_tree,
+static void on_message_clicked (ModestFolderView *folder_tree,
TnyMsgIface *message,
gpointer data);
static void on_headers_status_update (GtkWidget *header_view, const gchar *msg, gint status,
gpointer user_data);
-static void on_status_cleanup (gpointer user_data);
static void register_toolbar_callbacks (ModestUI *modest_ui);
show_attachments_inline = FALSE;
- message_view = GTK_WIDGET(modest_tny_msg_view_new (NULL));
+ message_view = GTK_WIDGET(modest_msg_view_new (NULL));
priv->message_view = message_view;
if (!message_view) {
g_warning ("failed to create message view");
static void
-on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
+on_folder_clicked (ModestFolderView *folder_tree,
TnyMsgFolderIface *folder,
gpointer data)
{
GtkWidget *win;
GtkWidget *button;
- ModestTnyHeaderTreeView *tree_view;
- ModestTnyMsgView *msg_view;
+ ModestHeaderView *tree_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
GtkWidget *scrollview;
priv = MODEST_UI_GET_PRIVATE(data);
scrollview = glade_xml_get_widget (priv->glade_xml,"mail_list");
- tree_view = MODEST_TNY_HEADER_TREE_VIEW (priv->header_view);
+ tree_view = MODEST_HEADER_VIEW (priv->header_view);
win = glade_xml_get_widget (priv->glade_xml, "main");
gtk_window_set_title (GTK_WINDOW(win),
tny_msg_folder_iface_get_name(folder));
- modest_tny_header_tree_view_set_folder (tree_view, folder);
+ modest_header_view_set_folder (tree_view, folder);
priv->current_folder = folder;
button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
gtk_widget_set_sensitive(button, FALSE);
}
- msg_view = MODEST_TNY_MSG_VIEW (priv->message_view);
+ msg_view = MODEST_MSG_VIEW (priv->message_view);
g_return_if_fail (msg_view);
- modest_tny_msg_view_set_message (msg_view, NULL);
+ modest_msg_view_set_message (msg_view, NULL);
}
static void
-on_message_clicked (ModestTnyFolderTreeView *folder_tree,
+on_message_clicked (ModestFolderView *folder_tree,
TnyMsgIface *message,
gpointer data)
{
GtkWidget *button;
- ModestTnyMsgView *msg_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
g_return_if_fail (data);
priv = MODEST_UI_GET_PRIVATE (data);
- msg_view = MODEST_TNY_MSG_VIEW (priv->message_view);
+ msg_view = MODEST_MSG_VIEW (priv->message_view);
- modest_tny_msg_view_set_message (msg_view, message);
+ modest_msg_view_set_message (msg_view, message);
button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
if (button) {
int i;
GSList *columns = NULL;
GtkWidget *header_tree;
- ModestTnyHeaderTreeViewColumn cols[] = {
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_COMPACT_HEADER
+ ModestHeaderViewColumn cols[] = {
+ MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
+ MODEST_HEADER_VIEW_COLUMN_ATTACH,
+ MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER
};
- for (i = 0 ; i != sizeof(cols) / sizeof(ModestTnyHeaderTreeViewColumn); ++i)
+ for (i = 0 ; i != sizeof(cols) / sizeof(ModestHeaderViewColumn); ++i)
columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
- header_tree = GTK_WIDGET(modest_tny_header_tree_view_new(folder, columns,
- MODEST_TNY_HEADER_TREE_VIEW_STYLE_NORMAL));
+ header_tree = GTK_WIDGET(modest_header_view_new(folder, columns,
+ MODEST_HEADER_VIEW_STYLE_NORMAL));
g_slist_free (columns);
if (!header_tree) {
{
GtkWidget *folder_tree;
- folder_tree = GTK_WIDGET (modest_tny_folder_tree_view_new (account_store));
+ folder_tree = GTK_WIDGET (modest_folder_view_new (account_store));
if (!folder_tree) {
g_warning ("could not create folder list");
return NULL;
{
ModestUI *modest_ui = (ModestUI *)user_data;
GtkWidget *view_attachments_item;
- ModestTnyMsgView *msg_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
gboolean view_attachments_inline;
view_attachments_item = glade_xml_get_widget (priv->glade_xml, "menu_view_attachments");
g_return_if_fail(view_attachments_item);
- msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
+ msg_view = MODEST_MSG_VIEW(priv->message_view);
view_attachments_inline = gtk_check_menu_item_get_active(
GTK_CHECK_MENU_ITEM(view_attachments_item));
GtkTreeIter iter;
GtkTreeModel *mymodel;
- ModestTnyHeaderTreeView *header_view;
- ModestTnyMsgView *msg_view;
+ ModestHeaderView *header_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
g_return_if_fail (modest_ui);
priv = MODEST_UI_GET_PRIVATE(modest_ui);
- msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
+ msg_view = MODEST_MSG_VIEW(priv->message_view);
g_return_if_fail (msg_view);
- header_view = MODEST_TNY_HEADER_TREE_VIEW(priv->header_view);
+ header_view = MODEST_HEADER_VIEW(priv->header_view);
g_return_if_fail (header_view);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
if (priv->header_view && priv->current_folder) {
- modest_tny_header_tree_view_set_folder (MODEST_TNY_HEADER_TREE_VIEW(priv->header_view),
+ modest_header_view_set_folder (MODEST_HEADER_VIEW(priv->header_view),
priv->current_folder);
gtk_widget_queue_draw (priv->header_view);
}
/* TODO: put in auto* */
#include <tny-text-buffer-stream.h>
#include <tny-msg-folder.h>
+#include <tny-list.h>
#include "../modest-ui.h"
#include "../modest-window-mgr.h"
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
TnyMsgHeaderIface *header;
- ModestTnyHeaderTreeView *header_view;
- ModestTnyMsgView *msg_view;
+ ModestHeaderView *header_view;
+ ModestMsgView *msg_view;
ModestUIPrivate *priv;
const TnyMsgIface *msg;
priv = MODEST_UI_GET_PRIVATE(modest_ui);
- msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
+ msg_view = MODEST_MSG_VIEW(priv->message_view);
g_return_if_fail (msg_view);
- header_view = MODEST_TNY_HEADER_TREE_VIEW(priv->header_view);
+ header_view = MODEST_HEADER_VIEW(priv->header_view);
g_return_if_fail (header_view);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
from = tny_msg_header_iface_get_from(header);
sent_date = tny_msg_header_iface_get_date_sent(header);
- unquoted = modest_tny_msg_view_get_selected_text(msg_view);
+ unquoted = modest_msg_view_get_selected_text(msg_view);
quoted = modest_tny_msg_actions_quote(msg, from, sent_date, line_limit, unquoted);
switch (qstype) {
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
gtk_widget_destroy(GTK_WIDGET(viewer_win));
}
+/* just to prevent warnings:
+ * warning: `%x' yields only last 2 digits of year in some locales
+ */
+static size_t
+my_strftime(char *s, size_t max, const char *fmt, const
+ struct tm *tm) {
+ return strftime(s, max, fmt, tm);
+}
+
static void
open_message_viewer_window(ModestUI *modest_ui)
GtkTreeModel *model;
GtkTreeIter iter;
GtkScrolledWindow *scroll;
- ModestTnyHeaderTreeView *header_view;
+ ModestHeaderView *header_view;
TnyMsgHeaderIface *header;
const TnyMsgFolderIface *folder;
TnyMsgIface *msg;
scroll = GTK_SCROLLED_WINDOW(gtk_paned_get_child1 (GTK_PANED(paned)));
g_return_if_fail (scroll);
- header_view = MODEST_TNY_HEADER_TREE_VIEW(gtk_bin_get_child (GTK_BIN(scroll)));
+ header_view = MODEST_HEADER_VIEW(gtk_bin_get_child (GTK_BIN(scroll)));
g_return_if_fail (header_view);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
from = tny_msg_header_iface_get_from(header);
to = tny_msg_header_iface_get_to(header);
sent_date = tny_msg_header_iface_get_date_sent(header);
- strftime (date_str, 100, "%c", localtime (&sent_date));
-
+ my_strftime (date_str, 100, "%c", localtime (&sent_date));
+
w = glade_xml_get_widget (windata->glade_xml, "from");
gtk_label_set_text(GTK_LABEL(w), from);
w = glade_xml_get_widget (windata->glade_xml, "to");
/* TODO: put in auto* */
#include <tny-text-buffer-stream.h>
#include <tny-msg-folder.h>
+#include <tny-account-store-iface.h>
#include "../modest-ui.h"
#include "../modest-window-mgr.h"
#include "../modest-account-mgr.h"
-#include "../modest-account-mgr.h"
#include "../modest-identity-mgr.h"
#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
+#include "../widgets/modest-folder-view.h"
+#include "../widgets/modest-header-view.h"
+#include "../widgets/modest-msg-view.h"
#include "../modest-tny-transport-actions.h"
#include "../modest-tny-store-actions.h"
{
ModestUIPrivate *priv = user_data;
- g_return_if_fail (MODEST_IS_TNY_FOLDER_TREE_VIEW (priv->folder_view));
- g_return_if_fail (MODEST_IS_TNY_HEADER_TREE_VIEW (priv->header_view));
-
- modest_tny_header_tree_view_set_folder (MODEST_TNY_HEADER_TREE_VIEW(priv->header_view),
+ g_return_if_fail (MODEST_IS_FOLDER_VIEW (priv->folder_view));
+ g_return_if_fail (MODEST_IS_HEADER_VIEW (priv->header_view));
+
+ modest_header_view_set_folder (MODEST_HEADER_VIEW(priv->header_view),
NULL);
- modest_tny_folder_tree_view_update_model(MODEST_TNY_FOLDER_TREE_VIEW(priv->folder_view),
- TNY_ACCOUNT_STORE(account_store));
+ modest_folder_view_update_model(MODEST_FOLDER_VIEW(priv->folder_view),
+ TNY_ACCOUNT_STORE_IFACE(account_store));
}
+++ /dev/null
-/* modest-ui.c */
-
-/* insert (c)/licensing information) */
-
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-#include <glib/gi18n.h>
-#include <string.h>
-
-/* TODO: put in auto* */
-#include <tny-text-buffer-stream.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /*HAVE_CONFIG_H*/
-
-#include "../modest-ui.h"
-#include "../modest-window-mgr.h"
-#include "../modest-account-mgr.h"
-
-#include "../modest-tny-account-store.h"
-#include "../modest-tny-folder-tree-view.h"
-#include "../modest-tny-header-tree-view.h"
-#include "../modest-tny-msg-view.h"
-#include "../modest-tny-transport-actions.h"
-
-
-#define MODEST_GLADE PREFIX "/share/modest/glade/modest.glade"
-#define MODEST_GLADE_MAIN_WIN "main"
-#define MODEST_GLADE_EDIT_WIN "new_mail"
-
-
-/* 'private'/'protected' functions */
-static void modest_ui_class_init (ModestUIClass *klass);
-static void modest_ui_init (ModestUI *obj);
-static void modest_ui_finalize (GObject *obj);
-
-static void modest_ui_window_destroy (GtkWidget *win, gpointer data);
-static void modest_ui_last_window_closed (GObject *obj, gpointer data);
-
-static GtkWidget* modest_main_window_toolbar (void);
-static GtkWidget* modest_main_window_folder_tree (ModestAccountMgr *modest_acc_mgr,
- TnyAccountStoreIface *account_store);
-static GtkWidget* modest_main_window_header_tree (TnyMsgFolderIface *folder);
-
-
-void on_account_settings1_activate (GtkMenuItem *,
- gpointer);
-static void on_password_requested (ModestTnyAccountStore *account_store,
- const gchar *account_name, gpointer user_data);
-
-static void on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
- TnyMsgFolderIface *folder,
- gpointer data);
-static void on_message_clicked (ModestTnyFolderTreeView *folder_tree,
- TnyMsgIface *message,
- gpointer data);
-static void on_new_mail_clicked (GtkWidget *widget, ModestUI *modest_ui);
-
-static void on_reply_clicked (GtkWidget *widget, ModestUI *modest_ui);
-
-static void on_send_button_clicked (GtkWidget *widget, ModestUI *modest_ui);
-
-static void register_toolbar_callbacks (ModestUI *modest_ui);
-
-
-/* list my signals */
-enum {
- /* MY_SIGNAL_1, */
- /* MY_SIGNAL_2, */
- LAST_SIGNAL
-};
-
-
-typedef struct _ModestUIPrivate ModestUIPrivate;
-struct _ModestUIPrivate {
-
- ModestConf *modest_conf;
- ModestAccountMgr *modest_acc_mgr;
- ModestWindowMgr *modest_window_mgr;
- TnyAccountStoreIface *account_store;
-
- GtkWindow *main_window;
- GladeXML *glade_xml;
-
-
-};
-#define MODEST_UI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
- MODEST_TYPE_UI, \
- ModestUIPrivate))
-/* globals */
-static GObjectClass *parent_class = NULL;
-
-/* uncomment the following if you have defined any signals */
-/* static guint signals[LAST_SIGNAL] = {0}; */
-
-GType
-modest_ui_get_type (void)
-{
- static GType my_type = 0;
- if (!my_type) {
- static const GTypeInfo my_info = {
- sizeof(ModestUIClass),
- NULL, /* base init */
- NULL, /* base finalize */
- (GClassInitFunc) modest_ui_class_init,
- NULL, /* class finalize */
- NULL, /* class data */
- sizeof(ModestUI),
- 1, /* n_preallocs */
- (GInstanceInitFunc) modest_ui_init,
- };
- my_type = g_type_register_static (G_TYPE_OBJECT,
- "ModestUI",
- &my_info, 0);
- }
- return my_type;
-}
-
-static void
-modest_ui_class_init (ModestUIClass *klass)
-{
- GObjectClass *gobject_class;
- gobject_class = (GObjectClass*) klass;
-
- parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = modest_ui_finalize;
-
- g_type_class_add_private (gobject_class, sizeof(ModestUIPrivate));
-
- /* signal definitions go here, e.g.: */
-/* signals[MY_SIGNAL_1] = */
-/* g_signal_new ("my_signal_1",....); */
-/* signals[MY_SIGNAL_2] = */
-/* g_signal_new ("my_signal_2",....); */
-/* etc. */
-}
-
-static void
-modest_ui_init (ModestUI *obj)
-{
- ModestUIPrivate *priv = MODEST_UI_GET_PRIVATE(obj);
-
- priv->modest_acc_mgr = NULL;
- priv->modest_conf = NULL;
- priv->modest_window_mgr = NULL;
- priv->glade_xml = NULL;
-
-}
-
-static void
-modest_ui_finalize (GObject *obj)
-{
- ModestUIPrivate *priv = MODEST_UI_GET_PRIVATE(obj);
-
- if (priv->modest_acc_mgr)
- g_object_unref (priv->modest_acc_mgr);
- priv->modest_acc_mgr = NULL;
-
- if (priv->modest_conf)
- g_object_unref (priv->modest_conf);
- priv->modest_conf = NULL;
-
- if (priv->modest_window_mgr)
- g_object_unref (priv->modest_window_mgr);
- priv->modest_window_mgr = NULL;
-}
-
-GObject*
-modest_ui_new (ModestConf *modest_conf)
-{
- GObject *obj;
- ModestUIPrivate *priv;
- ModestAccountMgr *modest_acc_mgr;
- TnyAccountStoreIface *account_store_iface;
-
- g_return_val_if_fail (modest_conf, NULL);
-
- obj = g_object_new(MODEST_TYPE_UI, NULL);
- priv = MODEST_UI_GET_PRIVATE(obj);
-
- modest_acc_mgr =
- MODEST_ACCOUNT_MGR(modest_account_mgr_new (modest_conf));
- if (!modest_acc_mgr) {
- g_warning ("could not create ModestAccountMgr instance");
- g_object_unref (obj);
- return NULL;
- }
-
- account_store_iface =
- TNY_ACCOUNT_STORE_IFACE(modest_tny_account_store_new (modest_acc_mgr));
- if (!account_store_iface) {
- g_warning ("could not initialze ModestTnyAccountStore");
- return NULL;
- }
- g_signal_connect (account_store_iface, "password_requested",
- G_CALLBACK(on_password_requested),
- NULL);
- glade_init ();
- priv->glade_xml = glade_xml_new (MODEST_GLADE,
- NULL,NULL);
- if (!priv->glade_xml) {
- g_warning ("failed to do glade stuff");
- g_object_unref (obj);
- return NULL;
- }
-
- /* FIXME: could be used, but doesn't work atm.
- * glade_xml_signal_autoconnect(priv->glade_xml);
- */
-
- priv->modest_acc_mgr = modest_acc_mgr;
- g_object_ref (priv->modest_conf = modest_conf);
-
- priv->account_store = account_store_iface;
-
- priv->modest_window_mgr = MODEST_WINDOW_MGR(modest_window_mgr_new());
- g_signal_connect (priv->modest_window_mgr, "last_window_closed",
- G_CALLBACK(modest_ui_last_window_closed),
- NULL);
- return obj;
-}
-
-
-gboolean
-modest_ui_show_main_window (ModestUI *modest_ui)
-{
- GtkWidget *win;
- int height, width;
- ModestUIPrivate *priv;
- GtkWidget *folder_view, *header_view;
- GtkWidget *message_view;
- GtkWidget *account_settings_item;
-
- GtkWidget *folder_view_holder,
- *header_view_holder,
- *mail_paned;
-
- priv = MODEST_UI_GET_PRIVATE(modest_ui);
-
- height = modest_conf_get_int (priv->modest_conf,
- MODEST_CONF_MAIN_WINDOW_HEIGHT,NULL);
- width = modest_conf_get_int (priv->modest_conf,
- MODEST_CONF_MAIN_WINDOW_WIDTH,NULL);
-
- win = glade_xml_get_widget (priv->glade_xml, "main");
- if (!win) {
- g_warning ("could not create main window");
- return FALSE;
- }
-
- folder_view =
- GTK_WIDGET(modest_main_window_folder_tree(priv->modest_acc_mgr,
- priv->account_store));
- folder_view_holder = glade_xml_get_widget (priv->glade_xml, "folders");
- if (!folder_view||!folder_view_holder) {
- g_warning ("failed to create folder tree");
- return FALSE;
- }
- gtk_container_add (GTK_CONTAINER(folder_view_holder), folder_view);
-
- header_view = GTK_WIDGET(modest_main_window_header_tree (NULL));
- header_view_holder = glade_xml_get_widget (priv->glade_xml, "mail_list");
- if (!header_view) {
- g_warning ("failed to create header tree");
- return FALSE;
- }
- gtk_container_add (GTK_CONTAINER(header_view_holder), header_view);
-
- g_signal_connect (G_OBJECT(folder_view), "folder_selected",
- G_CALLBACK(on_folder_clicked), modest_ui);
-
- message_view = GTK_WIDGET(modest_tny_msg_view_new (NULL));
- if (!message_view) {
- g_warning ("failed to create message view");
- return FALSE;
- }
- mail_paned = glade_xml_get_widget (priv->glade_xml, "mail_paned");
- gtk_paned_add2 (GTK_PANED(mail_paned), message_view);
-
- g_signal_connect (header_view, "message_selected",
- G_CALLBACK(on_message_clicked),
- modest_ui);
-
- account_settings_item = glade_xml_get_widget (priv->glade_xml, "account_settings1");
- if (!account_settings_item)
- {
- g_warning ("The account settings item isn't available!\n");
- return FALSE;
- }
-
- g_signal_connect (account_settings_item, "activate",
- G_CALLBACK(on_account_settings1_activate),
- modest_ui);
-
- register_toolbar_callbacks (modest_ui);
-
- modest_window_mgr_register (priv->modest_window_mgr,
- G_OBJECT(win), MODEST_MAIN_WINDOW, 0);
- g_signal_connect (win, "destroy", G_CALLBACK(modest_ui_window_destroy),
- modest_ui);
- gtk_widget_set_usize (GTK_WIDGET(win), height, width);
- gtk_window_set_title (GTK_WINDOW(win), PACKAGE_STRING);
-
- gtk_widget_show_all (win);
- return TRUE;
-}
-
-
-static void
-register_toolbar_callbacks (ModestUI *modest_ui)
-{
- ModestUIPrivate *priv;
- GtkWidget *button;
-
- g_return_if_fail (modest_ui);
-
- priv = MODEST_UI_GET_PRIVATE (modest_ui);
-
- button = glade_xml_get_widget (priv->glade_xml, "toolb_new_mail");
- if (button)
- g_signal_connect (button, "clicked",
- G_CALLBACK(on_new_mail_clicked), modest_ui);
-
- button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
- if (button)
- g_signal_connect (button, "clicked",
- G_CALLBACK(on_reply_clicked), modest_ui);
-}
-
-
-
-static void
-hide_edit_window (GtkWidget *win, gpointer data)
-{
- gtk_widget_hide (win);
-}
-
-
-
-
-gboolean
-modest_ui_show_edit_window (ModestUI *modest_ui, const gchar* to,
- const gchar* cc, const gchar* bcc,
- const gchar* subject, const gchar *body,
- const GSList* att)
-{
- GtkWidget *win, *to_entry, *subject_entry, *body_view;
-
- ModestUIPrivate *priv;
- GtkWidget *btn;
- GtkTextBuffer *buf;
-
- priv = MODEST_UI_GET_PRIVATE(modest_ui);
- int height = modest_conf_get_int (priv->modest_conf,
- MODEST_CONF_EDIT_WINDOW_HEIGHT,NULL);
- int width = modest_conf_get_int (priv->modest_conf,
- MODEST_CONF_EDIT_WINDOW_WIDTH,NULL);
-
- win = glade_xml_get_widget (priv->glade_xml, "new_mail");
- if (!win) {
- g_warning ("could not create new mail window");
- return FALSE;
- }
-
- modest_window_mgr_register (priv->modest_window_mgr,
- G_OBJECT(win), MODEST_EDIT_WINDOW, 0);
- to_entry = glade_xml_get_widget (priv->glade_xml, "to_entry");
- subject_entry = glade_xml_get_widget (priv->glade_xml, "subject_entry");
- body_view = glade_xml_get_widget (priv->glade_xml, "body_view");
-
- gtk_entry_set_text(GTK_ENTRY(subject_entry), subject);
- gtk_entry_set_text(GTK_ENTRY(to_entry), to);
-
- buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(body_view));
- gtk_text_buffer_set_text(buf, body, -1);
-
- g_signal_connect (win, "destroy", G_CALLBACK(hide_edit_window),
- NULL);
-
- gtk_widget_set_usize (GTK_WIDGET(win), height, width);
- gtk_window_set_title (GTK_WINDOW(win),
- subject ? subject : "Untitled");
-
-
- btn = glade_xml_get_widget (priv->glade_xml, "toolb_send");
- g_signal_connect (btn, "clicked", G_CALLBACK(on_send_button_clicked),
- modest_ui);
-
- gtk_widget_show_all (win);
-
- return TRUE;
-}
-
-
-static void
-modest_ui_window_destroy (GtkWidget *win, gpointer data)
-{
- ModestUIPrivate *priv;
-
- g_return_if_fail (data);
-
- priv = MODEST_UI_GET_PRIVATE((ModestUI*)data);
- if (!modest_window_mgr_unregister (priv->modest_window_mgr, G_OBJECT(win)))
- g_warning ("modest window mgr: failed to unregister %p",
- G_OBJECT(win));
-}
-
-
-static void
-modest_ui_last_window_closed (GObject *obj, gpointer data)
-{
- gtk_main_quit ();
-}
-
-void
-on_account_selector_selection_changed(GtkWidget *widget,
- gpointer user_data)
-{
- GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
- GtkTreeIter iter;
-
- gchar *account_name;
-
- if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
- {
- gtk_tree_model_get(GTK_TREE_MODEL(model),
- &iter,
- 0, &account_name,
- -1);
- }
- else
- {
- account_name="empty";
- }
-
- g_message("Value: '%s'\n", account_name);
-}
-
-void
-on_account_settings1_activate (GtkMenuItem *menuitem,
- gpointer user_data)
-{
- GladeXML *glade_xml;
- GtkWidget *advanced_account_setup;
- ModestUIPrivate *priv;
- gint retval;
- GSList *account_name_list;
- GSList *account_name_list_iter;
- GtkListStore *account_names;
- GtkTreeIter account_names_iter;
- GtkWidget *account_selector;
- GtkCellRenderer *renderer;
-
- priv = MODEST_UI_GET_PRIVATE(MODEST_UI(user_data));
-
- glade_xml = glade_xml_new(MODEST_GLADE, "mailbox_setup_advanced", NULL);
- advanced_account_setup = glade_xml_get_widget(glade_xml, "mailbox_setup_advanced");
-
- account_name_list=modest_account_mgr_account_names(priv->modest_acc_mgr, NULL);
- account_names = gtk_list_store_new(1, G_TYPE_STRING);
-
- for (account_name_list_iter=account_name_list;
- account_name_list_iter!=NULL;
- account_name_list_iter=g_slist_next(account_name_list_iter))
- {
- gtk_list_store_append(account_names, &account_names_iter);
- gtk_list_store_set(account_names, &account_names_iter,
- 0, account_name_list_iter->data,
- -1);
- }
-
- g_slist_free(account_name_list);
-
- account_selector = glade_xml_get_widget(glade_xml, "account_selector");
- gtk_combo_box_set_model(GTK_COMBO_BOX(account_selector), GTK_TREE_MODEL(account_names));
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (account_selector), renderer, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (account_selector), renderer,
- "text", 0,
- NULL);
-
- g_signal_connect(GTK_WIDGET(account_selector), "changed",
- G_CALLBACK(on_account_selector_selection_changed),
- GTK_WIDGET(advanced_account_setup));
-
- gtk_combo_box_set_active(GTK_COMBO_BOX(account_selector), 0);
-
- gtk_widget_show_all(GTK_WIDGET(advanced_account_setup));
-
- retval=gtk_dialog_run(GTK_DIALOG(advanced_account_setup));
-
- g_object_unref(account_names);
-
- gtk_widget_destroy(GTK_WIDGET(advanced_account_setup));
-
- g_object_unref(glade_xml);
-}
-
-
-static void
-on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
- TnyMsgFolderIface *folder,
- gpointer data)
-{
- GtkWidget *win;
- ModestTnyHeaderTreeView *tree_view;
- ModestUIPrivate *priv;
- GtkWidget *scrollview;
-
- g_return_if_fail (folder);
- g_return_if_fail (data);
-
- priv = MODEST_UI_GET_PRIVATE(data);
- scrollview = glade_xml_get_widget (priv->glade_xml,"mail_list");
-
- tree_view = MODEST_TNY_HEADER_TREE_VIEW(
- gtk_bin_get_child(GTK_BIN(scrollview)));
- win = glade_xml_get_widget (priv->glade_xml, "main");
- gtk_window_set_title (GTK_WINDOW(win),
- tny_msg_folder_iface_get_name(folder));
-
- modest_tny_header_tree_view_set_folder (tree_view,
- folder);
-}
-
-
-
-static void on_message_clicked (ModestTnyFolderTreeView *folder_tree,
- TnyMsgIface *message,
- gpointer data)
-{
- GtkWidget *paned;
- ModestTnyMsgView *msg_view;
- ModestUIPrivate *priv;
-
- g_return_if_fail (message);
- g_return_if_fail (data);
-
- priv = MODEST_UI_GET_PRIVATE(data);
- paned = glade_xml_get_widget (priv->glade_xml,"mail_paned");
- msg_view = MODEST_TNY_MSG_VIEW(gtk_paned_get_child2 (GTK_PANED(paned)));
-
- modest_tny_msg_view_set_message (msg_view,
- message);
-}
-
-static void
-on_password_requested (ModestTnyAccountStore *account_store,
- const gchar *account_name, gpointer user_data)
-{
-
- GtkWidget *passdialog;
- GtkWidget *vbox;
- GtkWidget *infolabel;
- GtkWidget *passentry;
- gint retval;
- const gchar *infostring=g_strconcat("Please enter the password for ", account_name, ".", NULL);
-
- passdialog = gtk_dialog_new_with_buttons("MyDialog",
- NULL,
- GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK,
- GTK_RESPONSE_ACCEPT,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_REJECT,
- NULL);
-
- vbox=gtk_vbox_new(FALSE, 0);
-
- infolabel=gtk_label_new(infostring);
- passentry=gtk_entry_new();
-
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(passdialog)->vbox), infolabel, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(passdialog)->vbox), passentry, FALSE, FALSE, 0);
- gtk_widget_show_all(passdialog);
-
- retval = gtk_dialog_run (GTK_DIALOG(passdialog));
-
- switch (retval)
- {
- case GTK_RESPONSE_ACCEPT:
- modest_account_mgr_set_server_account_string(modest_tny_account_store_get_accout_mgr(account_store),
- account_name,
- "password",
- gtk_entry_get_text(GTK_ENTRY(passentry)),
- NULL);
- break;
- case GTK_RESPONSE_CANCEL:
- /* FIXME:
- * What happens, if canceled?"
- */
- break;
- }
-
- gtk_widget_destroy (passdialog);
-}
-
-
-
-
-
-
-static GtkWidget*
-modest_main_window_header_tree (TnyMsgFolderIface *folder)
-{
- GtkWidget *header_tree;
-
- header_tree = GTK_WIDGET(modest_tny_header_tree_view_new(folder));
- if (!header_tree) {
- g_warning ("could not create header tree");
- return NULL;
- }
-
- return GTK_WIDGET(header_tree);
-}
-
-
-
-static GtkWidget*
-modest_main_window_folder_tree (ModestAccountMgr *modest_acc_mgr,
- TnyAccountStoreIface *account_store)
-{
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
- GtkWidget *folder_tree;
-
- folder_tree = GTK_WIDGET(modest_tny_folder_tree_view_new (account_store));
- if (!folder_tree) {
- g_warning ("could not create folder list");
- return NULL;
- }
-
- column = gtk_tree_view_column_new_with_attributes(_("All Mail Folders"),
- renderer,"text",
- TNY_ACCOUNT_TREE_MODEL_NAME_COLUMN,
- NULL);
- gtk_tree_view_column_set_resizable (column, TRUE);
- gtk_tree_view_append_column (GTK_TREE_VIEW(folder_tree), column);
-
- column = gtk_tree_view_column_new_with_attributes(_("Unread"),
- renderer, "text",
- TNY_ACCOUNT_TREE_MODEL_UNREAD_COLUMN,
- NULL);
- gtk_tree_view_column_set_resizable (column, TRUE);
- gtk_tree_view_append_column (GTK_TREE_VIEW(folder_tree), column);
-
-
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(folder_tree), TRUE);
- gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(folder_tree), TRUE);
-
- return folder_tree;
-}
-
-
-static void
-on_new_mail_clicked (GtkWidget *widget, ModestUI *modest_ui)
-{
- g_return_if_fail (modest_ui);
- modest_ui_show_edit_window (modest_ui, "", "", "", "", "", NULL);
-}
-
-static gchar*
-modest_ui_quote_msg(const TnyMsgIface *src, const gchar *from, time_t sent_date)
-{
- GList *parts;
- TnyMsgMimePartIface *part;
- TnyStreamIface* stream;
- TnyTextBufferStream *dest;
- TnyMsgMimePartIface *body = NULL;
- GtkTextBuffer *buf;
- GtkTextIter begin, end, iter1, iter2, iter3;
- gchar *txt, *line;
- gint tmp;
- gint indent;
- gboolean break_line;
-<<<<<<< .mine
- gchar sent_str[101];
- gchar from_cut[82];
- gchar reply_head[202];
-
-=======
-
->>>>>>> .r91
- buf = gtk_text_buffer_new(NULL);
- dest = tny_text_buffer_stream_new(buf);
- parts = (GList*) tny_msg_iface_get_parts (src);
-
- while (parts) {
- /* TODO: maybe we'd like to quote more than one part?
- * cleanup, fix leaks
- */
- TnyMsgMimePartIface *part =
- TNY_MSG_MIME_PART_IFACE(parts->data);
- if (tny_msg_mime_part_iface_content_type_is (part, "text/plain")) {
- body = part;
- break;
- }
- parts = parts->next;
- }
- if (!body) {
- return "";
- }
- buf = gtk_text_buffer_new (NULL);
- stream = TNY_STREAM_IFACE(tny_text_buffer_stream_new (buf));
-
- tny_stream_iface_reset (stream);
- tny_msg_mime_part_iface_decode_to_stream (body, stream);
- tny_stream_iface_reset (stream);
-
- /* format sent_date */
- strftime(sent_str, 100, "%c", localtime(&sent_date));
- strncpy(from_cut, from, 80);
- sprintf(reply_head, "On %s, %s wrote:\n", sent_str, from_cut);
-
- gtk_text_buffer_get_iter_at_line(buf, &iter1, 0);
- gtk_text_buffer_insert(buf, &iter1, reply_head, -1);
- gtk_text_buffer_get_iter_at_line(buf, &iter1, 1);
- while (TRUE) {
- /* at each beginning of this while, iter1 must be at the beginning of
- the (next) line to quote */
-
- iter2 = iter1;
-<<<<<<< .mine
- if (gtk_text_iter_get_chars_in_line(&iter1) > 1) {
- /* check whether line is already quoted */
- iter2 = iter1;
- gtk_text_iter_forward_char (&iter2);
- txt = gtk_text_buffer_get_text (buf, &iter1, &iter2, FALSE);
- } else {
- txt = "";
- }
-=======
- gtk_text_iter_forward_to_line_end(&iter2);
- txt = gtk_text_buffer_get_text (buf, &iter1, &iter2, FALSE);
- printf("%s\n", txt);
- /* check whether line is already quoted */
- iter2 = iter1;
-
- gtk_text_iter_forward_word_end(&iter2);
- txt = gtk_text_buffer_get_text (buf, &iter1, &iter2, FALSE);
-
->>>>>>> .r91
- /* insert quotation mark */
- tmp = gtk_text_iter_get_offset(&iter1);
- gtk_text_buffer_insert(buf, &iter1, "> ", -1);
-
- /* still at the beginning of the line */
- gtk_text_buffer_get_iter_at_offset(buf, &iter1, tmp);
- iter2 = iter1;
-
- if (strcmp(txt, ">") != 0) {
-
- /* line was not already quoted */
-
- /* now check whether the line must be broken: */
- if (gtk_text_iter_get_chars_in_line(&iter2) >= 79) {
-
- gtk_text_iter_set_line_offset(&iter2, 79);
-
- /* move iter1 behind quote mark at the beginnig of the line */
- gtk_text_iter_forward_word_end(&iter1);
-
- /* save iter2 position */
- iter3 = iter2;
-
- /* move iter2 back one word (from breakpoint in line) */
- gtk_text_iter_backward_word_start(&iter2);
-
- /* check for one-word line (up to iter2) */
- if (!gtk_text_iter_compare(&iter1, &iter2) < 0) {
- gtk_text_iter_forward_word_end(&iter2); /* BUG? */
- }
-
- /* insert linebreak */
- tmp = gtk_text_iter_get_offset(&iter2);
-<<<<<<< .mine
- gtk_text_buffer_insert(buf, &iter2, "\n", -1);
-=======
- gtk_text_buffer_insert(buf, &iter2, "\n#", -1);
-
->>>>>>> .r91
- gtk_text_buffer_get_iter_at_offset(buf, &iter1, tmp);
-
- /* move to the beginning of the "new" line */
- gtk_text_iter_forward_line(&iter1);
-
- /* try to kill 1 space */
- iter2 = iter1;
- gtk_text_iter_forward_char(&iter2);
- txt = gtk_text_buffer_get_text(buf, &iter1, &iter2, FALSE);
- if (strcmp(txt, " ") == 0) {
- tmp = gtk_text_iter_get_offset(&iter1);
- gtk_text_buffer_delete(buf, &iter1, &iter2);
- gtk_text_buffer_get_iter_at_offset(buf, &iter1, tmp);
- }
-
- /* check whether there is a next line to merge */
- iter3 = iter1;
- if (!gtk_text_iter_forward_line(&iter3)) {
- continue;
- }
-<<<<<<< .mine
- /* iter3 is now at the beginning of the next line.*/
-
-=======
-
->>>>>>> .r91
- /* check for empty line */
- if (gtk_text_iter_get_chars_in_line(&iter3) < 2) {
- continue;
- }
-
- /* check for quote */
- iter2 = iter3;
- gtk_text_iter_forward_char (&iter2);
- txt = gtk_text_buffer_get_text(buf, &iter3, &iter2, FALSE);
- if (strcmp(txt, ">") == 0) {
- /* iter1 is still at the beginning of the newly broken
- * so we don't have to cleanup */
- continue;
- }
-<<<<<<< .mine
-
-=======
-
- /* now merge in the next line */
->>>>>>> .r91
- if (!gtk_text_iter_forward_to_line_end(&iter1)) {
- /* no further lines to merge */
- continue;
- }
-
- /* "mark" newline */
- iter2 = iter1;
- gtk_text_iter_forward_char(&iter2);
-<<<<<<< .mine
-
- /* do the merge */
-=======
-
->>>>>>> .r91
- tmp = gtk_text_iter_get_offset(&iter1);
-<<<<<<< .mine
-=======
-
- /* do the merge */
->>>>>>> .r91
- gtk_text_buffer_delete (buf, &iter1, &iter2);
- gtk_text_buffer_get_iter_at_offset (buf, &iter1, tmp);
-
- /* insert space */
- gtk_text_buffer_insert(buf, &iter1, " ", -1);
- gtk_text_buffer_get_iter_at_offset (buf, &iter1, tmp);
-
- /* move to beginning of line and continue */
- gtk_text_iter_set_line_offset(&iter1, 0);
-<<<<<<< .mine
- continue;
-
-=======
-
->>>>>>> .r91
- } else {
- /* line doesn't have to be broken, we're done. */
- if (!gtk_text_iter_forward_line(&iter1)) {
- break;
- }
- continue;
- }
- } else {
- /* line was already quoted */
- if (!gtk_text_iter_forward_line(&iter1)) {
- break;
- }
- continue;
- }
- }
-
- gtk_text_buffer_get_bounds (buf, &begin, &end);
- txt = gtk_text_buffer_get_text (buf, &begin, &end, FALSE);
-
- return txt;
-}
-
-static void
-modest_ui_reply_to_msg (ModestUI *modest_ui, TnyMsgHeaderIface *header,
- ModestTnyMsgView *msg_view) {
- const gchar *subject, *from, *quoted;
- time_t sent_date;
- const TnyMsgIface *msg;
- const TnyMsgFolderIface *folder;
- gchar *re_sub;
-
- quoted = "";
- if (header) {
- folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header));
- if (!folder) {
- g_warning ("cannot find folder");
- return;
- }
-
- msg = tny_msg_folder_iface_get_message (TNY_MSG_FOLDER_IFACE(folder), header);
- if (!msg) {
- g_warning ("cannot find msg");
- return;
- }
- subject = tny_msg_header_iface_get_subject(header);
- /* TODO: checks, free */
- re_sub = malloc(strlen(subject) + 5);
- strcpy (re_sub, "Re: ");
- strcat (re_sub, subject);
- /* FIXME: honor replyto, cc */
- from = tny_msg_header_iface_get_from(header);
- sent_date = tny_msg_header_iface_get_date_sent(header);
- quoted = modest_ui_quote_msg(msg, from, sent_date);
-
- } else {
- printf("no header\n");
- return;
- }
-
- modest_ui_show_edit_window (modest_ui, from, "FIXME:cc", /* bcc */ "", re_sub, quoted, NULL);
-}
-
-
-/* WIP, testing az */
-static void
-on_reply_clicked (GtkWidget *widget, ModestUI *modest_ui)
-{
- GtkTreeSelection *sel;
- GtkWidget *paned;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkScrolledWindow *scroll;
-
- TnyMsgHeaderIface *header;
-
- ModestTnyHeaderTreeView *header_view;
- ModestTnyMsgView *msg_view;
- ModestUIPrivate *priv;
-
- g_return_if_fail (modest_ui);
-
- priv = MODEST_UI_GET_PRIVATE(modest_ui);
-
- paned = glade_xml_get_widget (priv->glade_xml,"mail_paned");
- g_return_if_fail (paned);
-
- scroll = GTK_SCROLLED_WINDOW(gtk_paned_get_child1 (GTK_PANED(paned)));
- g_return_if_fail (scroll);
-
- msg_view = MODEST_TNY_MSG_VIEW(gtk_paned_get_child2 (GTK_PANED(paned)));
- g_return_if_fail (msg_view);
-
- header_view = MODEST_TNY_HEADER_TREE_VIEW(gtk_bin_get_child (GTK_BIN(scroll)));
- g_return_if_fail (header_view);
-
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
- g_return_if_fail (sel);
-
- if (!gtk_tree_selection_get_selected (sel, &model, &iter))
- /* no message was selected. TODO: disable reply button in this case */
- return;
-
- gtk_tree_model_get (model, &iter,
- TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
- &header, -1);
-
- modest_ui_reply_to_msg (modest_ui, header, msg_view);
-}
-
-
-
-/* FIXME: truly evil --> we cannot really assume that
- * there is only one edit window open...
- */
-static void
-on_send_button_clicked (GtkWidget *widget, ModestUI *modest_ui)
-{
- ModestTnyTransportActions *actions;
- ModestUIPrivate *priv;
- GtkWidget *to_entry, *subject_entry, *body_view;
- const gchar *to, *subject;
- gchar *body;
- GtkTextIter start, end;
- GtkTextBuffer *buf;
- TnyAccountStoreIface *account_store;
- const GList *transport_accounts;
- TnyTransportAccountIface *transport_account;
-
- g_return_if_fail (modest_ui);
-
- actions = MODEST_TNY_TRANSPORT_ACTIONS
- (modest_tny_transport_actions_new ());
- priv = MODEST_UI_GET_PRIVATE(modest_ui);
-
- account_store = priv->account_store;
- transport_accounts =
- tny_account_store_iface_get_transport_accounts (account_store);
- if (!transport_accounts) {
- g_message ("cannot send message: no transport account defined");
- return;
- } else /* take the first one! */
- transport_account =
- TNY_TRANSPORT_ACCOUNT_IFACE(transport_accounts->data);
-
- to_entry = glade_xml_get_widget (priv->glade_xml, "to_entry");
- subject_entry = glade_xml_get_widget (priv->glade_xml, "subject_entry");
- body_view = glade_xml_get_widget (priv->glade_xml, "body_view");
-
- to = gtk_entry_get_text (GTK_ENTRY(to_entry));
- subject = gtk_entry_get_text (GTK_ENTRY(subject_entry));
-
- buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(body_view));
- gtk_text_buffer_get_bounds (buf, &start, &end);
- body = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
-
- g_message ("sending %s ==> %s", subject, to);
- modest_tny_transport_actions_send_message (actions,
- transport_account,
- "dirk-jan.binnema@nokia.com",
- to, "", "", subject,
- body);
- g_free (body);
- g_object_unref (G_OBJECT(actions));
-
- gtk_entry_set_text (GTK_ENTRY(to_entry), "");
- gtk_entry_set_text (GTK_ENTRY(subject_entry), "");
- gtk_text_buffer_set_text (buf, "", 0);
-
- gtk_widget_hide (glade_xml_get_widget (priv->glade_xml, "new_mail"));
-}
modest_account_mgr_class_init (ModestAccountMgrClass * klass)
{
GObjectClass *gobject_class;
- GType paramtypes[3] = {G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER};
-
gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
*
* Returns: TRUE if it worked, FALSE otherwise
*/
-gboolean modest_account_mgr_set_account_enabled (ModestAccountMgr *self, const gchar* name,
+gboolean modest_account_mgr_account_set_enabled (ModestAccountMgr *self, const gchar* name,
gboolean is_server_account, gboolean enabled);
+++ /dev/null
-/* 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.
- */
-
-#include "modest-account-view.h"
-/* include other impl specific header files */
-
-/* 'private'/'protected' functions */
-static void modest_account_view_class_init (ModestAccountViewClass *klass);
-static void modest_account_view_init (ModestAccountView *obj);
-static void modest_account_view_finalize (GObject *obj);
-
-
-enum _AccountViewColumns {
- ENABLED_COLUMN,
- NAME_COLUMN,
- PROTO_COLUMN,
- N_COLUMNS
-};
-typedef enum _AccountViewColumns AccountViewColumns;
-
-
-/* list my signals */
-enum {
- /* MY_SIGNAL_1, */
- /* MY_SIGNAL_2, */
- LAST_SIGNAL
-};
-
-typedef struct _ModestAccountViewPrivate ModestAccountViewPrivate;
-struct _ModestAccountViewPrivate {
- ModestAccountMgr *account_mgr;
-};
-#define MODEST_ACCOUNT_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
- MODEST_TYPE_ACCOUNT_VIEW, \
- ModestAccountViewPrivate))
-/* globals */
-static GtkTreeViewClass *parent_class = NULL;
-
-/* uncomment the following if you have defined any signals */
-/* static guint signals[LAST_SIGNAL] = {0}; */
-
-GType
-modest_account_view_get_type (void)
-{
- static GType my_type = 0;
- if (!my_type) {
- static const GTypeInfo my_info = {
- sizeof(ModestAccountViewClass),
- NULL, /* base init */
- NULL, /* base finalize */
- (GClassInitFunc) modest_account_view_class_init,
- NULL, /* class finalize */
- NULL, /* class data */
- sizeof(ModestAccountView),
- 1, /* n_preallocs */
- (GInstanceInitFunc) modest_account_view_init,
- };
- my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
- "ModestAccountView",
- &my_info, 0);
- }
- return my_type;
-}
-
-static void
-modest_account_view_class_init (ModestAccountViewClass *klass)
-{
- GObjectClass *gobject_class;
- gobject_class = (GObjectClass*) klass;
-
- parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = modest_account_view_finalize;
-
- g_type_class_add_private (gobject_class, sizeof(ModestAccountViewPrivate));
-
- /* signal definitions go here, e.g.: */
-/* signals[MY_SIGNAL_1] = */
-/* g_signal_new ("my_signal_1",....); */
-/* signals[MY_SIGNAL_2] = */
-/* g_signal_new ("my_signal_2",....); */
-/* etc. */
-}
-
-static void
-modest_account_view_init (ModestAccountView *obj)
-{
- ModestAccountViewPrivate *priv;
-
- priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(obj);
-
- priv->account_mgr = NULL;
-}
-
-static void
-modest_account_view_finalize (GObject *obj)
-{
- ModestAccountViewPrivate *priv;
-
- priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(obj);
-
- if (priv->account_mgr) {
- g_object_unref (G_OBJECT(priv->account_mgr));
- priv->account_mgr = NULL;
- }
-}
-
-
-
-static void
-update_account_view (ModestAccountMgr *account_mgr, ModestAccountView *view)
-{
- GSList *account_names, *cursor;
- GtkListStore *model;
- GtkTreeIter iter;
-
- model = GTK_LIST_STORE(gtk_tree_view_get_model (GTK_TREE_VIEW(view)));
- gtk_list_store_clear (model);
-
- cursor = account_names =
- modest_account_mgr_account_names (account_mgr, NULL);
-
- while (cursor) {
- gchar *proto, *store, *account_name;
- gboolean enabled;
-
- account_name = (gchar*)cursor->data;
-
- store = modest_account_mgr_get_string (account_mgr,
- account_name,
- MODEST_ACCOUNT_STORE_ACCOUNT,
- FALSE, NULL);
- if (store) {
- proto = modest_account_mgr_get_string (account_mgr,
- store,
- MODEST_ACCOUNT_PROTO,
- TRUE, NULL);
- g_free(store);
- }
-
- enabled = modest_account_mgr_account_get_enabled (account_mgr,
- account_name,
- FALSE);
- gtk_list_store_insert_with_values (
- model, NULL, 0,
- ENABLED_COLUMN, enabled,
- NAME_COLUMN, account_name,
- PROTO_COLUMN, proto,
- -1);
-
- g_free (account_name);
- g_free (proto);
-
- cursor = cursor->next;
- }
- g_slist_free (account_names);
-}
-
-
-static void
-on_account_changed (ModestAccountMgr *account_mgr,
- const gchar* account, const gchar* key,
- gboolean server_account, ModestAccountView *self)
-{
- ModestAccountViewPrivate *priv;
- priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(self);
-
- update_account_view (account_mgr, self);
-}
-
-
-static void
-on_account_removed (ModestAccountMgr *account_mgr,
- const gchar* account, gboolean server_account,
- gpointer user_data)
-{
- on_account_changed (account_mgr, account, NULL, server_account, user_data);
-}
-
-
-
-
-static void
-on_account_enable_toggled (GtkCellRendererToggle *cell_renderer, gchar *path,
- ModestAccountView *self)
-{
- GtkTreeIter iter;
- ModestAccountViewPrivate *priv;
- GtkTreeModel *model;
- gchar *account_name;
- gboolean enabled;
-
- priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(self);
- model = gtk_tree_view_get_model (GTK_TREE_VIEW(self));
-
- if (!gtk_tree_model_get_iter_from_string (model, &iter, path)) {
- g_printerr ("modest: cannot find iterator\n");
- return;
- }
-
- gtk_tree_model_get (model, &iter,
- ENABLED_COLUMN, &enabled,
- NAME_COLUMN, &account_name,
- -1);
-
- /* toggle enabled / disabled */
- modest_account_mgr_account_set_enabled (priv->account_mgr, account_name,
- FALSE, !enabled);
- g_free (account_name);
-}
-
-
-
-
-
-
-static
-init_view (ModestAccountView *self)
-{
- ModestAccountViewPrivate *priv;
- GtkTreeSelection *sel;
- GtkWidget *account_view;
- GtkCellRenderer *renderer;
- GtkListStore *model;
- GtkTreeIter iter;
-
- priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(self);
-
- model = gtk_list_store_new (3,
- G_TYPE_BOOLEAN, /* checkbox */
- G_TYPE_STRING, /* account name */
- G_TYPE_STRING); /* account type (pop, imap,...) */
-
- gtk_tree_view_set_model (GTK_TREE_VIEW(self), GTK_TREE_MODEL(model));
-
- renderer = gtk_cell_renderer_toggle_new ();
- g_object_set (G_OBJECT(renderer), "activatable", TRUE,"radio", FALSE, NULL);
-
- g_signal_connect (G_OBJECT(renderer), "toggled",
- G_CALLBACK(on_account_enable_toggled),
- self);
-
- gtk_tree_view_append_column (GTK_TREE_VIEW(self),
- gtk_tree_view_column_new_with_attributes (
- _("Enabled"), renderer,
- "active", ENABLED_COLUMN, NULL));
- gtk_tree_view_append_column (GTK_TREE_VIEW(self),
- gtk_tree_view_column_new_with_attributes (
- _("Account"),
- gtk_cell_renderer_text_new (),
- "text", NAME_COLUMN, NULL));
- gtk_tree_view_append_column (GTK_TREE_VIEW(self),
- gtk_tree_view_column_new_with_attributes (
- _("Type"),
- gtk_cell_renderer_text_new (),
- "text", PROTO_COLUMN, NULL));
-
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
-
- g_signal_connect (G_OBJECT(priv->account_mgr),
- "account_removed",
- G_CALLBACK(on_account_removed), self);
- g_signal_connect (G_OBJECT(priv->account_mgr),
- "account_changed",
- G_CALLBACK(on_account_changed), self);
-}
-
-
-
-GtkWidget*
-modest_account_view_new (ModestAccountMgr *account_mgr)
-{
- GObject *obj;
- ModestAccountViewPrivate *priv;
-
- g_return_val_if_fail (account_mgr, NULL);
-
- obj = g_object_new(MODEST_TYPE_ACCOUNT_VIEW, NULL);
- priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(obj);
-
- g_object_ref (G_OBJECT(account_mgr));
- priv->account_mgr = account_mgr;
-
- init_view (MODEST_ACCOUNT_VIEW (obj));
-
- return GTK_WIDGET(obj);
-}
-
+++ /dev/null
-/* 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_ACCOUNT_VIEW_H__
-#define __MODEST_ACCOUNT_VIEW_H__
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-#include "modest-account-mgr.h"
-
-G_BEGIN_DECLS
-
-/* convenience macros */
-#define MODEST_TYPE_ACCOUNT_VIEW (modest_account_view_get_type())
-#define MODEST_ACCOUNT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_ACCOUNT_VIEW,ModestAccountView))
-#define MODEST_ACCOUNT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_ACCOUNT_VIEW,GtkTreeView))
-#define MODEST_IS_ACCOUNT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_ACCOUNT_VIEW))
-#define MODEST_IS_ACCOUNT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_ACCOUNT_VIEW))
-#define MODEST_ACCOUNT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_ACCOUNT_VIEW,ModestAccountViewClass))
-
-typedef struct _ModestAccountView ModestAccountView;
-typedef struct _ModestAccountViewClass ModestAccountViewClass;
-
-struct _ModestAccountView {
- GtkTreeView parent;
- /* insert public members, if any */
-};
-
-struct _ModestAccountViewClass {
- GtkTreeViewClass parent_class;
- /* insert signal callback declarations, eg. */
- /* void (* my_event) (ModestAccountView* obj); */
-};
-
-/* member functions */
-GType modest_account_view_get_type (void) G_GNUC_CONST;
-
-
-
-GtkWidget* modest_account_view_new (ModestAccountMgr *account_mgr);
-
-G_END_DECLS
-
-#endif /* __MODEST_ACCOUNT_VIEW_H__ */
-
typedef struct _ModestEditorWindowPrivate ModestEditorWindowPrivate;
struct _ModestEditorWindowPrivate {
- GtkWidget *window;
gpointer user_data;
gboolean modified;
GList *attachments;
/* for now create a local test-window */
data = NULL;
- edit_win = modest_ui_new_editor_window(ui, &data);
+ edit_win = G_OBJECT(modest_ui_new_editor_window(ui, &data));
if (!edit_win)
return NULL;
if (!data)
g_message("editor window user data is emtpy");
- MODEST_EDITOR_WINDOW(self)->window = edit_win;
+ MODEST_EDITOR_WINDOW(self)->window = GTK_WINDOW(edit_win);
priv->user_data = data;
return self;
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <tny-list.h>
#include <tny-account-store-iface.h>
#include <tny-list-iface.h>
#include "modest-tny-transport-actions.h"
#include "modest-tny-account-store.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /*HAVE_CONFIG_H*/
#ifdef MODEST_ENABLE_HILDON /* Hildon includes */
#include <libosso.h>
{
GOptionContext *context = NULL;
ModestConf *modest_conf = NULL;
- ModestUI *modest_ui = NULL;
GError *err = NULL;
int retval = MODEST_ERR_NONE;
const gchar* subject, const gchar *body)
{
- GtkWidget *win;
ModestUI *modest_ui;
- gint ok, retval = 0;
+ gint retval = 0;
modest_ui = MODEST_UI(modest_ui_new (conf));
if (!modest_ui) {
TnyListIface *accounts = NULL;
TnyIteratorIface *iter = NULL;
-
- TnyTransportAccountIface *account = NULL;
-
+ TnyTransportAccountIface *account = NULL;
int retval;
- int i = 0;
acc_mgr = modest_account_mgr_new (conf);
acc_store = modest_tny_account_store_new (acc_mgr);
}
+
+/* just to prevent warnings:
+ * warning: `%x' yields only last 2 digits of year in some locales
+ */
+static size_t
+my_strftime(char *s, size_t max, const char *fmt, const
+ struct tm *tm) {
+ return strftime(s, max, fmt, tm);
+}
+
+
gchar *
modest_text_utils_quote (const gchar * to_quote, const gchar * from,
const time_t sent_date, const int limit)
gsize len;
/* format sent_date */
- strftime (sent_str, 100, "%c", localtime (&sent_date));
+ my_strftime (sent_str, 100, "%c", localtime (&sent_date));
q = g_string_new ("");
g_string_printf (q, "On %s, %s wrote:\n", sent_str, from);
TnyTransportAccountIface *account);
static void modest_tny_account_store_get_accounts (TnyAccountStoreIface *iface, TnyListIface *list,
TnyGetAccountsRequestType type);
-
/* list my signals */
enum {
PASSWORD_REQUESTED_SIGNAL,
priv->modest_acc_mgr = NULL;
}
+
if (priv->tny_session_camel) {
- g_object_unref (G_OBJECT(priv->tny_session_camel));
+// FIXME: how to kill a camel
+ //g_object_unref (G_OBJECT(priv->tny_session_camel));
priv->tny_session_camel = NULL;
}
priv->device = NULL;
}
- g_mutex_free (priv->store_lock);
+ if (priv->store_lock)
+ g_mutex_free (priv->store_lock);
g_free (priv->cache_dir);
priv->cache_dir = NULL;
}
+static gboolean
+modest_tny_account_store_alert (TnyAccountStoreIface *self, TnyAlertType type,
+ const gchar *prompt)
+{
+ return TRUE; /* FIXME: implement this */
+}
+
+
static void
modest_tny_account_store_iface_init (gpointer g_iface, gpointer iface_data)
{
modest_tny_account_store_get_accounts;
klass->add_transport_account_func =
modest_tny_account_store_add_transport_account;
+ klass->add_store_account_func =
+ modest_tny_account_store_add_store_account;
klass->get_cache_dir_func =
modest_tny_account_store_get_cache_dir;
klass->get_device_func =
modest_tny_account_store_get_device;
+ klass->alert_func =
+ modest_tny_account_store_alert;
}
void
GList *
modest_tny_attachment_new_list_from_msg(const TnyMsgIface *msg, gboolean with_body)
{
- GList *list = NULL;
+ // FIXME: does not work anymore. needs the new TnyList stuff...
+ return NULL;
+#if 0
+
+ TnyList *att_list
const GList *attachments = NULL;
TnyMsgMimePartIface *part;
ModestTnyAttachment *att;
-#if 0
+
if (with_body) {
/* TODO: make plain over html configurable */
part = modest_tny_msg_actions_find_body_part ((TnyMsgIface *)msg, "text/plain");
list = g_list_append(list, att);
}
}
-#endif
+
if (with_body) {
list = g_list_append(list, modest_tny_attachment_new_from_message(msg));
} else {
attachments = attachments->next;
}
return list;
+
+#endif
}
+++ /dev/null
-/* 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.
- */
-
-#include <glib/gi18n.h>
-#include <string.h>
-
-#include <tny-account-tree-model.h>
-#include <tny-account-store-iface.h>
-#include <tny-account-iface.h>
-#include <tny-msg-folder-iface.h>
-#include <tny-summary-window-iface.h>
-
-#include "modest-tny-folder-tree-view.h"
-
-#include <modest-icon-names.h>
-#include "modest-icon-factory.h"
-
-
-/* 'private'/'protected' functions */
-static void modest_tny_folder_tree_view_class_init (ModestTnyFolderTreeViewClass *klass);
-static void modest_tny_folder_tree_view_init (ModestTnyFolderTreeView *obj);
-static void modest_tny_folder_tree_view_finalize (GObject *obj);
-
-//static void modest_tny_folder_tree_view_iface_init (gpointer iface, gpointer data);
-static void modest_tny_folder_tree_view_set_account_store (TnySummaryWindowIface *self,
- TnyAccountStoreIface *account_store);
-static gboolean update_model (ModestTnyFolderTreeView *self,TnyAccountStoreIface *iface);
-static gboolean update_model_empty (ModestTnyFolderTreeView *self);
-
-static void selection_changed (GtkTreeSelection *sel, gpointer data);
-
-enum {
- FOLDER_SELECTED_SIGNAL,
- LAST_SIGNAL
-};
-
-typedef struct _ModestTnyFolderTreeViewPrivate ModestTnyFolderTreeViewPrivate;
-struct _ModestTnyFolderTreeViewPrivate {
-
- TnyAccountStoreIface *tny_account_store;
- TnyMsgFolderIface *cur_folder;
- gboolean view_is_empty;
-
- GMutex *lock;
-};
-#define MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE((o), \
- MODEST_TYPE_TNY_FOLDER_TREE_VIEW, \
- ModestTnyFolderTreeViewPrivate))
-/* globals */
-static GObjectClass *parent_class = NULL;
-
-static guint signals[LAST_SIGNAL] = {0};
-
-GType
-modest_tny_folder_tree_view_get_type (void)
-{
- static GType my_type = 0;
- if (!my_type) {
- static const GTypeInfo my_info = {
- sizeof(ModestTnyFolderTreeViewClass),
- NULL, /* base init */
- NULL, /* base finalize */
- (GClassInitFunc) modest_tny_folder_tree_view_class_init,
- NULL, /* class finalize */
- NULL, /* class data */
- sizeof(ModestTnyFolderTreeView),
- 1, /* n_preallocs */
- (GInstanceInitFunc) modest_tny_folder_tree_view_init,
- };
-
- my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
- "ModestTnyFolderTreeView",
- &my_info, 0);
- }
- return my_type;
-}
-
-static void
-modest_tny_folder_tree_view_class_init (ModestTnyFolderTreeViewClass *klass)
-{
- GObjectClass *gobject_class;
- gobject_class = (GObjectClass*) klass;
-
- parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = modest_tny_folder_tree_view_finalize;
-
- klass->update_model = modest_tny_folder_tree_view_update_model;
-
- g_type_class_add_private (gobject_class,
- sizeof(ModestTnyFolderTreeViewPrivate));
-
- signals[FOLDER_SELECTED_SIGNAL] =
- g_signal_new ("folder_selected",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ModestTnyFolderTreeViewClass,
- folder_selected),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-}
-
-
-
-static void
-text_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
-{
- GObject *rendobj;
- gchar *fname;
- gint unread;
- TnyMsgFolderType type;
-
- gtk_tree_model_get (tree_model, iter,
- TNY_ACCOUNT_TREE_MODEL_NAME_COLUMN, &fname,
- TNY_ACCOUNT_TREE_MODEL_TYPE_COLUMN, &type,
- TNY_ACCOUNT_TREE_MODEL_UNREAD_COLUMN, &unread, -1);
- rendobj = G_OBJECT(renderer);
-
- if (unread > 0) {
- gchar *folder_title = g_strdup_printf ("%s (%d)", fname, unread);
- g_object_set (rendobj,"text", folder_title, "weight", 800, NULL);
- g_free (folder_title);
- } else
- g_object_set (rendobj,"text", fname, "weight", 400, NULL);
-
- g_free (fname);
-}
-
-/* FIXME: move these to TnyMail */
-enum {
-
- TNY_MSG_FOLDER_TYPE_NOTES = TNY_MSG_FOLDER_TYPE_SENT + 1, /* urgh */
- TNY_MSG_FOLDER_TYPE_DRAFTS,
- TNY_MSG_FOLDER_TYPE_CONTACTS,
- TNY_MSG_FOLDER_TYPE_CALENDAR
-};
-
-static TnyMsgFolderType
-guess_folder_type (const gchar* name)
-{
- TnyMsgFolderType type;
- gchar *folder;
-
- g_return_val_if_fail (name, TNY_MSG_FOLDER_TYPE_NORMAL);
-
- type = TNY_MSG_FOLDER_TYPE_NORMAL;
- folder = g_utf8_strdown (name, strlen(name));
-
- if (strcmp (folder, "inbox") == 0 ||
- strcmp (folder, _("inbox")) == 0)
- type = TNY_MSG_FOLDER_TYPE_INBOX;
- else if (strcmp (folder, "outbox") == 0 ||
- strcmp (folder, _("outbox")) == 0)
- type = TNY_MSG_FOLDER_TYPE_OUTBOX;
- else if (g_str_has_prefix(folder, "junk") ||
- g_str_has_prefix(folder, _("junk")))
- type = TNY_MSG_FOLDER_TYPE_JUNK;
- else if (g_str_has_prefix(folder, "trash") ||
- g_str_has_prefix(folder, _("trash")))
- type = TNY_MSG_FOLDER_TYPE_JUNK;
- else if (g_str_has_prefix(folder, "sent") ||
- g_str_has_prefix(folder, _("sent")))
- type = TNY_MSG_FOLDER_TYPE_SENT;
-
- /* these are not *really* TNY_ types */
- else if (g_str_has_prefix(folder, "draft") ||
- g_str_has_prefix(folder, _("draft")))
- type = TNY_MSG_FOLDER_TYPE_DRAFTS;
- else if (g_str_has_prefix(folder, "notes") ||
- g_str_has_prefix(folder, _("notes")))
- type = TNY_MSG_FOLDER_TYPE_NOTES;
- else if (g_str_has_prefix(folder, "contacts") ||
- g_str_has_prefix(folder, _("contacts")))
- type = TNY_MSG_FOLDER_TYPE_CONTACTS;
- else if (g_str_has_prefix(folder, "calendar") ||
- g_str_has_prefix(folder, _("calendar")))
- type = TNY_MSG_FOLDER_TYPE_CALENDAR;
-
- g_free (folder);
- return type;
-}
-
-
-static void
-icon_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
-{
- GObject *rendobj;
- GdkPixbuf *pixbuf;
- TnyMsgFolderType type;
- gchar *fname = NULL;
- gint unread;
-
- rendobj = G_OBJECT(renderer);
- gtk_tree_model_get (tree_model, iter,
- TNY_ACCOUNT_TREE_MODEL_TYPE_COLUMN, &type,
- TNY_ACCOUNT_TREE_MODEL_NAME_COLUMN, &fname,
- TNY_ACCOUNT_TREE_MODEL_UNREAD_COLUMN, &unread, -1);
- rendobj = G_OBJECT(renderer);
-
- if (type == TNY_MSG_FOLDER_TYPE_NORMAL)
- type = guess_folder_type (fname);
-
- if (fname);
- g_free (fname);
-
- switch (type) {
- case TNY_MSG_FOLDER_TYPE_INBOX:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_INBOX);
- break;
- case TNY_MSG_FOLDER_TYPE_OUTBOX:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_OUTBOX);
- break;
- case TNY_MSG_FOLDER_TYPE_JUNK:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_JUNK);
- break;
- case TNY_MSG_FOLDER_TYPE_SENT:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_SENT);
- break;
- case TNY_MSG_FOLDER_TYPE_DRAFTS:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_DRAFTS);
- break;
- case TNY_MSG_FOLDER_TYPE_NOTES:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_NOTES);
- break;
- case TNY_MSG_FOLDER_TYPE_CALENDAR:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CALENDAR);
- break;
- case TNY_MSG_FOLDER_TYPE_CONTACTS:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CONTACTS);
- break;
- case TNY_MSG_FOLDER_TYPE_NORMAL:
- default:
- pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_NORMAL);
- break;
- }
-
- g_object_set (rendobj,
- "pixbuf-expander-open",
- modest_icon_factory_get_icon (MODEST_FOLDER_ICON_OPEN),
- "pixbuf-expander-closed",
- modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CLOSED),
- "pixbuf", pixbuf,
- NULL);
-}
-
-static void
-modest_tny_folder_tree_view_init (ModestTnyFolderTreeView *obj)
-{
- ModestTnyFolderTreeViewPrivate *priv;
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkTreeSelection *sel;
-
- priv = MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(obj);
-
- priv->view_is_empty = TRUE;
- priv->tny_account_store = NULL;
- priv->cur_folder = NULL;
-
- priv->lock = g_mutex_new ();
-
- column = gtk_tree_view_column_new ();
- gtk_tree_view_column_set_title (column,
- _("All Mail Folders"));
-
- gtk_tree_view_append_column (GTK_TREE_VIEW(obj),
- column);
-
- renderer = gtk_cell_renderer_pixbuf_new();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_cell_data_func(column, renderer,
- icon_cell_data, NULL, NULL);
-
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_column_pack_start (column, renderer, FALSE);
- gtk_tree_view_column_set_cell_data_func(column, renderer,
- text_cell_data, NULL, NULL);
-
- sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(obj));
- gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
-
- gtk_tree_view_column_set_spacing (column, 2);
- gtk_tree_view_column_set_resizable (column, TRUE);
- gtk_tree_view_column_set_fixed_width (column, TRUE);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(obj), TRUE);
- gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(obj), FALSE);
-
-}
-
-
-static void
-modest_tny_folder_tree_view_finalize (GObject *obj)
-{
- ModestTnyFolderTreeViewPrivate *priv;
-
- g_return_if_fail (obj);
-
- priv = MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(obj);
- if (priv->tny_account_store) {
- g_object_unref (G_OBJECT(priv->tny_account_store));
- priv->tny_account_store = NULL;
- }
-
-
- if (priv->lock) {
- g_mutex_free (priv->lock);
- priv->lock = NULL;
- }
-
- G_OBJECT_CLASS(parent_class)->finalize (obj);
-}
-
-
-static void
-modest_tny_folder_tree_view_set_account_store (TnySummaryWindowIface *self,
- TnyAccountStoreIface *account_store)
-{
- ModestTnyFolderTreeViewPrivate *priv;
-
- g_return_if_fail (self);
- g_return_if_fail (account_store);
-
- priv = MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(self);
- if (priv->tny_account_store) {
- g_object_unref (priv->tny_account_store);
- priv->tny_account_store = NULL;
- }
-
- g_object_ref (G_OBJECT(priv->tny_account_store = account_store));
-}
-
-
-
-static void
-on_accounts_update (TnyAccountStoreIface *account_store, const gchar *account,
- gpointer user_data)
-{
- update_model_empty (MODEST_TNY_FOLDER_TREE_VIEW(user_data));
-
- if (!update_model (MODEST_TNY_FOLDER_TREE_VIEW(user_data), account_store))
- g_printerr ("modest: failed to update model for changes in '%s'",
- account);
-}
-
-
-GtkWidget*
-modest_tny_folder_tree_view_new (TnyAccountStoreIface *account_store)
-{
- GObject *self;
- ModestTnyFolderTreeViewPrivate *priv;
- GtkTreeSelection *sel;
-
- self = G_OBJECT(g_object_new(MODEST_TYPE_TNY_FOLDER_TREE_VIEW, NULL));
- priv = MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(self);
-
- g_return_val_if_fail (account_store, NULL);
-
- if (!update_model (MODEST_TNY_FOLDER_TREE_VIEW(self), account_store))
- g_printerr ("modest: failed to update model");
-
- g_signal_connect (G_OBJECT(account_store), "update_accounts",
- G_CALLBACK (on_accounts_update), self);
-
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
- g_signal_connect (sel, "changed",
- G_CALLBACK(selection_changed), self);
-
- return self;
-}
-
-
-
-
-static gboolean
-update_model_empty (ModestTnyFolderTreeView *self)
-{
- GtkTreeIter iter;
- GtkTreeStore *store;
- ModestTnyFolderTreeViewPrivate *priv;
-
- g_return_val_if_fail (self, FALSE);
-
- store = gtk_tree_store_new (1, G_TYPE_STRING);
- gtk_tree_store_append (store, &iter, NULL);
-
- gtk_tree_store_set (store, &iter, 0,
- _("(empty)"), -1);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW(self),
- GTK_TREE_MODEL(store));
- g_object_unref (store);
-
- priv = MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(self);
- priv->view_is_empty = TRUE;
-
- return TRUE;
-}
-
-
-static gboolean
-update_model (ModestTnyFolderTreeView *self, TnyAccountStoreIface *account_store)
-{
- ModestTnyFolderTreeViewPrivate *priv;
- TnyListIface *account_list;
- GtkTreeModel *model, *sortable;
-
- g_return_val_if_fail (account_store, FALSE);
-
- priv = MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(self);
-
- model = GTK_TREE_MODEL(tny_account_tree_model_new ());
- account_list = TNY_LIST_IFACE(model);
-
- update_model_empty (self); /* cleanup */
- priv->view_is_empty = TRUE;
-
- tny_account_store_iface_get_accounts (account_store, account_list,
- TNY_ACCOUNT_STORE_IFACE_STORE_ACCOUNTS);
- if (!account_list) /* no store accounts found */
- return TRUE;
-
- sortable = gtk_tree_model_sort_new_with_model (model);
- gtk_tree_view_set_model (GTK_TREE_VIEW(self), sortable);
-
- priv->view_is_empty = FALSE;
- g_object_unref (model);
-
- return TRUE;
-}
-
-
-void
-selection_changed (GtkTreeSelection *sel, gpointer user_data)
-{
- GtkTreeModel *model;
- TnyMsgFolderIface *folder = NULL;
- GtkTreeIter iter;
- ModestTnyFolderTreeView *tree_view;
- ModestTnyFolderTreeViewPrivate *priv;
-
- g_return_if_fail (sel);
- g_return_if_fail (user_data);
-
- priv = MODEST_TNY_FOLDER_TREE_VIEW_GET_PRIVATE(user_data);
-
- /* is_empty means that there is only the 'empty' item */
- if (priv->view_is_empty)
- return;
-
- /* folder was _un_selected if true */
- if (!gtk_tree_selection_get_selected (sel, &model, &iter)) {
- priv->cur_folder = NULL;
- return;
- }
-
- tree_view = MODEST_TNY_FOLDER_TREE_VIEW (user_data);
-
- gtk_tree_model_get (model, &iter,
- TNY_ACCOUNT_TREE_MODEL_INSTANCE_COLUMN,
- &folder, -1);
-
- if (priv->cur_folder)
- tny_msg_folder_iface_expunge (priv->cur_folder);
- priv->cur_folder = folder;
-
- /* folder will not be defined if you click eg. on the root node */
- if (folder)
- g_signal_emit (G_OBJECT(tree_view), signals[FOLDER_SELECTED_SIGNAL], 0,
- folder);
-}
-
-
-gboolean
-modest_tny_folder_tree_view_update_model(ModestTnyFolderTreeView *self,
- TnyAccountStoreIface *iface)
-{
- g_return_val_if_fail (MODEST_IS_TNY_FOLDER_TREE_VIEW (self), FALSE);
-
- return update_model (self, iface);
-}
+++ /dev/null
-/* 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_TNY_FOLDER_TREE_VIEW_H__
-#define __MODEST_TNY_FOLDER_TREE_VIEW_H__
-
-#include <tny-account-tree-model.h>
-#include <tny-account-store-iface.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/* convenience macros */
-#define MODEST_TYPE_TNY_FOLDER_TREE_VIEW (modest_tny_folder_tree_view_get_type())
-#define MODEST_TNY_FOLDER_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_TNY_FOLDER_TREE_VIEW,ModestTnyFolderTreeView))
-#define MODEST_TNY_FOLDER_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_TNY_FOLDER_TREE_VIEW,ModestTnyFolderTreeViewClass))
-#define MODEST_IS_TNY_FOLDER_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_TNY_FOLDER_TREE_VIEW))
-#define MODEST_IS_TNY_FOLDER_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_TNY_FOLDER_TREE_VIEW))
-#define MODEST_TNY_FOLDER_TREE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_TNY_FOLDER_TREE_VIEW,ModestTnyFolderTreeViewClass))
-
-typedef struct _ModestTnyFolderTreeView ModestTnyFolderTreeView;
-typedef struct _ModestTnyFolderTreeViewClass ModestTnyFolderTreeViewClass;
-
-struct _ModestTnyFolderTreeView {
- GtkTreeView parent;
- /* insert public members, if any */
-};
-
-struct _ModestTnyFolderTreeViewClass {
- GtkTreeViewClass parent_class;
-
- /* emitted when a folder is clicked */
- void (*folder_selected) (ModestTnyFolderTreeView* self,
- TnyMsgFolderIface *folder,
- gpointer user_data);
-
- gboolean (*update_model) (ModestTnyFolderTreeView *self,
- TnyAccountStoreIface *iface);
-
-};
-
-
-/**
- * modest_tny_folder_tree_view_get_type:
- *
- * get the GType for ModestTnyFolderTreeView
- *
- * Returns: the GType
- */
-GType modest_tny_folder_tree_view_get_type (void) G_GNUC_CONST;
-
-
-/**
- * modest_tny_folder_tree_view_new:
- * @iface: a TnyAccountStoreIface object
- *
- * create a new ModestTnyFolderTreeView instance, based on an account store
- *
- * Returns: a new GtkWidget (a GtkTreeView-subclass)
- */
-GtkWidget* modest_tny_folder_tree_view_new (TnyAccountStoreIface *iface);
-
-
-/**
- * modest_tny_folder_tree_view_is_empty:
- * @self: a ModestTnyFolderTreeView instance
- *
- * check to see of the view is empty. Note that when it is empty,
- * there will still be one item, telling "(empty)" or similar
- *
- * Returns: TRUE if the tree view is empty, FALSE otherwise
- */
-gboolean modest_tny_folder_tree_view_is_empty (ModestTnyFolderTreeView *self);
-
-
-/**
- * modest_tny_folder_tree_view_update_model:
- * @self: a #ModestTnyFolderTreeView instance
- * @iface: a #TnyAccountStoreIface instance
- *
- * Update the thee model from a given account store.
- *
- * Returns: TRUE on success, FALSE otherwise
- */
-gboolean modest_tny_folder_tree_view_update_model(ModestTnyFolderTreeView *self,
- TnyAccountStoreIface *iface);
-
-
-G_END_DECLS
-
-#endif /* __MODEST_TNY_FOLDER_TREE_VIEW_H__ */
-
+++ /dev/null
-/* 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.
- */
-
-
-/* modest-tny-header-tree-view.c */
-
-#include <glib/gi18n.h>
-#include "modest-tny-header-tree-view.h"
-#include <tny-list-iface.h>
-#include <string.h>
-#include "modest-marshal.h"
-
-#include <modest-icon-names.h>
-#include "modest-icon-factory.h"
-
-static void modest_tny_header_tree_view_class_init (ModestTnyHeaderTreeViewClass *klass);
-static void modest_tny_header_tree_view_init (ModestTnyHeaderTreeView *obj);
-static void modest_tny_header_tree_view_finalize (GObject *obj);
-
-static void on_selection_changed (GtkTreeSelection *sel, gpointer user_data);
-static void on_column_clicked (GtkTreeViewColumn *treeviewcolumn, gpointer user_data);
-static gboolean refresh_folder_finish_status_update (gpointer user_data);
-
-enum {
- MESSAGE_SELECTED_SIGNAL,
- STATUS_UPDATE_SIGNAL,
- LAST_SIGNAL
-};
-
-typedef struct _ModestTnyHeaderTreeViewPrivate ModestTnyHeaderTreeViewPrivate;
-struct _ModestTnyHeaderTreeViewPrivate {
-
- TnyMsgFolderIface *tny_msg_folder;
- TnyListIface *headers;
-
- gint status_id;
- GSList *columns;
-
- GMutex *lock;
-
- ModestTnyHeaderTreeViewStyle style;
-};
-#define MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
- MODEST_TYPE_TNY_HEADER_TREE_VIEW, \
- ModestTnyHeaderTreeViewPrivate))
-/* globals */
-static GObjectClass *parent_class = NULL;
-
-/* uncomment the following if you have defined any signals */
-static guint signals[LAST_SIGNAL] = {0};
-
-GType
-modest_tny_header_tree_view_get_type (void)
-{
- static GType my_type = 0;
- if (!my_type) {
- static const GTypeInfo my_info = {
- sizeof(ModestTnyHeaderTreeViewClass),
- NULL, /* base init */
- NULL, /* base finalize */
- (GClassInitFunc) modest_tny_header_tree_view_class_init,
- NULL, /* class finalize */
- NULL, /* class data */
- sizeof(ModestTnyHeaderTreeView),
- 1, /* n_preallocs */
- (GInstanceInitFunc) modest_tny_header_tree_view_init,
- };
- my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
- "ModestTnyHeaderTreeView",
- &my_info, 0);
- }
- return my_type;
-}
-
-static void
-modest_tny_header_tree_view_class_init (ModestTnyHeaderTreeViewClass *klass)
-{
- GObjectClass *gobject_class;
- gobject_class = (GObjectClass*) klass;
-
- parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = modest_tny_header_tree_view_finalize;
-
- g_type_class_add_private (gobject_class, sizeof(ModestTnyHeaderTreeViewPrivate));
-
- signals[MESSAGE_SELECTED_SIGNAL] =
- g_signal_new ("message_selected",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ModestTnyHeaderTreeViewClass,message_selected),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- signals[STATUS_UPDATE_SIGNAL] =
- g_signal_new ("status_update",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ModestTnyHeaderTreeViewClass,message_selected),
- NULL, NULL,
- modest_marshal_VOID__STRING_INT,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
-}
-
-
-
-
-
-static void
-msgtype_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
-{
- TnyMsgHeaderFlags flags;
- GdkPixbuf *pixbuf = NULL;
-
- gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
- &flags, -1);
-
- if (flags & TNY_MSG_HEADER_FLAG_DELETED)
- pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_DELETED);
- else if (flags & TNY_MSG_HEADER_FLAG_SEEN)
- pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_READ);
- else
- pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_UNREAD);
-
- g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL);
-}
-
-static void
-attach_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
-{
- TnyMsgHeaderFlags flags;
- GdkPixbuf *pixbuf = NULL;
-
- gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
- &flags, -1);
-
- if (flags & TNY_MSG_HEADER_FLAG_ATTACHMENTS)
- pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_ATTACH);
-
- g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL);
-}
-
-
-static void
-header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
-{
- TnyMsgHeaderFlags flags;
-
- gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
- &flags, -1);
-
- g_object_set (G_OBJECT(renderer),
- "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800,
- "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ?
- PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
- NULL);
-}
-
-
-
-/* try to make a shorter display address; changes it arg in-place */
-static gchar*
-display_address (gchar *address)
-{
- gchar *cursor;
-
- if (!address)
- return;
-
- /* simplistic --> remove <email@address> from display name */
- cursor = g_strstr_len (address, strlen(address), "<");
- if (cursor)
- cursor[0]='\0';
-
- /* simplistic --> remove (bla bla) from display name */
- cursor = g_strstr_len (address, strlen(address), "(");
- if (cursor)
- cursor[0]='\0';
-
- return address;
-}
-
-
-
-static void
-sender_receiver_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gboolean is_sender)
-{
- TnyMsgHeaderFlags flags;
- gchar *address;
- gint sender_receiver_col;
-
- if (is_sender)
- sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN;
- else
- sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN;
-
- gtk_tree_model_get (tree_model, iter,
- sender_receiver_col, &address,
- TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
- -1);
-
- g_object_set (G_OBJECT(renderer),
- "text",
- display_address (address),
- "weight",
- (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400 : 800,
- "style",
- (flags & TNY_MSG_HEADER_FLAG_DELETED)?PANGO_STYLE_ITALIC:PANGO_STYLE_NORMAL,
- NULL);
-
- g_free (address);
-}
-
-
-/* not reentrant/thread-safe */
-const gchar*
-display_date (time_t date)
-{
- struct tm date_tm, now_tm;
- time_t now;
-
- const gint buf_size = 64;
- static gchar date_buf[64]; /* buf_size is not ... */
- static gchar now_buf[64]; /* ...const enough... */
-
- now = time (NULL);
-
- localtime_r(&now, &now_tm);
- localtime_r(&date, &date_tm);
-
- /* get today's date */
- strftime (date_buf, buf_size, "%x", &date_tm);
- strftime (now_buf, buf_size, "%x", &now_tm); /* today */
-
- /* if this is today, get the time instead of the date */
- if (strcmp (date_buf, now_buf) == 0)
- strftime (date_buf, buf_size, _("%X"), &date_tm);
-
- return date_buf;
-}
-
-
-static void
-compact_header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
- GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
-{
- GObject *rendobj;
- TnyMsgHeaderFlags flags;
- gchar *from, *subject;
- gchar *header;
- time_t date;
-
- gtk_tree_model_get (tree_model, iter,
- TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
- TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &from,
- TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject,
- TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &date,
- -1);
- rendobj = G_OBJECT(renderer);
-
- header = g_strdup_printf ("%s %s\n%s",
- display_address (from),
- display_date(date),
- subject);
-
- g_object_set (G_OBJECT(renderer),
- "text", header,
- "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800,
- "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ?
- PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
- NULL);
- g_free (header);
- g_free (from);
- g_free (subject);
-}
-
-
-static GtkTreeViewColumn*
-get_new_column (const gchar *name, GtkCellRenderer *renderer,
- gboolean resizable, gint sort_col_id, gboolean show_as_text,
- GtkTreeCellDataFunc cell_data_func, gpointer user_data)
-{
- GtkTreeViewColumn *column;
-
- column = gtk_tree_view_column_new_with_attributes(name, renderer, NULL);
- gtk_tree_view_column_set_resizable (column, resizable);
-
- if (show_as_text)
- gtk_tree_view_column_add_attribute (column, renderer, "text",
- sort_col_id);
- if (sort_col_id >= 0)
- gtk_tree_view_column_set_sort_column_id (column, sort_col_id);
-
- gtk_tree_view_column_set_sort_indicator (column, FALSE);
- gtk_tree_view_column_set_reorderable (column, TRUE);
-
- if (cell_data_func)
- gtk_tree_view_column_set_cell_data_func(column, renderer, cell_data_func,
- user_data, NULL);
-
-/* g_signal_connect (G_OBJECT (column), "clicked", */
-/* G_CALLBACK (column_clicked), obj); */
-
- return column;
-}
-
-
-
-
-static void
-remove_all_columns (ModestTnyHeaderTreeView *obj)
-{
- GList *columns, *cursor;
-
- columns = gtk_tree_view_get_columns (GTK_TREE_VIEW(obj));
-
- for (cursor = columns; cursor; cursor = cursor->next)
- gtk_tree_view_remove_column (GTK_TREE_VIEW(obj),
- GTK_TREE_VIEW_COLUMN(cursor->data));
- g_list_free (columns);
-}
-
-
-
-
-static void
-init_columns (ModestTnyHeaderTreeView *obj)
-{
- GtkTreeViewColumn *column=NULL;
- GtkCellRenderer *renderer_msgtype,
- *renderer_header,
- *renderer_attach;
-
- ModestTnyHeaderTreeViewPrivate *priv;
- GSList *cursor;
-
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(obj);
-
- renderer_msgtype = gtk_cell_renderer_pixbuf_new ();
- renderer_attach = gtk_cell_renderer_pixbuf_new ();
- renderer_header = gtk_cell_renderer_text_new ();
-
- remove_all_columns (obj);
-
- for (cursor = priv->columns; cursor; cursor = cursor->next) {
- ModestTnyHeaderTreeViewColumn col =
- (ModestTnyHeaderTreeViewColumn) GPOINTER_TO_INT(cursor->data);
-
- switch (col) {
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE:
-
- column = get_new_column (_("M"), renderer_msgtype, FALSE,
- TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
- FALSE, (GtkTreeCellDataFunc)msgtype_cell_data,
- NULL);
- break;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH:
-
- column = get_new_column (_("A"), renderer_attach, FALSE,
- TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
- FALSE, (GtkTreeCellDataFunc)attach_cell_data,
- NULL);
- break;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE:
- column = get_new_column (_("Received"), renderer_header, TRUE,
- TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_COLUMN,
- TRUE, (GtkTreeCellDataFunc)header_cell_data,
- NULL);
- break;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM:
- column = get_new_column (_("From"), renderer_header, TRUE,
- TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN,
- TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data,
- GINT_TO_POINTER(TRUE));
- break;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_TO:
- column = get_new_column (_("To"), renderer_header, TRUE,
- TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN,
- TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data,
- GINT_TO_POINTER(FALSE));
- break;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_COMPACT_HEADER:
- column = get_new_column (_("Header"), renderer_header, TRUE,
- TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN,
- TRUE, (GtkTreeCellDataFunc)compact_header_cell_data,
- NULL);
- break;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT:
- column = get_new_column (_("Subject"), renderer_header, TRUE,
- TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN,
- TRUE, (GtkTreeCellDataFunc)header_cell_data,
- NULL);
- break;
-
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SENT_DATE:
- column = get_new_column (_("Sent"), renderer_header, TRUE,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_COLUMN,
- TRUE, (GtkTreeCellDataFunc)header_cell_data,
- NULL);
- break;
- }
- gtk_tree_view_append_column (GTK_TREE_VIEW(obj), column);
- }
-}
-
-
-
-
-
-static void
-modest_tny_header_tree_view_init (ModestTnyHeaderTreeView *obj)
-{
- ModestTnyHeaderTreeViewPrivate *priv;
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(obj);
-
- priv->status_id = 0;
- priv->lock = g_mutex_new ();
-}
-
-static void
-modest_tny_header_tree_view_finalize (GObject *obj)
-{
- ModestTnyHeaderTreeView *self;
- ModestTnyHeaderTreeViewPrivate *priv;
-
- self = MODEST_TNY_HEADER_TREE_VIEW(obj);
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
-
- if (priv->headers)
- g_object_unref (G_OBJECT(priv->headers));
-
-
- if (priv->lock) {
- g_mutex_free (priv->lock);
- priv->lock = NULL;
- }
-
- priv->headers = NULL;
- priv->tny_msg_folder = NULL;
-
- G_OBJECT_CLASS(parent_class)->finalize (obj);
-}
-
-GtkWidget*
-modest_tny_header_tree_view_new (TnyMsgFolderIface *folder,
- GSList *columns,
- ModestTnyHeaderTreeViewStyle style)
-{
- GObject *obj;
- GtkTreeSelection *sel;
- ModestTnyHeaderTreeView *self;
-
- obj = G_OBJECT(g_object_new(MODEST_TYPE_TNY_HEADER_TREE_VIEW, NULL));
- self = MODEST_TNY_HEADER_TREE_VIEW(obj);
-
- if (!modest_tny_header_tree_view_set_folder (self, NULL)) {
- g_warning ("could not set the folder");
- g_object_unref (obj);
- return NULL;
- }
-
- modest_tny_header_tree_view_set_style (self, style);
- modest_tny_header_tree_view_set_columns (self, columns);
-
- /* all cols */
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(obj), TRUE);
- gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(obj), TRUE);
-
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(obj),
- TRUE); /* alternating row colors */
-
- sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
- g_signal_connect (sel, "changed",
- G_CALLBACK(on_selection_changed), self);
-
- return GTK_WIDGET(self);
-}
-
-gboolean
-modest_tny_header_tree_view_set_columns (ModestTnyHeaderTreeView *self, GSList *columns)
-{
- ModestTnyHeaderTreeViewPrivate *priv;
- GSList *cursor;
-
- g_return_val_if_fail (self, FALSE);
-
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
-
- g_slist_free (priv->columns);
-
- for (cursor = columns; cursor; cursor = cursor->next) {
- ModestTnyHeaderTreeViewColumn col =
- (ModestTnyHeaderTreeViewColumn) GPOINTER_TO_INT(cursor->data);
- if (0 > col || col >= MODEST_TNY_HEADER_TREE_VIEW_COLUMN_NUM)
- g_warning ("invalid column in column list");
- else
- priv->columns = g_slist_append (priv->columns, cursor->data);
- }
-
- init_columns (self); /* redraw them */
- return TRUE;
-}
-
-
-
-const GSList*
-modest_tny_header_tree_view_get_columns (ModestTnyHeaderTreeView *self)
-{
- ModestTnyHeaderTreeViewPrivate *priv;
-
- g_return_val_if_fail (self, FALSE);
-
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
- return priv->columns;
-}
-
-
-
-
-gboolean
-modest_tny_header_tree_view_set_style (ModestTnyHeaderTreeView *self,
- ModestTnyHeaderTreeViewStyle style)
-{
- g_return_val_if_fail (self, FALSE);
- g_return_val_if_fail (style >= 0 && style < MODEST_TNY_HEADER_TREE_VIEW_STYLE_NUM,
- FALSE);
-
- MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self)->style = style;
-
- return TRUE;
-}
-
-ModestTnyHeaderTreeViewStyle
-modest_tny_header_tree_view_get_style (ModestTnyHeaderTreeView *self)
-{
- g_return_val_if_fail (self, FALSE);
-
- return MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self)->style;
-}
-
-
-
-/* get the length of any prefix that should be ignored for sorting */
-static inline int
-get_prefix_len (const gchar *sub)
-{
- gint i = 0;
- const static gchar* prefix[] = {"Re:", "RE:", "Fwd:", "FWD:", "FW:", "AW:", NULL};
-
- if (sub[0] != 'R' && sub[0] != 'F') /* optimization */
- return 0;
-
- while (prefix[i]) {
- if (g_str_has_prefix(sub, prefix[i])) {
- int prefix_len = strlen(prefix[i]);
- if (sub[prefix_len] == ' ')
- ++prefix_len; /* ignore space after prefix as well */
- return prefix_len;
- }
- ++i;
- }
- return 0;
-}
-
-
-static inline gint
-cmp_normalized_subject (const gchar* s1, const gchar *s2)
-{
- gint result = 0;
- register gchar *n1, *n2;
-
- n1 = g_utf8_collate_key (s1 + get_prefix_len(s1), -1);
- n2 = g_utf8_collate_key (s2 + get_prefix_len(s2), -1);
-
- result = strcmp (n1, n2);
- g_free (n1);
- g_free (n2);
-
- return result;
-}
-
-
-static gint
-cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
- gpointer user_data)
-{
- gint col_id = GPOINTER_TO_INT (user_data);
- gint t1, t2;
- gint val1, val2;
- gchar *s1, *s2;
- gint cmp;
-
- g_return_val_if_fail (GTK_IS_TREE_MODEL(tree_model), -1);
-
- switch (col_id) {
-
- /* first one, we decide based on the time */
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_COMPACT_HEADER:
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE:
- gtk_tree_model_get (tree_model, iter1,
- TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
- &t1,-1);
- gtk_tree_model_get (tree_model, iter2,
- TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
- &t2,-1);
- return t1 - t2;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SENT_DATE:
- gtk_tree_model_get (tree_model, iter1,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
- &t1,-1);
- gtk_tree_model_get (tree_model, iter2,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
- &t2,-1);
- return t1 - t2;
-
-
- /* next ones, we try the search criteria first, if they're the same, then we use 'sent date' */
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT: {
-
- gtk_tree_model_get (tree_model, iter1,
- TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s1,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
- -1);
- gtk_tree_model_get (tree_model, iter2,
- TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s2,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
- -1);
-
- cmp = cmp_normalized_subject(s1, s2);
-
- g_free (s1);
- g_free (s2);
-
- return cmp ? cmp : t1 - t2;
- }
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM:
-
- gtk_tree_model_get (tree_model, iter1,
- TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s1,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
- -1);
- gtk_tree_model_get (tree_model, iter2,
- TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s2,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
- -1);
- cmp = strcmp (s1, s2);
- g_free (s1);
- g_free (s2);
-
- return cmp ? cmp : t1 - t2;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_TO:
-
- gtk_tree_model_get (tree_model, iter1,
- TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s1,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
- -1);
- gtk_tree_model_get (tree_model, iter2,
- TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s2,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
- -1);
- cmp = strcmp (s1, s2);
- g_free (s1);
- g_free (s2);
-
- return cmp ? cmp : t1 - t2;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH:
-
- gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1);
- gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1);
-
- cmp = (val1 & TNY_MSG_HEADER_FLAG_ATTACHMENTS) -
- (val2 & TNY_MSG_HEADER_FLAG_ATTACHMENTS);
-
- return cmp ? cmp : t1 - t2;
-
- case MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE:
- gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,-1);
- gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
- TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,-1);
- cmp = (val1 & TNY_MSG_HEADER_FLAG_SEEN) - (val2 & TNY_MSG_HEADER_FLAG_SEEN);
-
- return cmp ? cmp : t1 - t2;
-
- default:
- return &iter1 - &iter2; /* oughhhh */
- }
-}
-
-
-static void
-refresh_folder (TnyMsgFolderIface *folder, gboolean cancelled,
- gpointer user_data)
-{
- GtkTreeModel *oldsortable, *sortable;
- ModestTnyHeaderTreeView *self =
- MODEST_TNY_HEADER_TREE_VIEW(user_data);
- ModestTnyHeaderTreeViewPrivate *priv;
-
- g_return_if_fail (self);
-
- if (cancelled)
- return;
-
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
-
- if (!folder) /* when there is no folder */
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(self), FALSE);
-
- else { /* it's a new one or a refresh */
- GSList *col;
-
- priv->headers = TNY_LIST_IFACE(tny_msg_header_list_model_new ());
-
- tny_msg_folder_iface_get_headers (folder, priv->headers, FALSE);
- tny_msg_header_list_model_set_folder (TNY_MSG_HEADER_LIST_MODEL(priv->headers),
- folder, TRUE); /* async */
-
- oldsortable = gtk_tree_view_get_model(GTK_TREE_VIEW (self));
- if (oldsortable && GTK_IS_TREE_MODEL_SORT(oldsortable)) {
- GtkTreeModel *oldmodel = gtk_tree_model_sort_get_model
- (GTK_TREE_MODEL_SORT(oldsortable));
- if (oldmodel)
- g_object_unref (G_OBJECT(oldmodel));
- g_object_unref (oldsortable);
- }
-
- sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(priv->headers));
-
- /* install our special sorting functions */
- col = priv->columns;
- while (col) {
- gint col_id = GPOINTER_TO_INT (col->data);
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sortable), col_id,
- (GtkTreeIterCompareFunc)cmp_rows,
- GINT_TO_POINTER(col_id), NULL);
- col = col->next;
- }
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (self), sortable);
- gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(self), TRUE);
- /* no need to unref sortable */
- }
-
-}
-
-
-static void
-refresh_folder_status_update (TnyMsgFolderIface *folder, const gchar *msg,
- gint status_id, gpointer user_data)
-{
- ModestTnyHeaderTreeView *self;
- ModestTnyHeaderTreeViewPrivate *priv;
-
- self = MODEST_TNY_HEADER_TREE_VIEW (user_data);
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
-
- g_signal_emit (G_OBJECT(self),
- signals[STATUS_UPDATE_SIGNAL], 0,
- msg, status_id);
- if (msg)
- g_timeout_add (750,
- (GSourceFunc)refresh_folder_finish_status_update,
- self);
-
- priv->status_id = status_id;
-}
-
-
-static gboolean
-refresh_folder_finish_status_update (gpointer user_data)
-{
- ModestTnyHeaderTreeView *self;
- ModestTnyHeaderTreeViewPrivate *priv;
-
- self = MODEST_TNY_HEADER_TREE_VIEW (user_data);
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
-
- if (priv->status_id == 0)
- return FALSE;
-
- refresh_folder_status_update (NULL, NULL, priv->status_id,
- user_data);
- priv->status_id = 0;
-
- return FALSE;
-}
-
-
-gboolean
-modest_tny_header_tree_view_set_folder (ModestTnyHeaderTreeView *self,
- TnyMsgFolderIface *folder)
-{
- ModestTnyHeaderTreeViewPrivate *priv;
-
- g_return_val_if_fail (MODEST_IS_TNY_HEADER_TREE_VIEW (self), FALSE);
-
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
-
- g_mutex_lock (priv->lock);
-
- if (!folder) {/* when there is no folder */
- GtkTreeModel *model;
- model = gtk_tree_view_get_model (GTK_TREE_VIEW(self));
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(self), FALSE);
- gtk_tree_view_set_model (GTK_TREE_VIEW (self), NULL);
- if (model)
- g_object_unref (model);
- }
- else { /* it's a new one or a refresh */
- tny_msg_folder_iface_refresh_async (folder,
- refresh_folder,
- refresh_folder_status_update,
- self);
- }
-
- /* no message selected */
- g_signal_emit (G_OBJECT(self), signals[MESSAGE_SELECTED_SIGNAL], 0,
- NULL);
-
- g_mutex_unlock (priv->lock);
-
- return TRUE;
-}
-
-
-
-static void
-on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
-{
- GtkTreeModel *model;
- TnyMsgHeaderIface *header;
- GtkTreeIter iter;
- ModestTnyHeaderTreeView *self;
- ModestTnyHeaderTreeViewPrivate *priv;
-
- g_return_if_fail (sel);
- g_return_if_fail (user_data);
-
- self = MODEST_TNY_HEADER_TREE_VIEW (user_data);
- priv = MODEST_TNY_HEADER_TREE_VIEW_GET_PRIVATE(self);
-
-
- if (!gtk_tree_selection_get_selected (sel, &model, &iter))
- return; /* msg was _un_selected */
-
- //g_mutex_lock (priv->lock);
-
- gtk_tree_model_get (model, &iter,
- TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
- &header, -1);
-
- if (header) {
- const TnyMsgIface *msg = NULL;
- const TnyMsgFolderIface *folder;
-
- folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header));
- if (!folder)
- g_printerr ("modest: cannot find folder\n");
- else {
- msg = tny_msg_folder_iface_get_message (TNY_MSG_FOLDER_IFACE(folder),
- header);
- if (!msg) {
- g_printerr ("modest: cannot find msg\n");
- gtk_tree_store_remove (GTK_TREE_STORE(model),
- &iter);
- }
- }
-
- g_signal_emit (G_OBJECT(self), signals[MESSAGE_SELECTED_SIGNAL], 0,
- msg);
-
- /* mark message as seen; _set_flags crashes, bug in tinymail? */
- //flags = tny_msg_header_iface_get_flags (TNY_MSG_HEADER_IFACE(header));
- //tny_msg_header_iface_set_flags (header, TNY_MSG_HEADER_FLAG_SEEN);
- }
-
- // g_mutex_unlock (priv->lock);
-
-}
-
-static void
-on_column_clicked (GtkTreeViewColumn *col, gpointer user_data)
-{
- GtkTreeView *treeview;
- gint id;
-
- treeview = GTK_TREE_VIEW (user_data);
- id = gtk_tree_view_column_get_sort_column_id (col);
-
- gtk_tree_view_set_search_column (treeview, id);
-}
+++ /dev/null
-/* 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_TNY_HEADER_TREE_VIEW_H__
-#define __MODEST_TNY_HEADER_TREE_VIEW_H__
-
-#include <gtk/gtk.h>
-#include <tny-msg-folder-iface.h>
-#include <tny-account-tree-model.h>
-#include <tny-msg-iface.h>
-#include <tny-msg-header-iface.h>
-#include <tny-msg-header-list-model.h>
-
-G_BEGIN_DECLS
-
-/* convenience macros */
-#define MODEST_TYPE_TNY_HEADER_TREE_VIEW (modest_tny_header_tree_view_get_type())
-#define MODEST_TNY_HEADER_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_TNY_HEADER_TREE_VIEW,ModestTnyHeaderTreeView))
-#define MODEST_TNY_HEADER_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_TNY_HEADER_TREE_VIEW,ModestTnyHeaderTreeViewClass))
-#define MODEST_IS_TNY_HEADER_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_TNY_HEADER_TREE_VIEW))
-#define MODEST_IS_TNY_HEADER_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_TNY_HEADER_TREE_VIEW))
-#define MODEST_TNY_HEADER_TREE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_TNY_HEADER_TREE_VIEW,ModestTnyHeaderTreeViewClass))
-
-typedef struct _ModestTnyHeaderTreeView ModestTnyHeaderTreeView;
-typedef struct _ModestTnyHeaderTreeViewClass ModestTnyHeaderTreeViewClass;
-
-struct _ModestTnyHeaderTreeView {
- GtkTreeView parent;
- /* insert public members, if any */
-};
-
-struct _ModestTnyHeaderTreeViewClass {
- GtkTreeViewClass parent_class;
-
- void (*message_selected) (ModestTnyHeaderTreeView* self,
- TnyMsgIface *msg,
- gpointer user_data);
-
- /* msg == NULL implies that the operation is finished, ie.
- * the progress indictation can be hidden */
- void (*status_update) (ModestTnyHeaderTreeView* self,
- const gchar* msg,
- gint status,
- gpointer user_data);
-};
-
-
-enum {
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_TO,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SENT_DATE,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH,
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_COMPACT_HEADER,
-
- MODEST_TNY_HEADER_TREE_VIEW_COLUMN_NUM
-};
-typedef guint ModestTnyHeaderTreeViewColumn;
-
-enum {
- MODEST_TNY_HEADER_TREE_VIEW_STYLE_NORMAL,
- MODEST_TNY_HEADER_TREE_VIEW_STYLE_COMPACT,
-
- MODEST_TNY_HEADER_TREE_VIEW_STYLE_NUM
-};
-typedef guint ModestTnyHeaderTreeViewStyle;
-
-
-
-/**
- * modest_tny_header_tree_view_get_type:
- *
- * get the GType for ModestTnyHeaderTreeView
- *
- * Returns: the GType
- */
-GType modest_tny_header_tree_view_get_type (void) G_GNUC_CONST;
-
-
-/**
- * modest_tny_header_tree_view_new:
- * @folder: a TnyMsgFolderIface object
- * @columns: a list of ModestTnyHeaderTreeViewColumn
- * @style: a ModestTnyHeaderTreeViewColumn with the style of this listview
- * ( MODEST_TNY_HEADER_TREE_VIEW_STYLE_NORMAL or MODEST_TNY_HEADER_TREE_VIEW_STYLE_COMPACT)
- *
- * create a new ModestTnyHeaderTreeView instance, based on a folder iface
- *
- * Returns: a new GtkWidget (a GtkTreeView-subclass)
- */
-GtkWidget* modest_tny_header_tree_view_new (TnyMsgFolderIface *folder,
- GSList *columns,
- ModestTnyHeaderTreeViewStyle style);
-
-/**
- * modest_tny_header_tree_view_set_folder:
- * @self: a ModestTnyHeaderTreeView instance
- * @folder: a TnyMsgFolderIface object
- *
- * set the folder for this ModestTnyHeaderTreeView
- *
- * Returns: TRUE if it succeeded, FALSE otherwise
- */
-gboolean modest_tny_header_tree_view_set_folder (ModestTnyHeaderTreeView *self,
- TnyMsgFolderIface *folder);
-
-
-/**
- * modest_tny_header_tree_view_set_columns:
- * @self: a ModestTnyHeaderTreeView instance
- * @columns: a list of ModestTnyHeaderTreeViewColumn
- *
- * set the columns for this ModestTnyHeaderTreeView
- *
- * Returns: TRUE if it succeeded, FALSE otherwise
- */
-gboolean modest_tny_header_tree_view_set_columns (ModestTnyHeaderTreeView *self,
- GSList *columns);
-/**
- * modest_tny_header_tree_view_get_columns:
- * @self: a ModestTnyHeaderTreeView instance
- * @folder: a TnyMsgFolderIface object
- *
- * get the columns for this ModestTnyHeaderTreeView
- *
- * Returns: list of columms, or NULL in case of no columns or error
- */
-const GSList* modest_tny_header_tree_view_get_columns (ModestTnyHeaderTreeView *self);
-
-
-/**
- * modest_tny_header_tree_view_set_style:
- * @self: a ModestTnyHeaderTreeView instance
- * @style: the style for this tree view
- *
- * set the folder for this ModestTnyHeaderTreeView
- *
- * Returns: TRUE if it succeeded, FALSE otherwise
- */
-gboolean modest_tny_header_tree_view_set_style (ModestTnyHeaderTreeView *self,
- ModestTnyHeaderTreeViewStyle style);
-
-/**
- * modest_tny_header_tree_view_set_folder:
- * @self: a ModestTnyHeaderTreeView instance
- * @folder: a TnyMsgFolderIface object
- *
- * set the folder for this ModestTnyHeaderTreeView
- *
- * Returns: TRUE if it succeeded, FALSE otherwise
- */
-ModestTnyHeaderTreeViewStyle modest_tny_header_tree_view_get_style (ModestTnyHeaderTreeView *self);
-
-G_END_DECLS
-
-
-#endif /* __MODEST_TNY_HEADER_TREE_VIEW_H__ */
-
time_t sent_date, gint limit,
const gchar * to_quote)
{
- gchar *quoted;
-
/* 2 cases: */
/* a) quote text from selection */
+++ /dev/null
-/* 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.
- */
-
-#include <tny-text-buffer-stream.h>
-#include <string.h>
-#include <regex.h>
-#include <ctype.h>
-#include <glib/gi18n.h>
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-stream.h>
-#include <tny-list-iface.h>
-
-#include "modest-tny-msg-view.h"
-#include "modest-tny-stream-gtkhtml.h"
-#include "modest-tny-msg-actions.h"
-
-
-/* 'private'/'protected' functions */
-static void modest_tny_msg_view_class_init (ModestTnyMsgViewClass *klass);
-static void modest_tny_msg_view_init (ModestTnyMsgView *obj);
-static void modest_tny_msg_view_finalize (GObject *obj);
-
-
-static GSList* get_url_matches (GString *txt);
-static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri,
- ModestTnyMsgView *msg_view);
-static gboolean on_url_requested (GtkWidget *widget, const gchar *uri,
- GtkHTMLStream *stream,
- ModestTnyMsgView *msg_view);
-
-/*
- * we need these regexps to find URLs in plain text e-mails
- */
-typedef struct _UrlMatchPattern UrlMatchPattern;
-struct _UrlMatchPattern {
- gchar *regex;
- regex_t *preg;
- gchar *prefix;
-
-};
-
-#define ATT_PREFIX "att:"
-
-#define MAIL_VIEWER_URL_MATCH_PATTERNS { \
- { "(file|http|ftp|https)://[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]+[-A-Za-z0-9_$%&=?/~#]",\
- NULL, NULL },\
- { "www\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\
- NULL, "http://" },\
- { "ftp\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\
- NULL, "ftp://" },\
- { "(voipto|callto|chatto|jabberto|xmpp):[-_a-z@0-9.\\+]+", \
- NULL, NULL}, \
- { "mailto:[-_a-z0-9.\\+]+@[-_a-z0-9.]+", \
- NULL, NULL},\
- { "[-_a-z0-9.\\+]+@[-_a-z0-9.]+",\
- NULL, "mailto:"}\
- }
-
-
-/* list my signals */
-enum {
- LINK_CLICKED_SIGNAL,
- ATTACHMENT_CLICKED_SIGNAL,
- LAST_SIGNAL
-};
-
-typedef struct _ModestTnyMsgViewPrivate ModestTnyMsgViewPrivate;
-struct _ModestTnyMsgViewPrivate {
- GtkWidget *gtkhtml;
- const TnyMsgIface *msg;
-};
-#define MODEST_TNY_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
- MODEST_TYPE_TNY_MSG_VIEW, \
- ModestTnyMsgViewPrivate))
-/* globals */
-static GtkContainerClass *parent_class = NULL;
-
-/* uncomment the following if you have defined any signals */
-static guint signals[LAST_SIGNAL] = {0};
-
-GType
-modest_tny_msg_view_get_type (void)
-{
- static GType my_type = 0;
- if (!my_type) {
- static const GTypeInfo my_info = {
- sizeof(ModestTnyMsgViewClass),
- NULL, /* base init */
- NULL, /* base finalize */
- (GClassInitFunc) modest_tny_msg_view_class_init,
- NULL, /* class finalize */
- NULL, /* class data */
- sizeof(ModestTnyMsgView),
- 1, /* n_preallocs */
- (GInstanceInitFunc) modest_tny_msg_view_init,
- };
- my_type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW,
- "ModestTnyMsgView",
- &my_info, 0);
- }
- return my_type;
-}
-
-static void
-modest_tny_msg_view_class_init (ModestTnyMsgViewClass *klass)
-{
- GObjectClass *gobject_class;
- gobject_class = (GObjectClass*) klass;
-
- parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = modest_tny_msg_view_finalize;
-
- g_type_class_add_private (gobject_class, sizeof(ModestTnyMsgViewPrivate));
-
-
- signals[LINK_CLICKED_SIGNAL] =
- g_signal_new ("link_clicked",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(ModestTnyMsgViewClass, link_clicked),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
-
- signals[ATTACHMENT_CLICKED_SIGNAL] =
- g_signal_new ("attachment_clicked",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(ModestTnyMsgViewClass, attachment_clicked),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_INT);
-
-}
-
-static void
-modest_tny_msg_view_init (ModestTnyMsgView *obj)
-{
- ModestTnyMsgViewPrivate *priv;
-
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(obj);
-
- priv->msg = NULL;
- priv->gtkhtml = gtk_html_new();
-
- gtk_html_set_editable (GTK_HTML(priv->gtkhtml), FALSE);
- gtk_html_allow_selection (GTK_HTML(priv->gtkhtml), TRUE);
- gtk_html_set_caret_mode (GTK_HTML(priv->gtkhtml), FALSE);
- gtk_html_set_blocking (GTK_HTML(priv->gtkhtml), FALSE);
- gtk_html_set_images_blocking (GTK_HTML(priv->gtkhtml), FALSE);
-
- g_signal_connect (G_OBJECT(priv->gtkhtml), "link_clicked",
- G_CALLBACK(on_link_clicked), obj);
-
- g_signal_connect (G_OBJECT(priv->gtkhtml), "url_requested",
- G_CALLBACK(on_url_requested), obj);
-}
-
-
-static void
-modest_tny_msg_view_finalize (GObject *obj)
-{
- G_OBJECT_CLASS(parent_class)->finalize (obj);
-}
-
-
-GtkWidget*
-modest_tny_msg_view_new (const TnyMsgIface *msg)
-{
- GObject *obj;
- ModestTnyMsgView* self;
- ModestTnyMsgViewPrivate *priv;
-
- obj = G_OBJECT(g_object_new(MODEST_TYPE_TNY_MSG_VIEW, NULL));
- self = MODEST_TNY_MSG_VIEW(obj);
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE (self);
-
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- if (priv->gtkhtml)
- gtk_container_add (GTK_CONTAINER(obj), priv->gtkhtml);
-
- if (msg)
- modest_tny_msg_view_set_message (self, msg);
-
- return GTK_WIDGET(self);
-}
-
-
-static gboolean
-on_link_clicked (GtkWidget *widget, const gchar *uri, ModestTnyMsgView *msg_view)
-{
-
- int index;
-
- g_return_val_if_fail (msg_view, FALSE);
-
- /* is it an attachment? */
- if (g_str_has_prefix(uri, ATT_PREFIX)) {
-
- index = atoi (uri + strlen(ATT_PREFIX));
-
- if (index == 0) {
- /* index is 1-based, so 0 indicates an error */
- g_printerr ("modest: invalid attachment id: %s\n", uri);
- return FALSE;
- }
-
- g_signal_emit (G_OBJECT(msg_view), signals[ATTACHMENT_CLICKED_SIGNAL],
- 0, index);
- return FALSE;
- }
-
- g_signal_emit (G_OBJECT(msg_view), signals[LINK_CLICKED_SIGNAL], 0, uri);
-
- return FALSE;
-}
-
-
-static TnyMsgMimePartIface *
-find_cid_image (const TnyMsgIface *msg, const gchar *cid)
-{
- TnyMsgMimePartIface *part = NULL;
- const TnyListIface *parts;
- TnyIteratorIface *iter;
-
- g_return_val_if_fail (msg, NULL);
- g_return_val_if_fail (cid, NULL);
-
- parts = tny_msg_iface_get_parts ((TnyMsgIface*)msg); // FIXME: tinymail
- iter = tny_list_iface_create_iterator ((TnyListIface*)parts);
-
- while (!tny_iterator_iface_is_done(iter)) {
- const gchar *part_cid;
- part = TNY_MSG_MIME_PART_IFACE(tny_iterator_iface_current(iter));
- part_cid = tny_msg_mime_part_iface_get_content_id (part);
-
- if (part_cid && strcmp (cid, part_cid) == 0)
- break;
-
- part = NULL;
- tny_iterator_iface_next (iter);
- }
-
- g_object_unref (G_OBJECT(iter));
- return part;
-}
-
-
-static gboolean
-on_url_requested (GtkWidget *widget, const gchar *uri,
- GtkHTMLStream *stream,
- ModestTnyMsgView *msg_view)
-{
- ModestTnyMsgViewPrivate *priv;
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE (msg_view);
-
- if (g_str_has_prefix (uri, "cid:")) {
- /* +4 ==> skip "cid:" */
- const TnyMsgMimePartIface *part = find_cid_image (priv->msg, uri + 4);
- if (!part) {
- g_printerr ("modest: '%s' not found\n", uri + 4);
- gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
- } else {
- TnyStreamIface *tny_stream =
- TNY_STREAM_IFACE(modest_tny_stream_gtkhtml_new(stream));
- // FIXME: tinymail
- tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)part,
- tny_stream);
- gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
- }
- }
-
- return TRUE;
-}
-
-
-typedef struct {
- guint offset;
- guint len;
- const gchar* prefix;
-} url_match_t;
-
-
-
-/* render the attachments as hyperlinks in html */
-static gchar*
-attachments_as_html (ModestTnyMsgView *self, const TnyMsgIface *msg)
-{
- ModestTnyMsgViewPrivate *priv;
- GString *appendix;
- const TnyListIface *parts;
- TnyIteratorIface *iter;
- gchar *html;
- int index = 0;
-
- if (!msg)
- return NULL;
-
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE (self);
- parts = tny_msg_iface_get_parts ((TnyMsgIface*)msg);
- // FIXME: tinymail
- iter = tny_list_iface_create_iterator ((TnyListIface*)parts);
-
- appendix= g_string_new ("");
-
- while (!tny_iterator_iface_is_done(iter)) {
- TnyMsgMimePartIface *part;
-
- ++index; /* attachment numbers are 1-based */
-
- part = TNY_MSG_MIME_PART_IFACE(tny_iterator_iface_current (iter));
-
- if (tny_msg_mime_part_iface_is_attachment (part)) {
-
- const gchar *filename = tny_msg_mime_part_iface_get_filename(part);
- if (!filename)
- filename = _("attachment");
-
- g_string_append_printf (appendix, "<a href=\"%s%d\">%s</a> \n",
- ATT_PREFIX, index, filename);
- }
- tny_iterator_iface_next (iter);
- }
- g_object_unref (G_OBJECT(iter));
-
- if (appendix->len == 0)
- return g_string_free (appendix, TRUE);
-
- html = g_strdup_printf ("<strong>%s:</strong> %s\n<hr>",
- _("Attachments"), appendix->str);
- g_string_free (appendix, TRUE);
-
- return html;
-}
-
-
-
-static void
-hyperlinkify_plain_text (GString *txt)
-{
- GSList *cursor;
- GSList *match_list = get_url_matches (txt);
-
- /* we will work backwards, so the offsets stay valid */
- for (cursor = match_list; cursor; cursor = cursor->next) {
-
- url_match_t *match = (url_match_t*) cursor->data;
- gchar *url = g_strndup (txt->str + match->offset, match->len);
- gchar *repl = NULL; /* replacement */
-
- /* the prefix is NULL: use the one that is already there */
- repl = g_strdup_printf ("<a href=\"%s%s\">%s</a>",
- match->prefix ? match->prefix : "", url, url);
-
- /* replace the old thing with our hyperlink
- * replacement thing */
- g_string_erase (txt, match->offset, match->len);
- g_string_insert (txt, match->offset, repl);
-
- g_free (url);
- g_free (repl);
-
- g_free (cursor->data);
- }
-
- g_slist_free (match_list);
-}
-
-
-
-static gchar *
-convert_to_html (const gchar *data)
-{
- int i;
- gboolean first_space = TRUE;
- GString *html;
- gsize len;
-
- if (!data)
- return NULL;
-
- len = strlen (data);
- html = g_string_sized_new (len + 100); /* just a guess... */
-
- g_string_append_printf (html,
- "<html>"
- "<head>"
- "<meta http-equiv=\"content-type\""
- " content=\"text/html; charset=utf8\">"
- "</head>"
- "<body><tt>");
-
- /* replace with special html chars where needed*/
- for (i = 0; i != len; ++i) {
- char kar = data[i];
- switch (kar) {
-
- case 0: break; /* ignore embedded \0s */
- case '<' : g_string_append (html, "<"); break;
- case '>' : g_string_append (html, ">"); break;
- case '&' : g_string_append (html, """); break;
- case '\n': g_string_append (html, "<br>\n"); break;
- default:
- if (kar == ' ') {
- g_string_append (html, first_space ? " " : " ");
- first_space = FALSE;
- } else if (kar == '\t')
- g_string_append (html, " ");
- else {
- int charnum = 0;
- first_space = TRUE;
- /* optimization trick: accumulate 'normal' chars, then copy */
- do {
- kar = data [++charnum + i];
-
- } while ((i + charnum < len) &&
- (kar > '>' || (kar != '<' && kar != '>'
- && kar != '&' && kar != ' '
- && kar != '\n' && kar != '\t')));
- g_string_append_len (html, &data[i], charnum);
- i += (charnum - 1);
- }
- }
- }
-
- g_string_append (html, "</tt></body></html>");
- hyperlinkify_plain_text (html);
-
- return g_string_free (html, FALSE);
-}
-
-
-
-
-static gint
-cmp_offsets_reverse (const url_match_t *match1, const url_match_t *match2)
-{
- return match2->offset - match1->offset;
-}
-
-
-
-/*
- * check if the match is inside an existing match... */
-static void
-chk_partial_match (const url_match_t *match, int* offset)
-{
- if (*offset >= match->offset && *offset < match->offset + match->len)
- *offset = -1;
-}
-
-static GSList*
-get_url_matches (GString *txt)
-{
- regmatch_t rm;
- int rv, i, offset = 0;
- GSList *match_list = NULL;
-
- static UrlMatchPattern patterns[] = MAIL_VIEWER_URL_MATCH_PATTERNS;
- const size_t pattern_num = sizeof(patterns)/sizeof(UrlMatchPattern);
-
- /* initalize the regexps */
- for (i = 0; i != pattern_num; ++i) {
- patterns[i].preg = g_new0 (regex_t,1);
- g_assert(regcomp (patterns[i].preg, patterns[i].regex,
- REG_ICASE|REG_EXTENDED|REG_NEWLINE) == 0);
- }
- /* find all the matches */
- for (i = 0; i != pattern_num; ++i) {
- offset = 0;
- while (1) {
- int test_offset;
- if ((rv = regexec (patterns[i].preg, txt->str + offset, 1, &rm, 0)) != 0) {
- g_assert (rv == REG_NOMATCH); /* this should not happen */
- break; /* try next regexp */
- }
- if (rm.rm_so == -1)
- break;
-
- /* FIXME: optimize this */
- /* to avoid partial matches on something that was already found... */
- /* check_partial_match will put -1 in the data ptr if that is the case */
- test_offset = offset + rm.rm_so;
- g_slist_foreach (match_list, (GFunc)chk_partial_match, &test_offset);
-
- /* make a list of our matches (<offset, len, prefix> tupels)*/
- if (test_offset != -1) {
- url_match_t *match = g_new (url_match_t,1);
- match->offset = offset + rm.rm_so;
- match->len = rm.rm_eo - rm.rm_so;
- match->prefix = patterns[i].prefix;
- match_list = g_slist_prepend (match_list, match);
- }
- offset += rm.rm_eo;
- }
- }
-
- for (i = 0; i != pattern_num; ++i) {
- regfree (patterns[i].preg);
- g_free (patterns[i].preg);
- } /* don't free patterns itself -- it's static */
-
- /* now sort the list, so the matches are in reverse order of occurence.
- * that way, we can do the replacements starting from the end, so we don't need
- * to recalculate the offsets
- */
- match_list = g_slist_sort (match_list,
- (GCompareFunc)cmp_offsets_reverse);
- return match_list;
-}
-
-
-
-static gboolean
-set_html_message (ModestTnyMsgView *self, const TnyMsgMimePartIface *tny_body,
- const TnyMsgIface *msg)
-{
- gchar *html_attachments;
- TnyStreamIface *gtkhtml_stream;
- ModestTnyMsgViewPrivate *priv;
-
- g_return_val_if_fail (self, FALSE);
- g_return_val_if_fail (tny_body, FALSE);
-
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self);
-
- gtkhtml_stream =
- TNY_STREAM_IFACE(modest_tny_stream_gtkhtml_new
- (gtk_html_begin(GTK_HTML(priv->gtkhtml))));
-
- tny_stream_iface_reset (gtkhtml_stream);
-
- html_attachments = attachments_as_html(self, msg);
- if (html_attachments) {
- tny_stream_iface_write (gtkhtml_stream, html_attachments,
- strlen(html_attachments));
- tny_stream_iface_reset (gtkhtml_stream);
- g_free (html_attachments);
- }
-
- // FIXME: tinymail
- tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)tny_body,
- gtkhtml_stream);
-
- g_object_unref (G_OBJECT(gtkhtml_stream));
-
- return TRUE;
-}
-
-
-/* this is a hack --> we use the tny_text_buffer_stream to
- * get the message text, then write to gtkhtml 'by hand' */
-static gboolean
-set_text_message (ModestTnyMsgView *self, const TnyMsgMimePartIface *tny_body,
- const TnyMsgIface *msg)
-{
- GtkTextBuffer *buf;
- GtkTextIter begin, end;
- TnyStreamIface* txt_stream, *gtkhtml_stream;
- gchar *txt, *html_attachments;
- ModestTnyMsgViewPrivate *priv;
-
- g_return_val_if_fail (self, FALSE);
- g_return_val_if_fail (tny_body, FALSE);
-
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self);
-
- buf = gtk_text_buffer_new (NULL);
- txt_stream = TNY_STREAM_IFACE(tny_text_buffer_stream_new (buf));
-
- tny_stream_iface_reset (txt_stream);
-
- gtkhtml_stream =
- TNY_STREAM_IFACE(modest_tny_stream_gtkhtml_new
- (gtk_html_begin(GTK_HTML(priv->gtkhtml))));
-
- html_attachments = attachments_as_html(self, msg);
- if (html_attachments) {
- tny_stream_iface_write (gtkhtml_stream, html_attachments,
- strlen(html_attachments));
- tny_stream_iface_reset (gtkhtml_stream);
- g_free (html_attachments);
- }
-
- // FIXME: tinymail
- tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)tny_body,
- txt_stream);
- tny_stream_iface_reset (txt_stream);
-
- gtk_text_buffer_get_bounds (buf, &begin, &end);
- txt = gtk_text_buffer_get_text (buf, &begin, &end, FALSE);
- if (txt) {
- gchar *html = convert_to_html (txt);
- tny_stream_iface_write (gtkhtml_stream, html, strlen(html));
- tny_stream_iface_reset (gtkhtml_stream);
- g_free (txt);
- g_free (html);
- }
-
- g_object_unref (G_OBJECT(gtkhtml_stream));
- g_object_unref (G_OBJECT(txt_stream));
- g_object_unref (G_OBJECT(buf));
-
- return TRUE;
-}
-
-
-static gboolean
-set_empty_message (ModestTnyMsgView *self)
-{
- ModestTnyMsgViewPrivate *priv;
-
- g_return_val_if_fail (self, FALSE);
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self);
-
- gtk_html_load_from_string (priv->gtkhtml, "", 1);
-
- return TRUE;
-}
-
-
-gchar *
-modest_tny_msg_view_get_selected_text (ModestTnyMsgView *self)
-{
- ModestTnyMsgViewPrivate *priv;
- gchar *sel;
- GtkWidget *html;
- int len;
- GtkClipboard *clip;
-
- g_return_val_if_fail (self, NULL);
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self);
- html = priv->gtkhtml;
-
- /* I'm sure there is a better way to check for selected text */
- sel = gtk_html_get_selection_html(GTK_HTML(html), &len);
- if (!sel)
- return NULL;
-
- g_free(sel);
-
- clip = gtk_widget_get_clipboard(html, GDK_SELECTION_PRIMARY);
- return gtk_clipboard_wait_for_text(clip);
-}
-
-
-void
-modest_tny_msg_view_set_message (ModestTnyMsgView *self, const TnyMsgIface *msg)
-{
- TnyMsgMimePartIface *body;
- ModestTnyMsgViewPrivate *priv;
-
- g_return_if_fail (self);
-
- priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self);
-
- priv->msg = msg;
-
- if (!msg) {
- set_empty_message (self);
- return;
- }
-
- body = modest_tny_msg_actions_find_body_part (msg, TRUE);
- if (body) {
- if (tny_msg_mime_part_iface_content_type_is (body, "text/html"))
- set_html_message (self, body, msg);
- else
- set_text_message (self, body, msg);
- return;
- } else
- set_empty_message (self);
-}
+++ /dev/null
-/* 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.
- */
-
-
-/* modest-tny-msg-view.h */
-
-#ifndef __MODEST_TNY_MSG_VIEW_H__
-#define __MODEST_TNY_MSG_VIEW_H__
-
-
-#include <gtk/gtk.h>
-#include <tny-stream-iface.h>
-#include <tny-msg-iface.h>
-#include <tny-msg-mime-part-iface.h>
-
-#include "modest-conf.h"
-
-G_BEGIN_DECLS
-
-/* convenience macros */
-#define MODEST_TYPE_TNY_MSG_VIEW (modest_tny_msg_view_get_type())
-#define MODEST_TNY_MSG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_TNY_MSG_VIEW,ModestTnyMsgView))
-#define MODEST_TNY_MSG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_TNY_MSG_VIEW,ModestTnyMsgViewClass))
-#define MODEST_IS_TNY_MSG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_TNY_MSG_VIEW))
-#define MODEST_IS_TNY_MSG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_TNY_MSG_VIEW))
-#define MODEST_TNY_MSG_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_TNY_MSG_VIEW,ModestTnyMsgViewClass))
-
-typedef struct _ModestTnyMsgView ModestTnyMsgView;
-typedef struct _ModestTnyMsgViewClass ModestTnyMsgViewClass;
-
-struct _ModestTnyMsgView {
- GtkScrolledWindow parent;
-};
-
-struct _ModestTnyMsgViewClass {
- GtkScrolledWindowClass parent_class;
-
- void (*link_clicked) (GtkWidget *widget, const gchar* link, gpointer user_data);
- void (*attachment_clicked) (GtkWidget *widget, int index, gpointer user_data);
-};
-
-
-/**
- * modest_tny_msg_view_get_type
- *
- * get the GType for the this class
- *
- * Returns: the GType for this class
- */
-GType modest_tny_msg_view_get_type (void) G_GNUC_CONST;
-
-
-/**
- * modest_tny_msg_view_new
- * @tny_msg: a TnyMsgIface instance, or NULL
- *
- * create a new ModestTnyMsgView widget (a GtkScrolledWindow subclass),
- * and display the @tny_msg e-mail message in it. If @tny_msg is NULL,
- * then a blank page will be displayed
- *
- * Returns: a new ModestTnyMsgView widget, or NULL if there's an error
- */
-GtkWidget* modest_tny_msg_view_new (const TnyMsgIface *tny_msg);
-
-
-/**
- * modest_tny_msg_view_set_message
- * @self: a ModestTnyMsgView instance
- * @tny_msg: a TnyMsgIface instance, or NULL
- *
- * display the @tny_msg e-mail message. If @tny_msg is NULL,
- * then a blank page will be displayed
- * */
-void modest_tny_msg_view_set_message (ModestTnyMsgView *self,
- const TnyMsgIface *tny_msg);
-
-/**
- * modest_tny_msg_view_get_selected_text:
- * @self: a ModestTnyMsgView instance
- *
- * get the user selected part of the message
- *
- * Returns: a newly allocated string of the user's selection or NULL if nothing is selected
- */
-gchar * modest_tny_msg_view_get_selected_text (ModestTnyMsgView *self);
-
-G_END_DECLS
-
-#endif /* __MODEST_TNY_MSG_VIEW_H__ */
modest_tny_store_actions_update_folders (TnyStoreAccountIface *storage_account)
{
+// FIXME TODO: This results in failure on folder change.
+ /*
const TnyListIface* folders;
TnyIteratorIface* ifolders;
const TnyMsgFolderIface *cur_folder;
-#warning TODO: This results in failure on folder change.
-/* folders = tny_store_account_iface_get_folders (storage_account,
+
+ folders = tny_store_account_iface_get_folders (storage_account,
TNY_STORE_ACCOUNT_FOLDER_TYPE_SUBSCRIBED);
ifolders = tny_list_iface_create_iterator (folders);
#include <glib-object.h>
#include <gtk/gtkcontainer.h>
#include "modest-conf.h"
-#include "modest-tny-msg-view.h"
+#include "widgets/modest-msg-view.h"
G_BEGIN_DECLS
#include "modest-ui.h"
-#include "modest-tny-msg-view.h"
+#include "widgets/modest-msg-view.h"
#include "modest-viewer-window.h"
typedef struct _ModestViewerWindowPrivate ModestViewerWindowPrivate;
struct _ModestViewerWindowPrivate {
- ModestTnyMsgView *msg_view;
- gpointer user_data;
+ ModestMsgView *msg_view;
+ gpointer user_data;
};
#define MODEST_VIEWER_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
MODEST_TYPE_VIEWER_WINDOW, \
self = G_OBJECT(g_object_new(MODEST_TYPE_VIEWER_WINDOW, NULL));
priv = MODEST_VIEWER_WINDOW_GET_PRIVATE(self);
- msg_view = modest_tny_msg_view_new(msg);
+ msg_view = modest_msg_view_new(msg);
data = NULL;
w = GTK_WIDGET(modest_ui_new_viewer_window(ui, msg_view, msg, &data));
gtk_container_add(GTK_CONTAINER(self), w);
priv->user_data = data;
- priv->msg_view = MODEST_TNY_MSG_VIEW(msg_view);
+ priv->msg_view = MODEST_MSG_VIEW(msg_view);
return GTK_WIDGET(self);
}
}
-ModestTnyMsgView*
+ModestMsgView*
modest_viewer_window_get_tiny_msg_view(ModestViewerWindow *viewer_win)
{
ModestViewerWindowPrivate *priv;
g_return_val_if_fail (viewer_win, NULL);
-
+
priv = MODEST_VIEWER_WINDOW_GET_PRIVATE(viewer_win);
return priv->msg_view;
*
* Returns: the ModestTnyMsgView widget from the viewer instance
*/
-ModestTnyMsgView *modest_viewer_window_get_tiny_msg_view(ModestViewerWindow *viewer_win);
+ModestMsgView *modest_viewer_window_get_tiny_msg_view(ModestViewerWindow *viewer_win);
G_END_DECLS
static void modest_widget_factory_init (ModestWidgetFactory *obj);
static void modest_widget_factory_finalize (GObject *obj);
-static void on_folder_clicked (ModestTnyFolderTreeView *folder_view, TnyMsgFolderIface *folder,
- ModestWidgetFactory *self);
-static void on_message_selected (ModestTnyFolderTreeView *folder_view, TnyMsgIface *msg,
+static void on_folder_clicked (ModestFolderView *folder_view, TnyMsgFolderIface *folder,
+ ModestWidgetFactory *self);
+static void on_message_selected (ModestFolderView *folder_view, TnyMsgIface *msg,
ModestWidgetFactory *self);
/* list my signals */
ModestAccountMgr *account_mgr;
ModestConf *conf;
- ModestTnyHeaderTreeView *header_view;
- ModestTnyFolderTreeView *folder_view;
- ModestTnyMsgView *msg_preview;
+ ModestHeaderView *header_view;
+ ModestFolderView *folder_view;
+ ModestMsgView *msg_preview;
ModestAccountView *account_view;
gboolean auto_connect;
-ModestTnyFolderTreeView*
-modest_widget_factory_get_folder_tree_widget (ModestWidgetFactory *self)
+ModestFolderView*
+modest_widget_factory_get_folder_view (ModestWidgetFactory *self)
{
ModestWidgetFactoryPrivate *priv;
if (!priv->folder_view) {
priv->folder_view =
- MODEST_TNY_FOLDER_TREE_VIEW(modest_tny_folder_tree_view_new
- (TNY_ACCOUNT_STORE_IFACE(priv->account_store)));
+ MODEST_FOLDER_VIEW(modest_folder_view_new
+ (TNY_ACCOUNT_STORE_IFACE(priv->account_store)));
if (priv->folder_view && priv->auto_connect)
g_signal_connect (G_OBJECT(priv->folder_view), "folder_selected",
G_CALLBACK(on_folder_clicked), self);
}
-ModestTnyHeaderTreeView*
-modest_widget_factory_get_header_tree_widget (ModestWidgetFactory *self)
+ModestHeaderView*
+modest_widget_factory_get_header_view (ModestWidgetFactory *self)
{
ModestWidgetFactoryPrivate *priv;
if (!priv->header_view) {
priv->header_view =
- MODEST_TNY_HEADER_TREE_VIEW(modest_tny_header_tree_view_new
- (NULL, NULL,
- MODEST_TNY_HEADER_TREE_VIEW_STYLE_NORMAL));
+ MODEST_HEADER_VIEW(modest_header_view_new
+ (NULL, NULL,
+ MODEST_HEADER_VIEW_STYLE_NORMAL));
if (priv->header_view && priv->auto_connect)
g_signal_connect (G_OBJECT(priv->header_view), "message_selected",
G_CALLBACK(on_message_selected), self);
}
-ModestTnyMsgView*
-modest_widget_factory_get_msg_preview_widget (ModestWidgetFactory *self)
+ModestMsgView*
+modest_widget_factory_get_msg_preview (ModestWidgetFactory *self)
{
ModestWidgetFactoryPrivate *priv;
priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
if (!priv->msg_preview)
- priv->msg_preview =
- MODEST_TNY_MSG_VIEW(modest_tny_msg_view_new (NULL));
+ priv->msg_preview = MODEST_MSG_VIEW(modest_msg_view_new (NULL));
if (!priv->msg_preview)
g_printerr ("modest: cannot instantiate header view\n");
static void
-on_folder_clicked (ModestTnyFolderTreeView *folder_view, TnyMsgFolderIface *folder,
+on_folder_clicked (ModestFolderView *folder_view, TnyMsgFolderIface *folder,
ModestWidgetFactory *self)
{
ModestWidgetFactoryPrivate *priv;
priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
- modest_tny_header_tree_view_set_folder (priv->header_view, folder);
+ modest_header_view_set_folder (priv->header_view, folder);
}
static void
-on_message_selected (ModestTnyFolderTreeView *folder_view, TnyMsgIface *msg,
+on_message_selected (ModestFolderView *folder_view, TnyMsgIface *msg,
ModestWidgetFactory *self)
{
ModestWidgetFactoryPrivate *priv;
priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
- modest_tny_msg_view_set_message (priv->msg_preview, msg);
+ modest_msg_view_set_message (priv->msg_preview, msg);
}
ModestAccountView*
-modest_widget_factory_get_account_view_widget (ModestWidgetFactory *self)
+modest_widget_factory_get_account_view (ModestWidgetFactory *self)
{
ModestWidgetFactoryPrivate *priv;
if (!priv->account_view)
g_printerr ("modest: cannot create account view widget\n");
-
+
return priv->account_view;
}
#include <glib-object.h>
#include "modest-account-mgr.h"
#include "modest-tny-account-store.h"
-#include "modest-tny-header-tree-view.h"
-#include "modest-tny-folder-tree-view.h"
-#include "modest-tny-msg-view.h"
-#include "modest-account-view.h"
+#include "widgets/modest-header-view.h"
+#include "widgets/modest-folder-view.h"
+#include "widgets/modest-msg-view.h"
+#include "widgets/modest-account-view.h"
G_BEGIN_DECLS
ModestAccountMgr *account_mgr,
gboolean auto_connect);
/**
- * modest_widget_factory_get_folder_tree_widget
+ * modest_widget_factory_get_folder_view
* @self: a ModestWidgetFactory instance
*
* return the folder tree widget (ie. the widget with the list of folders);
*
* Returns: a folder tree view, or NULL in case of error
*/
-ModestTnyFolderTreeView* modest_widget_factory_get_folder_tree_widget (ModestWidgetFactory *self);
+ModestFolderView* modest_widget_factory_get_folder_view (ModestWidgetFactory *self);
/**
- * modest_widget_factory_get_header_tree_widget
+ * modest_widget_factory_get_header_view
* @self: a ModestWidgetFactory instance
*
* return the header tree widget (ie. the widget with the list of headers);
*
* Returns: a header tree view, or NULL in case of error
*/
-ModestTnyHeaderTreeView* modest_widget_factory_get_header_tree_widget (ModestWidgetFactory *self);
+ModestHeaderView* modest_widget_factory_get_header_view (ModestWidgetFactory *self);
/**
- * modest_widget_factory_get_header_tree_widget
+ * modest_widget_factory_get_msg_preview
* @self: a ModestWidgetFactory instance
*
* return the message preview widget (ie. the widget with shows the currently selected message);
*
* Returns: a header tree view, or NULL in case of error
*/
-ModestTnyMsgView* modest_widget_factory_get_msg_preview_widget (ModestWidgetFactory *self);
-
+ModestMsgView* modest_widget_factory_get_msg_preview (ModestWidgetFactory *self);
/**
- * modest_widget_factory_get_account_view_widget
+ * modest_widget_factory_get_account_view
* @self: a ModestWidgetFactory instance
*
* return an account view widget (ie. the widget that shows a list of accounts)
*
* Returns: the account view, or NULL in case of error
*/
-ModestAccountView* modest_widget_factory_get_account_view_widget (ModestWidgetFactory *self);
-
-
-
+ModestAccountView* modest_widget_factory_get_account_view (ModestWidgetFactory *self);
G_END_DECLS
--- /dev/null
+/* 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.
+ */
+
+#include "modest-account-view.h"
+/* include other impl specific header files */
+
+/* 'private'/'protected' functions */
+static void modest_account_view_class_init (ModestAccountViewClass *klass);
+static void modest_account_view_init (ModestAccountView *obj);
+static void modest_account_view_finalize (GObject *obj);
+
+
+enum _AccountViewColumns {
+ ENABLED_COLUMN,
+ NAME_COLUMN,
+ PROTO_COLUMN,
+ N_COLUMNS
+};
+typedef enum _AccountViewColumns AccountViewColumns;
+
+
+/* list my signals */
+enum {
+ /* MY_SIGNAL_1, */
+ /* MY_SIGNAL_2, */
+ LAST_SIGNAL
+};
+
+typedef struct _ModestAccountViewPrivate ModestAccountViewPrivate;
+struct _ModestAccountViewPrivate {
+ ModestAccountMgr *account_mgr;
+};
+#define MODEST_ACCOUNT_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
+ MODEST_TYPE_ACCOUNT_VIEW, \
+ ModestAccountViewPrivate))
+/* globals */
+static GtkTreeViewClass *parent_class = NULL;
+
+/* uncomment the following if you have defined any signals */
+/* static guint signals[LAST_SIGNAL] = {0}; */
+
+GType
+modest_account_view_get_type (void)
+{
+ static GType my_type = 0;
+ if (!my_type) {
+ static const GTypeInfo my_info = {
+ sizeof(ModestAccountViewClass),
+ NULL, /* base init */
+ NULL, /* base finalize */
+ (GClassInitFunc) modest_account_view_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof(ModestAccountView),
+ 1, /* n_preallocs */
+ (GInstanceInitFunc) modest_account_view_init,
+ };
+ my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
+ "ModestAccountView",
+ &my_info, 0);
+ }
+ return my_type;
+}
+
+static void
+modest_account_view_class_init (ModestAccountViewClass *klass)
+{
+ GObjectClass *gobject_class;
+ gobject_class = (GObjectClass*) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ gobject_class->finalize = modest_account_view_finalize;
+
+ g_type_class_add_private (gobject_class, sizeof(ModestAccountViewPrivate));
+
+ /* signal definitions go here, e.g.: */
+/* signals[MY_SIGNAL_1] = */
+/* g_signal_new ("my_signal_1",....); */
+/* signals[MY_SIGNAL_2] = */
+/* g_signal_new ("my_signal_2",....); */
+/* etc. */
+}
+
+static void
+modest_account_view_init (ModestAccountView *obj)
+{
+ ModestAccountViewPrivate *priv;
+
+ priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(obj);
+
+ priv->account_mgr = NULL;
+}
+
+static void
+modest_account_view_finalize (GObject *obj)
+{
+ ModestAccountViewPrivate *priv;
+
+ priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(obj);
+
+ if (priv->account_mgr) {
+ g_object_unref (G_OBJECT(priv->account_mgr));
+ priv->account_mgr = NULL;
+ }
+}
+
+
+
+static void
+update_account_view (ModestAccountMgr *account_mgr, ModestAccountView *view)
+{
+ GSList *account_names, *cursor;
+ GtkListStore *model;
+
+ model = GTK_LIST_STORE(gtk_tree_view_get_model (GTK_TREE_VIEW(view)));
+ gtk_list_store_clear (model);
+
+ cursor = account_names =
+ modest_account_mgr_account_names (account_mgr, NULL);
+
+ while (cursor) {
+ gchar *proto = NULL;
+ gchar *store, *account_name;
+ gboolean enabled;
+
+ account_name = (gchar*)cursor->data;
+
+ store = modest_account_mgr_get_string (account_mgr,
+ account_name,
+ MODEST_ACCOUNT_STORE_ACCOUNT,
+ FALSE, NULL);
+ if (store) {
+ proto = modest_account_mgr_get_string (account_mgr,
+ store,
+ MODEST_ACCOUNT_PROTO,
+ TRUE, NULL);
+ g_free(store);
+ }
+
+ enabled = modest_account_mgr_account_get_enabled (account_mgr,
+ account_name,
+ FALSE);
+ gtk_list_store_insert_with_values (
+ model, NULL, 0,
+ ENABLED_COLUMN, enabled,
+ NAME_COLUMN, account_name,
+ PROTO_COLUMN, proto,
+ -1);
+
+ g_free (account_name);
+ g_free (proto);
+
+ cursor = cursor->next;
+ }
+ g_slist_free (account_names);
+}
+
+
+static void
+on_account_changed (ModestAccountMgr *account_mgr,
+ const gchar* account, const gchar* key,
+ gboolean server_account, ModestAccountView *self)
+{
+ ModestAccountViewPrivate *priv;
+ priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(self);
+
+ update_account_view (account_mgr, self);
+}
+
+
+static void
+on_account_removed (ModestAccountMgr *account_mgr,
+ const gchar* account, gboolean server_account,
+ gpointer user_data)
+{
+ on_account_changed (account_mgr, account, NULL, server_account, user_data);
+}
+
+
+
+
+static void
+on_account_enable_toggled (GtkCellRendererToggle *cell_renderer, gchar *path,
+ ModestAccountView *self)
+{
+ GtkTreeIter iter;
+ ModestAccountViewPrivate *priv;
+ GtkTreeModel *model;
+ gchar *account_name;
+ gboolean enabled;
+
+ priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(self);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW(self));
+
+ if (!gtk_tree_model_get_iter_from_string (model, &iter, path)) {
+ g_printerr ("modest: cannot find iterator\n");
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter,
+ ENABLED_COLUMN, &enabled,
+ NAME_COLUMN, &account_name,
+ -1);
+
+ /* toggle enabled / disabled */
+ modest_account_mgr_account_set_enabled (priv->account_mgr, account_name,
+ FALSE, !enabled);
+ g_free (account_name);
+}
+
+
+static void
+init_view (ModestAccountView *self)
+{
+ ModestAccountViewPrivate *priv;
+ GtkTreeSelection *sel;
+ GtkCellRenderer *renderer;
+ GtkListStore *model;
+
+ priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(self);
+
+ model = gtk_list_store_new (3,
+ G_TYPE_BOOLEAN, /* checkbox */
+ G_TYPE_STRING, /* account name */
+ G_TYPE_STRING); /* account type (pop, imap,...) */
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW(self), GTK_TREE_MODEL(model));
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ g_object_set (G_OBJECT(renderer), "activatable", TRUE,"radio", FALSE, NULL);
+
+ g_signal_connect (G_OBJECT(renderer), "toggled",
+ G_CALLBACK(on_account_enable_toggled),
+ self);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW(self),
+ gtk_tree_view_column_new_with_attributes (
+ _("Enabled"), renderer,
+ "active", ENABLED_COLUMN, NULL));
+ gtk_tree_view_append_column (GTK_TREE_VIEW(self),
+ gtk_tree_view_column_new_with_attributes (
+ _("Account"),
+ gtk_cell_renderer_text_new (),
+ "text", NAME_COLUMN, NULL));
+ gtk_tree_view_append_column (GTK_TREE_VIEW(self),
+ gtk_tree_view_column_new_with_attributes (
+ _("Type"),
+ gtk_cell_renderer_text_new (),
+ "text", PROTO_COLUMN, NULL));
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
+
+ g_signal_connect (G_OBJECT(priv->account_mgr),
+ "account_removed",
+ G_CALLBACK(on_account_removed), self);
+ g_signal_connect (G_OBJECT(priv->account_mgr),
+ "account_changed",
+ G_CALLBACK(on_account_changed), self);
+}
+
+
+
+GtkWidget*
+modest_account_view_new (ModestAccountMgr *account_mgr)
+{
+ GObject *obj;
+ ModestAccountViewPrivate *priv;
+
+ g_return_val_if_fail (account_mgr, NULL);
+
+ obj = g_object_new(MODEST_TYPE_ACCOUNT_VIEW, NULL);
+ priv = MODEST_ACCOUNT_VIEW_GET_PRIVATE(obj);
+
+ g_object_ref (G_OBJECT(account_mgr));
+ priv->account_mgr = account_mgr;
+
+ init_view (MODEST_ACCOUNT_VIEW (obj));
+
+ return GTK_WIDGET(obj);
+}
+
--- /dev/null
+/* 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_ACCOUNT_VIEW_H__
+#define __MODEST_ACCOUNT_VIEW_H__
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <modest-account-mgr.h>
+
+G_BEGIN_DECLS
+
+/* convenience macros */
+#define MODEST_TYPE_ACCOUNT_VIEW (modest_account_view_get_type())
+#define MODEST_ACCOUNT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_ACCOUNT_VIEW,ModestAccountView))
+#define MODEST_ACCOUNT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_ACCOUNT_VIEW,GtkTreeView))
+#define MODEST_IS_ACCOUNT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_ACCOUNT_VIEW))
+#define MODEST_IS_ACCOUNT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_ACCOUNT_VIEW))
+#define MODEST_ACCOUNT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_ACCOUNT_VIEW,ModestAccountViewClass))
+
+typedef struct _ModestAccountView ModestAccountView;
+typedef struct _ModestAccountViewClass ModestAccountViewClass;
+
+struct _ModestAccountView {
+ GtkTreeView parent;
+ /* insert public members, if any */
+};
+
+struct _ModestAccountViewClass {
+ GtkTreeViewClass parent_class;
+ /* insert signal callback declarations, eg. */
+ /* void (* my_event) (ModestAccountView* obj); */
+};
+
+/* member functions */
+GType modest_account_view_get_type (void) G_GNUC_CONST;
+
+
+
+GtkWidget* modest_account_view_new (ModestAccountMgr *account_mgr);
+
+G_END_DECLS
+
+#endif /* __MODEST_ACCOUNT_VIEW_H__ */
+
--- /dev/null
+/* 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.
+ */
+
+#include <glib/gi18n.h>
+#include <string.h>
+
+#include <tny-account-tree-model.h>
+#include <tny-account-store-iface.h>
+#include <tny-account-iface.h>
+#include <tny-msg-folder-iface.h>
+#include <tny-summary-window-iface.h>
+#include <modest-icon-names.h>
+#include "modest-icon-factory.h"
+
+#include "modest-folder-view.h"
+
+
+/* 'private'/'protected' functions */
+static void modest_folder_view_class_init (ModestFolderViewClass *klass);
+static void modest_folder_view_init (ModestFolderView *obj);
+static void modest_folder_view_finalize (GObject *obj);
+
+static gboolean update_model (ModestFolderView *self,TnyAccountStoreIface *iface);
+static gboolean update_model_empty (ModestFolderView *self);
+
+static void selection_changed (GtkTreeSelection *sel, gpointer data);
+
+enum {
+ FOLDER_SELECTED_SIGNAL,
+ LAST_SIGNAL
+};
+
+typedef struct _ModestFolderViewPrivate ModestFolderViewPrivate;
+struct _ModestFolderViewPrivate {
+
+ TnyAccountStoreIface *tny_account_store;
+ TnyMsgFolderIface *cur_folder;
+ gboolean view_is_empty;
+
+ GMutex *lock;
+};
+#define MODEST_FOLDER_VIEW_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), \
+ MODEST_TYPE_FOLDER_VIEW, \
+ ModestFolderViewPrivate))
+/* globals */
+static GObjectClass *parent_class = NULL;
+
+static guint signals[LAST_SIGNAL] = {0};
+
+GType
+modest_folder_view_get_type (void)
+{
+ static GType my_type = 0;
+ if (!my_type) {
+ static const GTypeInfo my_info = {
+ sizeof(ModestFolderViewClass),
+ NULL, /* base init */
+ NULL, /* base finalize */
+ (GClassInitFunc) modest_folder_view_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof(ModestFolderView),
+ 1, /* n_preallocs */
+ (GInstanceInitFunc) modest_folder_view_init,
+ };
+
+ my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
+ "ModestFolderView",
+ &my_info, 0);
+ }
+ return my_type;
+}
+
+static void
+modest_folder_view_class_init (ModestFolderViewClass *klass)
+{
+ GObjectClass *gobject_class;
+ gobject_class = (GObjectClass*) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ gobject_class->finalize = modest_folder_view_finalize;
+
+ klass->update_model = modest_folder_view_update_model;
+
+ g_type_class_add_private (gobject_class,
+ sizeof(ModestFolderViewPrivate));
+
+ signals[FOLDER_SELECTED_SIGNAL] =
+ g_signal_new ("folder_selected",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ModestFolderViewClass,
+ folder_selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+}
+
+
+
+static void
+text_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
+{
+ GObject *rendobj;
+ gchar *fname;
+ gint unread;
+ TnyMsgFolderType type;
+
+ gtk_tree_model_get (tree_model, iter,
+ TNY_ACCOUNT_TREE_MODEL_NAME_COLUMN, &fname,
+ TNY_ACCOUNT_TREE_MODEL_TYPE_COLUMN, &type,
+ TNY_ACCOUNT_TREE_MODEL_UNREAD_COLUMN, &unread, -1);
+ rendobj = G_OBJECT(renderer);
+
+ if (unread > 0) {
+ gchar *folder_title = g_strdup_printf ("%s (%d)", fname, unread);
+ g_object_set (rendobj,"text", folder_title, "weight", 800, NULL);
+ g_free (folder_title);
+ } else
+ g_object_set (rendobj,"text", fname, "weight", 400, NULL);
+
+ g_free (fname);
+}
+
+/* FIXME: move these to TnyMail */
+enum {
+
+ TNY_MSG_FOLDER_TYPE_NOTES = TNY_MSG_FOLDER_TYPE_SENT + 1, /* urgh */
+ TNY_MSG_FOLDER_TYPE_DRAFTS,
+ TNY_MSG_FOLDER_TYPE_CONTACTS,
+ TNY_MSG_FOLDER_TYPE_CALENDAR
+};
+
+static TnyMsgFolderType
+guess_folder_type (const gchar* name)
+{
+ TnyMsgFolderType type;
+ gchar *folder;
+
+ g_return_val_if_fail (name, TNY_MSG_FOLDER_TYPE_NORMAL);
+
+ type = TNY_MSG_FOLDER_TYPE_NORMAL;
+ folder = g_utf8_strdown (name, strlen(name));
+
+ if (strcmp (folder, "inbox") == 0 ||
+ strcmp (folder, _("inbox")) == 0)
+ type = TNY_MSG_FOLDER_TYPE_INBOX;
+ else if (strcmp (folder, "outbox") == 0 ||
+ strcmp (folder, _("outbox")) == 0)
+ type = TNY_MSG_FOLDER_TYPE_OUTBOX;
+ else if (g_str_has_prefix(folder, "junk") ||
+ g_str_has_prefix(folder, _("junk")))
+ type = TNY_MSG_FOLDER_TYPE_JUNK;
+ else if (g_str_has_prefix(folder, "trash") ||
+ g_str_has_prefix(folder, _("trash")))
+ type = TNY_MSG_FOLDER_TYPE_JUNK;
+ else if (g_str_has_prefix(folder, "sent") ||
+ g_str_has_prefix(folder, _("sent")))
+ type = TNY_MSG_FOLDER_TYPE_SENT;
+
+ /* these are not *really* TNY_ types */
+ else if (g_str_has_prefix(folder, "draft") ||
+ g_str_has_prefix(folder, _("draft")))
+ type = TNY_MSG_FOLDER_TYPE_DRAFTS;
+ else if (g_str_has_prefix(folder, "notes") ||
+ g_str_has_prefix(folder, _("notes")))
+ type = TNY_MSG_FOLDER_TYPE_NOTES;
+ else if (g_str_has_prefix(folder, "contacts") ||
+ g_str_has_prefix(folder, _("contacts")))
+ type = TNY_MSG_FOLDER_TYPE_CONTACTS;
+ else if (g_str_has_prefix(folder, "calendar") ||
+ g_str_has_prefix(folder, _("calendar")))
+ type = TNY_MSG_FOLDER_TYPE_CALENDAR;
+
+ g_free (folder);
+ return type;
+}
+
+
+static void
+icon_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
+{
+ GObject *rendobj;
+ GdkPixbuf *pixbuf;
+ TnyMsgFolderType type;
+ gchar *fname = NULL;
+ gint unread;
+
+ rendobj = G_OBJECT(renderer);
+ gtk_tree_model_get (tree_model, iter,
+ TNY_ACCOUNT_TREE_MODEL_TYPE_COLUMN, &type,
+ TNY_ACCOUNT_TREE_MODEL_NAME_COLUMN, &fname,
+ TNY_ACCOUNT_TREE_MODEL_UNREAD_COLUMN, &unread, -1);
+ rendobj = G_OBJECT(renderer);
+
+ if (type == TNY_MSG_FOLDER_TYPE_NORMAL)
+ type = guess_folder_type (fname);
+
+ if (fname);
+ g_free (fname);
+
+ switch (type) {
+ case TNY_MSG_FOLDER_TYPE_INBOX:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_INBOX);
+ break;
+ case TNY_MSG_FOLDER_TYPE_OUTBOX:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_OUTBOX);
+ break;
+ case TNY_MSG_FOLDER_TYPE_JUNK:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_JUNK);
+ break;
+ case TNY_MSG_FOLDER_TYPE_SENT:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_SENT);
+ break;
+ case TNY_MSG_FOLDER_TYPE_DRAFTS:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_DRAFTS);
+ break;
+ case TNY_MSG_FOLDER_TYPE_NOTES:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_NOTES);
+ break;
+ case TNY_MSG_FOLDER_TYPE_CALENDAR:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CALENDAR);
+ break;
+ case TNY_MSG_FOLDER_TYPE_CONTACTS:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CONTACTS);
+ break;
+ case TNY_MSG_FOLDER_TYPE_NORMAL:
+ default:
+ pixbuf = modest_icon_factory_get_icon (MODEST_FOLDER_ICON_NORMAL);
+ break;
+ }
+
+ g_object_set (rendobj,
+ "pixbuf-expander-open",
+ modest_icon_factory_get_icon (MODEST_FOLDER_ICON_OPEN),
+ "pixbuf-expander-closed",
+ modest_icon_factory_get_icon (MODEST_FOLDER_ICON_CLOSED),
+ "pixbuf", pixbuf,
+ NULL);
+}
+
+static void
+modest_folder_view_init (ModestFolderView *obj)
+{
+ ModestFolderViewPrivate *priv;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *sel;
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE(obj);
+
+ priv->view_is_empty = TRUE;
+ priv->tny_account_store = NULL;
+ priv->cur_folder = NULL;
+
+ priv->lock = g_mutex_new ();
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column,
+ _("All Mail Folders"));
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW(obj),
+ column);
+
+ renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer,
+ icon_cell_data, NULL, NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer,
+ text_cell_data, NULL, NULL);
+
+ sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(obj));
+ gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE);
+
+ gtk_tree_view_column_set_spacing (column, 2);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ gtk_tree_view_column_set_fixed_width (column, TRUE);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(obj), TRUE);
+ gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(obj), FALSE);
+
+}
+
+
+static void
+modest_folder_view_finalize (GObject *obj)
+{
+ ModestFolderViewPrivate *priv;
+
+ g_return_if_fail (obj);
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE(obj);
+ if (priv->tny_account_store) {
+ g_object_unref (G_OBJECT(priv->tny_account_store));
+ priv->tny_account_store = NULL;
+ }
+
+
+ if (priv->lock) {
+ g_mutex_free (priv->lock);
+ priv->lock = NULL;
+ }
+
+ G_OBJECT_CLASS(parent_class)->finalize (obj);
+}
+
+
+static void
+on_accounts_update (TnyAccountStoreIface *account_store, const gchar *account,
+ gpointer user_data)
+{
+ update_model_empty (MODEST_FOLDER_VIEW(user_data));
+
+ if (!update_model (MODEST_FOLDER_VIEW(user_data), account_store))
+ g_printerr ("modest: failed to update model for changes in '%s'",
+ account);
+}
+
+
+GtkWidget*
+modest_folder_view_new (TnyAccountStoreIface *account_store)
+{
+ GObject *self;
+ ModestFolderViewPrivate *priv;
+ GtkTreeSelection *sel;
+
+ self = G_OBJECT(g_object_new(MODEST_TYPE_FOLDER_VIEW, NULL));
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
+
+ g_return_val_if_fail (account_store, NULL);
+
+ if (!update_model (MODEST_FOLDER_VIEW(self), account_store))
+ g_printerr ("modest: failed to update model");
+
+ g_signal_connect (G_OBJECT(account_store), "update_accounts",
+ G_CALLBACK (on_accounts_update), self);
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
+ g_signal_connect (sel, "changed",
+ G_CALLBACK(selection_changed), self);
+
+ return GTK_WIDGET(self);
+}
+
+
+
+
+static gboolean
+update_model_empty (ModestFolderView *self)
+{
+ GtkTreeIter iter;
+ GtkTreeStore *store;
+ ModestFolderViewPrivate *priv;
+
+ g_return_val_if_fail (self, FALSE);
+
+ store = gtk_tree_store_new (1, G_TYPE_STRING);
+ gtk_tree_store_append (store, &iter, NULL);
+
+ gtk_tree_store_set (store, &iter, 0,
+ _("(empty)"), -1);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW(self),
+ GTK_TREE_MODEL(store));
+ g_object_unref (store);
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
+ priv->view_is_empty = TRUE;
+
+ return TRUE;
+}
+
+
+static gboolean
+update_model (ModestFolderView *self, TnyAccountStoreIface *account_store)
+{
+ ModestFolderViewPrivate *priv;
+ TnyListIface *account_list;
+ GtkTreeModel *model, *sortable;
+
+ g_return_val_if_fail (account_store, FALSE);
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE(self);
+
+ model = GTK_TREE_MODEL(tny_account_tree_model_new ());
+ account_list = TNY_LIST_IFACE(model);
+
+ update_model_empty (self); /* cleanup */
+ priv->view_is_empty = TRUE;
+
+ tny_account_store_iface_get_accounts (account_store, account_list,
+ TNY_ACCOUNT_STORE_IFACE_STORE_ACCOUNTS);
+ if (!account_list) /* no store accounts found */
+ return TRUE;
+
+ sortable = gtk_tree_model_sort_new_with_model (model);
+ gtk_tree_view_set_model (GTK_TREE_VIEW(self), sortable);
+
+ priv->view_is_empty = FALSE;
+ g_object_unref (model);
+
+ return TRUE;
+}
+
+
+void
+selection_changed (GtkTreeSelection *sel, gpointer user_data)
+{
+ GtkTreeModel *model;
+ TnyMsgFolderIface *folder = NULL;
+ GtkTreeIter iter;
+ ModestFolderView *tree_view;
+ ModestFolderViewPrivate *priv;
+
+ g_return_if_fail (sel);
+ g_return_if_fail (user_data);
+
+ priv = MODEST_FOLDER_VIEW_GET_PRIVATE(user_data);
+
+ /* is_empty means that there is only the 'empty' item */
+ if (priv->view_is_empty)
+ return;
+
+ /* folder was _un_selected if true */
+ if (!gtk_tree_selection_get_selected (sel, &model, &iter)) {
+ priv->cur_folder = NULL;
+ return;
+ }
+
+ tree_view = MODEST_FOLDER_VIEW (user_data);
+
+ gtk_tree_model_get (model, &iter,
+ TNY_ACCOUNT_TREE_MODEL_INSTANCE_COLUMN,
+ &folder, -1);
+
+ if (priv->cur_folder)
+ tny_msg_folder_iface_expunge (priv->cur_folder);
+ priv->cur_folder = folder;
+
+ /* folder will not be defined if you click eg. on the root node */
+ if (folder)
+ g_signal_emit (G_OBJECT(tree_view), signals[FOLDER_SELECTED_SIGNAL], 0,
+ folder);
+}
+
+
+gboolean
+modest_folder_view_update_model(ModestFolderView *self,
+ TnyAccountStoreIface *iface)
+{
+ g_return_val_if_fail (MODEST_IS_FOLDER_VIEW (self), FALSE);
+
+ return update_model (self, iface);
+}
--- /dev/null
+/* 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_FOLDER_VIEW_H__
+#define __MODEST_FOLDER_VIEW_H__
+
+#include <tny-account-tree-model.h>
+#include <tny-account-store-iface.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* convenience macros */
+#define MODEST_TYPE_FOLDER_VIEW (modest_folder_view_get_type())
+#define MODEST_FOLDER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_FOLDER_VIEW,ModestFolderView))
+#define MODEST_FOLDER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_FOLDER_VIEW,ModestFolderViewClass))
+#define MODEST_IS_FOLDER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_FOLDER_VIEW))
+#define MODEST_IS_FOLDER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_FOLDER_VIEW))
+#define MODEST_FOLDER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_FOLDER_VIEW,ModestFolderViewClass))
+
+typedef struct _ModestFolderView ModestFolderView;
+typedef struct _ModestFolderViewClass ModestFolderViewClass;
+
+struct _ModestFolderView {
+ GtkTreeView parent;
+ /* insert public members, if any */
+};
+
+struct _ModestFolderViewClass {
+ GtkTreeViewClass parent_class;
+
+ /* emitted when a folder is clicked */
+ void (*folder_selected) (ModestFolderView* self,
+ TnyMsgFolderIface *folder,
+ gpointer user_data);
+
+ gboolean (*update_model) (ModestFolderView *self,
+ TnyAccountStoreIface *iface);
+
+};
+
+
+/**
+ * modest_folder_view_get_type:
+ *
+ * get the GType for ModestFolderView
+ *
+ * Returns: the GType
+ */
+GType modest_folder_view_get_type (void) G_GNUC_CONST;
+
+
+/**
+ * modest_folder_view_new:
+ * @iface: a TnyAccountStoreIface object
+ *
+ * create a new ModestFolderView instance, based on an account store
+ *
+ * Returns: a new GtkWidget (a GtkTreeView-subclass)
+ */
+GtkWidget* modest_folder_view_new (TnyAccountStoreIface *iface);
+
+
+/**
+ * modest_folder_view_is_empty:
+ * @self: a ModestFolderView instance
+ *
+ * check to see of the view is empty. Note that when it is empty,
+ * there will still be one item, telling "(empty)" or similar
+ *
+ * Returns: TRUE if the tree view is empty, FALSE otherwise
+ */
+gboolean modest_folder_view_is_empty (ModestFolderView *self);
+
+
+/**
+ * modest_folder_view_update_model:
+ * @self: a #ModestFolderView instance
+ * @iface: a #TnyAccountStoreIface instance
+ *
+ * Update the thee model from a given account store.
+ *
+ * Returns: TRUE on success, FALSE otherwise
+ */
+gboolean modest_folder_view_update_model(ModestFolderView *self,
+ TnyAccountStoreIface *iface);
+
+
+G_END_DECLS
+
+#endif /* __MODEST_FOLDER_VIEW_H__ */
+
--- /dev/null
+/* 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.
+ */
+
+
+/* modest-tny-header-tree-view.c */
+
+#include <glib/gi18n.h>
+#include "modest-header-view.h"
+#include <tny-list-iface.h>
+#include <string.h>
+#include <modest-marshal.h>
+
+#include <modest-icon-names.h>
+#include "modest-icon-factory.h"
+
+static void modest_header_view_class_init (ModestHeaderViewClass *klass);
+static void modest_header_view_init (ModestHeaderView *obj);
+static void modest_header_view_finalize (GObject *obj);
+
+static void on_selection_changed (GtkTreeSelection *sel, gpointer user_data);
+//static void on_column_clicked (GtkTreeViewColumn *treeviewcolumn, gpointer user_data);
+static gboolean refresh_folder_finish_status_update (gpointer user_data);
+
+enum {
+ MESSAGE_SELECTED_SIGNAL,
+ STATUS_UPDATE_SIGNAL,
+ LAST_SIGNAL
+};
+
+typedef struct _ModestHeaderViewPrivate ModestHeaderViewPrivate;
+struct _ModestHeaderViewPrivate {
+
+ TnyMsgFolderIface *tny_msg_folder;
+ TnyListIface *headers;
+
+ gint status_id;
+ GSList *columns;
+
+ GMutex *lock;
+
+ ModestHeaderViewStyle style;
+};
+#define MODEST_HEADER_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
+ MODEST_TYPE_HEADER_VIEW, \
+ ModestHeaderViewPrivate))
+/* globals */
+static GObjectClass *parent_class = NULL;
+
+/* uncomment the following if you have defined any signals */
+static guint signals[LAST_SIGNAL] = {0};
+
+GType
+modest_header_view_get_type (void)
+{
+ static GType my_type = 0;
+ if (!my_type) {
+ static const GTypeInfo my_info = {
+ sizeof(ModestHeaderViewClass),
+ NULL, /* base init */
+ NULL, /* base finalize */
+ (GClassInitFunc) modest_header_view_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof(ModestHeaderView),
+ 1, /* n_preallocs */
+ (GInstanceInitFunc) modest_header_view_init,
+ };
+ my_type = g_type_register_static (GTK_TYPE_TREE_VIEW,
+ "ModestHeaderView",
+ &my_info, 0);
+ }
+ return my_type;
+}
+
+static void
+modest_header_view_class_init (ModestHeaderViewClass *klass)
+{
+ GObjectClass *gobject_class;
+ gobject_class = (GObjectClass*) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ gobject_class->finalize = modest_header_view_finalize;
+
+ g_type_class_add_private (gobject_class, sizeof(ModestHeaderViewPrivate));
+
+ signals[MESSAGE_SELECTED_SIGNAL] =
+ g_signal_new ("message_selected",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ModestHeaderViewClass,message_selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ signals[STATUS_UPDATE_SIGNAL] =
+ g_signal_new ("status_update",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ModestHeaderViewClass,message_selected),
+ NULL, NULL,
+ modest_marshal_VOID__STRING_INT,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+}
+
+
+
+
+
+static void
+msgtype_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
+{
+ TnyMsgHeaderFlags flags;
+ GdkPixbuf *pixbuf = NULL;
+
+ gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
+ &flags, -1);
+
+ if (flags & TNY_MSG_HEADER_FLAG_DELETED)
+ pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_DELETED);
+ else if (flags & TNY_MSG_HEADER_FLAG_SEEN)
+ pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_READ);
+ else
+ pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_UNREAD);
+
+ g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL);
+}
+
+static void
+attach_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
+{
+ TnyMsgHeaderFlags flags;
+ GdkPixbuf *pixbuf = NULL;
+
+ gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
+ &flags, -1);
+
+ if (flags & TNY_MSG_HEADER_FLAG_ATTACHMENTS)
+ pixbuf = modest_icon_factory_get_icon (MODEST_HEADER_ICON_ATTACH);
+
+ g_object_set (G_OBJECT (renderer), "pixbuf", pixbuf, NULL);
+}
+
+
+static void
+header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
+{
+ TnyMsgHeaderFlags flags;
+
+ gtk_tree_model_get (tree_model, iter, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
+ &flags, -1);
+
+ g_object_set (G_OBJECT(renderer),
+ "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800,
+ "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ?
+ PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
+ NULL);
+}
+
+
+
+/* try to make a shorter display address; changes it arg in-place */
+static gchar*
+display_address (gchar *address)
+{
+ gchar *cursor;
+
+ if (!address)
+ return NULL;
+
+ /* simplistic --> remove <email@address> from display name */
+ cursor = g_strstr_len (address, strlen(address), "<");
+ if (cursor)
+ cursor[0]='\0';
+
+ /* simplistic --> remove (bla bla) from display name */
+ cursor = g_strstr_len (address, strlen(address), "(");
+ if (cursor)
+ cursor[0]='\0';
+
+ return address;
+}
+
+
+
+static void
+sender_receiver_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gboolean is_sender)
+{
+ TnyMsgHeaderFlags flags;
+ gchar *address;
+ gint sender_receiver_col;
+
+ if (is_sender)
+ sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN;
+ else
+ sender_receiver_col = TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN;
+
+ gtk_tree_model_get (tree_model, iter,
+ sender_receiver_col, &address,
+ TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
+ -1);
+
+ g_object_set (G_OBJECT(renderer),
+ "text",
+ display_address (address),
+ "weight",
+ (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400 : 800,
+ "style",
+ (flags & TNY_MSG_HEADER_FLAG_DELETED)?PANGO_STYLE_ITALIC:PANGO_STYLE_NORMAL,
+ NULL);
+
+ g_free (address);
+}
+
+
+
+/* just to prevent warnings:
+ * warning: `%x' yields only last 2 digits of year in some locales
+ */
+static size_t
+my_strftime(char *s, size_t max, const char *fmt, const
+ struct tm *tm) {
+ return strftime(s, max, fmt, tm);
+}
+
+
+
+/* not reentrant/thread-safe */
+const gchar*
+display_date (time_t date)
+{
+ struct tm date_tm, now_tm;
+ time_t now;
+
+ const gint buf_size = 64;
+ static gchar date_buf[64]; /* buf_size is not ... */
+ static gchar now_buf[64]; /* ...const enough... */
+
+ now = time (NULL);
+
+ localtime_r(&now, &now_tm);
+ localtime_r(&date, &date_tm);
+
+ /* get today's date */
+ my_strftime (date_buf, buf_size, "%x", &date_tm);
+ my_strftime (now_buf, buf_size, "%x", &now_tm); /* today */
+
+ /* if this is today, get the time instead of the date */
+ if (strcmp (date_buf, now_buf) == 0)
+ strftime (date_buf, buf_size, _("%X"), &date_tm);
+
+ return date_buf;
+}
+
+
+static void
+compact_header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data)
+{
+ GObject *rendobj;
+ TnyMsgHeaderFlags flags;
+ gchar *from, *subject;
+ gchar *header;
+ time_t date;
+
+ gtk_tree_model_get (tree_model, iter,
+ TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
+ TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &from,
+ TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN, &date,
+ -1);
+ rendobj = G_OBJECT(renderer);
+
+ header = g_strdup_printf ("%s %s\n%s",
+ display_address (from),
+ display_date(date),
+ subject);
+
+ g_object_set (G_OBJECT(renderer),
+ "text", header,
+ "weight", (flags & TNY_MSG_HEADER_FLAG_SEEN) ? 400: 800,
+ "style", (flags & TNY_MSG_HEADER_FLAG_DELETED) ?
+ PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL,
+ NULL);
+ g_free (header);
+ g_free (from);
+ g_free (subject);
+}
+
+
+static GtkTreeViewColumn*
+get_new_column (const gchar *name, GtkCellRenderer *renderer,
+ gboolean resizable, gint sort_col_id, gboolean show_as_text,
+ GtkTreeCellDataFunc cell_data_func, gpointer user_data)
+{
+ GtkTreeViewColumn *column;
+
+ column = gtk_tree_view_column_new_with_attributes(name, renderer, NULL);
+ gtk_tree_view_column_set_resizable (column, resizable);
+
+ if (show_as_text)
+ gtk_tree_view_column_add_attribute (column, renderer, "text",
+ sort_col_id);
+ if (sort_col_id >= 0)
+ gtk_tree_view_column_set_sort_column_id (column, sort_col_id);
+
+ gtk_tree_view_column_set_sort_indicator (column, FALSE);
+ gtk_tree_view_column_set_reorderable (column, TRUE);
+
+ if (cell_data_func)
+ gtk_tree_view_column_set_cell_data_func(column, renderer, cell_data_func,
+ user_data, NULL);
+
+/* g_signal_connect (G_OBJECT (column), "clicked", */
+/* G_CALLBACK (column_clicked), obj); */
+
+ return column;
+}
+
+
+
+
+static void
+remove_all_columns (ModestHeaderView *obj)
+{
+ GList *columns, *cursor;
+
+ columns = gtk_tree_view_get_columns (GTK_TREE_VIEW(obj));
+
+ for (cursor = columns; cursor; cursor = cursor->next)
+ gtk_tree_view_remove_column (GTK_TREE_VIEW(obj),
+ GTK_TREE_VIEW_COLUMN(cursor->data));
+ g_list_free (columns);
+}
+
+
+
+
+static void
+init_columns (ModestHeaderView *obj)
+{
+ GtkTreeViewColumn *column=NULL;
+ GtkCellRenderer *renderer_msgtype,
+ *renderer_header,
+ *renderer_attach;
+
+ ModestHeaderViewPrivate *priv;
+ GSList *cursor;
+
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(obj);
+
+ renderer_msgtype = gtk_cell_renderer_pixbuf_new ();
+ renderer_attach = gtk_cell_renderer_pixbuf_new ();
+ renderer_header = gtk_cell_renderer_text_new ();
+
+ remove_all_columns (obj);
+
+ for (cursor = priv->columns; cursor; cursor = cursor->next) {
+ ModestHeaderViewColumn col =
+ (ModestHeaderViewColumn) GPOINTER_TO_INT(cursor->data);
+
+ switch (col) {
+
+ case MODEST_HEADER_VIEW_COLUMN_MSGTYPE:
+
+ column = get_new_column (_("M"), renderer_msgtype, FALSE,
+ TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
+ FALSE, (GtkTreeCellDataFunc)msgtype_cell_data,
+ NULL);
+ break;
+
+ case MODEST_HEADER_VIEW_COLUMN_ATTACH:
+
+ column = get_new_column (_("A"), renderer_attach, FALSE,
+ TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN,
+ FALSE, (GtkTreeCellDataFunc)attach_cell_data,
+ NULL);
+ break;
+
+ case MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE:
+ column = get_new_column (_("Received"), renderer_header, TRUE,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_COLUMN,
+ TRUE, (GtkTreeCellDataFunc)header_cell_data,
+ NULL);
+ break;
+
+ case MODEST_HEADER_VIEW_COLUMN_FROM:
+ column = get_new_column (_("From"), renderer_header, TRUE,
+ TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN,
+ TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data,
+ GINT_TO_POINTER(TRUE));
+ break;
+
+ case MODEST_HEADER_VIEW_COLUMN_TO:
+ column = get_new_column (_("To"), renderer_header, TRUE,
+ TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN,
+ TRUE, (GtkTreeCellDataFunc)sender_receiver_cell_data,
+ GINT_TO_POINTER(FALSE));
+ break;
+
+ case MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER:
+ column = get_new_column (_("Header"), renderer_header, TRUE,
+ TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN,
+ TRUE, (GtkTreeCellDataFunc)compact_header_cell_data,
+ NULL);
+ break;
+
+ case MODEST_HEADER_VIEW_COLUMN_SUBJECT:
+ column = get_new_column (_("Subject"), renderer_header, TRUE,
+ TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN,
+ TRUE, (GtkTreeCellDataFunc)header_cell_data,
+ NULL);
+ break;
+
+
+ case MODEST_HEADER_VIEW_COLUMN_SENT_DATE:
+ column = get_new_column (_("Sent"), renderer_header, TRUE,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_COLUMN,
+ TRUE, (GtkTreeCellDataFunc)header_cell_data,
+ NULL);
+ break;
+ }
+ gtk_tree_view_append_column (GTK_TREE_VIEW(obj), column);
+ }
+}
+
+
+
+
+
+static void
+modest_header_view_init (ModestHeaderView *obj)
+{
+ ModestHeaderViewPrivate *priv;
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(obj);
+
+ priv->status_id = 0;
+ priv->lock = g_mutex_new ();
+}
+
+static void
+modest_header_view_finalize (GObject *obj)
+{
+ ModestHeaderView *self;
+ ModestHeaderViewPrivate *priv;
+
+ self = MODEST_HEADER_VIEW(obj);
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+ if (priv->headers)
+ g_object_unref (G_OBJECT(priv->headers));
+
+
+ if (priv->lock) {
+ g_mutex_free (priv->lock);
+ priv->lock = NULL;
+ }
+
+ priv->headers = NULL;
+ priv->tny_msg_folder = NULL;
+
+ G_OBJECT_CLASS(parent_class)->finalize (obj);
+}
+
+GtkWidget*
+modest_header_view_new (TnyMsgFolderIface *folder,
+ GSList *columns,
+ ModestHeaderViewStyle style)
+{
+ GObject *obj;
+ GtkTreeSelection *sel;
+ ModestHeaderView *self;
+
+ obj = G_OBJECT(g_object_new(MODEST_TYPE_HEADER_VIEW, NULL));
+ self = MODEST_HEADER_VIEW(obj);
+
+ if (!modest_header_view_set_folder (self, NULL)) {
+ g_warning ("could not set the folder");
+ g_object_unref (obj);
+ return NULL;
+ }
+
+ modest_header_view_set_style (self, style);
+ modest_header_view_set_columns (self, columns);
+
+ /* all cols */
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(obj), TRUE);
+ gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(obj), TRUE);
+
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(obj),
+ TRUE); /* alternating row colors */
+
+ sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(self));
+ g_signal_connect (sel, "changed",
+ G_CALLBACK(on_selection_changed), self);
+
+ return GTK_WIDGET(self);
+}
+
+gboolean
+modest_header_view_set_columns (ModestHeaderView *self, GSList *columns)
+{
+ ModestHeaderViewPrivate *priv;
+ GSList *cursor;
+
+ g_return_val_if_fail (self, FALSE);
+
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+ g_slist_free (priv->columns);
+
+ for (cursor = columns; cursor; cursor = cursor->next) {
+ ModestHeaderViewColumn col =
+ (ModestHeaderViewColumn) GPOINTER_TO_INT(cursor->data);
+ if (0 > col || col >= MODEST_HEADER_VIEW_COLUMN_NUM)
+ g_warning ("invalid column in column list");
+ else
+ priv->columns = g_slist_append (priv->columns, cursor->data);
+ }
+
+ init_columns (self); /* redraw them */
+ return TRUE;
+}
+
+
+
+const GSList*
+modest_header_view_get_columns (ModestHeaderView *self)
+{
+ ModestHeaderViewPrivate *priv;
+
+ g_return_val_if_fail (self, FALSE);
+
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+ return priv->columns;
+}
+
+
+
+
+gboolean
+modest_header_view_set_style (ModestHeaderView *self,
+ ModestHeaderViewStyle style)
+{
+ g_return_val_if_fail (self, FALSE);
+ g_return_val_if_fail (style >= 0 && style < MODEST_HEADER_VIEW_STYLE_NUM,
+ FALSE);
+
+ MODEST_HEADER_VIEW_GET_PRIVATE(self)->style = style;
+
+ return TRUE;
+}
+
+ModestHeaderViewStyle
+modest_header_view_get_style (ModestHeaderView *self)
+{
+ g_return_val_if_fail (self, FALSE);
+
+ return MODEST_HEADER_VIEW_GET_PRIVATE(self)->style;
+}
+
+
+
+/* get the length of any prefix that should be ignored for sorting */
+static inline int
+get_prefix_len (const gchar *sub)
+{
+ gint i = 0;
+ const static gchar* prefix[] = {"Re:", "RE:", "Fwd:", "FWD:", "FW:", "AW:", NULL};
+
+ if (sub[0] != 'R' && sub[0] != 'F') /* optimization */
+ return 0;
+
+ while (prefix[i]) {
+ if (g_str_has_prefix(sub, prefix[i])) {
+ int prefix_len = strlen(prefix[i]);
+ if (sub[prefix_len] == ' ')
+ ++prefix_len; /* ignore space after prefix as well */
+ return prefix_len;
+ }
+ ++i;
+ }
+ return 0;
+}
+
+
+static inline gint
+cmp_normalized_subject (const gchar* s1, const gchar *s2)
+{
+ gint result = 0;
+ register gchar *n1, *n2;
+
+ n1 = g_utf8_collate_key (s1 + get_prefix_len(s1), -1);
+ n2 = g_utf8_collate_key (s2 + get_prefix_len(s2), -1);
+
+ result = strcmp (n1, n2);
+ g_free (n1);
+ g_free (n2);
+
+ return result;
+}
+
+
+static gint
+cmp_rows (GtkTreeModel *tree_model, GtkTreeIter *iter1, GtkTreeIter *iter2,
+ gpointer user_data)
+{
+ gint col_id = GPOINTER_TO_INT (user_data);
+ gint t1, t2;
+ gint val1, val2;
+ gchar *s1, *s2;
+ gint cmp;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL(tree_model), -1);
+
+ switch (col_id) {
+
+ /* first one, we decide based on the time */
+ case MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER:
+ case MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE:
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
+ &t1,-1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_RECEIVED_TIME_T_COLUMN,
+ &t2,-1);
+ return t1 - t2;
+
+ case MODEST_HEADER_VIEW_COLUMN_SENT_DATE:
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
+ &t1,-1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN,
+ &t2,-1);
+ return t1 - t2;
+
+
+ /* next ones, we try the search criteria first, if they're the same, then we use 'sent date' */
+ case MODEST_HEADER_VIEW_COLUMN_SUBJECT: {
+
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
+ -1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_SUBJECT_COLUMN, &s2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
+ -1);
+
+ cmp = cmp_normalized_subject(s1, s2);
+
+ g_free (s1);
+ g_free (s2);
+
+ return cmp ? cmp : t1 - t2;
+ }
+
+ case MODEST_HEADER_VIEW_COLUMN_FROM:
+
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
+ -1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_FROM_COLUMN, &s2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
+ -1);
+ cmp = strcmp (s1, s2);
+ g_free (s1);
+ g_free (s2);
+
+ return cmp ? cmp : t1 - t2;
+
+ case MODEST_HEADER_VIEW_COLUMN_TO:
+
+ gtk_tree_model_get (tree_model, iter1,
+ TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,
+ -1);
+ gtk_tree_model_get (tree_model, iter2,
+ TNY_MSG_HEADER_LIST_MODEL_TO_COLUMN, &s2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,
+ -1);
+ cmp = strcmp (s1, s2);
+ g_free (s1);
+ g_free (s2);
+
+ return cmp ? cmp : t1 - t2;
+
+ case MODEST_HEADER_VIEW_COLUMN_ATTACH:
+
+ gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1, -1);
+ gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2, -1);
+
+ cmp = (val1 & TNY_MSG_HEADER_FLAG_ATTACHMENTS) -
+ (val2 & TNY_MSG_HEADER_FLAG_ATTACHMENTS);
+
+ return cmp ? cmp : t1 - t2;
+
+ case MODEST_HEADER_VIEW_COLUMN_MSGTYPE:
+ gtk_tree_model_get (tree_model, iter1, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val1,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t1,-1);
+ gtk_tree_model_get (tree_model, iter2, TNY_MSG_HEADER_LIST_MODEL_FLAGS_COLUMN, &val2,
+ TNY_MSG_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &t2,-1);
+ cmp = (val1 & TNY_MSG_HEADER_FLAG_SEEN) - (val2 & TNY_MSG_HEADER_FLAG_SEEN);
+
+ return cmp ? cmp : t1 - t2;
+
+ default:
+ return &iter1 - &iter2; /* oughhhh */
+ }
+}
+
+
+static void
+refresh_folder (TnyMsgFolderIface *folder, gboolean cancelled,
+ gpointer user_data)
+{
+ GtkTreeModel *oldsortable, *sortable;
+ ModestHeaderView *self =
+ MODEST_HEADER_VIEW(user_data);
+ ModestHeaderViewPrivate *priv;
+
+ g_return_if_fail (self);
+
+ if (cancelled)
+ return;
+
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+ if (!folder) /* when there is no folder */
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(self), FALSE);
+
+ else { /* it's a new one or a refresh */
+ GSList *col;
+
+ priv->headers = TNY_LIST_IFACE(tny_msg_header_list_model_new ());
+
+ tny_msg_folder_iface_get_headers (folder, priv->headers, FALSE);
+ tny_msg_header_list_model_set_folder (TNY_MSG_HEADER_LIST_MODEL(priv->headers),
+ folder, TRUE); /* async */
+
+ oldsortable = gtk_tree_view_get_model(GTK_TREE_VIEW (self));
+ if (oldsortable && GTK_IS_TREE_MODEL_SORT(oldsortable)) {
+ GtkTreeModel *oldmodel = gtk_tree_model_sort_get_model
+ (GTK_TREE_MODEL_SORT(oldsortable));
+ if (oldmodel)
+ g_object_unref (G_OBJECT(oldmodel));
+ g_object_unref (oldsortable);
+ }
+
+ sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(priv->headers));
+
+ /* install our special sorting functions */
+ col = priv->columns;
+ while (col) {
+ gint col_id = GPOINTER_TO_INT (col->data);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(sortable), col_id,
+ (GtkTreeIterCompareFunc)cmp_rows,
+ GINT_TO_POINTER(col_id), NULL);
+ col = col->next;
+ }
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (self), sortable);
+ gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(self), TRUE);
+ /* no need to unref sortable */
+ }
+
+}
+
+
+static void
+refresh_folder_status_update (TnyMsgFolderIface *folder, const gchar *msg,
+ gint status_id, gpointer user_data)
+{
+ ModestHeaderView *self;
+ ModestHeaderViewPrivate *priv;
+
+ self = MODEST_HEADER_VIEW (user_data);
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+ g_signal_emit (G_OBJECT(self),
+ signals[STATUS_UPDATE_SIGNAL], 0,
+ msg, status_id);
+ if (msg)
+ g_timeout_add (750,
+ (GSourceFunc)refresh_folder_finish_status_update,
+ self);
+
+ priv->status_id = status_id;
+}
+
+
+static gboolean
+refresh_folder_finish_status_update (gpointer user_data)
+{
+ ModestHeaderView *self;
+ ModestHeaderViewPrivate *priv;
+
+ self = MODEST_HEADER_VIEW (user_data);
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+ if (priv->status_id == 0)
+ return FALSE;
+
+ refresh_folder_status_update (NULL, NULL, priv->status_id,
+ user_data);
+ priv->status_id = 0;
+
+ return FALSE;
+}
+
+
+gboolean
+modest_header_view_set_folder (ModestHeaderView *self,
+ TnyMsgFolderIface *folder)
+{
+ ModestHeaderViewPrivate *priv;
+
+ g_return_val_if_fail (MODEST_IS_HEADER_VIEW (self), FALSE);
+
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+ g_mutex_lock (priv->lock);
+
+ if (!folder) {/* when there is no folder */
+ GtkTreeModel *model;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW(self));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(self), FALSE);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (self), NULL);
+ if (model)
+ g_object_unref (model);
+ }
+ else { /* it's a new one or a refresh */
+ tny_msg_folder_iface_refresh_async (folder,
+ refresh_folder,
+ refresh_folder_status_update,
+ self);
+ }
+
+ /* no message selected */
+ g_signal_emit (G_OBJECT(self), signals[MESSAGE_SELECTED_SIGNAL], 0,
+ NULL);
+
+ g_mutex_unlock (priv->lock);
+
+ return TRUE;
+}
+
+
+
+static void
+on_selection_changed (GtkTreeSelection *sel, gpointer user_data)
+{
+ GtkTreeModel *model;
+ TnyMsgHeaderIface *header;
+ GtkTreeIter iter;
+ ModestHeaderView *self;
+ ModestHeaderViewPrivate *priv;
+
+ g_return_if_fail (sel);
+ g_return_if_fail (user_data);
+
+ self = MODEST_HEADER_VIEW (user_data);
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
+
+
+ if (!gtk_tree_selection_get_selected (sel, &model, &iter))
+ return; /* msg was _un_selected */
+
+ //g_mutex_lock (priv->lock);
+
+ gtk_tree_model_get (model, &iter,
+ TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
+ &header, -1);
+
+ if (header) {
+ const TnyMsgIface *msg = NULL;
+ const TnyMsgFolderIface *folder;
+
+ folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header));
+ if (!folder)
+ g_printerr ("modest: cannot find folder\n");
+ else {
+ msg = tny_msg_folder_iface_get_message (TNY_MSG_FOLDER_IFACE(folder),
+ header);
+ if (!msg) {
+ g_printerr ("modest: cannot find msg\n");
+ gtk_tree_store_remove (GTK_TREE_STORE(model),
+ &iter);
+ }
+ }
+
+ g_signal_emit (G_OBJECT(self), signals[MESSAGE_SELECTED_SIGNAL], 0,
+ msg);
+
+ /* mark message as seen; _set_flags crashes, bug in tinymail? */
+ //flags = tny_msg_header_iface_get_flags (TNY_MSG_HEADER_IFACE(header));
+ //tny_msg_header_iface_set_flags (header, TNY_MSG_HEADER_FLAG_SEEN);
+ }
+
+ // g_mutex_unlock (priv->lock);
+
+}
+
+
+/* static void */
+/* on_column_clicked (GtkTreeViewColumn *col, gpointer user_data) */
+/* { */
+/* GtkTreeView *treeview; */
+/* gint id; */
+
+/* treeview = GTK_TREE_VIEW (user_data); */
+/* id = gtk_tree_view_column_get_sort_column_id (col); */
+
+/* gtk_tree_view_set_search_column (treeview, id); */
+/* } */
--- /dev/null
+/* 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_HEADER_VIEW_H__
+#define __MODEST_HEADER_VIEW_H__
+
+#include <gtk/gtk.h>
+#include <tny-msg-folder-iface.h>
+#include <tny-account-tree-model.h>
+#include <tny-msg-iface.h>
+#include <tny-msg-header-iface.h>
+#include <tny-msg-header-list-model.h>
+
+G_BEGIN_DECLS
+
+/* convenience macros */
+#define MODEST_TYPE_HEADER_VIEW (modest_header_view_get_type())
+#define MODEST_HEADER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_HEADER_VIEW,ModestHeaderView))
+#define MODEST_HEADER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_HEADER_VIEW,ModestHeaderViewClass))
+#define MODEST_IS_HEADER_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_HEADER_VIEW))
+#define MODEST_IS_HEADER_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_HEADER_VIEW))
+#define MODEST_HEADER_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_HEADER_VIEW,ModestHeaderViewClass))
+
+typedef struct _ModestHeaderView ModestHeaderView;
+typedef struct _ModestHeaderViewClass ModestHeaderViewClass;
+
+struct _ModestHeaderView {
+ GtkTreeView parent;
+ /* insert public members, if any */
+};
+
+struct _ModestHeaderViewClass {
+ GtkTreeViewClass parent_class;
+
+ void (*message_selected) (ModestHeaderView* self,
+ TnyMsgIface *msg,
+ gpointer user_data);
+
+ /* msg == NULL implies that the operation is finished, ie.
+ * the progress indictation can be hidden */
+ void (*status_update) (ModestHeaderView* self,
+ const gchar* msg,
+ gint status,
+ gpointer user_data);
+};
+
+
+enum {
+ MODEST_HEADER_VIEW_COLUMN_FROM,
+ MODEST_HEADER_VIEW_COLUMN_TO,
+ MODEST_HEADER_VIEW_COLUMN_SUBJECT,
+ MODEST_HEADER_VIEW_COLUMN_SENT_DATE,
+ MODEST_HEADER_VIEW_COLUMN_RECEIVED_DATE,
+ MODEST_HEADER_VIEW_COLUMN_MSGTYPE,
+ MODEST_HEADER_VIEW_COLUMN_ATTACH,
+ MODEST_HEADER_VIEW_COLUMN_COMPACT_HEADER,
+
+ MODEST_HEADER_VIEW_COLUMN_NUM
+};
+typedef guint ModestHeaderViewColumn;
+
+enum {
+ MODEST_HEADER_VIEW_STYLE_NORMAL,
+ MODEST_HEADER_VIEW_STYLE_COMPACT,
+
+ MODEST_HEADER_VIEW_STYLE_NUM
+};
+typedef guint ModestHeaderViewStyle;
+
+
+
+/**
+ * modest_header_view_get_type:
+ *
+ * get the GType for ModestHeaderView
+ *
+ * Returns: the GType
+ */
+GType modest_header_view_get_type (void) G_GNUC_CONST;
+
+
+/**
+ * modest_header_view_new:
+ * @folder: a TnyMsgFolderIface object
+ * @columns: a list of ModestHeaderViewColumn
+ * @style: a ModestHeaderViewColumn with the style of this listview
+ * ( MODEST_HEADER_VIEW_STYLE_NORMAL or MODEST_HEADER_VIEW_STYLE_COMPACT)
+ *
+ * create a new ModestHeaderView instance, based on a folder iface
+ *
+ * Returns: a new GtkWidget (a GtkTreeView-subclass)
+ */
+GtkWidget* modest_header_view_new (TnyMsgFolderIface *folder,
+ GSList *columns,
+ ModestHeaderViewStyle style);
+
+/**
+ * modest_header_view_set_folder:
+ * @self: a ModestHeaderView instance
+ * @folder: a TnyMsgFolderIface object
+ *
+ * set the folder for this ModestHeaderView
+ *
+ * Returns: TRUE if it succeeded, FALSE otherwise
+ */
+gboolean modest_header_view_set_folder (ModestHeaderView *self,
+ TnyMsgFolderIface *folder);
+
+
+/**
+ * modest_header_view_set_columns:
+ * @self: a ModestHeaderView instance
+ * @columns: a list of ModestHeaderViewColumn
+ *
+ * set the columns for this ModestHeaderView
+ *
+ * Returns: TRUE if it succeeded, FALSE otherwise
+ */
+gboolean modest_header_view_set_columns (ModestHeaderView *self,
+ GSList *columns);
+/**
+ * modest_header_view_get_columns:
+ * @self: a ModestHeaderView instance
+ * @folder: a TnyMsgFolderIface object
+ *
+ * get the columns for this ModestHeaderView
+ *
+ * Returns: list of columms, or NULL in case of no columns or error
+ */
+const GSList* modest_header_view_get_columns (ModestHeaderView *self);
+
+
+/**
+ * modest_header_view_set_style:
+ * @self: a ModestHeaderView instance
+ * @style: the style for this tree view
+ *
+ * set the folder for this ModestHeaderView
+ *
+ * Returns: TRUE if it succeeded, FALSE otherwise
+ */
+gboolean modest_header_view_set_style (ModestHeaderView *self,
+ ModestHeaderViewStyle style);
+
+/**
+ * modest_header_view_set_folder:
+ * @self: a ModestHeaderView instance
+ * @folder: a TnyMsgFolderIface object
+ *
+ * set the folder for this ModestHeaderView
+ *
+ * Returns: TRUE if it succeeded, FALSE otherwise
+ */
+ModestHeaderViewStyle modest_header_view_get_style (ModestHeaderView *self);
+
+G_END_DECLS
+
+
+#endif /* __MODEST_HEADER_VIEW_H__ */
+
--- /dev/null
+/* 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.
+ */
+
+#include <tny-text-buffer-stream.h>
+#include <string.h>
+#include <regex.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <glib/gi18n.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+#include <tny-list-iface.h>
+
+#include <modest-tny-msg-actions.h>
+#include "modest-msg-view.h"
+#include "modest-tny-stream-gtkhtml.h"
+
+
+/* 'private'/'protected' functions */
+static void modest_msg_view_class_init (ModestMsgViewClass *klass);
+static void modest_msg_view_init (ModestMsgView *obj);
+static void modest_msg_view_finalize (GObject *obj);
+
+
+static GSList* get_url_matches (GString *txt);
+static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri,
+ ModestMsgView *msg_view);
+static gboolean on_url_requested (GtkWidget *widget, const gchar *uri,
+ GtkHTMLStream *stream,
+ ModestMsgView *msg_view);
+
+/*
+ * we need these regexps to find URLs in plain text e-mails
+ */
+typedef struct _UrlMatchPattern UrlMatchPattern;
+struct _UrlMatchPattern {
+ gchar *regex;
+ regex_t *preg;
+ gchar *prefix;
+
+};
+
+#define ATT_PREFIX "att:"
+
+#define MAIL_VIEWER_URL_MATCH_PATTERNS { \
+ { "(file|http|ftp|https)://[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]+[-A-Za-z0-9_$%&=?/~#]",\
+ NULL, NULL },\
+ { "www\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\
+ NULL, "http://" },\
+ { "ftp\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\
+ NULL, "ftp://" },\
+ { "(voipto|callto|chatto|jabberto|xmpp):[-_a-z@0-9.\\+]+", \
+ NULL, NULL}, \
+ { "mailto:[-_a-z0-9.\\+]+@[-_a-z0-9.]+", \
+ NULL, NULL},\
+ { "[-_a-z0-9.\\+]+@[-_a-z0-9.]+",\
+ NULL, "mailto:"}\
+ }
+
+
+/* list my signals */
+enum {
+ LINK_CLICKED_SIGNAL,
+ ATTACHMENT_CLICKED_SIGNAL,
+ LAST_SIGNAL
+};
+
+typedef struct _ModestMsgViewPrivate ModestMsgViewPrivate;
+struct _ModestMsgViewPrivate {
+ GtkWidget *gtkhtml;
+ const TnyMsgIface *msg;
+};
+#define MODEST_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
+ MODEST_TYPE_MSG_VIEW, \
+ ModestMsgViewPrivate))
+/* globals */
+static GtkContainerClass *parent_class = NULL;
+
+/* uncomment the following if you have defined any signals */
+static guint signals[LAST_SIGNAL] = {0};
+
+GType
+modest_msg_view_get_type (void)
+{
+ static GType my_type = 0;
+ if (!my_type) {
+ static const GTypeInfo my_info = {
+ sizeof(ModestMsgViewClass),
+ NULL, /* base init */
+ NULL, /* base finalize */
+ (GClassInitFunc) modest_msg_view_class_init,
+ NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof(ModestMsgView),
+ 1, /* n_preallocs */
+ (GInstanceInitFunc) modest_msg_view_init,
+ };
+ my_type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW,
+ "ModestMsgView",
+ &my_info, 0);
+ }
+ return my_type;
+}
+
+static void
+modest_msg_view_class_init (ModestMsgViewClass *klass)
+{
+ GObjectClass *gobject_class;
+ gobject_class = (GObjectClass*) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ gobject_class->finalize = modest_msg_view_finalize;
+
+ g_type_class_add_private (gobject_class, sizeof(ModestMsgViewPrivate));
+
+
+ signals[LINK_CLICKED_SIGNAL] =
+ g_signal_new ("link_clicked",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(ModestMsgViewClass, link_clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[ATTACHMENT_CLICKED_SIGNAL] =
+ g_signal_new ("attachment_clicked",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(ModestMsgViewClass, attachment_clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+
+}
+
+static void
+modest_msg_view_init (ModestMsgView *obj)
+{
+ ModestMsgViewPrivate *priv;
+
+ priv = MODEST_MSG_VIEW_GET_PRIVATE(obj);
+
+ priv->msg = NULL;
+ priv->gtkhtml = gtk_html_new();
+
+ gtk_html_set_editable (GTK_HTML(priv->gtkhtml), FALSE);
+ gtk_html_allow_selection (GTK_HTML(priv->gtkhtml), TRUE);
+ gtk_html_set_caret_mode (GTK_HTML(priv->gtkhtml), FALSE);
+ gtk_html_set_blocking (GTK_HTML(priv->gtkhtml), FALSE);
+ gtk_html_set_images_blocking (GTK_HTML(priv->gtkhtml), FALSE);
+
+ g_signal_connect (G_OBJECT(priv->gtkhtml), "link_clicked",
+ G_CALLBACK(on_link_clicked), obj);
+
+ g_signal_connect (G_OBJECT(priv->gtkhtml), "url_requested",
+ G_CALLBACK(on_url_requested), obj);
+}
+
+
+static void
+modest_msg_view_finalize (GObject *obj)
+{
+ G_OBJECT_CLASS(parent_class)->finalize (obj);
+}
+
+
+GtkWidget*
+modest_msg_view_new (const TnyMsgIface *msg)
+{
+ GObject *obj;
+ ModestMsgView* self;
+ ModestMsgViewPrivate *priv;
+
+ obj = G_OBJECT(g_object_new(MODEST_TYPE_MSG_VIEW, NULL));
+ self = MODEST_MSG_VIEW(obj);
+ priv = MODEST_MSG_VIEW_GET_PRIVATE (self);
+
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ if (priv->gtkhtml)
+ gtk_container_add (GTK_CONTAINER(obj), priv->gtkhtml);
+
+ if (msg)
+ modest_msg_view_set_message (self, msg);
+
+ return GTK_WIDGET(self);
+}
+
+
+static gboolean
+on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view)
+{
+
+ int index;
+
+ g_return_val_if_fail (msg_view, FALSE);
+
+ /* is it an attachment? */
+ if (g_str_has_prefix(uri, ATT_PREFIX)) {
+
+ index = atoi (uri + strlen(ATT_PREFIX));
+
+ if (index == 0) {
+ /* index is 1-based, so 0 indicates an error */
+ g_printerr ("modest: invalid attachment id: %s\n", uri);
+ return FALSE;
+ }
+
+ g_signal_emit (G_OBJECT(msg_view), signals[ATTACHMENT_CLICKED_SIGNAL],
+ 0, index);
+ return FALSE;
+ }
+
+ g_signal_emit (G_OBJECT(msg_view), signals[LINK_CLICKED_SIGNAL], 0, uri);
+
+ return FALSE;
+}
+
+
+static TnyMsgMimePartIface *
+find_cid_image (const TnyMsgIface *msg, const gchar *cid)
+{
+ TnyMsgMimePartIface *part = NULL;
+ const TnyListIface *parts;
+ TnyIteratorIface *iter;
+
+ g_return_val_if_fail (msg, NULL);
+ g_return_val_if_fail (cid, NULL);
+
+ parts = tny_msg_iface_get_parts ((TnyMsgIface*)msg); // FIXME: tinymail
+ iter = tny_list_iface_create_iterator ((TnyListIface*)parts);
+
+ while (!tny_iterator_iface_is_done(iter)) {
+ const gchar *part_cid;
+ part = TNY_MSG_MIME_PART_IFACE(tny_iterator_iface_current(iter));
+ part_cid = tny_msg_mime_part_iface_get_content_id (part);
+
+ if (part_cid && strcmp (cid, part_cid) == 0)
+ break;
+
+ part = NULL;
+ tny_iterator_iface_next (iter);
+ }
+
+ g_object_unref (G_OBJECT(iter));
+ return part;
+}
+
+
+static gboolean
+on_url_requested (GtkWidget *widget, const gchar *uri,
+ GtkHTMLStream *stream,
+ ModestMsgView *msg_view)
+{
+ ModestMsgViewPrivate *priv;
+ priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
+
+ if (g_str_has_prefix (uri, "cid:")) {
+ /* +4 ==> skip "cid:" */
+ const TnyMsgMimePartIface *part = find_cid_image (priv->msg, uri + 4);
+ if (!part) {
+ g_printerr ("modest: '%s' not found\n", uri + 4);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
+ } else {
+ TnyStreamIface *tny_stream =
+ TNY_STREAM_IFACE(modest_tny_stream_gtkhtml_new(stream));
+ // FIXME: tinymail
+ tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)part,
+ tny_stream);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
+ }
+ }
+
+ return TRUE;
+}
+
+
+typedef struct {
+ guint offset;
+ guint len;
+ const gchar* prefix;
+} url_match_t;
+
+
+
+/* render the attachments as hyperlinks in html */
+static gchar*
+attachments_as_html (ModestMsgView *self, const TnyMsgIface *msg)
+{
+ ModestMsgViewPrivate *priv;
+ GString *appendix;
+ const TnyListIface *parts;
+ TnyIteratorIface *iter;
+ gchar *html;
+ int index = 0;
+
+ if (!msg)
+ return NULL;
+
+ priv = MODEST_MSG_VIEW_GET_PRIVATE (self);
+ parts = tny_msg_iface_get_parts ((TnyMsgIface*)msg);
+ // FIXME: tinymail
+ iter = tny_list_iface_create_iterator ((TnyListIface*)parts);
+
+ appendix= g_string_new ("");
+
+ while (!tny_iterator_iface_is_done(iter)) {
+ TnyMsgMimePartIface *part;
+
+ ++index; /* attachment numbers are 1-based */
+
+ part = TNY_MSG_MIME_PART_IFACE(tny_iterator_iface_current (iter));
+
+ if (tny_msg_mime_part_iface_is_attachment (part)) {
+
+ const gchar *filename = tny_msg_mime_part_iface_get_filename(part);
+ if (!filename)
+ filename = _("attachment");
+
+ g_string_append_printf (appendix, "<a href=\"%s%d\">%s</a> \n",
+ ATT_PREFIX, index, filename);
+ }
+ tny_iterator_iface_next (iter);
+ }
+ g_object_unref (G_OBJECT(iter));
+
+ if (appendix->len == 0)
+ return g_string_free (appendix, TRUE);
+
+ html = g_strdup_printf ("<strong>%s:</strong> %s\n<hr>",
+ _("Attachments"), appendix->str);
+ g_string_free (appendix, TRUE);
+
+ return html;
+}
+
+
+
+static void
+hyperlinkify_plain_text (GString *txt)
+{
+ GSList *cursor;
+ GSList *match_list = get_url_matches (txt);
+
+ /* we will work backwards, so the offsets stay valid */
+ for (cursor = match_list; cursor; cursor = cursor->next) {
+
+ url_match_t *match = (url_match_t*) cursor->data;
+ gchar *url = g_strndup (txt->str + match->offset, match->len);
+ gchar *repl = NULL; /* replacement */
+
+ /* the prefix is NULL: use the one that is already there */
+ repl = g_strdup_printf ("<a href=\"%s%s\">%s</a>",
+ match->prefix ? match->prefix : "", url, url);
+
+ /* replace the old thing with our hyperlink
+ * replacement thing */
+ g_string_erase (txt, match->offset, match->len);
+ g_string_insert (txt, match->offset, repl);
+
+ g_free (url);
+ g_free (repl);
+
+ g_free (cursor->data);
+ }
+
+ g_slist_free (match_list);
+}
+
+
+
+static gchar *
+convert_to_html (const gchar *data)
+{
+ int i;
+ gboolean first_space = TRUE;
+ GString *html;
+ gsize len;
+
+ if (!data)
+ return NULL;
+
+ len = strlen (data);
+ html = g_string_sized_new (len + 100); /* just a guess... */
+
+ g_string_append_printf (html,
+ "<html>"
+ "<head>"
+ "<meta http-equiv=\"content-type\""
+ " content=\"text/html; charset=utf8\">"
+ "</head>"
+ "<body><tt>");
+
+ /* replace with special html chars where needed*/
+ for (i = 0; i != len; ++i) {
+ char kar = data[i];
+ switch (kar) {
+
+ case 0: break; /* ignore embedded \0s */
+ case '<' : g_string_append (html, "<"); break;
+ case '>' : g_string_append (html, ">"); break;
+ case '&' : g_string_append (html, """); break;
+ case '\n': g_string_append (html, "<br>\n"); break;
+ default:
+ if (kar == ' ') {
+ g_string_append (html, first_space ? " " : " ");
+ first_space = FALSE;
+ } else if (kar == '\t')
+ g_string_append (html, " ");
+ else {
+ int charnum = 0;
+ first_space = TRUE;
+ /* optimization trick: accumulate 'normal' chars, then copy */
+ do {
+ kar = data [++charnum + i];
+
+ } while ((i + charnum < len) &&
+ (kar > '>' || (kar != '<' && kar != '>'
+ && kar != '&' && kar != ' '
+ && kar != '\n' && kar != '\t')));
+ g_string_append_len (html, &data[i], charnum);
+ i += (charnum - 1);
+ }
+ }
+ }
+
+ g_string_append (html, "</tt></body></html>");
+ hyperlinkify_plain_text (html);
+
+ return g_string_free (html, FALSE);
+}
+
+
+
+
+static gint
+cmp_offsets_reverse (const url_match_t *match1, const url_match_t *match2)
+{
+ return match2->offset - match1->offset;
+}
+
+
+
+/*
+ * check if the match is inside an existing match... */
+static void
+chk_partial_match (const url_match_t *match, int* offset)
+{
+ if (*offset >= match->offset && *offset < match->offset + match->len)
+ *offset = -1;
+}
+
+static GSList*
+get_url_matches (GString *txt)
+{
+ regmatch_t rm;
+ int rv, i, offset = 0;
+ GSList *match_list = NULL;
+
+ static UrlMatchPattern patterns[] = MAIL_VIEWER_URL_MATCH_PATTERNS;
+ const size_t pattern_num = sizeof(patterns)/sizeof(UrlMatchPattern);
+
+ /* initalize the regexps */
+ for (i = 0; i != pattern_num; ++i) {
+ patterns[i].preg = g_new0 (regex_t,1);
+ g_assert(regcomp (patterns[i].preg, patterns[i].regex,
+ REG_ICASE|REG_EXTENDED|REG_NEWLINE) == 0);
+ }
+ /* find all the matches */
+ for (i = 0; i != pattern_num; ++i) {
+ offset = 0;
+ while (1) {
+ int test_offset;
+ if ((rv = regexec (patterns[i].preg, txt->str + offset, 1, &rm, 0)) != 0) {
+ g_assert (rv == REG_NOMATCH); /* this should not happen */
+ break; /* try next regexp */
+ }
+ if (rm.rm_so == -1)
+ break;
+
+ /* FIXME: optimize this */
+ /* to avoid partial matches on something that was already found... */
+ /* check_partial_match will put -1 in the data ptr if that is the case */
+ test_offset = offset + rm.rm_so;
+ g_slist_foreach (match_list, (GFunc)chk_partial_match, &test_offset);
+
+ /* make a list of our matches (<offset, len, prefix> tupels)*/
+ if (test_offset != -1) {
+ url_match_t *match = g_new (url_match_t,1);
+ match->offset = offset + rm.rm_so;
+ match->len = rm.rm_eo - rm.rm_so;
+ match->prefix = patterns[i].prefix;
+ match_list = g_slist_prepend (match_list, match);
+ }
+ offset += rm.rm_eo;
+ }
+ }
+
+ for (i = 0; i != pattern_num; ++i) {
+ regfree (patterns[i].preg);
+ g_free (patterns[i].preg);
+ } /* don't free patterns itself -- it's static */
+
+ /* now sort the list, so the matches are in reverse order of occurence.
+ * that way, we can do the replacements starting from the end, so we don't need
+ * to recalculate the offsets
+ */
+ match_list = g_slist_sort (match_list,
+ (GCompareFunc)cmp_offsets_reverse);
+ return match_list;
+}
+
+
+
+static gboolean
+set_html_message (ModestMsgView *self, const TnyMsgMimePartIface *tny_body,
+ const TnyMsgIface *msg)
+{
+ gchar *html_attachments;
+ TnyStreamIface *gtkhtml_stream;
+ ModestMsgViewPrivate *priv;
+
+ g_return_val_if_fail (self, FALSE);
+ g_return_val_if_fail (tny_body, FALSE);
+
+ priv = MODEST_MSG_VIEW_GET_PRIVATE(self);
+
+ gtkhtml_stream =
+ TNY_STREAM_IFACE(modest_tny_stream_gtkhtml_new
+ (gtk_html_begin(GTK_HTML(priv->gtkhtml))));
+
+ tny_stream_iface_reset (gtkhtml_stream);
+
+ html_attachments = attachments_as_html(self, msg);
+ if (html_attachments) {
+ tny_stream_iface_write (gtkhtml_stream, html_attachments,
+ strlen(html_attachments));
+ tny_stream_iface_reset (gtkhtml_stream);
+ g_free (html_attachments);
+ }
+
+ // FIXME: tinymail
+ tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)tny_body,
+ gtkhtml_stream);
+
+ g_object_unref (G_OBJECT(gtkhtml_stream));
+
+ return TRUE;
+}
+
+
+/* this is a hack --> we use the tny_text_buffer_stream to
+ * get the message text, then write to gtkhtml 'by hand' */
+static gboolean
+set_text_message (ModestMsgView *self, const TnyMsgMimePartIface *tny_body,
+ const TnyMsgIface *msg)
+{
+ GtkTextBuffer *buf;
+ GtkTextIter begin, end;
+ TnyStreamIface* txt_stream, *gtkhtml_stream;
+ gchar *txt, *html_attachments;
+ ModestMsgViewPrivate *priv;
+
+ g_return_val_if_fail (self, FALSE);
+ g_return_val_if_fail (tny_body, FALSE);
+
+ priv = MODEST_MSG_VIEW_GET_PRIVATE(self);
+
+ buf = gtk_text_buffer_new (NULL);
+ txt_stream = TNY_STREAM_IFACE(tny_text_buffer_stream_new (buf));
+
+ tny_stream_iface_reset (txt_stream);
+
+ gtkhtml_stream =
+ TNY_STREAM_IFACE(modest_tny_stream_gtkhtml_new
+ (gtk_html_begin(GTK_HTML(priv->gtkhtml))));
+
+ html_attachments = attachments_as_html(self, msg);
+ if (html_attachments) {
+ tny_stream_iface_write (gtkhtml_stream, html_attachments,
+ strlen(html_attachments));
+ tny_stream_iface_reset (gtkhtml_stream);
+ g_free (html_attachments);
+ }
+
+ // FIXME: tinymail
+ tny_msg_mime_part_iface_decode_to_stream ((TnyMsgMimePartIface*)tny_body,
+ txt_stream);
+ tny_stream_iface_reset (txt_stream);
+
+ gtk_text_buffer_get_bounds (buf, &begin, &end);
+ txt = gtk_text_buffer_get_text (buf, &begin, &end, FALSE);
+ if (txt) {
+ gchar *html = convert_to_html (txt);
+ tny_stream_iface_write (gtkhtml_stream, html, strlen(html));
+ tny_stream_iface_reset (gtkhtml_stream);
+ g_free (txt);
+ g_free (html);
+ }
+
+ g_object_unref (G_OBJECT(gtkhtml_stream));
+ g_object_unref (G_OBJECT(txt_stream));
+ g_object_unref (G_OBJECT(buf));
+
+ return TRUE;
+}
+
+
+static gboolean
+set_empty_message (ModestMsgView *self)
+{
+ ModestMsgViewPrivate *priv;
+
+ g_return_val_if_fail (self, FALSE);
+ priv = MODEST_MSG_VIEW_GET_PRIVATE(self);
+
+ gtk_html_load_from_string (GTK_HTML(priv->gtkhtml),
+ "", 1);
+
+ return TRUE;
+}
+
+
+gchar *
+modest_msg_view_get_selected_text (ModestMsgView *self)
+{
+ ModestMsgViewPrivate *priv;
+ gchar *sel;
+ GtkWidget *html;
+ int len;
+ GtkClipboard *clip;
+
+ g_return_val_if_fail (self, NULL);
+ priv = MODEST_MSG_VIEW_GET_PRIVATE(self);
+ html = priv->gtkhtml;
+
+ /* I'm sure there is a better way to check for selected text */
+ sel = gtk_html_get_selection_html(GTK_HTML(html), &len);
+ if (!sel)
+ return NULL;
+
+ g_free(sel);
+
+ clip = gtk_widget_get_clipboard(html, GDK_SELECTION_PRIMARY);
+ return gtk_clipboard_wait_for_text(clip);
+}
+
+
+void
+modest_msg_view_set_message (ModestMsgView *self, const TnyMsgIface *msg)
+{
+ TnyMsgMimePartIface *body;
+ ModestMsgViewPrivate *priv;
+
+ g_return_if_fail (self);
+
+ priv = MODEST_MSG_VIEW_GET_PRIVATE(self);
+
+ priv->msg = msg;
+
+ if (!msg) {
+ set_empty_message (self);
+ return;
+ }
+
+ body = modest_tny_msg_actions_find_body_part (msg, TRUE);
+ if (body) {
+ if (tny_msg_mime_part_iface_content_type_is (body, "text/html"))
+ set_html_message (self, body, msg);
+ else
+ set_text_message (self, body, msg);
+ return;
+ } else
+ set_empty_message (self);
+}
--- /dev/null
+/* 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.
+ */
+
+
+/* modest-tny-msg-view.h */
+
+#ifndef __MODEST_MSG_VIEW_H__
+#define __MODEST_MSG_VIEW_H__
+
+#include <gtk/gtk.h>
+#include <tny-stream-iface.h>
+#include <tny-msg-iface.h>
+#include <tny-msg-mime-part-iface.h>
+#include <modest-conf.h>
+
+G_BEGIN_DECLS
+
+/* convenience macros */
+#define MODEST_TYPE_MSG_VIEW (modest_msg_view_get_type())
+#define MODEST_MSG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),MODEST_TYPE_MSG_VIEW,ModestMsgView))
+#define MODEST_MSG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),MODEST_TYPE_MSG_VIEW,ModestMsgViewClass))
+#define MODEST_IS_MSG_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),MODEST_TYPE_MSG_VIEW))
+#define MODEST_IS_MSG_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),MODEST_TYPE_MSG_VIEW))
+#define MODEST_MSG_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),MODEST_TYPE_MSG_VIEW,ModestMsgViewClass))
+
+typedef struct _ModestMsgView ModestMsgView;
+typedef struct _ModestMsgViewClass ModestMsgViewClass;
+
+struct _ModestMsgView {
+ GtkScrolledWindow parent;
+};
+
+struct _ModestMsgViewClass {
+ GtkScrolledWindowClass parent_class;
+
+ void (*link_clicked) (GtkWidget *widget, const gchar* link, gpointer user_data);
+ void (*attachment_clicked) (GtkWidget *widget, int index, gpointer user_data);
+};
+
+
+/**
+ * modest_msg_view_get_type
+ *
+ * get the GType for the this class
+ *
+ * Returns: the GType for this class
+ */
+GType modest_msg_view_get_type (void) G_GNUC_CONST;
+
+
+/**
+ * modest_msg_view_new
+ * @tny_msg: a TnyMsgIface instance, or NULL
+ *
+ * create a new ModestMsgView widget (a GtkScrolledWindow subclass),
+ * and display the @tny_msg e-mail message in it. If @tny_msg is NULL,
+ * then a blank page will be displayed
+ *
+ * Returns: a new ModestMsgView widget, or NULL if there's an error
+ */
+GtkWidget* modest_msg_view_new (const TnyMsgIface *tny_msg);
+
+
+/**
+ * modest_msg_view_set_message
+ * @self: a ModestMsgView instance
+ * @tny_msg: a TnyMsgIface instance, or NULL
+ *
+ * display the @tny_msg e-mail message. If @tny_msg is NULL,
+ * then a blank page will be displayed
+ * */
+void modest_msg_view_set_message (ModestMsgView *self,
+ const TnyMsgIface *tny_msg);
+
+/**
+ * modest_msg_view_get_selected_text:
+ * @self: a ModestMsgView instance
+ *
+ * get the user selected part of the message
+ *
+ * Returns: a newly allocated string of the user's selection or NULL if nothing is selected
+ */
+gchar * modest_msg_view_get_selected_text (ModestMsgView *self);
+
+G_END_DECLS
+
+#endif /* __MODEST_MSG_VIEW_H__ */