1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
|
2 /* |
|
3 * This program is free software; you can redistribute it and/or modify |
|
4 * it under the terms of the GNU General Public License version 2 as |
|
5 * published by the Free Software Foundation; |
|
6 * |
|
7 * This program is distributed in the hope that it will be useful, |
|
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
10 * GNU General Public License for more details. |
|
11 * |
|
12 * You should have received a copy of the GNU General Public License |
|
13 * along with this program; if not, write to the Free Software |
|
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
15 * |
|
16 * Authors: Faker Moatamri <faker.moatamri@sophia.inria.fr> |
|
17 * Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
|
18 */ |
|
19 #include "display-functions.h" |
|
20 #include "raw-text-config.h" |
|
21 #include "ns3/config.h" |
|
22 #include "ns3/string.h" |
|
23 #include "ns3/pointer.h" |
|
24 |
|
25 namespace ns3 { |
|
26 /** |
|
27 * This function includes the name of the attribute or the editable value |
|
28 * in the second column |
|
29 */ |
|
30 void |
|
31 cell_data_function_col_1 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, |
|
32 GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) |
|
33 { |
|
34 ModelNode *node; |
|
35 gtk_tree_model_get (model, iter, COL_NODE, &node, -1); |
|
36 if (node->type == ModelNode::NODE_ATTRIBUTE) |
|
37 { |
|
38 StringValue str; |
|
39 node->object->GetAttribute (node->name, str); |
|
40 g_object_set (renderer, "text", str.Get ().c_str (), (char*) 0); |
|
41 g_object_set (renderer, "editable", TRUE, (char*) 0); |
|
42 } |
|
43 else |
|
44 { |
|
45 g_object_set (renderer, "text", "", (char*) 0); |
|
46 g_object_set (renderer, "editable", FALSE, (char*) 0); |
|
47 } |
|
48 } |
|
49 /** |
|
50 * This function includes the name of the object, pointer, vector or vector item |
|
51 * in the first column |
|
52 */ |
|
53 void |
|
54 cell_data_function_col_0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, |
|
55 GtkTreeIter *iter, gpointer user_data) |
|
56 { |
|
57 ModelNode *node; |
|
58 gtk_tree_model_get (model, iter, COL_NODE, &node, -1); |
|
59 g_object_set (renderer, "editable", FALSE, (char*) 0); |
|
60 switch (node->type) |
|
61 { |
|
62 case ModelNode::NODE_OBJECT: |
|
63 g_object_set (renderer, "text", node->object->GetInstanceTypeId ().GetName ().c_str (), (char*) 0); |
|
64 break; |
|
65 case ModelNode::NODE_POINTER: |
|
66 g_object_set (renderer, "text", node->name.c_str (), (char*) 0); |
|
67 break; |
|
68 case ModelNode::NODE_VECTOR: |
|
69 g_object_set (renderer, "text", node->name.c_str (), (char*) 0); |
|
70 break; |
|
71 case ModelNode::NODE_VECTOR_ITEM: |
|
72 { |
|
73 std::stringstream oss; |
|
74 oss << node->index; |
|
75 g_object_set (renderer, "text", oss.str ().c_str (), (char*) 0); |
|
76 } |
|
77 break; |
|
78 case ModelNode::NODE_ATTRIBUTE: |
|
79 g_object_set (renderer, "text", node->name.c_str (), (char*) 0); |
|
80 break; |
|
81 } |
|
82 } |
|
83 |
|
84 /** |
|
85 * This is the callback called when the value of an attribute is changed |
|
86 */ |
|
87 void |
|
88 cell_edited_callback (GtkCellRendererText *cell, gchar *path_string, |
|
89 gchar *new_text, gpointer user_data) |
|
90 { |
|
91 GtkTreeModel *model = GTK_TREE_MODEL (user_data); |
|
92 GtkTreeIter iter; |
|
93 gtk_tree_model_get_iter_from_string (model, &iter, path_string); |
|
94 ModelNode *node; |
|
95 gtk_tree_model_get (model, &iter, COL_NODE, &node, -1); |
|
96 NS_ASSERT (node->type == ModelNode::NODE_ATTRIBUTE); |
|
97 node->object->SetAttribute (node->name, StringValue (new_text)); |
|
98 } |
|
99 |
|
100 /** |
|
101 * This function gets the column number 0 or 1 from the mouse |
|
102 * click |
|
103 */ |
|
104 int |
|
105 get_col_number_from_tree_view_column (GtkTreeViewColumn *col) |
|
106 { |
|
107 GList *cols; |
|
108 int num; |
|
109 g_return_val_if_fail (col != 0, -1); |
|
110 g_return_val_if_fail (col->tree_view != 0, -1); |
|
111 cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (col->tree_view)); |
|
112 num = g_list_index (cols, (gpointer) col); |
|
113 g_list_free (cols); |
|
114 return num; |
|
115 } |
|
116 |
|
117 /** |
|
118 * This function displays the tooltip for an object, pointer, vector |
|
119 * item or an attribute |
|
120 */ |
|
121 gboolean |
|
122 cell_tooltip_callback (GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, |
|
123 GtkTooltip *tooltip, gpointer user_data) |
|
124 { |
|
125 GtkTreeModel *model; |
|
126 GtkTreeIter iter; |
|
127 GtkTreeViewColumn * column; |
|
128 if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), &x, &y, |
|
129 keyboard_tip, &model, 0, &iter)) |
|
130 { |
|
131 return FALSE; |
|
132 } |
|
133 if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, 0, &column, 0, 0)) |
|
134 { |
|
135 return FALSE; |
|
136 } |
|
137 int col = get_col_number_from_tree_view_column (column); |
|
138 |
|
139 ModelNode *node; |
|
140 gtk_tree_model_get (model, &iter, COL_NODE, &node, -1); |
|
141 |
|
142 switch (node->type) |
|
143 { |
|
144 case ModelNode::NODE_OBJECT: |
|
145 if (col == 0) |
|
146 { |
|
147 std::string tip = "This object is of type " |
|
148 + node->object->GetInstanceTypeId ().GetName (); |
|
149 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
150 return TRUE; |
|
151 } |
|
152 break; |
|
153 case ModelNode::NODE_POINTER: |
|
154 if (col == 0) |
|
155 { |
|
156 PointerValue ptr; |
|
157 node->object->GetAttribute (node->name, ptr); |
|
158 std::string tip = "This object is of type " |
|
159 + ptr.GetObject ()->GetInstanceTypeId ().GetName (); |
|
160 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
161 return TRUE; |
|
162 } |
|
163 break; |
|
164 case ModelNode::NODE_VECTOR: |
|
165 break; |
|
166 case ModelNode::NODE_VECTOR_ITEM: |
|
167 if (col == 0) |
|
168 { |
|
169 std::string tip = "This object is of type " |
|
170 + node->object->GetInstanceTypeId ().GetName (); |
|
171 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
172 return TRUE; |
|
173 } |
|
174 break; |
|
175 case ModelNode::NODE_ATTRIBUTE: |
|
176 { |
|
177 uint32_t attrIndex = 0; |
|
178 TypeId tid; |
|
179 for (tid = node->object->GetInstanceTypeId (); tid.HasParent (); tid |
|
180 = tid.GetParent ()) |
|
181 { |
|
182 for (uint32_t i = 0; i < tid.GetAttributeN (); ++i) |
|
183 { |
|
184 if (tid.GetAttributeName (i) == node->name) |
|
185 { |
|
186 attrIndex = i; |
|
187 goto out; |
|
188 } |
|
189 } |
|
190 } |
|
191 out: if (col == 0) |
|
192 { |
|
193 std::string tip = tid.GetAttributeHelp (attrIndex); |
|
194 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
195 } |
|
196 else |
|
197 { |
|
198 Ptr<const AttributeChecker> checker = tid.GetAttributeChecker ( |
|
199 attrIndex); |
|
200 std::string tip; |
|
201 tip = "This attribute is of type " + checker->GetValueTypeName (); |
|
202 if (checker->HasUnderlyingTypeInformation ()) |
|
203 { |
|
204 tip += " " + checker->GetUnderlyingTypeInformation (); |
|
205 } |
|
206 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
207 } |
|
208 return TRUE; |
|
209 } |
|
210 break; |
|
211 } |
|
212 return FALSE; |
|
213 } |
|
214 |
|
215 /** |
|
216 * This is the main view opening the widget, getting tooltips and drawing the |
|
217 * tree of attributes... |
|
218 */ |
|
219 GtkWidget * |
|
220 create_view (GtkTreeStore *model) |
|
221 { |
|
222 GtkTreeViewColumn *col; |
|
223 GtkCellRenderer *renderer; |
|
224 GtkWidget *view; |
|
225 |
|
226 view = gtk_tree_view_new (); |
|
227 g_object_set (view, "has-tooltip", TRUE, (char*) 0); |
|
228 g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback, 0); |
|
229 |
|
230 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH); |
|
231 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); |
|
232 |
|
233 col = gtk_tree_view_column_new (); |
|
234 gtk_tree_view_column_set_title (col, "Object Attributes"); |
|
235 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); |
|
236 renderer = gtk_cell_renderer_text_new (); |
|
237 gtk_tree_view_column_pack_start (col, renderer, TRUE); |
|
238 gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_0, 0, 0); |
|
239 g_object_set (renderer, "editable", FALSE, (char*) 0); |
|
240 |
|
241 col = gtk_tree_view_column_new (); |
|
242 gtk_tree_view_column_set_title (col, "Attribute Value"); |
|
243 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); |
|
244 renderer = gtk_cell_renderer_text_new (); |
|
245 g_signal_connect (renderer, "edited", (GCallback) cell_edited_callback, model); |
|
246 gtk_tree_view_column_pack_start (col, renderer, TRUE); |
|
247 gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_1, 0, 0); |
|
248 |
|
249 gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (model)); |
|
250 |
|
251 g_object_unref (model); /* destroy model automatically with view */ |
|
252 |
|
253 return view; |
|
254 } |
|
255 |
|
256 /** |
|
257 * This is the action done when the user presses on the save button. |
|
258 * It will save the config to a file. |
|
259 */ |
|
260 void |
|
261 save_clicked (GtkButton *button, gpointer user_data) |
|
262 { |
|
263 GtkWidget *parent_window = GTK_WIDGET (user_data); |
|
264 GtkWidget *dialog; |
|
265 |
|
266 dialog = gtk_file_chooser_dialog_new ("Save File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_SAVE, |
|
267 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, |
|
268 GTK_RESPONSE_ACCEPT, (char *) 0); |
|
269 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), |
|
270 TRUE); |
|
271 |
|
272 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt"); |
|
273 |
|
274 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) |
|
275 { |
|
276 char *filename; |
|
277 |
|
278 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); |
|
279 RawTextConfigSave config; |
|
280 config.SetFilename (filename); |
|
281 config.Attributes (); |
|
282 g_free (filename); |
|
283 } |
|
284 |
|
285 gtk_widget_destroy (dialog); |
|
286 } |
|
287 |
|
288 /** |
|
289 * If the user presses the button load, it will load the config file into memory. |
|
290 */ |
|
291 void |
|
292 load_clicked (GtkButton *button, gpointer user_data) |
|
293 { |
|
294 GtkWidget *parent_window = GTK_WIDGET (user_data); |
|
295 GtkWidget *dialog; |
|
296 |
|
297 dialog = gtk_file_chooser_dialog_new ("Open File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_OPEN, |
|
298 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, |
|
299 GTK_RESPONSE_ACCEPT, (char *) 0); |
|
300 |
|
301 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) |
|
302 { |
|
303 char *filename; |
|
304 |
|
305 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); |
|
306 RawTextConfigLoad config; |
|
307 config.SetFilename (filename); |
|
308 config.Attributes (); |
|
309 } |
|
310 |
|
311 gtk_widget_destroy (dialog); |
|
312 } |
|
313 |
|
314 /** |
|
315 * Exit the window when exit button is pressed |
|
316 */ |
|
317 void |
|
318 exit_clicked_callback (GtkButton *button, gpointer user_data) |
|
319 { |
|
320 gtk_main_quit (); |
|
321 gtk_widget_hide (GTK_WIDGET (user_data)); |
|
322 } |
|
323 |
|
324 /** |
|
325 * Exit the application |
|
326 */ |
|
327 gboolean |
|
328 delete_event_callback (GtkWidget *widget, GdkEvent *event, gpointer user_data) |
|
329 { |
|
330 gtk_main_quit (); |
|
331 gtk_widget_hide (GTK_WIDGET (user_data)); |
|
332 return TRUE; |
|
333 } |
|
334 |
|
335 /** |
|
336 * Delete the tree model contents |
|
337 */ |
|
338 gboolean |
|
339 clean_model_callback (GtkTreeModel *model, GtkTreePath *path, |
|
340 GtkTreeIter *iter, gpointer data) |
|
341 { |
|
342 ModelNode *node; |
|
343 gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COL_NODE, &node, -1); |
|
344 delete node; |
|
345 gtk_tree_store_set (GTK_TREE_STORE (model), iter, COL_NODE, (ModelNode*) 0, |
|
346 -1); |
|
347 return FALSE; |
|
348 } |
|
349 |
|
350 /************************** display functions used by default configurator **********************/ |
|
351 /** |
|
352 * This function writes data in the second column, this data is going to be editable |
|
353 * if it is a NODE_ATTRIBUTE |
|
354 */ |
|
355 void |
|
356 cell_data_function_col_1_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, |
|
357 GtkTreeModel *model, GtkTreeIter *iter, |
|
358 gpointer user_data) |
|
359 { |
|
360 ModelTypeid *node; |
|
361 gtk_tree_model_get (model, iter, COL_TYPEID, &node, -1); |
|
362 if (node->type == ModelTypeid::NODE_ATTRIBUTE) |
|
363 { |
|
364 g_object_set (renderer, "text", node->defaultValue.c_str (), (char*) 0); |
|
365 g_object_set (renderer, "editable", TRUE, (char*) 0); |
|
366 } |
|
367 else |
|
368 { |
|
369 g_object_set (renderer, "text", "", (char*) 0); |
|
370 g_object_set (renderer, "editable", FALSE, (char*) 0); |
|
371 } |
|
372 } |
|
373 /** |
|
374 * This function writes the attribute or typeid name in the column 0 |
|
375 */ |
|
376 void |
|
377 cell_data_function_col_0_config_default (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, |
|
378 GtkTreeIter *iter, gpointer user_data) |
|
379 { |
|
380 ModelTypeid *node; |
|
381 gtk_tree_model_get (model, iter, COL_NODE, &node, -1); |
|
382 g_object_set (renderer, "editable", FALSE, (char*) 0); |
|
383 switch (node->type) |
|
384 { |
|
385 case ModelTypeid::NODE_TYPEID: |
|
386 g_object_set (renderer, "text", node->tid.GetName ().c_str (), (char*) 0); |
|
387 break; |
|
388 case ModelTypeid::NODE_ATTRIBUTE: |
|
389 g_object_set (renderer, "text", node->name.c_str (), (char*) 0); |
|
390 break; |
|
391 } |
|
392 } |
|
393 |
|
394 |
|
395 /** |
|
396 * This functions is called whenever there is a change in the value of an attribute |
|
397 * If the input value is ok, it will be updated in the default value and in the |
|
398 * gui, otherwise, it won't be updated in both. |
|
399 */ |
|
400 void |
|
401 cell_edited_callback_config_default (GtkCellRendererText *cell, gchar *path_string, |
|
402 gchar *new_text, gpointer user_data) |
|
403 { |
|
404 GtkTreeModel *model = GTK_TREE_MODEL (user_data); |
|
405 GtkTreeIter iter; |
|
406 gtk_tree_model_get_iter_from_string (model, &iter, path_string); |
|
407 ModelTypeid *node; |
|
408 gtk_tree_model_get (model, &iter, COL_NODE, &node, -1); |
|
409 NS_ASSERT (node->type == ModelTypeid::NODE_ATTRIBUTE); |
|
410 if (Config::SetDefaultFailSafe (node->tid.GetAttributeFullName (node->index),StringValue (new_text))) |
|
411 { |
|
412 node->defaultValue = new_text; |
|
413 } |
|
414 } |
|
415 |
|
416 /** |
|
417 * This function is used to display a tooltip whenever the user puts the mouse |
|
418 * over a type ID or an attribute. It will give the type and the possible values of |
|
419 * an attribute value and the type of the object for an attribute object or a |
|
420 * typeID object |
|
421 */ |
|
422 gboolean |
|
423 cell_tooltip_callback_config_default (GtkWidget *widget, gint x, gint y, |
|
424 gboolean keyboard_tip, GtkTooltip *tooltip, gpointer user_data) |
|
425 { |
|
426 GtkTreeModel *model; |
|
427 GtkTreeIter iter; |
|
428 GtkTreeViewColumn * column; |
|
429 if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget), &x, &y, |
|
430 keyboard_tip, &model, 0, &iter)) |
|
431 { |
|
432 return FALSE; |
|
433 } |
|
434 if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, 0, &column, 0, 0)) |
|
435 { |
|
436 return FALSE; |
|
437 } |
|
438 int col = get_col_number_from_tree_view_column (column); |
|
439 |
|
440 ModelTypeid *node; |
|
441 gtk_tree_model_get (model, &iter, COL_NODE, &node, -1); |
|
442 |
|
443 switch (node->type) |
|
444 { |
|
445 case ModelTypeid::NODE_TYPEID: |
|
446 if (col == 0) |
|
447 { |
|
448 std::string tip = "This object is of type " + node->tid.GetName (); |
|
449 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
450 return TRUE; |
|
451 } |
|
452 break; |
|
453 case ModelTypeid::NODE_ATTRIBUTE: |
|
454 { |
|
455 uint32_t attrIndex = node->index; |
|
456 if (col == 0) |
|
457 { |
|
458 std::string tip = node->tid.GetAttributeHelp (attrIndex); |
|
459 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
460 } |
|
461 else |
|
462 { |
|
463 Ptr<const AttributeChecker> checker = node->tid.GetAttributeChecker (attrIndex); |
|
464 std::string tip; |
|
465 tip = "This attribute is of type " + checker->GetValueTypeName (); |
|
466 if (checker->HasUnderlyingTypeInformation ()) |
|
467 { |
|
468 tip += " " + checker->GetUnderlyingTypeInformation (); |
|
469 } |
|
470 gtk_tooltip_set_text (tooltip, tip.c_str ()); |
|
471 } |
|
472 return TRUE; |
|
473 } |
|
474 break; |
|
475 } |
|
476 return FALSE; |
|
477 } |
|
478 |
|
479 /** |
|
480 * This is the action done when the user presses on the save button. |
|
481 * It will save the config to a file. |
|
482 */ |
|
483 void |
|
484 save_clicked_default (GtkButton *button, gpointer user_data) |
|
485 { |
|
486 GtkWidget *parent_window = GTK_WIDGET (user_data); |
|
487 GtkWidget *dialog; |
|
488 |
|
489 dialog = gtk_file_chooser_dialog_new ("Save File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_SAVE, |
|
490 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, |
|
491 GTK_RESPONSE_ACCEPT, (char *) 0); |
|
492 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), |
|
493 TRUE); |
|
494 |
|
495 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "config.txt"); |
|
496 |
|
497 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) |
|
498 { |
|
499 char *filename; |
|
500 |
|
501 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); |
|
502 RawTextConfigSave config; |
|
503 config.SetFilename (filename); |
|
504 config.Default (); |
|
505 g_free (filename); |
|
506 } |
|
507 |
|
508 gtk_widget_destroy (dialog); |
|
509 } |
|
510 |
|
511 /** |
|
512 * If the user presses the button load, it will load the config file into memory. |
|
513 */ |
|
514 void |
|
515 load_clicked_default (GtkButton *button, gpointer user_data) |
|
516 { |
|
517 GtkWidget *parent_window = GTK_WIDGET (user_data); |
|
518 GtkWidget *dialog; |
|
519 |
|
520 dialog = gtk_file_chooser_dialog_new ("Open File", GTK_WINDOW (parent_window), GTK_FILE_CHOOSER_ACTION_OPEN, |
|
521 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, |
|
522 GTK_RESPONSE_ACCEPT, (char *) 0); |
|
523 |
|
524 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) |
|
525 { |
|
526 char *filename; |
|
527 |
|
528 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); |
|
529 RawTextConfigLoad config; |
|
530 config.SetFilename (filename); |
|
531 config.Default (); |
|
532 } |
|
533 |
|
534 gtk_widget_destroy (dialog); |
|
535 } |
|
536 |
|
537 /** |
|
538 * This is the main view opening the widget, getting tooltips and drawing the |
|
539 * tree of attributes |
|
540 */ |
|
541 GtkWidget * |
|
542 create_view_config_default (GtkTreeStore *model) |
|
543 { |
|
544 GtkTreeViewColumn *col; |
|
545 GtkCellRenderer *renderer; |
|
546 GtkWidget *view; |
|
547 |
|
548 view = gtk_tree_view_new (); |
|
549 g_object_set (view, "has-tooltip", TRUE, (char*) 0); |
|
550 g_signal_connect (view, "query-tooltip", (GCallback) cell_tooltip_callback_config_default, 0); |
|
551 |
|
552 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH); |
|
553 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE); |
|
554 |
|
555 col = gtk_tree_view_column_new (); |
|
556 gtk_tree_view_column_set_title (col, "Object Attributes"); |
|
557 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); |
|
558 renderer = gtk_cell_renderer_text_new (); |
|
559 gtk_tree_view_column_pack_start (col, renderer, TRUE); |
|
560 gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_0_config_default, 0, 0); |
|
561 g_object_set (renderer, "editable", FALSE, (char*) 0); |
|
562 |
|
563 col = gtk_tree_view_column_new (); |
|
564 gtk_tree_view_column_set_title (col, "Attribute Value"); |
|
565 gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); |
|
566 renderer = gtk_cell_renderer_text_new (); |
|
567 g_signal_connect (renderer, "edited", (GCallback) cell_edited_callback_config_default, model); |
|
568 gtk_tree_view_column_pack_start (col, renderer, TRUE); |
|
569 gtk_tree_view_column_set_cell_data_func (col, renderer, cell_data_function_col_1_config_default, 0, 0); |
|
570 |
|
571 gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (model)); |
|
572 |
|
573 g_object_unref (model); /* destroy model automatically with view */ |
|
574 |
|
575 return view; |
|
576 } |
|
577 |
|
578 /** |
|
579 * Delete the tree model contents |
|
580 */ |
|
581 gboolean |
|
582 clean_model_callback_config_default (GtkTreeModel *model, GtkTreePath *path, |
|
583 GtkTreeIter *iter, gpointer data) |
|
584 { |
|
585 ModelTypeid *node; |
|
586 gtk_tree_model_get (GTK_TREE_MODEL (model), iter, COL_TYPEID, &node, -1); |
|
587 delete node; |
|
588 gtk_tree_store_set (GTK_TREE_STORE (model), iter, COL_TYPEID, (ModelTypeid*) 0, -1); |
|
589 return FALSE; |
|
590 } |
|
591 |
|
592 |
|
593 }//end ns3 namespace |
|
594 |
|