Showing folder stores

Recursively showing folder stores in a GtkTreeView

The basic idea

The reason why a TnyGtkFolderStoreTreeModel is a TnyFolderStore model rather than a TnyAccount or TnyStoreAccount model is because it can show any kind of TnyFolderStore. A TnyStoreAccount is just one kind of TnyFolderStore. A TnyFolder can also be a TnyFolderStore.

The example will use the platform factory to get the account store, using the account store it will pick a TnyStoreAccount account. This is explained in showing accounts.

Sample code for displaying and filling a GtkTreeView with a folder store

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;

  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);

  /* Get the first account */
  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 (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);

  g_object_unref (account_store);
  g_object_unref (platfact);

  gtk_widget_show (GTK_WIDGET (view));
  gtk_container_add (container, GTK_WIDGET (view));

  return;
}

Sample code for getting the selected folder

You can use the GtkTreeView and GtkTreeModel API with TnyGtkFolderStoreTreeModel instances.

Important to know is that when requesting the instance using gtk_tree_model_get on a G_TYPE_OBJECT columns, a reference gets added. The something_INSTANCE_COLUMNs in Tinymail are all G_TYPE_OBJECT columns. You must remove that reference once you are finished with the instance.

It's a good practice to test the retrieved value for being not-NULL. Under normal circumstances it should never be NULL in this case. Else gtk_tree_selection_get_selected would have returned FALSE.

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) {
			g_print ("Folder %s selected\n"
				tny_folder_get_name (folder));
			g_object_unref (folder);
		}
	}
  } 
}

static void 
create_ui_in (GtkContainer *container)
{
+   GtkTreeSelection *select;
    ...
+
+   select = gtk_tree_view_get_selection (view);
+   g_signal_connect (G_OBJECT (select), "changed",
+	G_CALLBACK (on_folder_selected), NULL);

    gtk_container_add (container, GTK_WIDGET (view));
}

With queries

Using a query you can limit the folders that will be put in the TnyList by the tny_folder_store_get_folders API of TnyFolderStore. The TnyGtkFolderStoreTreeModel also supports this mechanism.

The second argument of the constructor of the type is the query object. If you pass NULL, it means that no query is used. In other words, all folders will match. You can put a query that filters on subscription status, on name and on the folder id.

static void 
create_ui_in (GtkContainer *container)
{
+  TnyFolderStoreQuery *query;

+  query = tny_folder_store_query_new ();
+  tny_folder_store_query_add_item (query, "^GNOME$", 
+      TNY_FOLDER_STORE_QUERY_OPTION_MATCH_ON_NAME);
   ...
-  model = tny_gtk_folder_store_tree_model_new (FALSE, NULL);
+  model = tny_gtk_folder_store_tree_model_new (FALSE, query);
+  g_object_unref (query);
   ...
}

References to related other documentation