]> sigrok.org Git - sigrok-gtk.git/blame - toolbar.c
sr/cli/gtk/qt: s/configuration/config/.
[sigrok-gtk.git] / toolbar.c
CommitLineData
3f63165c
UH
1/*
2 * This file is part of the sigrok project.
3 *
4 * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <stdlib.h>
21
22#include <sigrok.h>
23
24#include <gtk/gtk.h>
25
26#include <stdlib.h>
27
28#include "sigrok-gtk.h"
29
30enum {
43132a90 31 DEV_PROP_HWCAP,
3f63165c
UH
32 DEV_PROP_TYPE,
33 DEV_PROP_SHORTNAME,
34 DEV_PROP_DESCRIPTION,
35 DEV_PROP_IS_TEXT,
36 DEV_PROP_TEXTVALUE,
37 DEV_PROP_BOOLVALUE,
38 MAX_DEV_PROP
39};
40
41static void prop_edited(GtkCellRendererText *cel, gchar *path, gchar *text,
42 GtkListStore *props)
43{
44 (void)cel;
45
ffe80b55 46 struct sr_dev *dev = g_object_get_data(G_OBJECT(props), "dev");
3f63165c
UH
47 GtkTreeIter iter;
48 int type, cap;
49 guint64 tmp_u64;
50 int ret = SR_ERR;
51
52 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(props), &iter, path);
53 gtk_tree_model_get(GTK_TREE_MODEL(props), &iter,
43132a90 54 DEV_PROP_HWCAP, &cap,
3f63165c
UH
55 DEV_PROP_TYPE, &type, -1);
56
57 switch (type) {
58 case SR_T_UINT64:
59 if (sr_parse_sizestring(text, &tmp_u64) != SR_OK)
60 return;
61
97fe0e2b 62 ret = dev->plugin->config_set(dev->plugin_index, cap, &tmp_u64);
3f63165c
UH
63 break;
64 case SR_T_CHAR:
97fe0e2b 65 ret = dev->plugin->config_set(dev->plugin_index, cap, text);
3f63165c
UH
66 break;
67 /* SR_T_BOOL will be handled by prop_toggled */
68 }
69
70 if (!ret)
71 gtk_list_store_set(props, &iter, DEV_PROP_TEXTVALUE, text, -1);
72}
73
74static void prop_toggled(GtkCellRendererToggle *cel, gchar *path,
75 GtkListStore *props)
76{
ffe80b55 77 struct sr_dev *dev = g_object_get_data(G_OBJECT(props), "dev");
3f63165c
UH
78 GtkTreeIter iter;
79 int type, cap;
80 int ret;
81 gboolean val;
82 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(props), &iter, path);
83 gtk_tree_model_get(GTK_TREE_MODEL(props), &iter,
43132a90 84 DEV_PROP_HWCAP, &cap,
3f63165c
UH
85 DEV_PROP_TYPE, &type, -1);
86
87 val = !gtk_cell_renderer_toggle_get_active(cel);
97fe0e2b
UH
88 ret = dev->plugin->config_set(dev->plugin_index, cap,
89 GINT_TO_POINTER(val));
3f63165c
UH
90
91 if (!ret)
92 gtk_list_store_set(props, &iter, DEV_PROP_BOOLVALUE, val, -1);
93}
94
95void dev_prop_bool_data_func(GtkCellLayout *cell_layout,
96 GtkCellRenderer *cell,
97 GtkTreeModel *tree_model,
98 GtkTreeIter *iter,
99 gpointer data)
100{
101 (void)cell_layout;
102 (void)data;
103
104 gboolean istext, val;
105 gtk_tree_model_get(tree_model, iter,
106 DEV_PROP_IS_TEXT, &istext,
107 DEV_PROP_BOOLVALUE, &val, -1);
108 g_object_set(G_OBJECT(cell), "visible", !istext, "active", val, NULL);
109}
110
111static void dev_set_options(GtkAction *action, GtkWindow *parent)
112{
113 (void)action;
114
ffe80b55
UH
115 struct sr_dev *dev = g_object_get_data(G_OBJECT(parent), "dev");
116 if (!dev)
3f63165c
UH
117 return;
118
119 GtkWidget *dialog = gtk_dialog_new_with_buttons("Device Properties",
120 parent, GTK_DIALOG_MODAL,
121 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
122 NULL);
123 GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
124 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
125 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
126 gtk_widget_set_size_request(sw, 300, 200);
127 GtkWidget *tv = gtk_tree_view_new();
128 gtk_container_add(GTK_CONTAINER(sw), tv);
129 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), sw,
130 TRUE, TRUE, 0);
131
132 /* Populate list store with config options */
133 GtkListStore *props = gtk_list_store_new(MAX_DEV_PROP,
134 G_TYPE_INT, G_TYPE_INT,
135 G_TYPE_STRING, G_TYPE_STRING,
136 G_TYPE_BOOLEAN, G_TYPE_STRING,
137 G_TYPE_BOOLEAN);
138 gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(props));
43132a90 139 int *hwcaps = dev->plugin->hwcap_get_all();
3f63165c
UH
140 int cap;
141 GtkTreeIter iter;
43132a90 142 for (cap = 0; hwcaps[cap]; cap++) {
3f63165c 143 struct sr_hwcap_option *hwo;
43132a90 144 if (!(hwo = sr_hw_hwcap_get(hwcaps[cap])))
3f63165c
UH
145 continue;
146 gtk_list_store_append(props, &iter);
147 gtk_list_store_set(props, &iter,
43132a90 148 DEV_PROP_HWCAP, hwcaps[cap],
3f63165c
UH
149 DEV_PROP_TYPE, hwo->type,
150 DEV_PROP_SHORTNAME, hwo->shortname,
151 DEV_PROP_DESCRIPTION, hwo->description,
152 DEV_PROP_IS_TEXT, hwo->type != SR_T_BOOL,
153 -1);
154 }
155
156 /* Popup tooltop containing description if mouse hovers */
157 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(tv),
158 DEV_PROP_DESCRIPTION);
159
160 /* Save device with list so that property can be set by edited
161 * handler. */
ffe80b55 162 g_object_set_data(G_OBJECT(props), "dev", dev);
3f63165c
UH
163
164 /* Add columns to the tree view */
165 GtkTreeViewColumn *col;
166 col = gtk_tree_view_column_new_with_attributes("Property",
167 gtk_cell_renderer_text_new(),
168 "text", DEV_PROP_SHORTNAME, NULL);
169 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
170 /* We pack both a text and toggle renderer. Only one will be visible.
171 * depending on type.
172 */
173 GtkCellRenderer *cel = gtk_cell_renderer_text_new();
174 g_object_set(cel, "editable", TRUE, NULL);
175 g_signal_connect(cel, "edited", G_CALLBACK(prop_edited), props);
176 col = gtk_tree_view_column_new_with_attributes("Value",
177 cel, "text", DEV_PROP_TEXTVALUE,
178 "visible", DEV_PROP_IS_TEXT, NULL);
179 cel = gtk_cell_renderer_toggle_new();
180 g_signal_connect(cel, "toggled", G_CALLBACK(prop_toggled), props);
181 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(col), cel, TRUE);
182 gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(col), cel,
183 dev_prop_bool_data_func, NULL, NULL);
184 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
185
186
187 gtk_widget_show_all(dialog);
188 gtk_dialog_run(GTK_DIALOG(dialog));
189
190 gtk_widget_destroy(dialog);
191}
192
193enum {
194 PROBE_NUMBER,
195 PROBE_ENABLED,
196 PROBE_NAME,
197 PROBE_TRIGGER,
198 MAX_PROBE
199};
200
201static void probe_toggled(GtkCellRenderer *cel, gchar *path,
202 GtkTreeModel *probes)
203{
ffe80b55 204 struct sr_dev *dev = g_object_get_data(G_OBJECT(probes), "dev");
3f63165c
UH
205 GtkTreeIter iter;
206 struct sr_probe *probe;
207 gint i;
208 gboolean en;
209
210 (void)cel;
211
212 gtk_tree_model_get_iter_from_string(probes, &iter, path);
213 gtk_tree_model_get(probes, &iter, PROBE_NUMBER, &i,
214 PROBE_ENABLED, &en, -1);
ffe80b55 215 probe = sr_dev_probe_find(dev, i);
3f63165c
UH
216 probe->enabled = !en;
217 gtk_list_store_set(GTK_LIST_STORE(probes), &iter,
218 PROBE_ENABLED, probe->enabled, -1);
219}
220
221static void probe_named(GtkCellRendererText *cel, gchar *path, gchar *text,
222 GtkTreeModel *probes)
223{
ffe80b55 224 struct sr_dev *dev = g_object_get_data(G_OBJECT(probes), "dev");
3f63165c
UH
225 GtkTreeIter iter;
226 gint i;
227
228 (void)cel;
229
230 gtk_tree_model_get_iter_from_string(probes, &iter, path);
231 gtk_tree_model_get(probes, &iter, PROBE_NUMBER, &i, -1);
ffe80b55 232 sr_dev_probe_name(dev, i, text);
3f63165c
UH
233 gtk_list_store_set(GTK_LIST_STORE(probes), &iter, PROBE_NAME, text, -1);
234}
235
236static void probe_trigger_set(GtkCellRendererText *cel, gchar *path,
237 gchar *text, GtkTreeModel *probes)
238{
ffe80b55 239 struct sr_dev *dev = g_object_get_data(G_OBJECT(probes), "dev");
3f63165c
UH
240 GtkTreeIter iter;
241 gint i;
242
243 (void)cel;
244
245 gtk_tree_model_get_iter_from_string(probes, &iter, path);
246 gtk_tree_model_get(probes, &iter, PROBE_NUMBER, &i, -1);
ffe80b55 247 sr_dev_trigger_set(dev, i, text);
3f63165c
UH
248 gtk_list_store_set(GTK_LIST_STORE(probes), &iter,
249 PROBE_TRIGGER, text, -1);
250}
251
252static void dev_set_probes(GtkAction *action, GtkWindow *parent)
253{
254 (void)action;
255
ffe80b55
UH
256 struct sr_dev *dev = g_object_get_data(G_OBJECT(parent), "dev");
257 if (!dev)
3f63165c
UH
258 return;
259
260 GtkWidget *dialog = gtk_dialog_new_with_buttons("Configure Probes",
261 parent, GTK_DIALOG_MODAL,
262 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
263 NULL);
264 GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
265 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
266 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
267 gtk_widget_set_size_request(sw, 300, 200);
268 GtkWidget *tv = gtk_tree_view_new();
269 gtk_container_add(GTK_CONTAINER(sw), tv);
270 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), sw,
271 TRUE, TRUE, 0);
272
273 /* Populate list store with probe options */
274 GtkListStore *probes = gtk_list_store_new(MAX_PROBE,
275 G_TYPE_INT, G_TYPE_BOOLEAN,
276 G_TYPE_STRING, GTK_TYPE_STRING);
277 gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(probes));
278 GtkTreeIter iter;
279 GSList *p;
280 int i;
ffe80b55 281 for (p = dev->probes, i = 1; p; p = g_slist_next(p), i++) {
3f63165c
UH
282 struct sr_probe *probe = p->data;
283 gtk_list_store_append(probes, &iter);
284 gtk_list_store_set(probes, &iter, PROBE_NUMBER, i,
285 PROBE_ENABLED, probe->enabled,
286 PROBE_NAME, probe->name,
287 PROBE_TRIGGER, probe->trigger,
288 -1);
289 }
290
291 /* Save device with list so that property can be set by edited
292 * handler. */
ffe80b55 293 g_object_set_data(G_OBJECT(probes), "dev", dev);
3f63165c
UH
294
295 /* Add columns to the tree view */
296 GtkTreeViewColumn *col;
297 col = gtk_tree_view_column_new_with_attributes("Probe",
298 gtk_cell_renderer_text_new(),
299 "text", PROBE_NUMBER, NULL);
300 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
301 GtkCellRenderer *cel = gtk_cell_renderer_toggle_new();
302 g_object_set(cel, "activatable", TRUE, NULL);
303 g_signal_connect(cel, "toggled", G_CALLBACK(probe_toggled), probes);
304 col = gtk_tree_view_column_new_with_attributes("En",
305 cel, "active", PROBE_ENABLED, NULL);
306 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
307 cel = gtk_cell_renderer_text_new();
308 g_object_set(cel, "editable", TRUE, NULL);
309 g_signal_connect(cel, "edited", G_CALLBACK(probe_named), probes);
310 col = gtk_tree_view_column_new_with_attributes("Signal Name", cel,
311 "text", PROBE_NAME,
312 "sensitive", PROBE_ENABLED, NULL);
313 gtk_tree_view_column_set_resizable(col, TRUE);
314 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
315 cel = gtk_cell_renderer_text_new();
316 g_object_set(cel, "editable", TRUE, NULL);
317 g_signal_connect(cel, "edited", G_CALLBACK(probe_trigger_set), probes);
318 col = gtk_tree_view_column_new_with_attributes("Trigger", cel,
319 "text", PROBE_TRIGGER,
320 "sensitive", PROBE_ENABLED, NULL);
321 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
322
323 gtk_widget_show_all(dialog);
324 gtk_dialog_run(GTK_DIALOG(dialog));
325
326 gtk_widget_destroy(dialog);
327}
328
329static void capture_run(GtkAction *action, GObject *parent)
330{
331 (void)action;
332
ffe80b55 333 struct sr_dev *dev = g_object_get_data(G_OBJECT(parent), "dev");
3f63165c
UH
334 GtkEntry *timesamples = g_object_get_data(parent, "timesamples");
335 GtkComboBox *timeunit = g_object_get_data(parent, "timeunit");
336 gint i = gtk_combo_box_get_active(timeunit);
337 guint64 time_msec = 0;
338 guint64 limit_samples = 0;
339
340 switch (i) {
341 case 0: /* Samples */
342 sr_parse_sizestring(gtk_entry_get_text(timesamples),
343 &limit_samples);
344 break;
345 case 1: /* Milliseconds */
346 time_msec = strtoull(gtk_entry_get_text(timesamples), NULL, 10);
347 break;
348 case 2: /* Seconds */
349 time_msec = strtoull(gtk_entry_get_text(timesamples), NULL, 10)
350 * 1000;
351 break;
352 }
353
354 if (time_msec) {
ffe80b55 355 if (sr_hw_has_hwcap(dev->plugin, SR_HWCAP_LIMIT_MSEC)) {
97fe0e2b
UH
356 if (dev->plugin->config_set(dev->plugin_index,
357 SR_HWCAP_LIMIT_MSEC,
358 &time_msec) != SR_OK) {
3f63165c
UH
359 g_critical("Failed to configure time limit.");
360 sr_session_destroy();
361 return;
362 }
363 } else {
364 /* time limit set, but device doesn't support this...
365 * convert to samples based on the samplerate.
366 */
367 limit_samples = 0;
ffe80b55 368 if (sr_dev_has_hwcap(dev, SR_HWCAP_SAMPLERATE)) {
3f63165c 369 guint64 tmp_u64;
ffe80b55
UH
370 tmp_u64 = *((uint64_t *)dev->plugin->get_dev_info(
371 dev->plugin_index,
3f63165c
UH
372 SR_DI_CUR_SAMPLERATE));
373 limit_samples = tmp_u64 * time_msec / (uint64_t) 1000;
374 }
375 if (limit_samples == 0) {
376 g_critical("Not enough time at this samplerate.");
377 return;
378 }
379
97fe0e2b
UH
380 if (dev->plugin->config_set(dev->plugin_index,
381 SR_HWCAP_LIMIT_SAMPLES,
382 &limit_samples) != SR_OK) {
3f63165c
UH
383 g_critical("Failed to configure time-based sample limit.");
384 return;
385 }
386 }
387 }
388 if (limit_samples) {
97fe0e2b
UH
389 if (dev->plugin->config_set(dev->plugin_index,
390 SR_HWCAP_LIMIT_SAMPLES,
391 &limit_samples) != SR_OK) {
3f63165c
UH
392 g_critical("Failed to configure sample limit.");
393 return;
394 }
395 }
396
97fe0e2b
UH
397 if (dev->plugin->config_set(dev->plugin_index,
398 SR_HWCAP_PROBECONFIG, (char *)dev->probes) != SR_OK) {
3f63165c
UH
399 printf("Failed to configure probes.\n");
400 sr_session_destroy();
401 return;
402 }
403
404 if (sr_session_start() != SR_OK) {
405 g_critical("Failed to start session.");
406 return;
407 }
408
409 sr_session_run();
410}
411
412static void dev_file_open(GtkAction *action, GtkWindow *parent)
413{
414 (void)action;
415 static GtkWidget *dialog;
416 const gchar *filename;
417
418 if(!dialog)
419 dialog = gtk_file_chooser_dialog_new("Open", parent,
420 GTK_FILE_CHOOSER_ACTION_OPEN,
421 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
422 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
423 g_signal_connect(dialog, "delete-event",
424 G_CALLBACK(gtk_widget_hide_on_delete),
425 NULL);
426
427 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
428 /* Dialog was cancelled or closed */
429 gtk_widget_hide(dialog);
430 return;
431 }
432
433 gtk_widget_hide(dialog);
434
435 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
436 load_input_file(parent, filename);
437}
438
439void toggle_log(GtkToggleAction *action, GObject *parent)
440{
441 GtkWidget *log = g_object_get_data(parent, "logview");
442 gtk_widget_set_visible(log, gtk_toggle_action_get_active(action));
443}
444
445void zoom_in(GtkAction *action, GObject *parent)
446{
447 (void)action;
448
449 GtkWidget *sigview = g_object_get_data(parent, "sigview");
450 sigview_zoom(sigview, 1.5, 0);
451}
452
453void zoom_out(GtkAction *action, GObject *parent)
454{
455 (void)action;
456
457 GtkWidget *sigview = g_object_get_data(parent, "sigview");
458 sigview_zoom(sigview, 1/1.5, 0);
459}
460
461void zoom_fit(GtkAction *action, GObject *parent)
462{
463 (void)action;
464
465 GtkWidget *sigview = g_object_get_data(parent, "sigview");
466 sigview_zoom(sigview, 0, 0);
467}
468
469static const GtkActionEntry action_items[] = {
470 /* name, stock-id, label, accel, tooltip, callback */
471 {"DevMenu", NULL, "_Device", NULL, NULL, NULL},
472 {"DevOpen", GTK_STOCK_OPEN, "_Open", "<control>O",
473 "Open Session File", G_CALLBACK(dev_file_open)},
474 {"DevSelectMenu", NULL, "Select Device", NULL, NULL, NULL},
475 {"DevRescan", GTK_STOCK_REFRESH, "_Rescan", "<control>R",
476 "Rescan for LA devices", G_CALLBACK(dev_select_rescan)},
477 {"DevProperties", GTK_STOCK_PROPERTIES, "_Properties", "<control>P",
478 "Configure LA", G_CALLBACK(dev_set_options)},
479 {"DevProbes", GTK_STOCK_COLOR_PICKER, "_Probes", "<control>O",
480 "Configure Probes", G_CALLBACK(dev_set_probes)},
481 {"DevAcquire", GTK_STOCK_EXECUTE, "_Acquire", "<control>A",
482 "Acquire Samples", G_CALLBACK(capture_run)},
483 {"Exit", GTK_STOCK_QUIT, "E_xit", "<control>Q",
484 "Exit the program", G_CALLBACK(gtk_main_quit) },
485
486 {"ViewMenu", NULL, "_View", NULL, NULL, NULL},
487 {"ViewZoomIn", GTK_STOCK_ZOOM_IN, "Zoom _In", "<control>z", NULL,
488 G_CALLBACK(zoom_in)},
489 {"ViewZoomOut", GTK_STOCK_ZOOM_OUT, "Zoom _Out", "<control><shift>Z",
490 NULL, G_CALLBACK(zoom_out)},
491 {"ViewZoomFit", GTK_STOCK_ZOOM_FIT, NULL, NULL,
492 NULL, G_CALLBACK(zoom_fit)},
493
494 {"HelpMenu", NULL, "_Help", NULL, NULL, NULL},
495 {"HelpWiki", GTK_STOCK_ABOUT, "Sigrok _Wiki", NULL, NULL,
496 G_CALLBACK(help_wiki)},
497 {"HelpAbout", GTK_STOCK_ABOUT, "_About", NULL, NULL,
498 G_CALLBACK(help_about)},
499};
500
501static const GtkToggleActionEntry toggle_items[] = {
502 /* name, stock-id, label, accel, tooltip, callback, isactive */
503 {"ViewLog", GTK_STOCK_JUSTIFY_LEFT, "_Log", NULL, NULL,
504 G_CALLBACK(toggle_log), FALSE},
505};
506
507static const char ui_xml[] =
508"<ui>"
509" <menubar>"
510" <menu action='DevMenu'>"
511" <menuitem action='DevOpen'/>"
512" <separator/>"
513" <menu action='DevSelectMenu'>"
514" <separator/>"
515" <menuitem action='DevRescan'/>"
516" </menu>"
517" <menuitem action='DevProperties'/>"
518" <menuitem action='DevProbes'/>"
519" <separator/>"
520" <menuitem action='DevAcquire'/>"
521" <separator/>"
522" <menuitem action='Exit'/>"
523" </menu>"
524" <menu action='ViewMenu'>"
525" <menuitem action='ViewZoomIn'/>"
526" <menuitem action='ViewZoomOut'/>"
527" <menuitem action='ViewZoomFit'/>"
528" <separator/>"
529" <menuitem action='ViewLog'/>"
530" </menu>"
531" <menu action='HelpMenu'>"
532" <menuitem action='HelpWiki'/>"
533" <menuitem action='HelpAbout'/>"
534" </menu>"
535" </menubar>"
536" <toolbar>"
537" <placeholder name='DevSelect'/>"
538" <toolitem action='DevRescan'/>"
539" <toolitem action='DevProperties'/>"
540" <toolitem action='DevProbes'/>"
541" <separator/>"
542" <placeholder name='DevSampleCount' />"
543" <toolitem action='DevAcquire'/>"
544" <separator/>"
545" <toolitem action='ViewZoomIn'/>"
546" <toolitem action='ViewZoomOut'/>"
547" <toolitem action='ViewZoomFit'/>"
548" <separator/>"
549" </toolbar>"
550"</ui>";
551
552GtkWidget *toolbar_init(GtkWindow *parent)
553{
554 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
555 GtkToolbar *toolbar;
556 GtkActionGroup *ag = gtk_action_group_new("Actions");
557 gtk_action_group_add_actions(ag, action_items,
558 G_N_ELEMENTS(action_items), parent);
559 gtk_action_group_add_toggle_actions(ag, toggle_items,
560 G_N_ELEMENTS(toggle_items), parent);
561
562 GtkUIManager *ui = gtk_ui_manager_new();
563 g_object_set_data(G_OBJECT(parent), "ui_manager", ui);
564 gtk_ui_manager_insert_action_group(ui, ag, 0);
565 GtkAccelGroup *accel = gtk_ui_manager_get_accel_group(ui);
566 gtk_window_add_accel_group(parent, accel);
567
568 GError *error = NULL;
569 if (!gtk_ui_manager_add_ui_from_string (ui, ui_xml, -1, &error)) {
570 g_message ("building menus failed: %s", error->message);
571 g_error_free (error);
572 exit (-1);
573 }
574
575 GtkWidget *menubar = gtk_ui_manager_get_widget(ui, "/menubar");
576 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(menubar), FALSE, TRUE, 0);
577 toolbar = GTK_TOOLBAR(gtk_ui_manager_get_widget(ui, "/toolbar"));
578 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(toolbar), FALSE, TRUE, 0);
579
580 /* Device selection GtkComboBox */
581 GtkToolItem *toolitem = gtk_tool_item_new();
582 GtkWidget *align = gtk_alignment_new(0.5, 0.5, 2, 0);
583 GtkWidget *dev = dev_select_combo_box_new(parent);
584
585 gtk_container_add(GTK_CONTAINER(align), dev);
586 gtk_container_add(GTK_CONTAINER(toolitem), align);
587 gtk_toolbar_insert(toolbar, toolitem, 0);
588
589 /* Time/Samples entry */
590 toolitem = gtk_tool_item_new();
591 GtkWidget *timesamples = gtk_entry_new();
592 gtk_entry_set_text(GTK_ENTRY(timesamples), "100");
593 gtk_entry_set_alignment(GTK_ENTRY(timesamples), 1.0);
594 gtk_widget_set_size_request(timesamples, 100, -1);
595 gtk_container_add(GTK_CONTAINER(toolitem), timesamples);
596 gtk_toolbar_insert(toolbar, toolitem, 7);
597
598 /* Time unit combo box */
599 toolitem = gtk_tool_item_new();
600 align = gtk_alignment_new(0.5, 0.5, 2, 0);
601 GtkWidget *timeunit = gtk_combo_box_new_text();
602 gtk_combo_box_append_text(GTK_COMBO_BOX(timeunit), "samples");
603 gtk_combo_box_append_text(GTK_COMBO_BOX(timeunit), "ms");
604 gtk_combo_box_append_text(GTK_COMBO_BOX(timeunit), "s");
605 gtk_combo_box_set_active(GTK_COMBO_BOX(timeunit), 0);
606 gtk_container_add(GTK_CONTAINER(align), timeunit);
607 gtk_container_add(GTK_CONTAINER(toolitem), align);
608 gtk_toolbar_insert(toolbar, toolitem, 8);
609
610 g_object_set_data(G_OBJECT(parent), "timesamples", timesamples);
611 g_object_set_data(G_OBJECT(parent), "timeunit", timeunit);
612
613 return GTK_WIDGET(vbox);
614}
615