Showing headers of a folder
About TnyHeader
Note that some naming decisions might confuse some readers: a TnyHeader of a message means all the header lines that are usually put in the summary of a folder. A list of TnyHeader instances is usually the model of a summary view. Therefore can you also think of a TnyHeader as being a summary item.
In the IMAP world you can compare the content of a TnyHeader instance with the ENVELOPE response. In the POP world you can compare it with some of the headers returned by TOP.
However, a TnyHeader that you get from a specific TnyMsg using the tny_msg_get_header API is not the same TnyHeader instance as the one that you will get when using the TnyFolder API, tny_folder_get_headers for that message. The one that you get from TnyMsg can have an empty UID property (tny_header_get_uid will return NULL). This means that you can't use TnyHeader instances that you get from a TnyMsg with the TnyFolder API (like the tny_folder_transfer_msgs).
The Tinymail team knows that this can confuse people. A new version of the API will most likely fix this API confusion by introducing two different types for these instances.
Just showing them, the hello world of headers
The basic idea
You need a TnyFolder instance to get the headers. Both showing folder stores as showing accounts explain in detail how to do that.
Once you have the instance, you can use the tny_folder_get_headers API to get TnyHeader instances in a TnyList.
Sample code getting headers
static void
callback (TnyFolder *self, gboolean cancelled, TnyList *headers, GError *err, gpointer user_data)
{
TnyIterator *iter;
iter = tny_list_create_iterator (headers);
while (!tny_iterator_is_done (iter))
{
ThyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
g_print ("%s\n", tny_header_get_subject (header));
g_object_unref (header);
tny_iterator_next (iter);
}
g_object_unref (iter);
}
static void
status_callback (GObject *self, TnyStatus *status, gpointer user_data)
{
return;
}
static void
on_folder_selected (GtkTreeSelection *selection, gpointer user_data)
{
GtkTreeIter iter;
GtkTreeModel *model;
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
gint type;
gtk_tree_model_get (model, &iter,
TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
&type, -1);
if (type != TNY_FOLDER_TYPE_ROOT) {
TnyFolder *folder = NULL;
gtk_tree_model_get (model, &iter,
TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
&folder, -1);
if (folder != NULL) {
gboolean perform_refresh = TRUE;
TnyList *headers = tny_simple_list_new ();
g_print ("Folder %s selected\n"
tny_folder_get_name (folder));
tny_folder_get_headers_async (folder, headers, perform_refresh,
callback, status_callback, NULL);
g_object_unref (headers);
g_object_unref (folder);
}
}
}
}
static void
create_ui_in (GtkContainer *container)
{
TnyList *accounts;
TnyPlatformFactory *platfact;
TnyAccountStore *account_store;
TnyIterator *iter;
TnyFolderStore *root;
GtkTreeModel *model;
GtkTreeView *view;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
const gchar *name;
GtkTreeSelection *select;
platfact = tny_gnome_platform_factory_get_instance ();
account_store = tny_platform_factory_new_account_store (platfact);
accounts = tny_simple_list_new ();
tny_account_store_get_accounts (account_store, accounts,
TNY_ACCOUNT_STORE_STORE_ACCOUNTS);
iter = tny_list_create_iterator (accounts);
root = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
g_object_unref (iter);
g_object_unref (accounts);
name = tny_account_get_name (TNY_ACCOUNT (root));
model = tny_gtk_folder_store_tree_model_new (FALSE, NULL);
tny_gtk_folder_store_tree_model_prepend (model, root, name);
g_object_unref (G_OBJECT (root));
view = GTK_TREE_VIEW (gtk_tree_view_new ());
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Folder", renderer,
"text", TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN, NULL);
gtk_tree_view_column_set_sort_column_id (column,
TNY_GTK_FOLDER_STORE_TREE_MODEL_NAME_COLUMN);
gtk_tree_view_append_column (view, column);
gtk_tree_view_set_model (view, model);
select = gtk_tree_view_get_selection (view);
g_signal_connect (G_OBJECT (select), "changed",
G_CALLBACK (on_folder_selected), NULL);
g_object_unref (account_store);
g_object_unref (platfact);
gtk_widget_show (GTK_WIDGET (view));
gtk_container_add (container, GTK_WIDGET (view));
}
Showing them in a GtkTreeView
The basic idea
You need a TnyFolder instance to get the headers. Both showing folder stores as showing accounts explain in detail how to do that.
Once you have the instance, you can use the tny_gtk_header_list_model_set_folder API of a TnyGtkHeaderListModel and use that as the model for a GtkTreeView.
Sample code for getting headers and displaying them in a GtkTreeView
static void
callback (TnyFolder *self, gboolean cancelled, TnyList *model, GError *err, gpointer user_data)
{
GtkTreeView *header_view = user_data;
gtk_tree_view_set_model (header_view, GTK_TREE_MODEL (model));
g_object_unref (header_view);
}
static void
status_callback (GObject *self, TnyStatus *status, gpointer user_data)
{
return;
}
static void
on_folder_selected (GtkTreeSelection *selection, gpointer user_data)
{
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreeView *header_view = user_data;
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
gint type;
gtk_tree_model_get (model, &iter,
TNY_GTK_FOLDER_STORE_TREE_MODEL_TYPE_COLUMN,
&type, -1);
if (type != TNY_FOLDER_TYPE_ROOT) {
TnyFolder *folder = NULL;
gtk_tree_model_get (model, &iter,
TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN,
&folder, -1);
if (folder != NULL) {
gboolean perform_refresh = TRUE;
GtkTreeModel *model = tny_gtk_header_list_model_new ();
g_print ("Folder %s selected\n"
tny_folder_get_name (folder));
tny_gtk_header_list_model_set_folder (model, folder, perform_refresh,
callback, status_callback, g_object_ref (header_view));
g_object_unref (model);
g_object_unref (folder);
}
}
}
}
static void
create_ui_in (GtkContainer *container)
{
+ GtkTreeView *header_view = GTK_TREE_VIEW (gtk_tree_view_new ());
+ GtkTreeSelection *select;
...
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Subject",
+ renderer, "text", TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN,
+ NULL);
+ gtk_tree_view_append_column (header_view, column);
+
+ select = gtk_tree_view_get_selection (view);
+ g_signal_connect (G_OBJECT (select), "changed",
+ G_CALLBACK (on_folder_selected), header_view);
gtk_container_add (container, GTK_WIDGET (view));
}
Now that I have the header, now what?
You can for example ask the folder instance for the entire message and ask a message viewer to display it and its mime parts.
For more information about this, continue reading at the showing messages page.
