1 /* Widgets/GdaTree display
2  *
3  * This demonstration program creates a GdaTree object,
4  * feeds it to a GdauiTreeStore (which implements the GtkTreeModel
5  * interface, and creates a GtkTreeView to display the contents
6  * of the GdaTree
7  *
8  * The GdaTreeManager objects used here are:
9  *
10  * manager1: one node on which a timer modifies some attributes
11  *
12  * manager2: one node for each table in the @demo_cnc connection
13  */
14 
15 /*
16  * The GdaTreeManager structure is as follows:
17  * .
18  * |-- manager1
19  * |   `-- manager2
20  * `-- manager2
21  *
22  * Resulting in the following tree's contents:
23  * .
24  * |-- Scaling...
25  * |   |-- categories
26  * |   |-- customers
27  * |   |-- locations
28  * |   |-- order_contents
29  * |   |-- orders
30  * |   |-- pictures
31  * |   |-- products
32  * |   |-- roles
33  * |   |-- sales_orga
34  * |   |-- salesrep
35  * |   `-- warehouses
36  * |-- categories
37  * |-- customers
38  * |-- locations
39  * |-- order_contents
40  * |-- orders
41  * |-- pictures
42  * |-- products
43  * |-- roles
44  * |-- sales_orga
45  * |-- salesrep
46  * `-- warehouses
47  */
48 
49 #include <libgda-ui/libgda-ui.h>
50 
51 static GtkWidget *window = NULL;
52 extern GdaConnection *demo_cnc;
53 
54 static gboolean
timout_cb(GdaTreeNode * node)55 timout_cb (GdaTreeNode *node)
56 {
57 	const GValue *cvalue;
58 	GValue *scale;
59 	gdouble sc;
60 
61 	cvalue = gda_tree_node_get_node_attribute (node, "scale");
62 	g_assert (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_DOUBLE));
63 	sc = g_value_get_double (cvalue);
64 	sc += 0.05;
65 	if (sc > 1.2)
66 		sc = .8;
67 	g_value_set_double ((scale = gda_value_new (G_TYPE_DOUBLE)), sc);
68 	gda_tree_node_set_node_attribute (node, "scale", scale, NULL);
69 	gda_value_free (scale);
70 
71 	return TRUE;
72 }
73 
74 static GSList *
node_func(GdaTreeManager * manager,GdaTreeNode * node,const GSList * children_nodes,G_GNUC_UNUSED gboolean * out_error,G_GNUC_UNUSED GError ** error)75 node_func (GdaTreeManager *manager, GdaTreeNode *node, const GSList *children_nodes,
76 	   G_GNUC_UNUSED gboolean *out_error, G_GNUC_UNUSED GError **error)
77 {
78 	if (children_nodes) {
79 		/* we don't create or modify already created GdaTreeNode object => simply ref them */
80 		g_slist_foreach ((GSList*) children_nodes, (GFunc) g_object_ref, NULL);
81 		return g_slist_copy ((GSList*) children_nodes);
82 	}
83 	else {
84 		GSList *list;
85 		GdaTreeNode *snode;
86 		GValue *scale;
87 
88 		snode = gda_tree_manager_create_node (manager, node, "Scaling...");
89 		g_value_set_double ((scale = gda_value_new (G_TYPE_DOUBLE)), 1.);
90 		gda_tree_node_set_node_attribute (snode, "scale", scale, NULL);
91 		gda_value_free (scale);
92 		g_timeout_add (200, (GSourceFunc) timout_cb, g_object_ref (snode));
93 
94 		g_value_set_boolean ((scale = gda_value_new (G_TYPE_BOOLEAN)), TRUE);
95 		gda_tree_node_set_node_attribute (snode, "scale-set", scale, NULL);
96 		gda_value_free (scale);
97 
98 		list = g_slist_append (NULL, snode);
99 		return list;
100 	}
101 }
102 
103 GtkWidget *
do_tree(GtkWidget * do_widget)104 do_tree (GtkWidget *do_widget)
105 {
106 	if (!window) {
107 		GtkWidget *label, *treeview;
108 		GdaTree *tree;
109 		GdaTreeManager *manager1, *manager2;
110 		GtkTreeModel *model;
111 		GtkCellRenderer *renderer;
112 		GtkTreeViewColumn *column;
113 
114 		window = gtk_dialog_new_with_buttons ("GdaTree display",
115 						      GTK_WINDOW (do_widget),
116 						      0,
117 						      GTK_STOCK_CLOSE,
118 						      GTK_RESPONSE_NONE,
119 						      NULL);
120 		g_signal_connect (window, "response",
121 				  G_CALLBACK (gtk_widget_destroy), NULL);
122 		g_signal_connect (window, "destroy",
123 				  G_CALLBACK (gtk_widget_destroyed), &window);
124 
125 		label = gtk_label_new ("This demonstration program creates a GdaTree object,\n"
126 				       "feeds it to a GdauiTreeStore (which implements the GtkTreeModel\n"
127 				       "interface, and creates a GtkTreeView to display the contents\n"
128 				       "of the GdaTree");
129 		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (window))),
130 				    label, TRUE, TRUE, 0);
131 
132 		/* create GdaTree */
133 		tree = gda_tree_new ();
134 		manager1 = gda_tree_manager_new_with_func (node_func);
135 		manager2 = gda_tree_mgr_tables_new (demo_cnc, NULL);
136 		gda_tree_manager_add_manager (manager1, manager2);
137 		gda_tree_add_manager (tree, manager1);
138 		gda_tree_add_manager (tree, manager2);
139 		g_object_unref (manager1);
140 		g_object_unref (manager2);
141 
142 		gda_tree_update_all (tree, NULL);
143 
144 		/* create GtkTreeModel and GtkTreeView */
145 		model = gdaui_tree_store_new (tree, 3,
146 					      G_TYPE_STRING, GDA_ATTRIBUTE_NAME,
147 					      G_TYPE_DOUBLE, "scale",
148 					      G_TYPE_BOOLEAN, "scale-set");
149 		treeview = gtk_tree_view_new_with_model (model);
150 		g_object_unref (model);
151 		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (window))),
152 				    treeview, TRUE, TRUE, 0);
153 
154 		/* create GtkTreeView's column */
155 		enum {
156 			COLUMN_NAME,
157 			COLUMN_SCALE,
158 			COLUMN_SCALE_SET
159 		};
160 		renderer = gtk_cell_renderer_text_new ();
161 		column = gtk_tree_view_column_new_with_attributes ("Name", renderer,
162 								   "text", COLUMN_NAME,
163 								   "scale-set", COLUMN_SCALE_SET,
164 								   "scale", COLUMN_SCALE,
165 								   NULL);
166 		gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
167 	}
168 
169 	gboolean visible;
170 	g_object_get (G_OBJECT (window), "visible", &visible, NULL);
171 	if (!visible)
172 		gtk_widget_show_all (window);
173 	else {
174 		gtk_widget_destroy (window);
175 		window = NULL;
176 	}
177 
178 	return window;
179 }
180 
181 
182