hyperbola-nav-tree.c 4.29 KB
Newer Older
1 2 3 4 5
#include <libnautilus/libnautilus.h>
#include "hyperbola-filefmt.h"
#include <gtk/gtk.h>

typedef struct {
6
  NautilusViewFrame *view_frame;
7 8 9 10 11 12 13

  GtkWidget *ctree;
  HyperbolaDocTree *doc_tree;

  gint notify_count;
} HyperbolaNavigationTree;

14
BonoboObject *hyperbola_navigation_tree_new(void);
Darin Adler's avatar
Darin Adler committed
15

16 17 18 19
static void hyperbola_navigation_tree_select_row(GtkCTree *ctree,
						 GtkCTreeNode *node,
						 gint column,
						 HyperbolaNavigationTree *view);
20
static void hyperbola_navigation_tree_notify_location_change (NautilusViewFrame *view_frame,
21
							      Nautilus_NavigationInfo *navi,
22
							      HyperbolaNavigationTree *hview);
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

typedef struct {
  HyperbolaNavigationTree *view;
  GtkCTreeNode *sibling, *parent;
} PopulateInfo;

static gboolean
ctree_populate_subnode(gpointer key, gpointer value, gpointer user_data)
{
  HyperbolaTreeNode *node = value;
  PopulateInfo *pi = (PopulateInfo *)user_data, subpi;
  gboolean term;

  term = (node->type == HYP_TREE_NODE_PAGE) || !node->children;
  pi->sibling = gtk_ctree_insert_node(GTK_CTREE(pi->view->ctree), pi->parent, NULL, &node->title, 5,
				      NULL, NULL, NULL, NULL, term, FALSE);
  node->user_data = pi->sibling;

  gtk_ctree_node_set_row_data(GTK_CTREE(pi->view->ctree), pi->sibling, node);

  if(node->children)
    {
      subpi.view = pi->view;
      subpi.sibling = NULL;
      subpi.parent = pi->sibling;
      g_tree_traverse(node->children, ctree_populate_subnode, G_IN_ORDER, &subpi);
    }

  return FALSE;
}

static void
ctree_populate(HyperbolaNavigationTree *view)
{
Darin Adler's avatar
Darin Adler committed
57
  PopulateInfo subpi = { NULL, NULL, NULL };
58 59 60 61 62 63

  subpi.view = view;

  g_tree_traverse(view->doc_tree->children, ctree_populate_subnode, G_IN_ORDER, &subpi);
}

64
BonoboObject *
65 66 67 68 69 70 71 72
hyperbola_navigation_tree_new(void)
{
  static const char *titles[] = {"Document Tree"};
  GtkWidget *wtmp;
  HyperbolaNavigationTree *view;
  
  view = g_new0(HyperbolaNavigationTree, 1);

73 74
  view->view_frame = NAUTILUS_VIEW_FRAME(gtk_widget_new(nautilus_meta_view_frame_get_type(), NULL));
  gtk_signal_connect(GTK_OBJECT(view->view_frame), "notify_location_change", hyperbola_navigation_tree_notify_location_change,
75 76
		     view);

77
  nautilus_meta_view_frame_set_label(NAUTILUS_META_VIEW_FRAME(view->view_frame), _("Help Contents"));
78 79 80 81 82 83 84 85 86 87 88 89 90

  view->ctree = gtk_ctree_new_with_titles(1, 0, (gchar **)titles);
  gtk_clist_freeze(GTK_CLIST(view->ctree));
  gtk_clist_set_selection_mode(GTK_CLIST(view->ctree), GTK_SELECTION_BROWSE);
  gtk_signal_connect(GTK_OBJECT(view->ctree), "tree_select_row", hyperbola_navigation_tree_select_row, view);
  view->doc_tree = hyperbola_doc_tree_new();
  hyperbola_doc_tree_populate(view->doc_tree);

  ctree_populate(view);

  wtmp = gtk_scrolled_window_new(gtk_clist_get_hadjustment(GTK_CLIST(view->ctree)),
				 gtk_clist_get_vadjustment(GTK_CLIST(view->ctree)));
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(wtmp), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
91
  gtk_container_add(GTK_CONTAINER(view->view_frame), wtmp);
92 93 94 95 96 97

  gtk_container_add(GTK_CONTAINER(wtmp), view->ctree);
  gtk_clist_columns_autosize(GTK_CLIST(view->ctree));
  gtk_clist_thaw(GTK_CLIST(view->ctree));
  gtk_widget_show(view->ctree);
  gtk_widget_show(wtmp);
Elliot Lee's avatar
Elliot Lee committed
98
  gtk_widget_show(GTK_WIDGET(view->view_frame));
99

100
  return nautilus_view_frame_get_bonobo_object(view->view_frame);
101 102 103
}

static void
104
hyperbola_navigation_tree_notify_location_change (NautilusViewFrame *view_frame,
105
						  Nautilus_NavigationInfo *navi,
106 107 108 109 110 111 112 113 114
						  HyperbolaNavigationTree *hview)
{
  HyperbolaTreeNode *tnode;

  if(hview->notify_count > 0)
    return;

  hview->notify_count++;

115
  tnode = g_hash_table_lookup(hview->doc_tree->global_by_uri, navi->requested_uri);
116 117 118 119 120 121 122 123 124 125 126

  if(tnode)
    gtk_ctree_select(GTK_CTREE(hview->ctree), tnode->user_data);

  hview->notify_count--;
}

static void hyperbola_navigation_tree_select_row(GtkCTree *ctree, GtkCTreeNode *node,
						 gint column, HyperbolaNavigationTree *view)
{
  HyperbolaTreeNode *tnode;
127
  Nautilus_NavigationRequestInfo nri;
128 129 130 131 132 133 134 135 136 137 138

  if(view->notify_count > 0)
    return;

  tnode = gtk_ctree_node_get_row_data(ctree, node);

  if(!tnode || !tnode->uri)
    return;

  view->notify_count++;

139 140 141
  memset(&nri, 0, sizeof(nri));
  nri.requested_uri = tnode->uri;
  nri.new_window_default = nri.new_window_suggested = nri.new_window_enforced = Nautilus_V_UNKNOWN;
142
  nautilus_view_frame_request_location_change(view->view_frame, &nri);
143 144 145

  view->notify_count--;
}