gnome-utils r7986 - in trunk/baobab: . src



Author: pborelli
Date: Mon Aug  4 09:05:32 2008
New Revision: 7986
URL: http://svn.gnome.org/viewvc/gnome-utils?rev=7986&view=rev

Log:
2008-08-04  Paolo Borelli  <pborelli katamail com>

	Patch contributed by Eduardo Lima <elima igalia com>, bug #541407

	* src/baobab-chart.c:
	* src/baobab.c:
	* src/baobab-ringschart.c:
	* src/baobab-chart.h:
	* src/baobab.h:
	* src/baobab-rngschart.h:
	* src/callbacks.c:
	* src/callbacks.h:

	Reimplemeny the ringschart as a subclass of BaobabChart.



Modified:
   trunk/baobab/ChangeLog
   trunk/baobab/src/baobab-chart.c
   trunk/baobab/src/baobab-chart.h
   trunk/baobab/src/baobab-ringschart.c
   trunk/baobab/src/baobab-ringschart.h
   trunk/baobab/src/baobab.c
   trunk/baobab/src/baobab.h
   trunk/baobab/src/callbacks.c
   trunk/baobab/src/callbacks.h

Modified: trunk/baobab/src/baobab-chart.c
==============================================================================
--- trunk/baobab/src/baobab-chart.c	(original)
+++ trunk/baobab/src/baobab-chart.c	Mon Aug  4 09:05:32 2008
@@ -51,22 +51,8 @@
 };
 
 
-typedef struct _BaobabChartContextMenu BaobabChartContextMenu;
-
-struct _BaobabChartContextMenu
-{
-  GtkWidget *menu;
-  GtkWidget *set_root_item;
-  GtkWidget *up_item;
-  GtkWidget *zoom_in_item;
-  GtkWidget *zoom_out_item;
-  GtkWidget *snapshot_item;
-};
-
-
 struct _BaobabChartPrivate
 {
-  gchar *total_fs_size;
   gboolean summary_mode;
 
   guint name_column;
@@ -87,15 +73,12 @@
   GList *first_item;
   GList *last_item;
   GList *highlighted_item;
-
-  BaobabChartContextMenu context_menu;
 };
 
 /* Signals */
 enum
 {
-  SECTOR_ACTIVATED,
-  POPULATE_MENU,
+  ITEM_ACTIVATED,
   LAST_SIGNAL
 };
 
@@ -183,8 +166,6 @@
                                             gboolean    keyboard_mode,
                                             GtkTooltip *tooltip,
                                             gpointer    user_data);
-static gboolean baobab_chart_on_set_root_item (GtkCheckMenuItem *menuitem,
-                                               gpointer data);
 
 
 static void
@@ -209,6 +190,8 @@
 
   /* Baobab Chart abstract methods */
   class->draw_item               = NULL;
+  class->pre_draw                = NULL;
+  class->post_draw               = NULL;
   class->calculate_item_geometry = NULL;
   class->is_point_over_item      = NULL;
   class->get_item_rectangle      = NULL;
@@ -239,26 +222,16 @@
                                    GTK_TYPE_TREE_ITER,
                                    G_PARAM_READWRITE));
 
-  baobab_chart_signals[SECTOR_ACTIVATED] =
-    g_signal_new ("sector_activated",
+  baobab_chart_signals[ITEM_ACTIVATED] =
+    g_signal_new ("item_activated",
           G_TYPE_FROM_CLASS (obj_class),
           G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-          G_STRUCT_OFFSET (BaobabChartClass, sector_activated),
+          G_STRUCT_OFFSET (BaobabChartClass, item_activated),
           NULL, NULL,
           g_cclosure_marshal_VOID__BOXED,
           G_TYPE_NONE, 1,
           GTK_TYPE_TREE_ITER);
 
-  baobab_chart_signals[POPULATE_MENU] =
-    g_signal_new ("populate_menu",
-          G_TYPE_FROM_CLASS (obj_class),
-          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-          G_STRUCT_OFFSET (BaobabChartClass, sector_activated),
-          NULL, NULL,
-          g_cclosure_marshal_VOID__BOXED,
-          G_TYPE_NONE, 1,
-          GTK_TYPE_WIDGET);
-
   g_type_class_add_private (obj_class, sizeof (BaobabChartPrivate));
 }
 
@@ -266,12 +239,10 @@
 baobab_chart_init (BaobabChart *chart)
 {
   BaobabChartPrivate *priv;
-  BaobabChartContextMenu *menu;
 
   priv = BAOBAB_CHART_GET_PRIVATE (chart);
   chart->priv = priv;
 
-  priv->total_fs_size = NULL;
   priv->summary_mode = TRUE;
   priv->model = NULL;
   priv->max_depth = BAOBAB_CHART_MAX_DEPTH;
@@ -288,48 +259,6 @@
   priv->first_item = NULL;
   priv->last_item = NULL;
   priv->highlighted_item = NULL;
-
-  /* Init Context Menu */
-  menu = &priv->context_menu;
-  menu->set_root_item = NULL;
-
-  menu->menu = gtk_menu_new ();
-
-  menu->up_item = gtk_image_menu_item_new_with_label (_("Move to parent folder"));
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu->up_item),
-                                 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
-                                                           GTK_ICON_SIZE_MENU));
-
-  menu->zoom_in_item = gtk_image_menu_item_new_with_label (_("Zoom in"));
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu->zoom_in_item),
-                                 gtk_image_new_from_stock (GTK_STOCK_ADD,
-                                                           GTK_ICON_SIZE_MENU));
-
-  menu->zoom_out_item = gtk_image_menu_item_new_with_label (_("Zoom out"));
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu->zoom_out_item),
-                                 gtk_image_new_from_stock (GTK_STOCK_REMOVE,
-                                                           GTK_ICON_SIZE_MENU));
-
-  menu->snapshot_item = gtk_image_menu_item_new_with_label (_("Save snapshot"));
-  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu->snapshot_item),
-                                 gtk_image_new_from_file (BAOBAB_PIX_DIR "shot.png"));
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
-                         menu->up_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
-                         gtk_separator_menu_item_new ());
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
-                         menu->zoom_in_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
-                         menu->zoom_out_item);
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
-                         gtk_separator_menu_item_new ());
-
-  gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu),
-                         menu->snapshot_item);
-
-  gtk_widget_show_all (menu->menu);
 }
 
 static void
@@ -341,13 +270,6 @@
 
   priv = BAOBAB_CHART (object)->priv;
 
-  /* Free context menu */
-  g_object_unref (priv->context_menu.menu);
-
-  /* Free total filesystem capacity label */
-  if (priv->total_fs_size != NULL)
-    g_free (priv->total_fs_size);
-
   if (priv->model)
     {
       baobab_chart_disconnect_signals (GTK_WIDGET (object),
@@ -555,8 +477,8 @@
 
       g_free (item->name);
       g_free (item->size);
-      if (item->data != NULL)
-        g_free (item->data);
+
+      g_free (item->data);
       item->data = NULL;
 
       g_free (item);
@@ -574,7 +496,7 @@
 baobab_chart_get_items (GtkWidget *chart, GtkTreePath *root)
 {
   BaobabChartPrivate *priv;
-  BaobabChartItem *item;
+  BaobabChartItem *item, *child_item;
 
   GList *node;
   GtkTreeIter initial_iter = {0};
@@ -601,27 +523,27 @@
   model_root_path = gtk_tree_path_new_first ();
   gtk_tree_model_get_iter (priv->model, &model_root_iter, model_root_path);
   gtk_tree_path_free (model_root_path);
+
   gtk_tree_model_get (priv->model, &model_root_iter,
                       priv->percentage_column, &size, -1);
 
+  /* Create first item */
+  node = baobab_chart_add_item (chart, 0, 0, 100, initial_iter);
+
+  /* If summary mode, insert a new item that will become root */
   if (priv->summary_mode)
     {
-      node = baobab_chart_add_item (chart, 0, 0, 100, initial_iter);
       item = (BaobabChartItem *) node->data;
-      g_free (item->name);
       g_free (item->size);
-      item->name = g_strdup (_("Total filesystem capacity"));
-      item->size = g_strdup (priv->total_fs_size);
+      item->size = NULL;
 
       child_node = baobab_chart_add_item (chart, 1, 0, size, initial_iter);
-      item = (BaobabChartItem *) child_node->data;
-      item->parent = node;
-      g_free (item->name);
-      item->name = g_strdup (_("Total filesystem usage"));
+      child_item = (BaobabChartItem *) child_node->data;
+      child_item->parent = node;
+      child_item->name = item->name;
+
+      item->name = NULL;
     }
-  else
-    /* Create first item */
-    node = baobab_chart_add_item (chart, 0, 0, 100, initial_iter);
 
   /* Iterate through childs building the list */
   class = BAOBAB_CHART_GET_CLASS (chart);
@@ -629,7 +551,9 @@
   do
     {
       item = (BaobabChartItem *) node->data;
-      item->has_any_child = gtk_tree_model_iter_children (priv->model, &child_iter, &(item->iter));
+      item->has_any_child = gtk_tree_model_iter_children (priv->model, 
+                                                          &child_iter, 
+                                                          &(item->iter));
 
       /* Calculate item geometry */
       class->calculate_item_geometry (chart, item);
@@ -687,6 +611,10 @@
   priv = BAOBAB_CHART_GET_PRIVATE (chart);
   class = BAOBAB_CHART_GET_CLASS (chart);
 
+  /* call pre-draw abstract method */
+  if (class->pre_draw)
+    class->pre_draw (chart, cr);
+
   cairo_save (cr);
 
   node = priv->first_item;
@@ -705,6 +633,10 @@
     }
 
   cairo_restore (cr);
+
+  /* call post-draw abstract method */
+  if (class->post_draw)
+    class->post_draw (chart, cr);
 }
 
 static void
@@ -884,8 +816,10 @@
       if (priv->root != NULL)
         root_path = gtk_tree_row_reference_get_path (priv->root);
 
-      if (root_path == NULL)
+      if (root_path == NULL) {
         root_path = gtk_tree_path_new_first ();
+        priv->root = NULL;
+      }
 
       /* Check if tree model was modified in any way */
       if ((priv->model_changed) ||
@@ -981,20 +915,19 @@
                              GdkEventButton *event)
 {
   BaobabChartPrivate *priv;
-  GtkTreePath *root_path;
-  BaobabChartContextMenu *menu;
-  BaobabChartItem *item;
-  char *text;
 
   priv = BAOBAB_CHART (widget)->priv;
 
+  if (priv->is_frozen)
+    return TRUE;
+
   switch (event->button)
     {
     case LEFT_BUTTON:
       /* Enter into a subdir */
       if (priv->highlighted_item != NULL)
         g_signal_emit (BAOBAB_CHART (widget),
-                       baobab_chart_signals[SECTOR_ACTIVATED],
+                       baobab_chart_signals[ITEM_ACTIVATED],
                        0, &((BaobabChartItem*) priv->highlighted_item->data)->iter);
 
       break;
@@ -1003,64 +936,9 @@
       /* Go back to the parent dir */
       baobab_chart_move_up_root (widget);
       break;
-
-    case RIGHT_BUTTON:
-      {
-        /* Popup context menu */
-        root_path = baobab_chart_get_root (widget);
-
-        menu = &priv->context_menu;
-
-        if (menu->set_root_item != NULL)
-          {
-            g_signal_handlers_disconnect_by_func (menu->set_root_item,
-                                                  baobab_chart_on_set_root_item,
-                                                  widget);
-            gtk_container_remove (GTK_CONTAINER (menu->menu), menu->set_root_item);
-            menu->set_root_item = NULL;
-          }
-
-        if ((! priv->summary_mode) &&
-            (priv->highlighted_item != NULL) &&
-            (priv->highlighted_item != priv->first_item))
-          {
-            item = (BaobabChartItem *) priv->highlighted_item->data;
-            text = g_strconcat ("Move to folder '", item->name, "'", NULL);
-
-            menu->set_root_item = gtk_image_menu_item_new_with_label (_(text));
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu->set_root_item),
-                                           gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,
-                                                                     GTK_ICON_SIZE_MENU));
-            gtk_menu_shell_prepend (GTK_MENU_SHELL (menu->menu),
-                                    menu->set_root_item);
-
-            g_signal_connect (menu->set_root_item, "activate",
-                              G_CALLBACK (baobab_chart_on_set_root_item), widget);
-
-            gtk_widget_show (menu->set_root_item);
-
-            g_free (text);
-          }
-
-        gtk_widget_set_sensitive (menu->up_item,
-                                 ((root_path != NULL) &&
-                                 (gtk_tree_path_get_depth (root_path) > 1)));
-        gtk_widget_set_sensitive (menu->zoom_in_item,
-                                  (baobab_chart_get_max_depth (widget) > BAOBAB_CHART_MIN_DEPTH));
-        gtk_widget_set_sensitive (menu->zoom_out_item,
-                                  (baobab_chart_get_max_depth (widget) < BAOBAB_CHART_MAX_DEPTH));
-
-        g_signal_emit (BAOBAB_CHART (widget),
-                       baobab_chart_signals[POPULATE_MENU],
-                       0, menu->menu);
-
-        gtk_menu_popup (GTK_MENU (menu->menu), NULL, NULL, NULL, NULL,
-                        event->button, event->time);
-      }
-      break;
     }
 
-  return TRUE;
+  return FALSE;
 }
 
 static gint
@@ -1074,7 +952,7 @@
     case GDK_SCROLL_LEFT :
     case GDK_SCROLL_UP :
       baobab_chart_zoom_out (widget);
-      /* change the selected sector when zooming */
+      /* change the selected item when zooming */
       baobab_chart_motion_notify (widget, (GdkEventMotion *)event);
       break;
 
@@ -1172,58 +1050,10 @@
   return FALSE;
 }
 
-static gboolean
-baobab_chart_on_set_root_item (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  BaobabChartPrivate *priv;
-
-  priv = BAOBAB_CHART_GET_PRIVATE (data);
-
-  g_signal_emit (BAOBAB_CHART (data),
-                 baobab_chart_signals[SECTOR_ACTIVATED],
-                 0, &((BaobabChartItem*) priv->highlighted_item->data)->iter);
-
-  return TRUE;
-}
-
-static gboolean
-baobab_chart_on_up_menu_item (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  baobab_chart_move_up_root (GTK_WIDGET (data));
-
-  return TRUE;
-}
-
-static gboolean
-baobab_chart_on_zoom_in_menu_item (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  baobab_chart_zoom_in (GTK_WIDGET (data));
-
-  return TRUE;
-}
-
-static gboolean
-baobab_chart_on_zoom_out_menu_item (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  baobab_chart_zoom_out (GTK_WIDGET (data));
-
-  return TRUE;
-}
-
-static gboolean
-baobab_chart_on_snapshot_menu_item (GtkCheckMenuItem *menuitem, gpointer data)
-{
-  baobab_chart_save_snapshot (GTK_WIDGET (data));
-
-  return TRUE;
-}
-
 static inline void
 baobab_chart_connect_signals (GtkWidget *chart,
                               GtkTreeModel *model)
 {
-  BaobabChartContextMenu *menu;
-
   g_signal_connect (model,
                     "row_changed",
                     G_CALLBACK (baobab_chart_row_changed),
@@ -1244,12 +1074,10 @@
                     "rows_reordered",
                     G_CALLBACK (baobab_chart_rows_reordered),
                     chart);
-
   g_signal_connect (chart,
                     "query-tooltip",
                     G_CALLBACK (baobab_chart_query_tooltip),
                     chart);
-
   g_signal_connect (chart,
                     "motion-notify-event",
                     G_CALLBACK (baobab_chart_motion_notify),
@@ -1258,31 +1086,16 @@
                     "leave-notify-event",
                     G_CALLBACK (baobab_chart_leave_notify),
                     chart);
-
   g_signal_connect (chart,
                     "button-release-event",
                     G_CALLBACK (baobab_chart_button_release),
                     chart);
-
-  /* Activate context menu callbacks */
-  menu = &BAOBAB_CHART_GET_PRIVATE (chart)->context_menu;
-
-  g_signal_connect (menu->up_item, "activate",
-                    G_CALLBACK (baobab_chart_on_up_menu_item), chart);
-  g_signal_connect (menu->zoom_in_item, "activate",
-                    G_CALLBACK (baobab_chart_on_zoom_in_menu_item), chart);
-  g_signal_connect (menu->zoom_out_item, "activate",
-                    G_CALLBACK (baobab_chart_on_zoom_out_menu_item), chart);
-  g_signal_connect (menu->snapshot_item, "activate",
-                    G_CALLBACK (baobab_chart_on_snapshot_menu_item), chart);
 }
 
 static inline void
 baobab_chart_disconnect_signals (GtkWidget *chart,
                                  GtkTreeModel *model)
 {
-  BaobabChartContextMenu *menu;
-
   g_signal_handlers_disconnect_by_func (model,
                                         baobab_chart_row_changed,
                                         chart);
@@ -1298,37 +1111,18 @@
   g_signal_handlers_disconnect_by_func (model,
                                         baobab_chart_rows_reordered,
                                         chart);
-
   g_signal_handlers_disconnect_by_func (chart,
                                         baobab_chart_query_tooltip,
                                         chart);
-
   g_signal_handlers_disconnect_by_func (chart,
                                         baobab_chart_motion_notify,
                                         chart);
   g_signal_handlers_disconnect_by_func (chart,
                                         baobab_chart_leave_notify,
                                         chart);
-
   g_signal_handlers_disconnect_by_func (chart,
                                         baobab_chart_button_release,
                                         chart);
-
-  /* Deactivate context menu callbacks */
-  menu = &BAOBAB_CHART_GET_PRIVATE (chart)->context_menu;
-
-  g_signal_handlers_disconnect_by_func (menu->up_item,
-                                        baobab_chart_on_up_menu_item,
-                                        chart);
-  g_signal_handlers_disconnect_by_func (menu->zoom_in_item,
-                                        baobab_chart_on_zoom_in_menu_item,
-                                        chart);
-  g_signal_handlers_disconnect_by_func (menu->zoom_out_item,
-                                        baobab_chart_on_zoom_out_menu_item,
-                                        chart);
-  g_signal_handlers_disconnect_by_func (menu->snapshot_item,
-                                        baobab_chart_on_snapshot_menu_item,
-                                        chart);
 }
 
 static gboolean
@@ -1350,6 +1144,9 @@
 
   item = (BaobabChartItem *) priv->highlighted_item->data;
 
+  if ( (item->name == NULL) || (item->size == NULL) )
+    return FALSE;
+
   gtk_tooltip_set_tip_area (tooltip, &item->rect);
 
   markup = g_strconcat (item->name,
@@ -1434,13 +1231,13 @@
  **/
 void
 baobab_chart_set_model_with_columns (GtkWidget *chart,
-                                          GtkTreeModel *model,
-                                          guint name_column,
-                                          guint size_column,
-                                          guint info_column,
-                                          guint percentage_column,
-                                          guint valid_column,
-                                          GtkTreePath *root)
+                                     GtkTreeModel *model,
+                                     guint name_column,
+                                     guint size_column,
+                                     guint info_column,
+                                     guint percentage_column,
+                                     guint valid_column,
+                                     GtkTreePath *root)
 {
   BaobabChartPrivate *priv;
 
@@ -1604,6 +1401,8 @@
                        GtkTreePath *root)
 {
   BaobabChartPrivate *priv;
+  GtkTreeIter iter = {0};
+  GtkTreePath *current_root;
 
   g_return_if_fail (BAOBAB_IS_CHART (chart));
 
@@ -1611,8 +1410,15 @@
 
   g_return_if_fail (priv->model != NULL);
 
-  if (priv->root)
+  if (priv->root) {
+    /* Check that given root is different from current */
+    current_root = gtk_tree_row_reference_get_path (priv->root);
+    if ( (current_root) && (gtk_tree_path_compare (current_root, root) == 0) )
+      return;
+
+    /* Free current root */
     gtk_tree_row_reference_free (priv->root);
+  }
 
   priv->root = gtk_tree_row_reference_new (priv->model, root);
 
@@ -1829,7 +1635,7 @@
       gtk_tree_path_free (parent_path);
 
       g_signal_emit (BAOBAB_CHART (chart),
-                     baobab_chart_signals[SECTOR_ACTIVATED],
+                     baobab_chart_signals[ITEM_ACTIVATED],
                      0, &parent_iter);
 
       gtk_widget_queue_draw (chart);
@@ -1842,7 +1648,8 @@
  * baobab_chart_save_snapshot:
  * @chart: the #BaobabChart requested to be exported to image.
  *
- * Opens a dialog to allow saving the current chart's image as a PNG, JPEG or BMP image.
+ * Opens a dialog to allow saving the current chart's image as a PNG, JPEG or 
+ * BMP image.
  *
  * Fails if @chart is not a #BaobabChart.
  **/
@@ -1863,11 +1670,6 @@
 
   g_return_if_fail (BAOBAB_IS_CHART (chart));
 
-  /* Popdown context menu */
-  priv = BAOBAB_CHART_GET_PRIVATE (chart);
-  gtk_menu_popdown (GTK_MENU (priv->context_menu.menu));
-  gtk_widget_queue_draw (chart);
-
   while (gtk_events_pending ())
     gtk_main_iteration ();
 
@@ -1941,43 +1743,84 @@
 }
 
 /**
- * baobab_chart_set_total_fs_size:
- * @chart: the #BaobabChart to set the filesystem size to.
- * @total_fs_size: The total filesystem size.
+ * baobab_chart_set_summary_mode:
+ * @chart: the #BaobabChart to set summary mode to.
+ * @summary_mode: boolean specifying TRUE is summary mode is on.
  *
- * Sets the total filesystem size, to be shown as tooltip when summary mode is on.
+ * Toggles on/off the summary mode (the initial mode that shows general state
+ * before any scan has been made).
  *
  * Fails if @chart is not a #BaobabChart.
  **/
 void
-baobab_chart_set_total_fs_size (GtkWidget *chart, guint64 total_fs_size)
+baobab_chart_set_summary_mode (GtkWidget *chart,
+                               gboolean summary_mode)
 {
   BaobabChartPrivate *priv;
 
   g_return_if_fail (BAOBAB_IS_CHART (chart));
 
   priv = BAOBAB_CHART_GET_PRIVATE (chart);
-  priv->total_fs_size = g_format_size_for_display (total_fs_size);
+  priv->summary_mode = summary_mode;
 }
 
 /**
- * baobab_chart_set_summary_mode:
- * @chart: the #BaobabChart to set summary mode to.
- * @summary_mode: boolean specifying TRUE is summary mode is on.
+ * baobab_chart_get_summary_mode:
+ * @chart: the #BaobabChart to obtain summary mode from.
  *
- * Toggles on/off the summary mode (the initial mode that shows filesystem
- * usage and capacity.
+ * Returns a boolean representing whether the chart is in summary mode (the 
+ * initial mode that shows general state before any scan has been made).
  *
  * Fails if @chart is not a #BaobabChart.
  **/
-void
-baobab_chart_set_summary_mode (GtkWidget *chart,
-                               gboolean summary_mode)
+gboolean
+baobab_chart_get_summary_mode (GtkWidget *chart)
 {
   BaobabChartPrivate *priv;
 
   g_return_if_fail (BAOBAB_IS_CHART (chart));
 
   priv = BAOBAB_CHART_GET_PRIVATE (chart);
-  priv->summary_mode = summary_mode;
+  return priv->summary_mode;
+}
+
+/**
+ * baobab_chart_is_frozen:
+ * @chart: the #BaobabChart to ask if frozen.
+ *
+ * Returns a boolean telling whether the chart is in a frozen state, meanning 
+ * that no actions should be taken uppon it.
+ *
+ * Fails if @chart is not a #BaobabChart.
+ **/
+gboolean
+baobab_chart_is_frozen (GtkWidget *chart)
+{
+  BaobabChartPrivate *priv;
+
+  g_return_if_fail (BAOBAB_IS_CHART (chart));
+
+  priv = BAOBAB_CHART_GET_PRIVATE (chart);
+  return priv->is_frozen;
+}
+
+/**
+ * baobab_chart_is_frozen:
+ * @chart: the #BaobabChart to obtain the highlighted it from.
+ *
+ * Returns a BaobabChartItem corresponding to the item that currently has mouse 
+ * pointer over, or NULL if no item is highlighted.
+ *
+ * Fails if @chart is not a #BaobabChart.
+ **/
+BaobabChartItem *
+baobab_chart_get_highlighted_item (GtkWidget *chart)
+{
+  BaobabChartPrivate *priv;
+
+  g_return_if_fail (BAOBAB_IS_CHART (chart));
+
+  priv = BAOBAB_CHART_GET_PRIVATE (chart);
+  return (priv->highlighted_item ? 
+    (BaobabChartItem *) priv->highlighted_item->data : NULL);
 }

Modified: trunk/baobab/src/baobab-chart.h
==============================================================================
--- trunk/baobab/src/baobab-chart.h	(original)
+++ trunk/baobab/src/baobab-chart.h	Mon Aug  4 09:05:32 2008
@@ -93,7 +93,7 @@
   GtkWidgetClass parent_class;
 
   /* Signal prototypes */
-  void (* sector_activated) (BaobabChart *chart,
+  void (* item_activated) (BaobabChart *chart,
                              GtkTreeIter *iter);
 
   /* Abstract methods */
@@ -102,6 +102,12 @@
                       BaobabChartItem *item,
                       gboolean highlighted);
 
+  void (* pre_draw) (GtkWidget *chart,
+                     cairo_t *cr);
+
+  void (* post_draw) (GtkWidget *chart,
+                      cairo_t *cr);
+
   void (* calculate_item_geometry) (GtkWidget *chart,
                                     BaobabChartItem *item);
 
@@ -143,10 +149,11 @@
 void baobab_chart_zoom_in (GtkWidget *chart);
 void baobab_chart_zoom_out (GtkWidget *chart);
 void baobab_chart_save_snapshot (GtkWidget *chart);
-void baobab_chart_set_total_fs_size (GtkWidget *chart,
-                                     guint64 total_fs_size);
 void baobab_chart_set_summary_mode (GtkWidget *chart,
                                     gboolean summary_mode);
+gboolean baobab_chart_get_summary_mode (GtkWidget *chart);
+gboolean baobab_chart_is_frozen (GtkWidget *chart);
+BaobabChartItem *baobab_chart_get_highlighted_item (GtkWidget *chart);
 
 G_END_DECLS
 

Modified: trunk/baobab/src/baobab-ringschart.c
==============================================================================
--- trunk/baobab/src/baobab-ringschart.c	(original)
+++ trunk/baobab/src/baobab-ringschart.c	Mon Aug  4 09:05:32 2008
@@ -1,7 +1,7 @@
 /*
  * baobab-ringschart.c
  *
- * Copyright (C) 2006, 2007, 2008 Igalia
+ * Copyright (C) 2008 Igalia
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
  * Boston, MA  02110-1301  USA
  *
  * Authors:
@@ -31,1763 +31,609 @@
  *   Alejandro Garcia <alex igalia com>
  */
 
-#include <config.h>
 #include <math.h>
+#include <string.h>
+
 #include <gtk/gtk.h>
 #include <pango/pangocairo.h>
-#include <glib/gi18n.h>
 
+#include "baobab-chart.h"
 #include "baobab-ringschart.h"
 
-#define MIN_DRAWABLE_ANGLE 0.03
-#define EDGE_ANGLE 0.01
-#define FILE_COLOR 0.6
-#define WINDOW_PADDING 5
-#define TOOLTIP_PADDING 3
-#define SUBFOLDERTIP_TRANSP 0.666
-#define TOOLTIP_TRANSP 0.666
-#define TOOLTIP_SPACING 1
-#define TOOLTIP_TIMEOUT 300 /* miliseconds before showing the tooltip
-                               window after mouse pointer rests over
-                               a sector */
-
 #define BAOBAB_RINGSCHART_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
                                             BAOBAB_RINGSCHART_TYPE, \
                                             BaobabRingschartPrivate))
 
-G_DEFINE_TYPE (BaobabRingschart, baobab_ringschart, GTK_TYPE_WIDGET);
+#define CENTER_X(widget) (widget->allocation.width / 2)
+#define CENTER_Y(widget) (widget->allocation.height / 2)
 
-enum {
-  LEFT_BUTTON = 1,
-  MIDDLE_BUTTON = 2,
-  RIGHT_BUTTON = 3
-};
+#define ITEM_BORDER_WIDTH  1
+#define CHART_PADDING     13
+#define ITEM_MIN_ANGLE     0.03
+#define EDGE_ANGLE         0.004
 
-struct _BaobabRingschartPrivate {
-  GtkTreeModel *model;
-  gdouble center_x;
-  gdouble center_y;
-  gdouble max_radius;
-  gdouble min_radius;
-  gdouble thickness;
-  gdouble pointer_x;
-  gdouble pointer_y;
-  guint max_depth;
-  guint name_column;
-  guint size_column;
-  guint info_column;
-  guint percentage_column;
-  guint valid_column;
-  guint current_depth;
-  gint drawn_elements;
-  gdouble current_init_angle;
-  gdouble current_final_angle;
-  gdouble point_angle;
-  gboolean button_pressed;
-  gboolean real_sector;
-  gboolean is_frozen;
-  gboolean transparent_tips;
-  gboolean subfoldertips_enabled;
-  guint timeout_event_source;
-  gboolean draw_tooltip;
-  gboolean draw_children_tooltips;
-  guint init_depth;
-  gboolean draw_center;
-  cairo_surface_t *memento;
-  GtkTreeRowReference *root;
-};
-
-typedef struct _Color Color;
-
-struct _Color {
-  gdouble red;
-  gdouble green;
-  gdouble blue;
-};
-
-typedef struct _Tooltip Tooltip;
-
-struct _Tooltip {
-  gdouble init_angle;
-  gdouble final_angle;
-  gint depth;
-  gchar *name;
-  gchar *size;
-  GtkTreeRowReference *ref;
-};
+#define SUBFOLDER_TIP_PADDING 3
 
-struct _Tooltip_rectangle {
-  gdouble x;
-  gdouble y;
-  gdouble width;
-  gdouble height;
-};
+G_DEFINE_TYPE (BaobabRingschart, baobab_ringschart, BAOBAB_CHART_TYPE);
 
-typedef struct _Tooltip_rectangle Tooltip_rectangle;
+typedef struct _BaobabRingschartItem BaobabRingschartItem;
 
-/* Signals */
-enum {
-  SECTOR_ACTIVATED,
-  LAST_SIGNAL
+struct _BaobabRingschartItem
+{
+  gdouble min_radius;
+  gdouble max_radius;
+  gdouble start_angle;
+  gdouble angle;
+  gboolean continued;
 };
 
-static guint ringschart_signals [LAST_SIGNAL] = { 0 };
-
-/* Properties */
-enum {
-  PROP_0,
-  PROP_MAX_DEPTH,
-  PROP_MODEL,
-  PROP_ROOT,
+struct _BaobabRingschartPrivate
+{
+  gboolean subfoldertips_enabled;
+  BaobabChartItem *highlighted_item;
+  guint tips_timeout_event;
+  GList *subtip_items;
+  gboolean drawing_subtips;
+  gint subtip_timeout;
 };
 
-const Color tango_colors[]  = {{0.94, 0.16, 0.16}, /* tango: ef2929 */
-                               {0.68, 0.49, 0.66}, /* tango: ad7fa8 */
-                               {0.45, 0.62, 0.82}, /* tango: 729fcf */
-                               {0.54, 0.89, 0.20}, /* tango: 8ae234 */
-                               {0.91, 0.73, 0.43}, /* tango: e9b96e */
-                               {0.99, 0.68, 0.25}}; /* tango: fcaf3e */
-
 static void baobab_ringschart_class_init (BaobabRingschartClass *class);
 static void baobab_ringschart_init (BaobabRingschart *object);
-static void baobab_ringschart_realize (GtkWidget *widget);
-static void baobab_ringschart_dispose (GObject *object);
-static void baobab_ringschart_size_allocate (GtkWidget *widget,
-                                             GtkAllocation *allocation);
-static void baobab_ringschart_set_property (GObject *object,
-                                            guint prop_id,
-                                            const GValue *value,
-                                            GParamSpec *pspec);
-static void baobab_ringschart_get_property (GObject *object,
-                                            guint prop_id,
-                                            GValue *value,
-                                            GParamSpec *pspec);
-static void baobab_ringschart_update_draw (BaobabRingschart *rchart,
-                                           GtkTreePath *path);
-static void baobab_ringschart_row_changed (GtkTreeModel *model,
-                                           GtkTreePath *path,
-                                           GtkTreeIter *iter,
-                                           gpointer data);
-static void baobab_ringschart_row_inserted (GtkTreeModel *model,
-                                            GtkTreePath *path,
-                                            GtkTreeIter *iter,
-                                            gpointer data);
-static void baobab_ringschart_row_has_child_toggled (GtkTreeModel *model,
-                                                     GtkTreePath *path,
-                                                     GtkTreeIter *iter,
-                                                     gpointer data);
-static void baobab_ringschart_row_deleted (GtkTreeModel *model,
-                                           GtkTreePath *path,
-                                           gpointer data);
-static void baobab_ringschart_rows_reordered (GtkTreeModel *model,
-                                              GtkTreePath *parent,
-                                              GtkTreeIter *iter,
-                                              gint *new_order,
-                                              gpointer data);
-static gboolean baobab_ringschart_expose (GtkWidget *rchart, 
-                                          GdkEventExpose *event);
-static void baobab_ringschart_draw (GtkWidget *rchart, 
-                                    cairo_t *cr);
-static void draw_sector (cairo_t *cr, 
-                         gdouble center_x, 
-                         gdouble center_y,
-                         gdouble radius,
-                         gdouble thickness,
-                         gdouble init_angle,
-                         gdouble final_angle,
-                         Color fill_color,
-                         gboolean continued);
-static void draw_circle (cairo_t *cr, 
-                         gdouble center_x, 
-                         gdouble center_y,
-                         gdouble radius,
-                         gboolean highlighted);
-static void draw_tooltips (GtkWidget *rchart,
-                           cairo_t *cr,
-                           GSList *tooltips);
-static void draw_tip (cairo_t *cr,
-                      GtkWidget *rchart,
-                      gdouble init_angle,
-                      gdouble final_angle,
-                      gdouble depth,
-                      gchar *name,
-                      gchar *size);
-static void draw_folder_tip (cairo_t *cr,
-                             GtkWidget *rchart,
-                             gdouble init_angle,
-                             gdouble final_angle,
-                             gdouble depth,
-                             gchar *name,
-                             gchar *size,
-                             Tooltip_rectangle *previous_rectangle);
-static void interpolate_colors (Color *color,
-                                Color colora,
-                                Color colorb,
-                                gdouble percentage);
-static void get_color (Color *color,
-                       gdouble angle,
-                       gint circle_number,
-                       gboolean highlighted);
-static void tree_traverse (cairo_t *cr,
-                           BaobabRingschart *rchart,
-                           GtkTreeIter *iter,
-                           guint depth,
-                           gdouble radius,
-                           gdouble init_angle,
-                           gdouble final_angle,
-                           GSList **tooltips,
-                           gboolean real_draw);
-static gint baobab_ringschart_button_release (GtkWidget *widget,
-                                              GdkEventButton *event);
-static gint baobab_ringschart_scroll (GtkWidget *widget,
-                                      GdkEventScroll *event);
-static gint baobab_ringschart_motion_notify (GtkWidget *widget,
-                                             GdkEventMotion *event);
-static inline void baobab_ringschart_disconnect_signals (GtkWidget *rchart, 
-                                                         GtkTreeModel *model);
-static inline void baobab_ringschart_connect_signals (GtkWidget *rchart,
-                                                      GtkTreeModel *model);
+static void baobab_ringschart_draw_sector (cairo_t *cr,
+                                           gdouble center_x, gdouble center_y,
+                                           gdouble radius, gdouble thickness,
+                                           gdouble init_angle, gdouble final_angle,
+                                           BaobabChartColor fill_color,
+                                           gboolean continued, guint border);
+static void baobab_ringschart_draw_item (GtkWidget *chart,
+                                         cairo_t *cr,
+                                         BaobabChartItem *item,
+                                         gboolean highlighted);
+static void baobab_ringschart_calculate_item_geometry (GtkWidget *chart,
+                                                       BaobabChartItem *item);
+static gboolean baobab_ringschart_is_point_over_item (GtkWidget *chart,
+                                                      BaobabChartItem *item,
+                                                      gdouble x,
+                                                      gdouble y);
+static void baobab_ringschart_get_point_min_rect (gdouble cx, gdouble cy,
+                                                  gdouble radius, gdouble angle,
+                                                  GdkRectangle *rect);
+static void baobab_ringschart_get_item_rectangle (GtkWidget *chart,
+                                                  BaobabChartItem *item);
+static void baobab_ringschart_pre_draw (GtkWidget *chart, cairo_t *cr);
+static void baobab_ringschart_post_draw (GtkWidget *chart, cairo_t *cr);
 
 
 static void
 baobab_ringschart_class_init (BaobabRingschartClass *class)
 {
   GObjectClass *obj_class;
-  GtkWidgetClass *widget_class;
+  BaobabChartClass *chart_class;
 
   obj_class = G_OBJECT_CLASS (class);
-  widget_class = GTK_WIDGET_CLASS (class);
+  chart_class = BAOBAB_CHART_CLASS (class);
 
-  /* GtkObject signals */
-  obj_class->set_property = baobab_ringschart_set_property;
-  obj_class->get_property = baobab_ringschart_get_property;
-  obj_class->dispose = baobab_ringschart_dispose;
-
-  /* GtkWidget signals */
-  widget_class->realize = baobab_ringschart_realize;
-  widget_class->expose_event = baobab_ringschart_expose;
-  widget_class->size_allocate = baobab_ringschart_size_allocate;
-  widget_class->button_release_event = baobab_ringschart_button_release;
-  widget_class->scroll_event = baobab_ringschart_scroll;
-  widget_class->motion_notify_event = baobab_ringschart_motion_notify;
-
-  g_object_class_install_property (obj_class,
-                                   PROP_MAX_DEPTH,
-                                   g_param_spec_int ("max-depth",
-                                                     _("Maximum depth"),
-                                                     _("The maximum depth drawn in the rings chart from the root"),
-                                                     1,
-                                                     MAX_DRAWABLE_DEPTH,
-                                                     MAX_DRAWABLE_DEPTH,
-                                                     G_PARAM_READWRITE));
-
-  g_object_class_install_property (obj_class,
-                                   PROP_MODEL,
-                                   g_param_spec_object ("model",
-							_("Rings chart model"),
-							_("Set the model of the rings chart"),
-							GTK_TYPE_TREE_MODEL,
-							G_PARAM_READWRITE));
-
-  g_object_class_install_property (obj_class,
-                                   PROP_ROOT,
-                                   g_param_spec_boxed ("root",
-                                                       _("Rings chart root node"),
-                                                       _("Set the root node from the model"),
-                                                       GTK_TYPE_TREE_ITER,
-                                                       G_PARAM_READWRITE));
-
-  ringschart_signals[SECTOR_ACTIVATED] =
-    g_signal_new ("sector_activated",
-		  G_TYPE_FROM_CLASS (obj_class),
-		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		  G_STRUCT_OFFSET (BaobabRingschartClass, sector_activated),
-		  NULL, NULL,
-                  g_cclosure_marshal_VOID__BOXED,
-		  G_TYPE_NONE, 1,
-		  GTK_TYPE_TREE_ITER);
+  /* BaobabChart abstract methods */
+  chart_class->draw_item = baobab_ringschart_draw_item;
+  chart_class->calculate_item_geometry = baobab_ringschart_calculate_item_geometry;
+  chart_class->is_point_over_item = baobab_ringschart_is_point_over_item;
+  chart_class->get_item_rectangle = baobab_ringschart_get_item_rectangle;
+  chart_class->pre_draw = baobab_ringschart_pre_draw;
+  chart_class->post_draw = baobab_ringschart_post_draw;
 
   g_type_class_add_private (obj_class, sizeof (BaobabRingschartPrivate));
 }
 
 static void
-baobab_ringschart_init (BaobabRingschart *rchart)
+baobab_ringschart_init (BaobabRingschart *chart)
 {
   BaobabRingschartPrivate *priv;
+  GtkSettings* settings;
+  gint timeout;
 
-  priv = BAOBAB_RINGSCHART_GET_PRIVATE (rchart);
-  rchart->priv = priv;
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (chart);
 
-  priv->model = NULL;
-  priv->center_x = 0;  
-  priv->center_y = 0;
-  priv->max_radius= 0;
-  priv->min_radius= 0;
-  priv->thickness= 0;
-  priv->max_depth = MAX_DRAWABLE_DEPTH;
-  priv->name_column = 0;
-  priv->size_column = 0;
-  priv->info_column = 0;
-  priv->percentage_column = 0;
-  priv->valid_column = 0;
-  /* we want to avoid to paint the first time */
-  priv->current_depth = MAX_DRAWABLE_DEPTH +1;
-  priv->drawn_elements = 0;
-  priv->current_init_angle = 0; 
-  priv->current_final_angle = 2*G_PI;
-  priv->real_sector = FALSE;
-  priv->button_pressed = FALSE;
-  priv->is_frozen = FALSE;
-  priv->transparent_tips = FALSE;
   priv->subfoldertips_enabled = FALSE;
-  priv->init_depth = 0;
-  priv->timeout_event_source = 0;
-  priv->draw_tooltip = FALSE;
-  priv->draw_children_tooltips = FALSE;
-  priv->draw_center = FALSE;
-  priv->memento = NULL;
-  priv->root = NULL;
+  priv->highlighted_item = NULL;
+  priv->tips_timeout_event = 0;
+  priv->subtip_items = NULL;
+  priv->drawing_subtips = FALSE;
+
+  settings = gtk_settings_get_default ();
+  g_object_get (G_OBJECT (settings), "gtk-tooltip-timeout", &timeout, NULL);
+  priv->subtip_timeout = 2 * timeout;
 }
 
 static void
-baobab_ringschart_dispose (GObject *object)
-{
-  BaobabRingschartPrivate *priv;
-
-  priv = BAOBAB_RINGSCHART (object)->priv;
-
-  if (priv->model)
-    {
-      baobab_ringschart_disconnect_signals (GTK_WIDGET (object),
-					    priv->model);
-
-      g_object_unref (priv->model);
+baobab_ringschart_draw_sector (cairo_t *cr,
+                               gdouble center_x,
+                               gdouble center_y,
+                               gdouble radius,
+                               gdouble thickness,
+                               gdouble init_angle,
+                               gdouble final_angle,
+                               BaobabChartColor fill_color,
+                               gboolean continued,
+                               guint border)
+{
+  cairo_set_line_width (cr, border);
+  if (radius > 0)
+    cairo_arc (cr, center_x, center_y, radius, init_angle, final_angle);
+  cairo_arc_negative (cr, center_x, center_y, radius+thickness,
+                      final_angle, init_angle);
+  cairo_close_path(cr);
 
-      priv->model = NULL;
-    }
+  cairo_set_source_rgb (cr, fill_color.red, fill_color.green, fill_color.blue);
+  cairo_fill_preserve (cr);
+  cairo_set_source_rgb (cr, 0, 0, 0);
+  cairo_stroke (cr);
 
-  if (priv->root)
+  if (continued)
     {
-      gtk_tree_row_reference_free (priv->root);
-
-      priv->root = NULL;
+      cairo_set_line_width (cr, 3);
+      cairo_arc (cr, center_x, center_y, radius+thickness + 4,
+                 init_angle+EDGE_ANGLE, final_angle-EDGE_ANGLE);
+      cairo_stroke (cr);
     }
-
-  (* G_OBJECT_CLASS (baobab_ringschart_parent_class)->dispose) (object);
 }
 
 static void
-baobab_ringschart_realize (GtkWidget *widget)
-{
-  BaobabRingschart *ringc;
-  GdkWindowAttr attributes;
-  gint attributes_mask;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (widget));
-
-  ringc = BAOBAB_RINGSCHART (widget);
-  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-
-  attributes.window_type = GDK_WINDOW_CHILD;
-  attributes.x = widget->allocation.x;
-  attributes.y = widget->allocation.y;
-  attributes.width = widget->allocation.width;
-  attributes.height = widget->allocation.height;
-  attributes.wclass = GDK_INPUT_OUTPUT;
-  attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
-  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
-
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-
-  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
-  gdk_window_set_user_data (widget->window, ringc);
-
-  widget->style = gtk_style_attach (widget->style, widget->window);
-  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
-
-  gtk_widget_add_events (widget,
-                         GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | 
-                         GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
+baobab_ringschart_draw_item (GtkWidget *chart,
+                             cairo_t *cr,
+                             BaobabChartItem *item,
+                             gboolean highlighted)
+{
+  BaobabRingschartPrivate *priv;
+  BaobabRingschartItem *data;
+  BaobabChartColor fill_color;
+
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (chart);
+
+  data = (BaobabRingschartItem *) item->data;
+
+  if (priv->drawing_subtips)
+    if ( (priv->highlighted_item) && (item->parent) &&
+         (((BaobabChartItem *) item->parent->data) == priv->highlighted_item) )
+      {
+        GList *node;
+        node = g_new0 (GList, 1);
+        node->data = (gpointer) item;
+
+        node->next = priv->subtip_items;
+        if (priv->subtip_items)
+          priv->subtip_items->prev = node;
+        priv->subtip_items = node;
+      }
+
+  baobab_chart_get_item_color (&fill_color,
+                               data->start_angle / M_PI * 99,
+                               item->depth,
+                               highlighted);
+
+  baobab_ringschart_draw_sector (cr,
+                                 CENTER_X (chart), CENTER_Y (chart),
+                                 data->min_radius,
+                                 data->max_radius - data->min_radius,
+                                 data->start_angle,
+                                 data->start_angle + data->angle,
+                                 fill_color,
+                                 data->continued,
+                                 ITEM_BORDER_WIDTH);
 }
 
 static void
-baobab_ringschart_size_allocate (GtkWidget     *widget,
-                                 GtkAllocation *allocation)
-{
-  BaobabRingschartPrivate *priv;
+baobab_ringschart_calculate_item_geometry (GtkWidget *chart,
+                                           BaobabChartItem *item)
+{
+  BaobabRingschartItem *data;
+  BaobabRingschartItem p_data;
+  BaobabChartItem *parent = NULL;
 
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (widget));
-  g_return_if_fail (allocation != NULL);
+  gdouble max_radius;
+  gdouble thickness;
+  guint max_depth;
 
-  priv = BAOBAB_RINGSCHART (widget)->priv;
+  max_depth = baobab_chart_get_max_depth (chart);
 
-  widget->allocation = *allocation;
+  if (item->data == NULL)
+    item->data = g_new (BaobabRingschartItem, 1);
 
-  if (GTK_WIDGET_REALIZED (widget))
-    {
-      gdk_window_move_resize (widget->window,
-			      allocation->x, allocation->y,
-			      allocation->width, allocation->height);
-    }
-  
-  priv->center_x = widget->allocation.width / 2;  
-  priv->center_y = widget->allocation.height / 2;
-  priv->max_radius= MIN (widget->allocation.width / 2,
-                         widget->allocation.height / 2) - WINDOW_PADDING*2;
-  priv->min_radius= priv->max_radius / (priv->max_depth + 1);
-  priv->thickness= priv->min_radius;
-}
+  data = (BaobabRingschartItem *) item->data;
 
-static void
-baobab_ringschart_set_property (GObject         *object,
-                                guint            prop_id,
-                                const GValue    *value,
-                                GParamSpec      *pspec)
-{
-  BaobabRingschart *rings_chart;
+  data->continued = FALSE;
+  item->visible = FALSE;
 
-  rings_chart = BAOBAB_RINGSCHART (object);
+  max_radius = MIN (CENTER_X (chart), CENTER_Y (chart)) - CHART_PADDING;
+  thickness = max_radius / (max_depth + 1);
 
-  switch (prop_id)
+  if (item->parent == NULL)
     {
-    case PROP_MAX_DEPTH:
-      baobab_ringschart_set_max_depth (GTK_WIDGET (rings_chart), g_value_get_int (value));
-      break;
-    case PROP_MODEL:
-      baobab_ringschart_set_model (GTK_WIDGET (rings_chart), g_value_get_object (value));
-      break;
-    case PROP_ROOT:
-      baobab_ringschart_set_root (GTK_WIDGET (rings_chart), g_value_get_object (value));
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
+      data->min_radius = 0;
+      data->max_radius = thickness;
+      data->start_angle = 0;
+      data->angle = 2 * M_PI;
     }
-}
-
-static void
-baobab_ringschart_get_property (GObject    *object,
-                                guint       prop_id,
-                                GValue     *value,
-                                GParamSpec *pspec)
-{
-  BaobabRingschartPrivate *priv;
-
-  priv = BAOBAB_RINGSCHART (object)->priv;
-
-  switch (prop_id)
+  else
     {
-    case PROP_MAX_DEPTH:
-      g_value_set_int (value, priv->max_depth);
-      break;
-    case PROP_MODEL:
-      g_value_set_object (value, priv->model);
-      break;
-    case PROP_ROOT:
-      g_value_set_object (value, priv->root);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
-}
+      parent = (BaobabChartItem *) item->parent->data;
+      g_memmove (&p_data, parent->data, sizeof (BaobabRingschartItem));
 
-static void 
-baobab_ringschart_update_draw (BaobabRingschart* rchart,
-                               GtkTreePath *path)
-{
-  BaobabRingschartPrivate *priv;
-  GtkTreePath *root_path = NULL;
-  gint root_depth, node_depth;
+      data->min_radius = (item->depth) * thickness;
 
-  if (!GTK_WIDGET_REALIZED (rchart))
-    return;
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  if (priv->root != NULL)
-    {
-      root_path = gtk_tree_row_reference_get_path (priv->root);
-      
-      if (root_path == NULL)
-        {
-          gtk_tree_row_reference_free (priv->root);
-          priv->root = NULL;
-        }
-    }
+      if (data->min_radius + thickness > max_radius)
+        return;
+      else
+        data->max_radius = data->min_radius + thickness;
 
-  if (priv->root == NULL)
-    root_path = gtk_tree_path_new_first ();
+      data->angle = p_data.angle * item->rel_size / 100;
+      if (data->angle < ITEM_MIN_ANGLE)
+        return;
 
+      data->start_angle = p_data.start_angle + p_data.angle * item->rel_start / 100;
 
-  root_depth = gtk_tree_path_get_depth (root_path);
-  node_depth = gtk_tree_path_get_depth (path);
+      data->continued = (item->has_any_child) && (item->depth == max_depth);
 
-  if (((node_depth-root_depth)<=priv->max_depth)&&
-      ((gtk_tree_path_is_ancestor (root_path, path))||
-       (gtk_tree_path_compare (root_path, path) == 0)))
-    {
-      gtk_widget_queue_draw (GTK_WIDGET (rchart));
+      parent->has_visible_children = TRUE;
     }
 
-  gtk_tree_path_free (root_path);
+  item->visible = TRUE;
+  baobab_ringschart_get_item_rectangle (chart, item);
+}
+
+static gboolean
+baobab_ringschart_is_point_over_item (GtkWidget *chart,
+                                      BaobabChartItem *item,
+                                      gdouble x,
+                                      gdouble y)
+{
+  BaobabRingschartItem *data;
+  gdouble radius, angle;
+
+  data = (BaobabRingschartItem *) item->data;
+  x = x - CENTER_X (chart);
+  y = y - CENTER_Y (chart);
+
+  radius = sqrt (x*x + y*y);
+  angle = atan2 (y, x);
+  angle = (angle > 0) ? angle : angle + 2*G_PI;
+
+  return (radius >= data->min_radius) &&
+         (radius <= data->max_radius) &&
+         (angle >= data->start_angle) &&
+         (angle <= data->start_angle + data->angle);
 }
 
-static void 
-baobab_ringschart_row_changed (GtkTreeModel    *model,
-                               GtkTreePath     *path,
-                               GtkTreeIter     *iter,
-                               gpointer         data)
+static void
+baobab_ringschart_get_point_min_rect (gdouble cx,
+                                      gdouble cy,
+                                      gdouble radius,
+                                      gdouble angle,
+                                      GdkRectangle *rect)
 {
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (data));
-  g_return_if_fail (path != NULL || iter != NULL);
+  gdouble x, y;
 
-  baobab_ringschart_update_draw (BAOBAB_RINGSCHART (data), path);
+  x = cx + cos (angle) * radius;
+  y = cy + sin (angle) * radius;
 
+  rect->x = MIN (rect->x, x);
+  rect->y = MIN (rect->y, y);
+  rect->width = MAX (rect->width, x);
+  rect->height = MAX (rect->height, y);
 }
 
-static void 
-baobab_ringschart_row_inserted (GtkTreeModel    *model,
-                                GtkTreePath     *path,
-                                GtkTreeIter     *iter,
-                                gpointer         data)
+static void
+baobab_ringschart_get_item_rectangle (GtkWidget *chart,
+                                       BaobabChartItem *item)
 {
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (data));
-  g_return_if_fail (path != NULL || iter != NULL);
-  
-  baobab_ringschart_update_draw (BAOBAB_RINGSCHART (data), path);
+  BaobabRingschartItem *data;
+  GdkRectangle rect;
+  gdouble cx, cy, r1, r2, a1, a2;
 
-}
+  data = (BaobabRingschartItem *) item->data;
 
-static void 
-baobab_ringschart_row_has_child_toggled (GtkTreeModel    *model,
-                                         GtkTreePath     *path,
-                                         GtkTreeIter     *iter,
-                                         gpointer         data)
-{
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (data));
-  g_return_if_fail (path != NULL || iter != NULL);
+  cx = CENTER_X (chart);
+  cy = CENTER_Y (chart);
+  r1 = data->min_radius;
+  r2 = data->max_radius;
+  a1 = data->start_angle;
+  a2 = data->start_angle + data->angle;
 
-  baobab_ringschart_update_draw (BAOBAB_RINGSCHART (data), path);
+  rect.x = chart->allocation.width;
+  rect.y = chart->allocation.height;
+  rect.width = 0;
+  rect.height = 0;
 
-}
+  baobab_ringschart_get_point_min_rect (cx, cy, r1, a1, &rect);
+  baobab_ringschart_get_point_min_rect (cx, cy, r2, a1, &rect);
+  baobab_ringschart_get_point_min_rect (cx, cy, r1, a2, &rect);
+  baobab_ringschart_get_point_min_rect (cx, cy, r2, a2, &rect);
 
-static void 
-baobab_ringschart_row_deleted (GtkTreeModel    *model,
-                               GtkTreePath     *path,
-                               gpointer         data)
-{
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (data));
-  g_return_if_fail (path != NULL);
-  
-  baobab_ringschart_update_draw (BAOBAB_RINGSCHART (data), path);
+  if ( (a1 <= M_PI/2) && (a2 >= M_PI/2) )
+    rect.height = MAX (rect.height, cy + sin (M_PI/2) * r2);
 
-}
+  if ( (a1 <= M_PI) && (a2 >= M_PI) )
+    rect.x = MIN (rect.x, cx + cos (M_PI) * r2);
 
-static void 
-baobab_ringschart_rows_reordered (GtkTreeModel    *model,
-                                  GtkTreePath     *path,
-                                  GtkTreeIter     *iter,
-                                  gint            *new_order,
-                                  gpointer         data)
-{
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (data));
-  g_return_if_fail (path != NULL || iter != NULL);
+  if ( (a1 <= M_PI*1.5) && (a2 >= M_PI*1.5) )
+    rect.y = MIN (rect.y, cy + sin (M_PI*1.5) * r2);
+
+  if ( (a1 <= M_PI*2) && (a2 >= M_PI*2) )
+    rect.width = MAX (rect.width, cx + cos (M_PI*2) * r2);
 
-  baobab_ringschart_update_draw (BAOBAB_RINGSCHART (data), path);
+  rect.width -= rect.x;
+  rect.height -= rect.y;
 
+  item->rect = rect;
 }
 
-static gboolean
-baobab_ringschart_expose (GtkWidget *rchart, GdkEventExpose *event)
+gboolean
+baobab_ringschart_subfolder_tips_timeout (gpointer data)
 {
-  cairo_t *cr;
   BaobabRingschartPrivate *priv;
 
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  /* the columns are not set we paint nothing */
-  if (priv->name_column == priv->percentage_column)
-    return FALSE;
-
-  /* get a cairo_t */
-  cr = gdk_cairo_create (rchart->window);
-
-  cairo_rectangle (cr,
-                   event->area.x, event->area.y,
-                   event->area.width, event->area.height);
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (data);
 
-  /* there is no model we can not paint */
-  if ((priv->is_frozen) || (priv->model == NULL))
-    {
-      if (priv->memento != NULL)
-        { 
-          gint w, h;
-
-          w = cairo_image_surface_get_width (priv->memento);
-          h = cairo_image_surface_get_height (priv->memento);
-
-          cairo_clip (cr);
-          
-          if (w > 0 && h > 0 &&
-	      !(rchart->allocation.width == w &&
-                rchart->allocation.height == h))
-            {
-              gdouble p, sx, sy;
-	  
-              /* minimal available proportion */
-              p = MIN (rchart->allocation.width / (1.0 * w),
-                       rchart->allocation.height / (1.0 * h));
-              
-              sx = (gdouble) (rchart->allocation.width - w * p) / 2.0;
-              sy = (gdouble) (rchart->allocation.height - h * p) / 2.0;
-
-              cairo_translate (cr, sx, sy);
-              cairo_scale (cr, p, p);
-            }
-
-          cairo_set_source_surface (cr,
-                                    priv->memento,
-                                    0, 0);
-          cairo_paint (cr);
-        }         
-    }
-  else 
-    {
-      cairo_set_source_rgb (cr, 1, 1, 1);
-      cairo_fill_preserve (cr);
+  priv->drawing_subtips = TRUE;
 
-      cairo_clip (cr);
-      
-      baobab_ringschart_draw (rchart, cr);
-    }
-
-  cairo_destroy (cr);
+  gtk_widget_queue_draw (GTK_WIDGET (data));
 
   return FALSE;
 }
 
-static void
-baobab_ringschart_draw (GtkWidget *rchart, cairo_t *cr)
+void
+baobab_ringschart_clean_subforlder_tips_state (GtkWidget *chart)
 {
   BaobabRingschartPrivate *priv;
-  GtkTreeIter initial_iter = {0};  
-  GSList *tooltips = NULL;
-  gdouble perc;
-  gdouble max_angle;
+  GList *node;
 
-  cairo_stroke (cr); 
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (chart);
 
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
+  if (priv->drawing_subtips)
+    gtk_widget_queue_draw (chart);
 
-  if (priv->root != NULL)
-    {
-      GtkTreePath *path = gtk_tree_row_reference_get_path (priv->root);
-      if (path != NULL)
-        {
-          gtk_tree_model_get_iter (priv->model, &initial_iter, path);
-          gtk_tree_path_free (path);
-        }
-      else 
-        {
-          gtk_tree_row_reference_free (priv->root);
-          priv->root = NULL;
-        }
-    }
+  priv->drawing_subtips = FALSE;
 
-  if (priv->root == NULL)
-    gtk_tree_model_get_iter_first (priv->model, &initial_iter);
+  if (priv->highlighted_item == NULL)
+    return;
 
-  priv->drawn_elements = 0;
-  priv->current_init_angle = 0;  
-  priv->current_final_angle = 3*G_PI;
-  priv->real_sector = FALSE;
-  
-  /* the tree has just one node */
-  if (priv->init_depth == 0)     
-    max_angle = 2*G_PI;
-  else
+  if (priv->tips_timeout_event)
     {
-      gtk_tree_model_get (priv->model, &initial_iter, 
-                          priv->percentage_column, &perc, -1);
-
-      max_angle = 2*G_PI*perc*0.01;
+      g_source_remove (priv->tips_timeout_event);
+      priv->tips_timeout_event = 0;
     }
 
-  if (priv->draw_center)
-    draw_circle (cr, priv->center_x, priv->center_y, priv->min_radius, FALSE);
+  priv->highlighted_item = NULL;
 
-  tree_traverse(cr, BAOBAB_RINGSCHART (rchart), &initial_iter, 
-                priv->init_depth, priv->min_radius, 0, max_angle, &tooltips, 
-                !priv->button_pressed);
-
-  if (priv->root)
+  /* Free subtip_items GList */
+  node = priv->subtip_items;
+  while (node != NULL)
     {
-      /* the root should not be invalid ;-) */
-      GtkTreePath *path = gtk_tree_row_reference_get_path (priv->root);
-      gtk_tree_model_get_iter (priv->model, &initial_iter, path);
-      gtk_tree_path_free (path);
-    }
+      priv->subtip_items = node->next;
+      g_free (node);
 
-  /* no matter what happens in the draw now the button will be
-     unpressed */
-  priv->button_pressed = FALSE;
-  
-  if (priv->draw_tooltip)
-    {
-      draw_tooltips (rchart, cr, tooltips);
+      node = priv->subtip_items;
     }
-
-}
-
-static void 
-draw_sector (cairo_t *cr, 
-             gdouble center_x, 
-             gdouble center_y,
-             gdouble radius,
-             gdouble thickness,
-             gdouble init_angle,
-             gdouble final_angle,
-             Color fill_color,
-             gboolean continued)
-{
-  cairo_save (cr);
-
-  cairo_set_line_width (cr, 1);
-  cairo_arc (cr, center_x, center_y, radius, init_angle, final_angle);
-  cairo_arc_negative (cr, center_x, center_y, radius+thickness, final_angle, init_angle);
-
-  cairo_close_path(cr);
-
-  cairo_set_source_rgb (cr, fill_color.red, fill_color.green, fill_color.blue);
-  cairo_fill_preserve (cr);
-  cairo_set_source_rgb (cr, 0, 0, 0);
-  cairo_stroke (cr);
-
-  if (continued)
-    {
-      cairo_set_line_width (cr, 3);
-      cairo_arc (cr, center_x, center_y, radius+thickness+4, init_angle+EDGE_ANGLE, 
-                 final_angle-EDGE_ANGLE); 
-      cairo_stroke (cr); 
-    }
-
-  cairo_restore (cr);
-}
-
-static void 
-draw_circle (cairo_t *cr, 
-             gdouble center_x, 
-             gdouble center_y,
-             gdouble radius,
-             gboolean highlighted)
-{
-  Color fill_color;
-  
-  get_color (&fill_color, 0, 0, highlighted);
-  
-  cairo_save (cr);
-
-  cairo_set_line_width (cr, 1);
-  cairo_arc (cr, center_x, center_y, radius, 0, 2*G_PI);
-
-  cairo_set_source_rgb (cr, fill_color.red, fill_color.green, fill_color.blue);
-  cairo_fill_preserve (cr);
-  cairo_set_source_rgb (cr, 0, 0, 0);
-  cairo_stroke (cr);
-
-  cairo_restore (cr);
+  priv->subtip_items = NULL;
 }
 
 static void
-draw_tooltips (GtkWidget *rchart,
-               cairo_t *cr,
-               GSList *tooltips)
+baobab_ringschart_draw_subfolder_tips (GtkWidget *chart, cairo_t *cr)
 {
   BaobabRingschartPrivate *priv;
+  GList *node;
+  BaobabChartItem *item;
+  BaobabRingschartItem *data;
 
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
+  gdouble q_angle, q_width, q_height;
 
-  /* FIXME: replace this list of tips with just a variable, we are not
-     going to have more than one tooltip */
-  if (tooltips)
-    {
-      do
-        {
-          GSList *tips_iter = NULL;
-          Tooltip *tooltip = NULL;
-          GtkTreeIter child  = {0};
-          GtkTreeIter iter = {0};
-          Tooltip_rectangle *previous_rectangle = NULL;
-          GtkTreePath *path = NULL;
-
-          tips_iter = tooltips;
-          tooltip = tips_iter->data;
-
-          path = gtk_tree_row_reference_get_path (tooltip->ref);
-          gtk_tree_model_get_iter (priv->model, &iter, path);
-
-          /* draw the child tooltips */
-          if (priv->draw_children_tooltips && 
-              (gtk_tree_model_iter_has_child (priv->model, &iter) && 
-               (tooltip->depth == -1 || tooltip->depth < priv->max_depth-1)))
-            {
-              gdouble _init_angle, _final_angle;
-
-              gtk_tree_model_iter_children (priv->model, &child, &iter);
-              _init_angle = tooltip->init_angle;
-
-              previous_rectangle = g_new (Tooltip_rectangle, 1);
-              previous_rectangle->x = 0.0;
-              previous_rectangle->y = 0.0;
-              previous_rectangle->width = 0.0;
-              previous_rectangle->height = 0.0;
-
-              do
-                {
-                  gchar *name;
-                  gchar *size_column;
-                  gdouble percentage;
-
-                  gtk_tree_model_get (priv->model, &child, 
-                                      priv->name_column, &name,
-                                      priv->size_column, &size_column,
-                                      priv->percentage_column, &percentage, -1);             
-                  
-                  _final_angle = _init_angle + 
-                    (tooltip->final_angle - tooltip->init_angle) * percentage/100;
-
-                  if (percentage > 0)
-                    draw_folder_tip (cr, rchart, _init_angle, 
-                                     _final_angle, tooltip->depth+1, name, 
-                                     size_column, previous_rectangle);                 
-
-                  g_free (name);
-                  g_free (size_column);
-                          
-                  _init_angle = _final_angle;
-
-                } while (gtk_tree_model_iter_next (priv->model, &child));
-            }
-
-          gtk_tree_path_free (path);
-
-          /* check if the root is highlihgted in order to redraw it*/
-          if ((priv->draw_center) && (tooltip->depth == -1))
-                  draw_circle (cr, priv->center_x, priv->center_y, priv->min_radius, TRUE);
-
-          draw_tip (cr, rchart, tooltip->init_angle, tooltip->final_angle, 
-                    tooltip->depth, tooltip->name, tooltip->size);
-
-          g_free (tooltip->name);
-          g_free (tooltip->size);
-          gtk_tree_row_reference_free (tooltip->ref);
+  gdouble tip_angle, tip_x, tip_y;
+  gdouble middle_angle, middle_angle_n, middle_radius;
+  gdouble min_angle, max_angle;
+  gdouble sector_center_x, sector_center_y;
+  gdouble a;
+  guint i;
 
-          tooltips = g_slist_remove_link (tooltips, tips_iter);
-
-          g_free (tooltip);
-          g_slist_free_1 (tips_iter);
-        }
-      while (g_slist_next(tooltips));
-    }
-}
-
-static void 
-draw_tip (cairo_t *cr,
-          GtkWidget *rchart,
-          gdouble init_angle,
-          gdouble final_angle,
-          gdouble depth,
-          gchar *name,
-          gchar *size)
-{
-  BaobabRingschartPrivate *priv;
-  gdouble medium_angle;
-  gdouble start_radius;
-  gdouble max_radius;
-  gdouble origin_x;
-  gdouble origin_y;
-  gdouble tooltip_x;
-  gdouble tooltip_y;
-  gdouble end_x;
-  gdouble end_y;
-  gdouble tooltip_height;
-  gdouble tooltip_width;  
-  PangoRectangle rect;
   PangoLayout *layout;
-  gchar *text = NULL;
-
-  priv = BAOBAB_RINGSCHART_GET_PRIVATE (rchart);
-
-  /* angle to start drawing from */
-  /* medium_angle = ((final_angle - init_angle)/2) + init_angle; */
-  medium_angle = priv->point_angle;
-
-  /* radius to start drawing from */
-  start_radius = (depth != -1) ? (depth + 0.1) * priv->thickness + priv->min_radius : 0;
+  PangoRectangle layout_rect;
+  gchar *markup = NULL;
 
-  /* coordinates of the starting point of the line */
-  origin_x = priv->center_x + (cos(medium_angle) * start_radius);
-  origin_y = priv->center_y + (sin(medium_angle) * start_radius);
+  cairo_rectangle_t tooltip_rect;
+  GdkRectangle _rect, last_rect;
 
-  /* get the size of the text label */
-  text = (size != NULL)
-    ? g_strconcat (name, "\n", size, NULL)
-    : g_strdup (name);
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (chart);
 
-  layout = gtk_widget_create_pango_layout (rchart, NULL);
-  pango_layout_set_markup (layout, text, -1);
+  q_width = chart->allocation.width / 2;
+  q_height = chart->allocation.height / 2;
+  q_angle = atan2 (q_height, q_width);
 
-  pango_layout_get_pixel_extents (layout, NULL, &rect);
+  memset (&last_rect, 0, sizeof (GdkRectangle));
 
-  tooltip_width = floor(rect.width+TOOLTIP_PADDING*2);  
-  tooltip_height = floor(rect.height+TOOLTIP_PADDING*2);
-
-  /* TODO */
-  tooltip_x = MAX (priv->pointer_x - tooltip_width, 0);
-  tooltip_x = ((tooltip_x + tooltip_width) > rchart->allocation.width) ?
-    rchart->allocation.width - tooltip_width : tooltip_x;
-  tooltip_y = MAX (priv->pointer_y - tooltip_height, 0);
-  tooltip_y = ((tooltip_y + tooltip_height) > rchart->allocation.height) ?
-    rchart->allocation.height - tooltip_height : tooltip_y;
-
-  /* avoid blurred lines */
-  tooltip_x = round (tooltip_x) + 0.5;
-  tooltip_y = round (tooltip_y) + 0.5;  
-
-  /* Time to do the drawing stuff */
   cairo_save (cr);
-  cairo_set_source_rgb (cr, 0, 0, 0);
-
-  cairo_set_line_width (cr, 1);
-  cairo_rectangle (cr, tooltip_x, tooltip_y, tooltip_width, tooltip_height);
-  cairo_set_source_rgb (cr, 0.99, 0.91, 0.31); /* tango: fce94f */
-  cairo_fill_preserve (cr);
-
-  cairo_set_source_rgb (cr, 0, 0, 0);
-  cairo_move_to (cr, tooltip_x+TOOLTIP_PADDING, tooltip_y+TOOLTIP_PADDING);
-  pango_cairo_show_layout (cr, layout);
-
-  cairo_stroke (cr);
-
-  cairo_restore (cr);
-
-  g_object_unref (layout);
-  g_free (text);
-}
-
-/* this function returns the area (rectangle) filled by this
-particular tooltip in previous_rectangle, so that the next tooltip to
-be drawn can decide wether it has enough space or not; in case that
-the tooltip can't be drawn, then the values of previous_rectangle
-remain unchanged */
-static void
-draw_folder_tip (cairo_t *cr,
-                 GtkWidget *rchart,
-                 gdouble init_angle,
-                 gdouble final_angle,
-                 gdouble depth,
-                 gchar *name,
-                 gchar *size,
-                 Tooltip_rectangle *previous_rectangle)
-{
-  BaobabRingschartPrivate *priv;
-  gdouble medium_angle;
-  gdouble start_radius;
-  gdouble max_radius;
-  gdouble origin_x;
-  gdouble origin_y;
-  gdouble max_radius_x;
-  gdouble max_radius_y;
-  gdouble tooltip_x;
-  gdouble tooltip_y;
-  gdouble end_x;
-  gdouble end_y;
-  gdouble tooltip_height;
-  gdouble tooltip_width;  
-  PangoRectangle rect;
-  PangoRectangle ink_rect;
-  PangoLayout *layout;
-  gchar *text = NULL;
-  gint i = 0;
-  gboolean valid = FALSE;
-  gdouble angle;
-  gdouble *test_angles;
-  gint n_test_angles;
 
-  priv = BAOBAB_RINGSCHART_GET_PRIVATE (rchart);
-
-  if (final_angle - init_angle < MIN_DRAWABLE_ANGLE)
-    return;
-
-  if (!priv->subfoldertips_enabled)
+  node = priv->subtip_items;
+  while (node != NULL)
     {
-      /* subfoldertips aren't enabled */ 
-      return;
-    }
-
-  /* prepare the angles to study */
-  angle = final_angle - init_angle;
-  test_angles = NULL;
-  n_test_angles = 0;
+      item = (BaobabChartItem *) node->data;
+      data = (BaobabRingschartItem *) item->data;
 
-  if (angle < G_PI/18) /* less than 10 degrees */
-    {
-      n_test_angles = 1;
-      test_angles = g_malloc (n_test_angles * sizeof (gdouble));
-      test_angles[0] = 0.5;    
-    }
-  else if (angle < G_PI/4)
-    {
-      n_test_angles = 3;
-      test_angles = g_malloc (n_test_angles * sizeof (gdouble));
-      test_angles[0] = 0.5;
-      test_angles[1] = 0.20;
-      test_angles[2] = 0.80;
-    }
-  else if (angle < G_PI/2)
-    {
-      n_test_angles = 5;
-      test_angles = g_malloc (n_test_angles * sizeof (gdouble));
-      test_angles[0] = 0.5;
-      test_angles[1] = 0.33;
-      test_angles[2] = 0.67; 
-      test_angles[3] = 0.17;
-      test_angles[4] = 0.83;
-    } 
-  else if (angle < 3*G_PI/4)
-    {
-      n_test_angles = 7;
-      test_angles = g_malloc (n_test_angles * sizeof (gdouble));
-      test_angles[0] = 0.5; 
-      test_angles[1] = 0.375;
-      test_angles[2] = 0.625; 
-      test_angles[3] = 0.25; 
-      test_angles[4] = 0.75;
-      test_angles[5] = 0.125;
-      test_angles[6] = 0.875;
-    }
-  else 
-    {
-      n_test_angles = 9;
-      test_angles = g_malloc (n_test_angles * sizeof (gdouble));
-      test_angles[0] = 0.5; 
-      test_angles[1] = 0.4;
-      test_angles[2] = 0.6; 
-      test_angles[3] = 0.3; 
-      test_angles[4] = 0.7;
-      test_angles[5] = 0.2;
-      test_angles[6] = 0.8;
-      test_angles[7] = 0.1; 
-      test_angles[8] = 0.9;
-    }
+      /* get the middle angle */
+      middle_angle = data->start_angle + data->angle / 2;
 
-  /* get the size of the text label */
-  /* text = (size != NULL) ? g_strconcat (name, "\n", size, NULL) : g_strdup (name); */
-  /* only the name is shown */
-  text = g_strconcat("<span size=\"small\">", name, "</span>", NULL);
-  
-  layout = gtk_widget_create_pango_layout (rchart, NULL);
-  pango_layout_set_markup (layout, text, -1);
-  
-  pango_layout_set_indent (layout, 0);
-  pango_layout_set_spacing (layout, 0);
-  
-  pango_layout_get_pixel_extents (layout, &ink_rect, &rect);
-  
-  tooltip_width = rect.width + TOOLTIP_PADDING*2;
-  tooltip_height = rect.height + TOOLTIP_PADDING*2;
-  
-  /* radius to start drawing from */
-  start_radius = (depth != -1) ? (depth + 0.5) * priv->thickness + priv->min_radius : 0;
+      /* normalize the middle angle (take it to the first quadrant) */
+      middle_angle_n = middle_angle;
+      while (middle_angle_n > M_PI/2)
+        middle_angle_n -= M_PI;
+      middle_angle_n = ABS (middle_angle_n);
+
+      /* get the pango layout and its enclosing rectangle */
+      layout = gtk_widget_create_pango_layout (chart, NULL);
+      markup = g_strconcat ("<span size=\"small\">", item->name, "</span>", NULL);
+      pango_layout_set_markup (layout, markup, -1);
+      g_free (markup);
+      pango_layout_set_indent (layout, 0);
+      pango_layout_set_spacing (layout, 0);
+      pango_layout_get_pixel_extents (layout, NULL, &layout_rect);
 
-  /* try a maximum of n_test_angles different angles */
-  while ( i < n_test_angles && !valid)
-    {
-      gint closest_x, closest_y;
-
-      /* angle to start drawing from */
-      medium_angle = angle*test_angles[i] + init_angle;
-
-      i++;
-
-      /* coordinates of the starting point of the line */
-      origin_x = priv->center_x + (cos (medium_angle) * start_radius);
-      origin_y = priv->center_y + (sin (medium_angle) * start_radius);
-
-      /* Horizontal radius */
-      max_radius_x = ABS ((priv->center_x - (tooltip_width/2 + WINDOW_PADDING)) / cos (medium_angle));
-
-      /* and vertical one */
-      max_radius_y = ABS ((priv->center_y - (tooltip_height/2 + WINDOW_PADDING)) / sin (medium_angle));
-
-      /* get the minor radius */
-      max_radius = MIN (max_radius_x, max_radius_y);
-
-      /* there is an alternative way */
-      /* max_radius = MIN( (priv->center_x - (tooltip_width/2 + WINDOW_PADDING)), (priv->center_y - (tooltip_height/2 + WINDOW_PADDING)) ); */
-
-      /* now we get the final coordinates of the line */
-      end_x = priv->center_x + (max_radius * cos (medium_angle));
-      end_y = priv->center_y + (max_radius * sin (medium_angle));
-
-      /* and the position on the tip */
-      tooltip_x = end_x - tooltip_width*0.5;
-      tooltip_y = end_y - tooltip_height*0.5;
-
-      /* coordinates of the closest point to the center */
-      closest_x = (ABS (priv->center_x - tooltip_x) < ABS (priv->center_x - tooltip_x - tooltip_width))? tooltip_x : tooltip_x + tooltip_width;
-      closest_y = (ABS (priv->center_y - tooltip_y) < ABS (priv->center_y - tooltip_y - tooltip_height))? tooltip_y : tooltip_y + tooltip_height;
-
-      /* check for overlaps: */
-      if ((((tooltip_x <= previous_rectangle->x) && (tooltip_x + tooltip_width >= previous_rectangle->x) ||
-          (tooltip_x >= previous_rectangle->x) && (tooltip_x <= previous_rectangle->x + previous_rectangle->width))
-          &&
-          ((tooltip_y <= previous_rectangle->y) && (tooltip_y + tooltip_height >= previous_rectangle->y) ||
-              (tooltip_y >= previous_rectangle->y) && (tooltip_y <= previous_rectangle->y + previous_rectangle->height)))
-              ||
-              /* intersection between the rectangle and the circle at current_depth (or better, current_depth+1) */
-              ( sqrt(pow(priv->center_x - closest_x, 2) + pow(priv->center_y - closest_y, 2)) < ((depth + 0.1) * priv->thickness + priv->min_radius))
-              ||
-              /* tooltip's width greater than half of the widget's */
-              ( tooltip_width > priv->center_x))
+      /* get the center point of the tooltip rectangle */
+      if (middle_angle_n < q_angle)
         {
-          continue;
+          tip_x = q_width - layout_rect.width/2 - SUBFOLDER_TIP_PADDING * 2;
+          tip_y = tan (middle_angle_n) * tip_x;
         }
-      else 
+      else
         {
-          previous_rectangle->x = tooltip_x;
-          previous_rectangle->y = tooltip_y;
-          previous_rectangle->width = tooltip_width+TOOLTIP_SPACING;
-          previous_rectangle->height = tooltip_height+TOOLTIP_SPACING;
-          valid = TRUE;
+          tip_y = q_height - layout_rect.height/2 - SUBFOLDER_TIP_PADDING * 2;
+          tip_x = tip_y / tan (middle_angle_n);
         }
-    }
 
-  g_free (text);
-  g_free (test_angles);
-  
-  if (!valid)
-    {
-      g_object_unref (layout);
-      return;
-    }
+      /* get the tooltip rectangle */
+      tooltip_rect.x = q_width + tip_x - layout_rect.width/2 - SUBFOLDER_TIP_PADDING;
+      tooltip_rect.y = q_height + tip_y - layout_rect.height/2 - SUBFOLDER_TIP_PADDING;
+      tooltip_rect.width = layout_rect.width + SUBFOLDER_TIP_PADDING * 2;
+      tooltip_rect.height = layout_rect.height + SUBFOLDER_TIP_PADDING * 2;
 
-  /* Time to the drawing stuff */
-  cairo_save (cr);
-  
-  if ((origin_x < tooltip_x) || (origin_x > tooltip_x + tooltip_width)
-      || (origin_y < tooltip_y) || (origin_y > tooltip_y + tooltip_height))
-    {
-      gdouble t_h;
-      gdouble t_w;
-      gdouble c_x;
-      gdouble c_y;
-      gdouble t_x;
-      gdouble t_y;
-      gdouble x_intersection;
-      gdouble y_intersection;
-
-      cairo_set_line_width (cr, 1);
-      cairo_move_to(cr, origin_x, origin_y);
-      /* we have to calculate the intersection point */
-      /* the space is divided in four sectors, like an X or so, and on
-         each one of those the line intersects a different edge of the
-         rectangle */
-      /* it's quite likely that the following code can be greatly simplified */
-      t_h = (gdouble)tooltip_height;
-      t_w = (gdouble)tooltip_width;
-      /* center of the tooltip */
-      c_x = (gdouble)(end_x - priv->center_x);
-      c_y = (gdouble)(priv->center_y - end_y);
-      /* top left corner of the tooltip */
-      t_x = (gdouble)(tooltip_x - priv->center_x);
-      t_y = (gdouble)(priv->center_y - tooltip_y);
-      /* intersection point */
-      x_intersection = c_x;
-      y_intersection = c_y;
-
-      if (c_x > 0) {
-        if (c_y > 0) 
-          { /* top right */
-            /* does it intersect the bottom edge? y = 
-               t_y - tooltip_height  :  x_intersection = 
-               (c_x/c_y)*(t_y - tooltip_height) */
-            /* or the left one? x = t_x  :  y_intersection = (c_y/c_x)*(t_x) */
-            gdouble y_left_intersection = (c_y/c_x)*(t_x);
-
-            if ((y_left_intersection <= t_y) && (y_left_intersection > t_y - t_h)) 
-              {  /* left edge */
-                x_intersection = t_x;
-                y_intersection = y_left_intersection;
-              } 
-            else 
-              { /* bottom edge */
-                y_intersection = t_y - t_h;
-                x_intersection = (c_x/c_y)*(t_y - t_h);
-              }
-          } 
-        else 
-          { /* bottom right */
-            /* top : y = t_y  ;  x = (c_x/c_y)*t_y */
-            /* left :  x = t_x  ;  y_intersection = (c_y/c_x)*(t_x) */
-            gdouble y_left_intersection = (c_y/c_x)*(t_x);
-
-            if ((y_left_intersection <= t_y) && (y_left_intersection > t_y - t_h)) 
-              {  /* left edge */
-                x_intersection = t_x;
-                y_intersection = y_left_intersection;
-              } 
-            else 
-              { /* bottom edge */
-                y_intersection = t_y;
-                x_intersection = (c_x/c_y)*(t_y);
-              }
-          }
-      }
-      else  
-        { 
-          if (c_y > 0) 
-            {/* top left */
-              /* right edge : x = t_x + t_w ; y = (c_y/c_x)*(t_x + t_w) */
-              /* bottom :  y = t_y - t_h  :  x = (c_x/c_y)*(t_y + t_h) */
-              gdouble y_right_intersection = (c_y/c_x)*(t_x + t_w);
-
-              if ((y_right_intersection <= t_y) && (y_right_intersection > t_y - t_h)) 
-                {
-                  x_intersection = t_x + t_w;
-                  y_intersection = y_right_intersection;
-                } 
-              else 
-                {
-                  x_intersection =  (c_x/c_y)*(t_y - t_h);
-                  y_intersection = t_y - t_h;
-                }
-            } 
-          else 
-            { /* bottom left */
-              /* top : y = t_y  ;  x = (c_x/c_y)*t_y */
-              /* right :  x = t_x + t_w  ;  y_intersection = (c_y/c_x)*(t_x + t_w) */
-              gdouble y_left_intersection = (c_y/c_x)*(t_x + t_w);
-
-              if ((y_left_intersection <= t_y) && (y_left_intersection > t_y - t_h)) 
-                {  /* left edge */
-                  x_intersection = t_x + t_w;
-                  y_intersection = y_left_intersection;
-                } 
-              else 
-                { /* bottom edge */
-                  y_intersection = t_y;
-                  x_intersection = (c_x/c_y)*(t_y);
-                }
-            }
+      /* Check tooltip's width is not greater than half of the widget */
+      if (tooltip_rect.width > q_width)
+        {
+          g_object_unref (layout);
+          node = node->next;
+          continue;
         }
 
-      end_x = (gint)((gdouble)priv->center_x + x_intersection);
-      end_y = (gint)((gdouble)priv->center_y - y_intersection);
-
-      cairo_set_source_rgb (cr, 0.8275, 0.8431, 0.8118); /* tango: #d3d7cf */
-      cairo_line_to (cr, end_x, end_y);      
-      cairo_stroke (cr);
-
-      cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6666 );
-      cairo_arc (cr, origin_x, origin_y, 1.0, 0, 2*G_PI );
-      cairo_stroke (cr);
-    }
-  
-  cairo_set_line_width (cr, 0.5);
-
-  /* avoid blurred lines */
-  tooltip_x = round (tooltip_x) + 0.5;
-  tooltip_y = round (tooltip_y) + 0.5;   
-
-  cairo_rectangle (cr, tooltip_x, tooltip_y, tooltip_width, tooltip_height);
-  cairo_set_source_rgb (cr, 0.8275, 0.8431, 0.8118);  /* tango: #d3d7cf */
-  cairo_fill_preserve(cr);
-  cairo_set_source_rgb (cr, 0.5333, 0.5412, 0.5216);  /* tango: #888a85 */
-  cairo_stroke (cr);
-
-  cairo_move_to (cr, tooltip_x+TOOLTIP_PADDING-PANGO_LBEARING (ink_rect), tooltip_y+TOOLTIP_PADDING);
-
-  cairo_set_source_rgb (cr, 0, 0, 0);
-  pango_cairo_show_layout (cr, layout);
-  cairo_set_line_width (cr, 1);
-  cairo_stroke (cr);
-  cairo_restore (cr);
-
-  g_object_unref (layout);
-}
-
-static void
-interpolate_colors (Color *color,
-                    Color colora,
-                    Color colorb,
-                    gdouble percentage)
-{
-  gdouble diff;
-
-  diff = colora.red - colorb.red;
-  color->red = colora.red-diff*percentage;
-
-  diff = colora.green - colorb.green;
-  color->green = colora.green-diff*percentage;
-
-  diff = colora.blue - colorb.blue;
-  color->blue = colora.blue-diff*percentage; 
-}
+      /* translate tooltip rectangle and edge angles to the original quadrant */
+      a = middle_angle;
+      i = 0;
+      while (a > M_PI/2)
+        {
+          if (i % 2 == 0)
+            tooltip_rect.x = chart->allocation.width - tooltip_rect.x
+                             - tooltip_rect.width;
+          else
+            tooltip_rect.y = chart->allocation.height - tooltip_rect.y
+                             - tooltip_rect.height;
 
-static void
-get_color (Color *color,
-           gdouble angle,
-      	   gint circle_number,
-      	   gboolean highlighted)
-{
-  gdouble intensity;
-  gint color_number;
-  gint next_color_number;
+          i++;
+          a -= M_PI/2;
+        }
 
-  intensity = 1-(((circle_number-1)*0.3)/MAX_DRAWABLE_DEPTH);
+      /* get the GdkRectangle of the tooltip (with a little padding) */
+      _rect.x = tooltip_rect.x - 1;
+      _rect.y = tooltip_rect.y - 1;
+      _rect.width = tooltip_rect.width + 2;
+      _rect.height = tooltip_rect.height + 2;
+
+      /* Check if tooltip overlaps */
+      if (! gdk_rectangle_intersect (&_rect, &last_rect, NULL))
+        {
+          g_memmove (&last_rect, &_rect, sizeof (GdkRectangle));
+
+          /* Finally draw the tooltip to cairo! */
+
+          /* TODO: Do not hardcode colors */
+
+          /* avoid blurred lines */
+          tooltip_rect.x = floor (tooltip_rect.x) + 0.5;
+          tooltip_rect.y = floor (tooltip_rect.y) + 0.5;
+
+          middle_radius = data->min_radius + (data->max_radius - data->min_radius) / 2;
+          sector_center_x = q_width + middle_radius * cos (middle_angle);
+          sector_center_y = q_height + middle_radius * sin (middle_angle);
+
+          /* draw line from sector center to tooltip center */
+          cairo_set_line_width (cr, 1);
+          cairo_move_to (cr, sector_center_x, sector_center_y);
+          cairo_set_source_rgb (cr, 0.8275, 0.8431, 0.8118); /* tango: #d3d7cf */
+          cairo_line_to (cr, tooltip_rect.x + tooltip_rect.width / 2,
+                             tooltip_rect.y + tooltip_rect.height / 2);
+          cairo_stroke (cr);
+
+          /* draw a tiny circle in sector center */
+          cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6666 );
+          cairo_arc (cr, sector_center_x, sector_center_y, 1.0, 0, 2 * G_PI );
+          cairo_stroke (cr);
+
+          /* draw tooltip box */
+          cairo_set_line_width (cr, 0.5);
+          cairo_rectangle (cr, tooltip_rect.x, tooltip_rect.y,
+                               tooltip_rect.width, tooltip_rect.height);
+          cairo_set_source_rgb (cr, 0.8275, 0.8431, 0.8118);  /* tango: #d3d7cf */
+          cairo_fill_preserve(cr);
+          cairo_set_source_rgb (cr, 0.5333, 0.5412, 0.5216);  /* tango: #888a85 */
+          cairo_stroke (cr);
+
+          /* draw the text inside the box */
+          cairo_set_source_rgb (cr, 0, 0, 0);
+          cairo_move_to (cr, tooltip_rect.x + SUBFOLDER_TIP_PADDING,
+                             tooltip_rect.y + SUBFOLDER_TIP_PADDING);
+          pango_cairo_show_layout (cr, layout);
+          cairo_set_line_width (cr, 1);
+          cairo_stroke (cr);
+        }
 
-  if (circle_number == 0)
-    {
-      static const Color circle_color = {0.83, 0.84, 0.82};
+      /* Free stuff */
+      g_object_unref (layout);
 
-      *color = circle_color;
+      node = node->next;
     }
-  else
-    {
-      color_number = angle / (G_PI/3);
-      next_color_number = (color_number+1) % 6;
 
-      interpolate_colors (color,
-                          tango_colors[color_number],
-                          tango_colors[next_color_number],
-                          (angle-color_number*G_PI/3)/(G_PI/3));
-      color->red = color->red * intensity;
-      color->green = color->green * intensity;
-      color->blue = color->blue * intensity;
-    }
-  
-  if (highlighted)
-    {
-      gdouble maximum;
-      
-      maximum = MAX (color->red,
-                     MAX (color->green,
-                          color->blue));
-      color->red /= maximum;
-      color->green /= maximum;
-      color->blue /= maximum;
-    }
+  cairo_restore (cr);
 }
 
 static void
-tree_traverse (cairo_t *cr,
-               BaobabRingschart *rchart,
-               GtkTreeIter *iter,
-               guint depth,
-               gdouble radius,
-               gdouble init_angle,
-               gdouble final_angle,
-               GSList **tooltips,
-               gboolean real_draw)
+baobab_ringschart_pre_draw (GtkWidget *chart, cairo_t *cr)
 {
   BaobabRingschartPrivate *priv;
-  Color fill_color;
-  gboolean highlighted = FALSE;
+  BaobabChartItem *hl_item;
 
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (chart);
 
-  if (final_angle - init_angle < MIN_DRAWABLE_ANGLE)
+  if ( (! priv->subfoldertips_enabled) ||
+       (baobab_chart_get_summary_mode (chart)) )
     return;
-      
-  if ((priv->current_depth == depth) && (priv->current_final_angle == 3*G_PI))
-    {
-      if (priv->point_angle < final_angle)
-        {
-          if (priv->point_angle >= init_angle)
-            {
-              GtkTreePath *path;
-              GtkTreeRowReference *ref;
-              
-              path = gtk_tree_model_get_path (priv->model, iter);
-              ref = gtk_tree_row_reference_new (priv->model, path);
-
-              if (priv->button_pressed)
-                {
-                  if (priv->root) 
-                    gtk_tree_row_reference_free (priv->root);
-
-                  priv->root = ref;
-                  priv->button_pressed = FALSE;
-                  real_draw = TRUE;
-                  depth = priv->init_depth;
-                  radius = priv->min_radius;
-                  init_angle = 0;
-                  final_angle = 2*G_PI;
-                  
-                  g_signal_emit (BAOBAB_RINGSCHART (rchart),
-                                 ringschart_signals[SECTOR_ACTIVATED],
-                                 0, iter);
-                }
-              else 
-                {
-                  gchar *name;
-                  gchar *size_column;
-                  Tooltip *tip = g_new0 (Tooltip, 1);
-             
-                  priv->current_init_angle = init_angle;
-                  priv->current_final_angle = final_angle;
-                  priv->real_sector = depth >  priv->init_depth;
- 
-                  gtk_tree_model_get (priv->model, iter, 
-                                      priv->name_column, &name,
-                                      priv->size_column, &size_column, -1);             
-
-                  tip->init_angle = init_angle;
-                  tip->final_angle = final_angle;
-                  tip->depth = depth-1;
-                  tip->name = name;
-                  tip->size = size_column;
-                  tip->ref = ref;
-                  
-                  *tooltips = g_slist_prepend (*tooltips , tip);
-                  highlighted = TRUE;
-                }
-
-              gtk_tree_path_free (path);
-            }
-          else 
-            priv->current_final_angle = init_angle;            
-        }
-      else
-        priv->current_init_angle = final_angle;
-    }
-
-  if (real_draw)
-    {
-      if ((depth != 0)||(priv->init_depth>0))
-        {
-          gboolean has_child_max_depth;
 
-          /* FIXME: there is a problem when we are not in the
-             max_depth but we are not going to paint any child because
-             they are too small, the sector will not have a line but
-             it should */
-          has_child_max_depth = gtk_tree_model_iter_has_child (priv->model, iter) 
-            && (depth >= priv->max_depth);
-
-          get_color (&fill_color, init_angle, depth, highlighted);
-          draw_sector(cr, priv->center_x, priv->center_y, radius, priv->thickness, 
-                      init_angle, final_angle, fill_color, has_child_max_depth);
+  hl_item = baobab_chart_get_highlighted_item (chart);
 
-      	  /* Update drawn elements count */
-      	  priv->drawn_elements++;
-        }
-    }
-
-  if (gtk_tree_model_iter_has_child (priv->model, iter) && (depth < priv->max_depth))
+  if ( (hl_item == NULL) || (! hl_item->has_visible_children) )
     {
-      GtkTreeIter child  = {0};
-      gdouble _init_angle, _final_angle;
-
-      gtk_tree_model_iter_children (priv->model, &child, iter);
-
-      _init_angle = init_angle;
-
-      do
-        {
-          gdouble size;
-          guint next_radius;
-
-          next_radius = depth == 0 ? radius : radius+priv->thickness;
-
-          gtk_tree_model_get (priv->model, &child,
-                              priv->percentage_column, &size, -1);
-
-          if (size >= 0)
-            {
-              _final_angle = _init_angle + (final_angle - init_angle) * size/100;
-              
-              tree_traverse (cr, rchart, &child, depth+1, next_radius, 
-                             _init_angle, _final_angle, 
-                             tooltips, real_draw);
-
-              highlighted = TRUE;
-            }
-
-          _init_angle = _final_angle;
-        }
-      while (gtk_tree_model_iter_next (priv->model, &child));
-    }
-}
+      baobab_ringschart_clean_subforlder_tips_state (chart);
 
-static gint 
-baobab_ringschart_button_release (GtkWidget *widget,
-                                  GdkEventButton *event)
-{
-  BaobabRingschartPrivate *priv;
-  GtkTreeIter parent_iter;
-
-  priv = BAOBAB_RINGSCHART (widget)->priv;
-
-  switch (event->button)
-    {      
-    case LEFT_BUTTON:
-      /* Enter into a subdir */
-      if (priv->real_sector)
-	{
-	  priv->button_pressed = TRUE;		  
-
-	  gtk_widget_queue_draw (widget);
-	}   	  
-      break;
-    case MIDDLE_BUTTON:
-      /* Go back to the parent dir */
-
-      if (priv->root != NULL) 
-	{
-          GtkTreePath *path = gtk_tree_row_reference_get_path (priv->root);
-          GtkTreeIter root_iter;
-
-          if (path != NULL)
-            gtk_tree_model_get_iter (priv->model, &root_iter, path);
-          else
-            return FALSE;
-
-	  if (gtk_tree_model_iter_parent (priv->model, &parent_iter, &root_iter)) 
-	    {
-              gint valid;
-              GtkTreePath *parent_path;
-
-              gtk_tree_model_get (priv->model, &parent_iter, priv->valid_column,
-                                  &valid, -1);
-
-              if (valid == -1)
-                return FALSE;
-              
-              gtk_tree_row_reference_free (priv->root);
-              parent_path = gtk_tree_model_get_path (priv->model, &parent_iter);
-              priv->root = gtk_tree_row_reference_new (priv->model, parent_path);
-              gtk_tree_path_free (parent_path);
-
-	      g_signal_emit (BAOBAB_RINGSCHART (widget),
-			     ringschart_signals[SECTOR_ACTIVATED],
-			     0, &parent_iter);
-            
-              gtk_widget_queue_draw (widget);
-	    }
-
-          gtk_tree_path_free (path);
-	}
-      break;
-    case RIGHT_BUTTON: 
-      break;
-    }
-
-  return FALSE;
-}
-
-static gint 
-baobab_ringschart_scroll (GtkWidget *widget,
-                          GdkEventScroll *event)
-{
-  guint current_depth = baobab_ringschart_get_max_depth (widget);
-
-  switch (event->direction)
-    {
-    case GDK_SCROLL_LEFT :
-    case GDK_SCROLL_UP :
-      baobab_ringschart_set_max_depth (widget, current_depth + 1);
-      break;
-    case GDK_SCROLL_RIGHT :
-    case GDK_SCROLL_DOWN :
-      baobab_ringschart_set_max_depth (widget, current_depth - 1);
-      break;
+      return;
     }
 
-  /* change the selected sector when zooming */
-  baobab_ringschart_motion_notify (widget, (GdkEventMotion *)event);
-
-  return FALSE;
-}
-
-gboolean
-baobab_ringschart_no_pointer_motion (GtkWidget *widget)
-{
-  BaobabRingschartPrivate *priv;
-
-  priv = BAOBAB_RINGSCHART (widget)->priv;
-
-  if (!priv->draw_tooltip)
+  if (hl_item != priv->highlighted_item)
     {
-      /* At this function we are sure the mouse pointer didn't move during
-         TOOLTIP_TIMEOUT miliseconds, so we redraw the chart, asking to
-         draw the tooltip also. */
-      priv->draw_tooltip = TRUE;
-      priv->draw_children_tooltips = FALSE;
-      
-      gtk_widget_queue_draw (widget);
-
-      /* It's important to return FALSE to prevent the timeout from
-         executing again */
-      return TRUE;
-    }
-  else
-    {
-      priv->draw_children_tooltips = TRUE;
+      baobab_ringschart_clean_subforlder_tips_state (chart);
 
-      gtk_widget_queue_draw (widget);
+      priv->highlighted_item = hl_item;
 
-      return FALSE;
+      /* Launch timer to show subfolder tooltips */
+      priv->tips_timeout_event = g_timeout_add (priv->subtip_timeout,
+                        (GSourceFunc) baobab_ringschart_subfolder_tips_timeout,
+                        (gpointer) chart);
     }
 }
 
-static gint 
-baobab_ringschart_motion_notify (GtkWidget        *widget,
-                                 GdkEventMotion   *event)
+static void
+baobab_ringschart_post_draw (GtkWidget *chart, cairo_t *cr)
 {
   BaobabRingschartPrivate *priv;
-  gdouble angle;
-  gdouble x, y;
-  guint depth;
-  guint old_depth;
-  gboolean redraw = FALSE;
-
-  priv = BAOBAB_RINGSCHART (widget)->priv;
-  
-  /* First remove a previous timeout that never fired, if any */
-  if (priv->timeout_event_source > 0)
-    {
-      g_source_remove (priv->timeout_event_source);
-    }
-      
-  /* We will redraw the chart here only in one of these situations:
 
-     1) If the tooltip window is being shown, to hide it (our
-     behavior is "hide tooltip while moving pointer")
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (chart);
 
-     2) If the mouse pointer is inside the maximun depth
-     (priv->max_depth) of the chart and if it hasn't move out
-     from the current sector */
-  
-  /* Situation 1 */
-  if (priv->draw_tooltip)
+  if (priv->drawing_subtips)
     {
-      priv->draw_tooltip = FALSE; /* To avoid drawing the tooltip in the
-                                     chart redraw */
-      redraw = TRUE;
-      
-      /* Add a new timeout for the tooltip */
-      priv->timeout_event_source = 
-        g_timeout_add (TOOLTIP_TIMEOUT,
-                       (GSourceFunc) baobab_ringschart_no_pointer_motion,
-                       widget);
-    }
-  else
-    {
-      /* Situation 2  */
+      /* Reverse the glist, which was created from the tail */
+      priv->subtip_items = g_list_reverse (priv->subtip_items);
 
-      /* We need to calculate depth and angle first */
-      priv->pointer_x = event->x;
-      priv->pointer_y = event->y;
-
-      x = priv->pointer_x - priv->center_x;
-      y = priv->pointer_y - priv->center_y;
-
-      /* FIXME: could we use cairo_in_stroke or cairo_in_fill? would it be
-         a better solution */
-      angle = atan2 (y, x);
-      angle = (angle > 0) ? angle : angle + 2*G_PI;
-
-      depth = sqrt (x*x + y*y) / (priv->thickness);
-
-      old_depth = priv->current_depth; 
-      priv->current_depth = depth;
-      priv->point_angle = angle;
-
-      if (depth <= priv->max_depth) {
-
-        /* At this point we know the mouse pointer is potentially over a
-           sector, so let's start the timeout to show the tooltip */
-
-        /* Add a new timeout for the tooltip */
-        priv->timeout_event_source = 
-          g_timeout_add (TOOLTIP_TIMEOUT,
-                         (GSourceFunc) baobab_ringschart_no_pointer_motion,
-                         widget);
-
-        /* Now we check we moved out from current sector */
-        if ((depth != old_depth) || (angle < priv->current_init_angle) || 
-            (angle > priv->current_final_angle))
-          {
-            redraw = TRUE;
-          }
-      }
+      baobab_ringschart_draw_subfolder_tips (chart, cr);
     }
-
-  /* Ask redrawing if so stated */
-  if (redraw)
-    {
-      gtk_widget_queue_draw (widget);
-    }
-
-  return FALSE;
-}
-
-static inline void
-baobab_ringschart_disconnect_signals (GtkWidget *rchart, 
-                                      GtkTreeModel *model)
-{
-  g_signal_handlers_disconnect_by_func (model,
-                                        baobab_ringschart_row_changed,
-                                        rchart);
-  g_signal_handlers_disconnect_by_func (model,
-                                        baobab_ringschart_row_inserted,
-                                        rchart);
-  g_signal_handlers_disconnect_by_func (model,
-                                        baobab_ringschart_row_has_child_toggled,
-                                        rchart);
-  g_signal_handlers_disconnect_by_func (model,
-                                        baobab_ringschart_row_deleted,
-                                        rchart);
-  g_signal_handlers_disconnect_by_func (model,
-                                        baobab_ringschart_rows_reordered,
-                                        rchart);     
-}
-
-static inline void
-baobab_ringschart_connect_signals (GtkWidget *rchart,
-                                   GtkTreeModel *model)
-{
-  g_signal_connect (model,
-                    "row_changed",
-                    G_CALLBACK (baobab_ringschart_row_changed),
-                    rchart);
-  g_signal_connect (model,
-                    "row_inserted",
-                    G_CALLBACK (baobab_ringschart_row_inserted),
-                    rchart);
-  g_signal_connect (model,
-                    "row_has_child_toggled",
-                    G_CALLBACK (baobab_ringschart_row_has_child_toggled),
-                    rchart);
-  g_signal_connect (model,
-                    "row_deleted",
-                    G_CALLBACK (baobab_ringschart_row_deleted),
-                    rchart);
-  g_signal_connect (model,
-                    "rows_reordered",
-                    G_CALLBACK (baobab_ringschart_rows_reordered),
-                    rchart);
 }
 
 /* Public functions start here */
 
 /**
  * baobab_ringschart_new:
- * 
+ *
  * Constructor for the baobab_ringschart class
  *
  * Returns: a new #BaobabRingschart object
@@ -1800,444 +646,27 @@
 }
 
 /**
- * baobab_ringschart_set_model_with_columns:
- * @rchart: the #BaobabRingschart whose model is going to be set
- * @model: the #GtkTreeModel which is going to set as the model of
- * @rchart
- * @name_column: number of column inside @model where the file name is
- * stored
- * @size_column: number of column inside @model where the file size is
- * stored
- * @info_column: number of column inside @model where the percentage
- * of disk usage is stored
- * @percentage_column: number of column inside @model where the disk
- * usage percentage is stored
- * @valid_column: number of column inside @model where the flag indicating
- * if the row data is right or not.
- * @root: a #GtkTreePath indicating the node of @model which will be
- * used as root.
+ * baobab_ringschart_set_subfoldertips_enabled:
+ * @chart: the #BaobabRingschart to set the
+ * @enabled: boolean to determine whether to show sub-folder tips.
  *
- * Sets @model as the #GtkTreeModel used by @rchart. Indicates the
- * columns inside @model where the values file name, file
- * size, file information, disk usage percentage and data correction are stored, and
- * the node which will be used as the root of @rchart.  Once
- * the model has been successfully set, a redraw of the window is
- * forced.
- * This function is intended to be used the first time a #GtkTreeModel
- * is assigned to @rchart, or when the columns containing the needed data
- * are going to change. In other cases, #baobab_ringschart_set_model should
- * be used.
- * This function does not change the state of the signals from the model, which
- * is controlled by he #baobab_ringschart_freeze_updates and the 
- * #baobab_ringschart_thaw_updates functions. 
- * 
- * Fails if @rchart is not a #BaobabRingschart or if @model is not a
- * #GtkTreeModel.
- **/
-void 
-baobab_ringschart_set_model_with_columns (GtkWidget *rchart, 
-                                          GtkTreeModel *model,
-                                          guint name_column,
-                                          guint size_column,
-                                          guint info_column,
-                                          guint percentage_column,
-                                          guint valid_column,
-                                          GtkTreePath *root)
-{
-  BaobabRingschartPrivate *priv;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-  g_return_if_fail (GTK_IS_TREE_MODEL (model));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  baobab_ringschart_set_model (rchart, model);
-  
-  if (root != NULL)
-    {
-      priv->root = gtk_tree_row_reference_new (model, root);
-      g_object_notify (G_OBJECT (rchart), "root");
-    }
-
-  priv->name_column = name_column;
-  priv->size_column = size_column;
-  priv->info_column = info_column;
-  priv->percentage_column = percentage_column;
-  priv->valid_column = valid_column;
-}
-
-/**
- * baobab_ringschart_set_model:
- * @rchart: the #BaobabRingschart whose model is going to be set
- * @model: the #GtkTreeModel which is going to set as the model of
- * @rchart
+ * Enables/disables drawing tooltips of sub-forlders of the highlighted sector.
  *
- * Sets @model as the #GtkTreeModel used by @rchart, and takes the needed
- * data from the columns especified in the last call to 
- * #baobab_ringschart_set_model_with_colums.
- * This function does not change the state of the signals from the model, which
- * is controlled by he #baobab_ringschart_freeze_updates and the 
- * #baobab_ringschart_thaw_updates functions. 
- * 
- * Fails if @rchart is not a #BaobabRingschart or if @model is not a
- * #GtkTreeModel.
- **/
-void 
-baobab_ringschart_set_model (GtkWidget *rchart,
-                             GtkTreeModel *model)
-{
-  BaobabRingschartPrivate *priv;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-  g_return_if_fail (GTK_IS_TREE_MODEL (model));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  if (model == priv->model)
-    return;
-
-  if (priv->model)
-    {
-      if (!priv->is_frozen)
-        baobab_ringschart_disconnect_signals (rchart, 
-                                              priv->model);
-      g_object_unref (priv->model);
-    }
-
-  priv->model = model;
-  g_object_ref (priv->model);
-
-  if (!priv->is_frozen)
-    baobab_ringschart_connect_signals (rchart, 
-                                       priv->model);
-
-  if (priv->root)
-    {
-      gtk_tree_row_reference_free (priv->root);
-    }
-
-  priv->root = NULL;
-
-  g_object_notify (G_OBJECT (rchart), "model");
-
-  gtk_widget_queue_draw (rchart);
-}
-
-/**
- * baobab_ringschart_get_model:
- * @rchart: a #BaobabRingschart whose model will be returned.
- *
- * Returns the #GtkTreeModel which is the model used by @rchart.
+ * Fails if @chart is not a #BaobabRingschart.
  *
- * Returns: %NULL if @rchart is not a #BaobabRingschart.
- **/ 
-GtkTreeModel *
-baobab_ringschart_get_model (GtkWidget *rchart)
-{
-  g_return_val_if_fail (BAOBAB_IS_RINGSCHART (rchart), NULL);
-
-  return BAOBAB_RINGSCHART (rchart)->priv->model;
-}
-
-/**
- * baobab_ringschart_set_max_depth:
- * @rchart: a #BaobabRingschart 
- * @max_depth: the new maximum depth to show in the widget.
- *
- * Sets the maximum number of rings that are going to be show in the
- * wigdet, and causes a redraw of the widget to show the new maximum
- * depth. If max_depth is < 1 MAX_DRAWABLE_DEPTH is used.
- *
- * Fails if @rchart is not a #BaobabRingschart.
  **/
-void 
-baobab_ringschart_set_max_depth (GtkWidget *rchart, 
-                                 guint max_depth)
+void
+baobab_ringschart_set_subfoldertips_enabled (GtkWidget *chart, gboolean enabled)
 {
   BaobabRingschartPrivate *priv;
 
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
+  priv = BAOBAB_RINGSCHART_GET_PRIVATE (chart);
 
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
+  priv->subfoldertips_enabled = enabled;
 
-  if (max_depth != priv->max_depth)
+  if ( (! enabled) && (priv->drawing_subtips) )
     {
-      priv->max_depth = MAX (1, MIN (max_depth, MAX_DRAWABLE_DEPTH));
-      priv->max_radius = MIN (rchart->allocation.width / 2,
-                              rchart->allocation.height / 2) - WINDOW_PADDING*2;
-      priv->min_radius = priv->max_radius / (priv->max_depth + 1);
-      priv->thickness = priv->min_radius;
-      g_object_notify (G_OBJECT (rchart), "max-depth");
-
-      priv->draw_tooltip = FALSE;
-
-      gtk_widget_queue_draw (rchart);
+      /* Turn off currently drawn tips */
+      baobab_ringschart_clean_subforlder_tips_state (chart);
     }
 }
-
-/**
- * baobab_ringschart_get_max_depth:
- * @rchart: a #BaobabRingschart.
- *
- * Returns the maximum number of circles that will be show in the
- * widget.
- *
- * Fails if @rchart is not a #BaobabRingschart.
- **/
-guint
-baobab_ringschart_get_max_depth (GtkWidget *rchart)
-{
-  g_return_val_if_fail (BAOBAB_IS_RINGSCHART (rchart), 0);
-
-  return BAOBAB_RINGSCHART (rchart)->priv->max_depth;
-}
-
-/**
- * baobab_ringschart_set_root:
- * @rchart: a #BaobabRingschart 
- * @root: a #GtkTreePath indicating the node which will be used as
- * the widget root.
- *
- * Sets the node pointed by @root as the new root of the widget
- * @rchart.
- *
- * Fails if @rchart is not a #BaobabRingschart or if @rchart has not
- * a #GtkTreeModel set.
- **/
-void 
-baobab_ringschart_set_root (GtkWidget *rchart, 
-                            GtkTreePath *root)
-{
-  BaobabRingschartPrivate *priv;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  g_return_if_fail (priv->model != NULL);
-
-  if (priv->root) 
-    gtk_tree_row_reference_free (priv->root);
-    
-  priv->root = gtk_tree_row_reference_new (priv->model, root);
-  
-  g_object_notify (G_OBJECT (rchart), "root");
-
-  gtk_widget_queue_draw (rchart); 
-}
-
-/**
- * baobab_ringschart_get_root:
- * @rchart: a #BaobabRingschart.
- *
- * Returns a #GtkTreePath pointing to the root of the widget. The
- * programmer has the responsability to free the used memory once
- * finished with the returned value. It returns NULL if there is no
- * root node defined
- *
- * Fails if @rchart is not a #BaobabRingschart.
- **/
-GtkTreePath *
-baobab_ringschart_get_root (GtkWidget *rchart)
-{
-  g_return_val_if_fail (BAOBAB_IS_RINGSCHART (rchart), NULL);
-
-  if (BAOBAB_RINGSCHART (rchart)->priv->root) 
-    return gtk_tree_row_reference_get_path (BAOBAB_RINGSCHART (rchart)->priv->root);
-  else
-    return NULL;
-}
-
-/**
- * baobab_ringschart_get_drawn_elements:
- * @rchart: a #BaobabRingschart.
- *
- * Returns the number of sectors (folders) that are been shown
- * by the @rchart with its current maximum depth.
- *
- * Fails if @rchart is not a #BaobabRingschart.
- **/
-gint 
-baobab_ringschart_get_drawn_elements (GtkWidget *rchart)
-{
-  g_return_val_if_fail (BAOBAB_IS_RINGSCHART (rchart), 0);
-
-  return BAOBAB_RINGSCHART (rchart)->priv->drawn_elements;  
-}
-
-/**
- * baobab_ringschart_freeze_updates:
- * @rchart: the #BaobabRingschart whose model signals are going to be frozen.
- *
- * Disconnects @rchart from the signals emitted by its model, and sets
- * the window of @rchart to a "processing" state, so that the window 
- * ignores changes in the ringschart's model and mouse events.
- * In order to connect again the window to the model, a call to 
- * #baobab_ringschart_thaw_updates must be done. 
- *
- * Fails if @rchart is not a #BaobabRingschart.
- **/
-void 
-baobab_ringschart_freeze_updates (GtkWidget *rchart)
-{
-  BaobabRingschartPrivate *priv;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  if (!priv->is_frozen) 
-    {
-      cairo_surface_t *surface = NULL;
-      cairo_t *cr = NULL;
-
-      if (priv->model)
-        baobab_ringschart_disconnect_signals (rchart, 
-                                              priv->model);
-
-      surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                            rchart->allocation.width, 
-                                            rchart->allocation.height);
-
-      if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
-        {
-          cr = cairo_create (surface);
-
-          /* we want to avoid the draw of the tips */
-          priv->current_depth = priv->max_depth+1;
-
-          baobab_ringschart_draw (rchart, cr);
-
-          cairo_rectangle (cr,
-                           0, 0,
-                           rchart->allocation.width,
-                           rchart->allocation.height);
-
-          cairo_set_source_rgba (cr, 0.93, 0.93, 0.93, 0.5);  /* tango: eeeeec */
-          cairo_fill_preserve (cr);
-
-          cairo_clip (cr);
-          
-          priv->memento = surface;
-
-          cairo_destroy (cr);
-
-        }
-
-      priv->is_frozen = TRUE;
-      gtk_widget_queue_draw (rchart); 
-    }
-}
-
-/**
- * baobab_ringschart_thaw_updates:
- * @rchart: the #BaobabRingschart whose model signals are frozen.
- *
- * Reconnects @rchart to the signals emitted by its model, which
- * were disconnected through a call to #baobab_ringschart_freeze_updates.
- * Takes the window out of its "processing" state and forces a redraw
- * of the widget.
- *
- * Fails if @rchart is not a #BaobabRingschart.
- **/
-void 
-baobab_ringschart_thaw_updates (GtkWidget *rchart)
-{
-  BaobabRingschartPrivate *priv;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  if (priv->is_frozen)
-    {
-      if (priv->model)
-        baobab_ringschart_connect_signals (rchart,
-                                           priv->model);
-
-      if (priv->memento)
-        {
-          cairo_surface_destroy (priv->memento);
-          priv->memento = NULL;
-        }
-
-      priv->is_frozen = FALSE;
-      gtk_widget_queue_draw (rchart); 
-    }
-}
-
-/**
- * baobab_ringschart_set_init_depth:
- * @rchart: the #BaobabRingschart widget.
- * @depth: the depth we want the widget to paint the root node
- *
- * This function allows the developer to change the level we want to
- * paint the root node, in other words, if we want to paint the root
- * level in the center we have to set depth to 0. The default value is
- * 0.
- **/
-void 
-baobab_ringschart_set_init_depth (GtkWidget *rchart, 
-                                  guint depth)
-{  
-  BaobabRingschartPrivate *priv;
-  
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  priv->init_depth = depth;
-  gtk_widget_queue_draw (rchart); 
-}
-
-/**
- * baobab_ringschart_draw_center:
- * @rchart: the #BaobabRingschart widget.
- * @draw_center: TRUE if you want the widget to paint the center
- * circle, no matter the selected init depth.
- *
- * If the draw_center is TRUE the widget will paint the center circle
- * even when you start painting in a level over the 0.
- **/
-void 
-baobab_ringschart_draw_center (GtkWidget *rchart, 
-                               gboolean draw_center)
-{
-  BaobabRingschartPrivate *priv;
-  
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  priv->draw_center = draw_center;
-  gtk_widget_queue_draw (rchart);   
-}
-
-void 
-baobab_ringschart_set_subfoldertips_enabled (GtkWidget *rchart, 
-                                             gboolean enabled)
-{
-  BaobabRingschartPrivate *priv;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  if (enabled != priv->subfoldertips_enabled)
-    {
-      priv->subfoldertips_enabled = enabled;
-      gtk_widget_queue_draw (rchart);
-    }
-}
-
-gboolean 
-baobab_ringschart_get_subfoldertips_enabled (GtkWidget *rchart)
-{
-  BaobabRingschartPrivate *priv;
-
-  g_return_if_fail (BAOBAB_IS_RINGSCHART (rchart));
-
-  priv = BAOBAB_RINGSCHART (rchart)->priv;
-
-  return priv->subfoldertips_enabled;  
-}

Modified: trunk/baobab/src/baobab-ringschart.h
==============================================================================
--- trunk/baobab/src/baobab-ringschart.h	(original)
+++ trunk/baobab/src/baobab-ringschart.h	Mon Aug  4 09:05:32 2008
@@ -1,7 +1,7 @@
 /*
  * baobab-ringschart.h
  *
- * Copyright (C) 2006, 2007, 2008 Igalia
+ * Copyright (C) 2008 igalia
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,12 +35,10 @@
 #define __BAOBAB_RINGSCHART_H__
 
 #include <gtk/gtk.h>
-#include <gtk/gtktreemodel.h>
+#include "baobab-chart.h"
 
 G_BEGIN_DECLS
 
-#define MAX_DRAWABLE_DEPTH 8
-
 #define BAOBAB_RINGSCHART_TYPE		(baobab_ringschart_get_type ())
 #define BAOBAB_RINGSCHART(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), BAOBAB_RINGSCHART_TYPE, BaobabRingschart))
 #define BAOBAB_RINGSCHART_CLASS(obj)	(G_TYPE_CHECK_CLASS_CAST ((obj), BAOBAB_RINGSCHART, BaobabRingschartClass))
@@ -54,51 +52,20 @@
 
 struct _BaobabRingschart
 {
-  GtkWidget parent;
+  BaobabChart parent;
   
-  /* < private > */
   BaobabRingschartPrivate *priv;
 };
 
 struct _BaobabRingschartClass
 {
-  GtkWidgetClass parent_class;
-
-  void (* sector_activated) (BaobabRingschart *rchart,
-                             GtkTreeIter *iter);
-  
+  BaobabChartClass parent_class;
 };
 
 GType baobab_ringschart_get_type (void) G_GNUC_CONST;
-
 GtkWidget *baobab_ringschart_new (void);
-void baobab_ringschart_set_model_with_columns (GtkWidget *rchart,
-                                               GtkTreeModel *model,
-                                               guint name_column,
-                                               guint size_column,
-                                               guint info_column,
-                                               guint percentage_column,
-                                               guint valid_column,
-                                               GtkTreePath *root);
-void baobab_ringschart_set_model (GtkWidget *rchart,
-                                  GtkTreeModel *model);
-GtkTreeModel *baobab_ringschart_get_model (GtkWidget *rchart);
-void baobab_ringschart_set_max_depth (GtkWidget *rchart, 
-                                      guint max_depth);
-guint baobab_ringschart_get_max_depth (GtkWidget *rchart);
-void baobab_ringschart_set_root (GtkWidget *rchart, 
-                                 GtkTreePath *root);
-GtkTreePath *baobab_ringschart_get_root (GtkWidget *rchart);
-gint baobab_ringschart_get_drawn_elements (GtkWidget *rchart);
-void baobab_ringschart_freeze_updates (GtkWidget *rchart);
-void baobab_ringschart_thaw_updates (GtkWidget *rchart);
-void baobab_ringschart_set_init_depth (GtkWidget *rchart, 
-                                       guint depth);
-void baobab_ringschart_draw_center (GtkWidget *rchart, 
-                                    gboolean draw_center);
-void baobab_ringschart_set_subfoldertips_enabled (GtkWidget *rchart, 
+void baobab_ringschart_set_subfoldertips_enabled (GtkWidget *chart, 
                                                   gboolean enabled);
-gboolean baobab_ringschart_get_subfoldertips_enabled (GtkWidget *rchart);
 
 G_END_DECLS
 

Modified: trunk/baobab/src/baobab.c
==============================================================================
--- trunk/baobab/src/baobab.c	(original)
+++ trunk/baobab/src/baobab.c	Mon Aug  4 09:05:32 2008
@@ -40,6 +40,7 @@
 #include "gedit-spinner.h"
 
 #include "baobab-treemap.h"
+#include "baobab-ringschart.h"
 
 static GVolumeMonitor 	 *monitor_vol;
 static GFileMonitor	 *monitor_home;
@@ -61,13 +62,15 @@
 static gboolean
 scan_is_local (GFile	*file)
 {
-	gchar	*uri_scheme;
-	gboolean	ret=FALSE;
-	
+	gchar *uri_scheme;
+	gboolean ret = FALSE;
+
 	uri_scheme = g_file_get_uri_scheme (file);
-	if (g_ascii_strcasecmp(uri_scheme,"file") == 0) ret= TRUE;
-	
+	if (g_ascii_strcasecmp(uri_scheme,"file") == 0)
+		ret = TRUE;
+
 	g_free (uri_scheme);
+
 	return ret;
 }
 
@@ -84,18 +87,21 @@
 		cursor = busy_cursor;
 
 		gedit_spinner_start (GEDIT_SPINNER (baobab.spinner));
- 		baobab_ringschart_freeze_updates (baobab.ringschart);
-		baobab_ringschart_set_init_depth (baobab.ringschart, 0);
+
+		baobab_chart_freeze_updates (baobab.rings_chart);
+		baobab_chart_set_summary_mode (baobab.rings_chart, FALSE);
 
 		baobab_chart_freeze_updates (baobab.treemap_chart);
 		baobab_chart_set_summary_mode (baobab.treemap_chart, FALSE);
+
 		gtk_widget_set_sensitive (baobab.chart_type_combo, FALSE);
 	}
 	else {
 		gedit_spinner_stop (GEDIT_SPINNER (baobab.spinner));
- 		baobab_ringschart_thaw_updates (baobab.ringschart);
 
+		baobab_chart_thaw_updates (baobab.rings_chart);
 		baobab_chart_thaw_updates (baobab.treemap_chart);
+
 		gtk_widget_set_sensitive (baobab.chart_type_combo, TRUE);
 	}
 
@@ -116,7 +122,7 @@
 
 		set_statusbar (_("Scanning..."));
 		set_glade_widget_sens ("expand_all", TRUE);
-		set_glade_widget_sens ("collapse_all", TRUE);		
+		set_glade_widget_sens ("collapse_all", TRUE);
 	}
 
 	set_glade_widget_sens ("tbscanhome", !scanning);
@@ -181,7 +187,7 @@
 				show_bars,
 				NULL);
 
-	baobab_ringschart_set_max_depth (baobab.ringschart, baobab.model_max_depth);
+	baobab_chart_set_max_depth (baobab.rings_chart, baobab.model_max_depth);
 	baobab_chart_set_max_depth (baobab.treemap_chart, baobab.model_max_depth);
 
 	baobab_set_busy (FALSE);
@@ -568,20 +574,20 @@
 
 	separator = gtk_separator_tool_item_new ();
 	gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (separator), FALSE);
-	gtk_tool_item_set_expand (GTK_TOOL_ITEM (separator), TRUE);	
+	gtk_tool_item_set_expand (GTK_TOOL_ITEM (separator), TRUE);
 	gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (separator));
 	gtk_widget_show (GTK_WIDGET (separator));
 
 	baobab.spinner = gedit_spinner_new ();
-	item = gtk_tool_item_new ();		
+	item = gtk_tool_item_new ();
 	gtk_container_add (GTK_CONTAINER (item), baobab.spinner);
-  	gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (item));
+	gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (item));
 	gtk_widget_show (GTK_WIDGET (baobab.spinner));
 	gtk_widget_show (GTK_WIDGET (item));
 
 	g_signal_connect (item, "toolbar-reconfigured",
 			  G_CALLBACK (toolbar_reconfigured_cb), baobab.spinner);
-        toolbar_reconfigured_cb (item, GEDIT_SPINNER (baobab.spinner));
+	toolbar_reconfigured_cb (item, GEDIT_SPINNER (baobab.spinner));
 	baobab_toolbar_style (NULL, 0, NULL, NULL);
 
 	visible = gconf_client_get_bool (baobab.gconf_client,
@@ -615,7 +621,7 @@
 			       GConfEntry *entry,
 			       gpointer user_data)
 {
-        baobab_ringschart_set_subfoldertips_enabled (baobab.ringschart,
+	baobab_ringschart_set_subfoldertips_enabled (baobab.rings_chart,
 						     gconf_client_get_bool (baobab.gconf_client,
 									    BAOBAB_SUBFLSTIPS_VISIBLE_KEY,
 									    NULL));
@@ -754,8 +760,8 @@
 {
 	ContextMenu *menu = NULL;
 
-	baobab.rchart_menu = g_new0 (ContextMenu, 1);
-	menu = baobab.rchart_menu;
+	baobab.chart_menu = g_new0 (ContextMenu, 1);
+	menu = baobab.chart_menu;
 
 	menu->widget = gtk_menu_new ();
 		
@@ -771,12 +777,22 @@
 	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu->zoom_out_item), 
 				       gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU));       
 		
+	menu->snapshot_item = gtk_image_menu_item_new_with_label (_("Save snapshot"));
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu->snapshot_item),
+									gtk_image_new_from_file (BAOBAB_PIX_DIR "shot.png"));
+
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu->widget),
 			       menu->up_item);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu->widget),
+			       gtk_separator_menu_item_new ());
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu->widget),
 			       menu->zoom_in_item);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu->widget),
 			       menu->zoom_out_item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu->widget),
+			       gtk_separator_menu_item_new ());
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu->widget),
+			       menu->snapshot_item);
 
 	/* connect signals */
 	g_signal_connect (menu->up_item, "activate",
@@ -785,65 +801,33 @@
 			  G_CALLBACK (on_zoom_in_cb), NULL);
 	g_signal_connect (menu->zoom_out_item, "activate",
 			  G_CALLBACK (on_zoom_out_cb), NULL);
-	
+	g_signal_connect (menu->snapshot_item, "activate",
+					  G_CALLBACK (on_chart_snapshot_cb), NULL);
+
 	gtk_widget_show_all (menu->widget);
 }
 
 static void
 initialize_ringschart (void)
 {
-        GtkWidget *hpaned_main;
-        GtkWidget *ringschart_frame;
-        ContextMenu *menu = NULL;
+	GtkWidget *hpaned_main;
+	GtkWidget *chart_frame;
 	GtkWidget *hbox1;
 
-        baobab.ringschart = GTK_WIDGET (baobab_ringschart_new ());
-        baobab_ringschart_set_model_with_columns (baobab.ringschart,
-                                                  GTK_TREE_MODEL (baobab.model),
-                                                  COL_DIR_NAME,
-                                                  COL_DIR_SIZE,
-                                                  COL_H_PARSENAME,
-                                                  COL_H_PERC,
-                                                  COL_H_ELEMENTS,
-                                                  NULL);
-        baobab_ringschart_set_init_depth (baobab.ringschart, 1);
-
-	baobab_ringschart_set_max_depth (baobab.ringschart, 1);
-
-	baobab_ringschart_set_subfoldertips_enabled(baobab.ringschart, 
-						    gconf_client_get_bool (baobab.gconf_client,
-									   BAOBAB_SUBFLSTIPS_VISIBLE_KEY,
-									   NULL));
-
-        g_signal_connect (baobab.ringschart, "sector_activated",
-                          G_CALLBACK (on_rchart_sector_activated), NULL);
-
-        ringschart_frame = gtk_frame_new (NULL);
-        gtk_frame_set_label_align (GTK_FRAME (ringschart_frame), 0.0, 0.0);
-        gtk_frame_set_shadow_type (GTK_FRAME (ringschart_frame), GTK_SHADOW_IN);
-
-        gtk_container_add (GTK_CONTAINER (ringschart_frame),
-                           baobab.ringschart);
-
-        hpaned_main = glade_xml_get_widget (baobab.main_xml, "hpaned_main");
-        gtk_paned_pack2 (GTK_PANED (hpaned_main),
-                         ringschart_frame, TRUE, TRUE);
-        gtk_paned_set_position (GTK_PANED (hpaned_main), 480);
-
-        baobab_ringschart_draw_center (baobab.ringschart, TRUE);
-
-	create_context_menu ();
-
-	g_signal_connect (baobab.ringschart, "button-release-event", 
-			  G_CALLBACK (on_rchart_button_release), NULL);
-
-        gtk_widget_show_all (ringschart_frame);
+	chart_frame = gtk_frame_new (NULL);
+	gtk_frame_set_label_align (GTK_FRAME (chart_frame), 0.0, 0.0);
+	gtk_frame_set_shadow_type (GTK_FRAME (chart_frame), GTK_SHADOW_IN);
+
+	hpaned_main = glade_xml_get_widget (baobab.main_xml, "hpaned_main");
+	gtk_paned_pack2 (GTK_PANED (hpaned_main),
+			 chart_frame, TRUE, TRUE);
+	gtk_paned_set_position (GTK_PANED (hpaned_main), 480);
 
 	baobab.chart_type_combo = gtk_combo_box_new_text ();
 	gtk_combo_box_append_text (GTK_COMBO_BOX (baobab.chart_type_combo), 
-								_("View as Rings Chart"));
+				   _("View as Rings Chart"));
 	gtk_combo_box_append_text (GTK_COMBO_BOX (baobab.chart_type_combo), 
-								_("View as Treemap Chart"));
+				   _("View as Treemap Chart"));
 	gtk_combo_box_set_active (GTK_COMBO_BOX (baobab.chart_type_combo), 0);
 	gtk_widget_show (baobab.chart_type_combo);
 	g_signal_connect (baobab.chart_type_combo,
@@ -861,23 +845,54 @@
 
 	/* Baobab's Treemap Chart */
 	baobab.treemap_chart = baobab_treemap_new ();
-	baobab_chart_set_total_fs_size (baobab.treemap_chart, g_fs.total);
 	baobab_chart_set_model_with_columns (baobab.treemap_chart,
-										GTK_TREE_MODEL (baobab.model),
-										COL_DIR_NAME,
-										COL_DIR_SIZE,
-										COL_H_PARSENAME,
-										COL_H_PERC,
-										COL_H_ELEMENTS,
-										NULL);
+					     GTK_TREE_MODEL (baobab.model),
+					     COL_DIR_NAME,
+					     COL_DIR_SIZE,
+					     COL_H_PARSENAME,
+					     COL_H_PERC,
+					     COL_H_ELEMENTS,
+					     NULL);
 	baobab_chart_set_max_depth (baobab.treemap_chart, 1);
-	g_signal_connect (baobab.treemap_chart, "sector_activated",
-					G_CALLBACK (on_rchart_sector_activated), NULL);
+	g_signal_connect (baobab.treemap_chart, "item_activated",
+					G_CALLBACK (on_chart_item_activated), NULL);
+	g_signal_connect (baobab.treemap_chart, "button-release-event", 
+					G_CALLBACK (on_chart_button_release), NULL);
 	gtk_widget_show (baobab.treemap_chart);
 	/* Ends Baobab's Treemap Chart */
 
-	baobab.current_chart = baobab.ringschart;
+	/* Baobab's Rings Chart */
+	baobab.rings_chart = (GtkWidget *) baobab_ringschart_new ();
+	baobab_chart_set_model_with_columns (baobab.rings_chart,
+					     GTK_TREE_MODEL (baobab.model),
+					     COL_DIR_NAME,
+					     COL_DIR_SIZE,
+					     COL_H_PARSENAME,
+					     COL_H_PERC,
+					     COL_H_ELEMENTS,
+					     NULL);
+	baobab_ringschart_set_subfoldertips_enabled (baobab.rings_chart,
+						     gconf_client_get_bool (baobab.gconf_client,
+									    BAOBAB_SUBFLSTIPS_VISIBLE_KEY,
+									    NULL));
+	baobab_chart_set_max_depth (baobab.rings_chart, 1);
+	g_signal_connect (baobab.rings_chart, "item_activated",
+					G_CALLBACK (on_chart_item_activated), NULL);
+	g_signal_connect (baobab.rings_chart, "button-release-event", 
+					G_CALLBACK (on_chart_button_release), NULL);
+	gtk_widget_show (baobab.rings_chart);
+	/* Ends Baobab's Treemap Chart */
+
+	baobab.current_chart = baobab.rings_chart;
+
 	g_object_ref_sink (baobab.treemap_chart);
+	baobab_chart_freeze_updates (baobab.treemap_chart);
+
+	gtk_container_add (GTK_CONTAINER (chart_frame),
+			   baobab.current_chart);
+	gtk_widget_show_all (chart_frame);
+
+	create_context_menu ();
 }
 
 static gboolean
@@ -928,8 +943,8 @@
                 gtk_message_dialog_format_secondary_text
                                                         (GTK_MESSAGE_DIALOG(dialog),
                                                          _("Without mount points disk usage cannot be analyzed."));
- 		gtk_dialog_run (GTK_DIALOG (dialog));
- 		gtk_widget_destroy (dialog);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
 		goto closing;
 	}
 

Modified: trunk/baobab/src/baobab.h
==============================================================================
--- trunk/baobab/src/baobab.h	(original)
+++ trunk/baobab/src/baobab.h	Mon Aug  4 09:05:32 2008
@@ -55,17 +55,19 @@
 	GtkWidget* zoom_in_item;
 	GtkWidget* zoom_out_item;
 	GtkWidget* subfolders_item;
+	GtkWidget* snapshot_item;
+	GtkWidget* set_root_item;
 };
 
 struct _baobab_application {
 	GladeXML *main_xml;
   	GtkWidget *window;
   	GtkWidget *tree_view;
-  	GtkWidget *ringschart;
+	GtkWidget *rings_chart;
 	GtkWidget *treemap_chart;
 	GtkWidget *current_chart;
 	GtkWidget *chart_type_combo;
-	ContextMenu *rchart_menu;
+	ContextMenu *chart_menu;
 	GtkWidget *toolbar;
 	GtkWidget *spinner;
 	GtkWidget *statusbar;

Modified: trunk/baobab/src/callbacks.c
==============================================================================
--- trunk/baobab/src/callbacks.c	(original)
+++ trunk/baobab/src/callbacks.c	Mon Aug  4 09:05:32 2008
@@ -370,15 +370,15 @@
                 
 		path = gtk_tree_model_get_path (GTK_TREE_MODEL (baobab.model), &iter);
                 
+		baobab_chart_set_root (baobab.rings_chart, path);
 		baobab_chart_set_root (baobab.treemap_chart, path);
-		baobab_ringschart_set_root (baobab.ringschart, path);
 		
 		gtk_tree_path_free (path);
 	}
 }
 
 void
-on_rchart_sector_activated (BaobabRingschart *rchart, GtkTreeIter *iter)
+on_chart_item_activated (BaobabChart *chart, GtkTreeIter *iter)
 {
 	GtkTreePath *path;
 
@@ -392,26 +392,31 @@
 	gtk_tree_path_free (path);
 }
 
-
 gboolean
-on_rchart_button_release (BaobabRingschart *rchart, GdkEventButton *event,
+on_chart_button_release (BaobabChart *chart, GdkEventButton *event,
                           gpointer data)
 {
-  ContextMenu *menu = baobab.rchart_menu;
+  ContextMenu *menu;
+  
+  if (baobab_chart_is_frozen (baobab.current_chart))
+    return FALSE;
+
+  menu = baobab.chart_menu;
   
   if (event->button== 3) /* right button */
     {
       GtkTreePath *root_path = NULL;
 
-      root_path = baobab_ringschart_get_root (baobab.ringschart);
+      root_path = baobab_chart_get_root (baobab.current_chart);
 
       gtk_widget_set_sensitive (menu->up_item,
                                 ((root_path != NULL) &&
                                  (gtk_tree_path_get_depth (root_path) > 1)));
       gtk_widget_set_sensitive (menu->zoom_in_item,
-                                (baobab_ringschart_get_max_depth (baobab.ringschart) > 1));
+                                (baobab_chart_get_max_depth (baobab.current_chart) > 1));
       gtk_widget_set_sensitive (menu->zoom_out_item,
-                                (baobab_ringschart_get_max_depth (baobab.ringschart) < MAX_DRAWABLE_DEPTH));
+                               (baobab_chart_get_max_depth (baobab.current_chart) 
+                                < BAOBAB_CHART_MAX_DEPTH));
 
       /* show the menu */
       gtk_menu_popup (GTK_MENU (menu->widget), NULL, NULL, NULL, NULL,
@@ -426,57 +431,25 @@
 void
 on_move_upwards_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data)
 {
-  GtkTreePath *path = baobab_ringschart_get_root (baobab.ringschart);
-
-  /* Go back to the parent dir */
-  if (path != NULL)
-    {
-      GtkTreeIter parent_iter;
-      GtkTreeIter root_iter;
-
-      if (path != NULL)
-        {
-          gtk_tree_model_get_iter (GTK_TREE_MODEL (baobab.model), &root_iter, path);
-
-          if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (baobab.model), &parent_iter, &root_iter))
-            {
-              gint valid;
-              GtkTreePath *parent_path;
-
-              gtk_tree_model_get (GTK_TREE_MODEL (baobab.model), &parent_iter, COL_H_ELEMENTS,
-                                  &valid, -1);
-
-              if (valid != -1)
-                {
-                  parent_path = gtk_tree_model_get_path (GTK_TREE_MODEL (baobab.model), &parent_iter);
-
-                  baobab_ringschart_set_root (baobab.ringschart, parent_path);
-                  baobab_chart_set_root (baobab.treemap_chart, parent_path);
-
-                  gtk_tree_path_free (parent_path);
-                }
-            }
-        }
-      gtk_tree_path_free (path);
-    }
+  baobab_chart_move_up_root (baobab.current_chart);
 }
 
 void
 on_zoom_in_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data)
 {
-  baobab_ringschart_set_max_depth (baobab.ringschart,
-                                   baobab_ringschart_get_max_depth (baobab.ringschart) - 1);
-
-  baobab_chart_zoom_in (baobab.treemap_chart);
+  baobab_chart_zoom_in (baobab.current_chart);
 }
 
 void
 on_zoom_out_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data)
 {
-  baobab_ringschart_set_max_depth (baobab.ringschart,
-                                   baobab_ringschart_get_max_depth (baobab.ringschart) + 1);
+  baobab_chart_zoom_out (baobab.current_chart);
+}
 
-  baobab_chart_zoom_out (baobab.treemap_chart);
+void
+on_chart_snapshot_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data)
+{
+  baobab_chart_save_snapshot (baobab.current_chart);
 }
 
 void
@@ -485,25 +458,20 @@
   GtkWidget *chart;
   GtkWidget *frame;
 
-  guint active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
+  guint active;
 
-  if (active != 0)
-    chart = baobab.treemap_chart;
+  active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
+
+  if (active == 0)
+    chart = baobab.rings_chart;
   else
-    chart = baobab.ringschart;
+    if (active == 1)
+      chart = baobab.treemap_chart;
 
   frame = gtk_widget_get_parent (baobab.current_chart);
 
-  if (BAOBAB_IS_CHART (baobab.current_chart))
-    {
-      baobab_chart_freeze_updates (baobab.current_chart);
-      baobab_ringschart_thaw_updates (chart);
-    }
-  else
-    {
-      baobab_chart_thaw_updates (chart);
-      baobab_ringschart_freeze_updates (baobab.current_chart);
-    }
+  baobab_chart_freeze_updates (baobab.current_chart);
+  baobab_chart_thaw_updates (chart);
 
   g_object_ref_sink (baobab.current_chart);
   gtk_container_remove (GTK_CONTAINER (frame), baobab.current_chart);

Modified: trunk/baobab/src/callbacks.h
==============================================================================
--- trunk/baobab/src/callbacks.h	(original)
+++ trunk/baobab/src/callbacks.h	Mon Aug  4 09:05:32 2008
@@ -24,7 +24,7 @@
 #define __BAOBAB_CALLBACKS_H__
 
 #include <gtk/gtk.h>
-#include "baobab-ringschart.h"
+#include "baobab-chart.h"
 
 void on_about_activate (GtkMenuItem *menuitem, gpointer user_data);
 void on_menuscanhome_activate (GtkMenuItem *menuitem, gpointer user_data);
@@ -61,11 +61,13 @@
 void on_ck_allocated_activate (GtkCheckMenuItem *checkmenuitem, gpointer user_data);
 void on_helpcontents_activate (GtkMenuItem *menuitem, gpointer user_data);
 void on_tv_selection_changed (GtkTreeSelection *selection, gpointer user_data);
-void on_rchart_sector_activated (BaobabRingschart *rchart, GtkTreeIter *iter);
-gboolean on_rchart_button_release (BaobabRingschart *rchart, GdkEventButton *event, gpointer data);
+void on_chart_item_activated (BaobabChart *chart, GtkTreeIter *iter);
+gboolean on_chart_button_release (BaobabChart *chart, GdkEventButton *event, 
+                                  gpointer data);
 void on_move_upwards_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data);
 void on_zoom_in_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data);
 void on_zoom_out_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data);
+void on_chart_snapshot_cb (GtkCheckMenuItem *checkmenuitem, gpointer user_data);
 void on_chart_type_change (GtkWidget *combo, gpointer user_data);
 
 #endif /* __BAOBAB_CALLBACKS_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]