]> sigrok.org Git - sigrok-gtk.git/blame - devselect.c
sr/srd: Use SR_LOG_*/SRD_LOG_* macros.
[sigrok-gtk.git] / devselect.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 <sigrok.h>
21#include <gtk/gtk.h>
22#include "sigrok-gtk.h"
23
24static void dev_selected(GtkComboBox *dev, GObject *parent)
25{
26 GtkTreeModel *devlist = gtk_combo_box_get_model(dev);
27 GtkTreeIter iter;
28 const gchar *name;
29 GtkCheckMenuItem *menuitem;
30 struct sr_device *device;
31
32 if (!gtk_combo_box_get_active_iter(dev, &iter)) {
33 g_object_set_data(parent, "device", NULL);
34 return;
35 }
36 gtk_tree_model_get(devlist, &iter, 0, &name, 1, &device,
37 2, &menuitem, -1);
38
39 gtk_check_menu_item_set_active(menuitem, TRUE);
40
41 sr_session_device_clear();
42 if (sr_session_device_add(device) != SR_OK) {
43 g_critical("Failed to use device.");
44 sr_session_destroy();
45 device = NULL;
46 }
47 g_object_set_data(parent, "device", device);
48}
49
50static void dev_menuitem_toggled(GtkMenuItem *item, GtkComboBox *combo)
51{
52 GtkTreeModel *model = gtk_combo_box_get_model(combo);
53 GtkTreeIter iter;
54
55 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)))
56 return;
57
58 if (gtk_tree_model_get_iter_first(model, &iter)) do {
59 gchar *name;
60 gtk_tree_model_get(model, &iter, 0, &name, -1);
61 if (g_str_equal(name, gtk_menu_item_get_label(item))) {
62 gtk_combo_box_set_active_iter(combo, &iter);
63 return;
64 }
65 } while (gtk_tree_model_iter_next(model, &iter));
66}
67
68#define GET_DEVICE_INSTANCE(device) \
69 (device)->plugin->get_device_info((device)->plugin_index, \
70 SR_DI_INSTANCE);
71
72void dev_select_rescan(GtkAction *action, GtkWindow *parent)
73{
74 GtkComboBox *dev = g_object_get_data(G_OBJECT(parent), "devcombo");
75 g_return_if_fail(dev != NULL);
76 GtkListStore *devlist = GTK_LIST_STORE(gtk_combo_box_get_model(dev));
77 GtkTreeIter iter;
78 struct sr_device *device;
79 struct sr_device_instance *sdi;
80 gchar *sdevname = NULL;
81 GSList *devices, *l;
82 GtkUIManager *ui = g_object_get_data(G_OBJECT(parent), "ui_manager");
83 GtkWidget *menuitem = gtk_ui_manager_get_widget(ui,
84 "/menubar/DevMenu/DevSelectMenu");
85 GtkMenuShell *devmenu = GTK_MENU_SHELL(gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)));
86 GSList *radiolist = NULL;
87
88 (void)action;
89
90 /* Make a copy of the selected device's short name for comparison.
91 * We wish to select the same device after the refresh if possible.
92 */
93 if (gtk_combo_box_get_active_iter(dev, &iter)) {
94 gtk_tree_model_get(GTK_TREE_MODEL(devlist), &iter, 1, &device, -1);
95 /* FIXME: Use something other than device->plugin->name */
96 sdevname = g_strdup(device->plugin->name);
97 }
98
99 /* Destroy the old menu items */
100 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(devlist), &iter)) do {
101 GtkMenuItem *item;
102 gtk_tree_model_get(GTK_TREE_MODEL(devlist), &iter, 2, &item, -1);
103 gtk_object_destroy(GTK_OBJECT(item));
104 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(devlist), &iter));
105
106 gtk_list_store_clear(devlist);
107
108 /* Scan for new devices and update our list */
109 /* TODO: Fix this in libsigrok first. */
110 /*sr_device_scan();*/
111 devices = sr_device_list();
112 for (l = devices; l; l = l->next) {
113 device = l->data;
114 sdi = GET_DEVICE_INSTANCE(device);
115 gchar *name = sdi->model ? sdi->model : sdi->vendor;
116 if (!name)
117 name = "(unknown)";
118
119 menuitem = gtk_radio_menu_item_new_with_label(radiolist, name);
120 gtk_widget_show(GTK_WIDGET(menuitem));
121 if (!radiolist)
122 radiolist = gtk_radio_menu_item_get_group(
123 GTK_RADIO_MENU_ITEM(menuitem));
124 g_signal_connect(menuitem, "toggled",
125 G_CALLBACK(dev_menuitem_toggled), dev);
126 gtk_menu_shell_prepend(devmenu, menuitem);
127
128 gtk_list_store_append(devlist, &iter);
129 gtk_list_store_set(devlist, &iter,
130 0, name,
131 1, device,
132 2, menuitem,
133 -1);
134
135 if (sdevname && g_str_equal(sdevname, device->plugin->name))
136 gtk_combo_box_set_active_iter(dev, &iter);
137 }
138 if (sdevname)
139 g_free(sdevname);
140
141 /* Select a default if nothing selected */
142 if (!gtk_combo_box_get_active_iter(dev, &iter)) {
143 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(devlist), &iter))
144 return;
145 /* Skip demo if there's another available */
146 GtkTreeIter first = iter;
147 if (gtk_tree_model_iter_next(GTK_TREE_MODEL(devlist), &iter))
148 gtk_combo_box_set_active_iter(dev, &iter);
149 else
150 gtk_combo_box_set_active_iter(dev, &first);
151 }
152}
153
154GtkWidget *dev_select_combo_box_new(GtkWindow *parent)
155{
156 GtkWidget *dev = gtk_combo_box_new();
157
158 /* Populate device list */
159 GtkListStore *devlist = gtk_list_store_new(3,
160 G_TYPE_STRING, G_TYPE_POINTER, GTK_TYPE_CHECK_MENU_ITEM);
161 GtkCellRenderer *cel = gtk_cell_renderer_text_new();
162 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dev), cel, TRUE);
163 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(dev), cel, "text", 0);
164 gtk_combo_box_set_model(GTK_COMBO_BOX(dev), GTK_TREE_MODEL(devlist));
165 g_signal_connect(dev, "changed", G_CALLBACK(dev_selected), parent);
166
167 g_object_set_data(G_OBJECT(parent), "devcombo", dev);
168 dev_select_rescan(NULL, parent);
169
170 return dev;
171}
172