CEBL  2.1
TabEEGRecording.cpp
Go to the documentation of this file.
1 
7 #include "TabEEGRecording.hpp"
8 #include "WidgetUtils.hpp"
9 #include "TextUtils.hpp"
10 #include <fstream>
11 //----------------------------------------------------------------------
12 // Constructors / Destructor
13 
15 {
16 
17 }
18 
19 
20 //----------------------------------------------------------------------
21 // Create the GUI
22 
23 
25 {
26  //add title
27  GtkWidget *title = gtk_label_new("");
28  gtk_label_set_markup(GTK_LABEL(title),view->getString("RecordingTitle"));
29  TabAdd(title);
30  TabAdd(gtk_hseparator_new());
31 
32 
33 
34 
35  //----------------------------------------
36  // Get CEBL model values values
37 
38 
39  string channel_config_file = getView()->getModel()->channelsGetConfigFilename();
40  num_channel_boxes = getView()->getModel()->channelsGetMaxNumChannels();
41 
42 
43  //----------------------------------------
44  // Initialize widget arrays
45  enabled_boxes.resize(num_channel_boxes);
46  reference_boxes.resize(num_channel_boxes);
47  entry_electrode_names.resize(num_channel_boxes);
48 
49 
50  //----------------------------------------
51  // Top button box
52  GtkWidget *config_file_box = gtk_vbox_new(false, 0);
53  GtkWidget *btn_box = gtk_hbutton_box_new();
54  gtk_button_box_set_layout(GTK_BUTTON_BOX(btn_box),GTK_BUTTONBOX_START);
55 
56  control_btn_load = gtk_button_new_with_label(view->getString("RecordingStr1"));
57  g_signal_connect(G_OBJECT(control_btn_load),
58  "clicked",
59  G_CALLBACK(CB_LoadChannelsFile),
60  (gpointer) this);
61 
62 
63  control_btn_save = gtk_button_new_with_label(view->getString("RecordingStr2"));
64  g_signal_connect(G_OBJECT(control_btn_save),
65  "clicked",
66  G_CALLBACK(CB_SaveChannelsFile),
67  (gpointer) this);
68 
69 
70  control_btn_clear = gtk_button_new_with_label(view->getString("RecordingStr3"));
71  g_signal_connect(G_OBJECT(control_btn_clear),
72  "clicked",
73  G_CALLBACK(CB_ClearChannels),
74  (gpointer) this);
75 
76 
77  gtk_box_pack_start(GTK_BOX(btn_box),control_btn_load,false,false,2);
78  gtk_box_pack_start(GTK_BOX(btn_box),control_btn_save,false,false,2);
79  gtk_box_pack_start(GTK_BOX(btn_box),control_btn_clear,false,false,2);
80 
81  //----------------------------------------
82  // File name box
83  GtkWidget *label_file = gtk_label_new("");
84  gtk_label_set_markup(GTK_LABEL(label_file),view->getString("RecordingStr4"));
85  label_filename = gtk_label_new(channel_config_file.c_str());
86  GtkWidget *hbox_filename = gtk_hbox_new(false,0);
87 
88  gtk_box_pack_start(GTK_BOX(hbox_filename),label_file,false,false,0);
89  gtk_box_pack_start(GTK_BOX(hbox_filename),label_filename,false,false,0);
90 
91  gtk_box_pack_start(GTK_BOX(config_file_box),btn_box, false, false, 2);
92  gtk_box_pack_start(GTK_BOX(config_file_box),hbox_filename, false, false, 2);
93 
94  TabFrameAdd(config_file_box);
95 
96  //----------------------------------------
97  // Channel boxes
98 
99  suppress_channel_callbacks = false;
100 
101  GtkWidget *main_hbox = gtk_hbox_new(false,0);
102 
103  const int cols = 4;
104  GtkWidget *channels_hbox = gtk_hbox_new(false,0);
105  GtkWidget *channels_table = gtk_table_new(num_channel_boxes + 1, cols,false);
106 
107  //add some padding between rows and columns
108  gtk_table_set_row_spacings(GTK_TABLE(channels_table),1);
109  gtk_table_set_col_spacings(GTK_TABLE(channels_table),10);
110 
111  //top row labels
112  GtkWidget * label1 = gtk_label_new("");
113  gtk_label_set_markup(GTK_LABEL(label1),view->getString("RecordingStr5"));
114  GtkWidget * label2 = gtk_label_new("");
115  gtk_label_set_markup(GTK_LABEL(label2),view->getString("RecordingStr6"));
116  GtkWidget * label3 = gtk_label_new("");
117  gtk_label_set_markup(GTK_LABEL(label3),view->getString("RecordingStr7"));
118  GtkWidget * label4 = gtk_label_new("");
119  gtk_label_set_markup(GTK_LABEL(label4),view->getString("RecordingStr8"));
120 
121  gtk_table_attach(GTK_TABLE(channels_table)
122  ,label1
123  ,0,1,0,1,
124  GTK_FILL, GTK_SHRINK,0,0);
125  gtk_table_attach(GTK_TABLE(channels_table)
126  ,label2
127  ,1,2,0,1,GTK_FILL,GTK_SHRINK,0,0);
128  gtk_table_attach(GTK_TABLE(channels_table)
129  ,label3
130  ,2,3,0,1,GTK_FILL,GTK_SHRINK,0,0);
131  gtk_table_attach(GTK_TABLE(channels_table)
132  ,label4
133  ,3,4,0,1,GTK_FILL,GTK_SHRINK,0,0);
134 
135  //create all check boxes, entries, and labels
136  for(int i=0;i<num_channel_boxes;i++)
137  {
138  //first column
139  gtk_table_attach(GTK_TABLE(channels_table)
140  ,gtk_label_new(TextUtils::IntToString(i+1).c_str())
141  ,0,1,i+1,i+2,GTK_FILL,GTK_SHRINK,0,0);
142 
143  entry_electrode_names[i] = gtk_entry_new_with_max_length(10);
144  g_signal_connect(G_OBJECT(entry_electrode_names[i]),
145  "changed",
146  G_CALLBACK(CB_ChangeChannel),
147  (gpointer) this);
148 
149  //gtk_entry_set_text(GTK_ENTRY(label_entry[i]),electrode_labels[i]->c_str());
150  gtk_widget_set_size_request(entry_electrode_names[i], 30, 20);//make the entry box small and sleek
151  gtk_table_attach(GTK_TABLE(channels_table)
152  ,entry_electrode_names[i]
153  ,1,2,i+1,i+2,GTK_FILL,GTK_SHRINK,0,0);
154 
155  reference_boxes[i] = gtk_check_button_new();
156  g_signal_connect(G_OBJECT(reference_boxes[i]),
157  "toggled",
158  G_CALLBACK(CB_ChangeChannel),
159  (gpointer) this);
160  gtk_table_attach(GTK_TABLE(channels_table)
161  ,reference_boxes[i]
162  ,2,3,i+1,i+2,GTK_FILL,GTK_SHRINK,0,0);
163 
164 
165  enabled_boxes[i] = gtk_check_button_new();
166  g_signal_connect(G_OBJECT(enabled_boxes[i]),
167  "toggled",
168  G_CALLBACK(CB_ChangeChannel),
169  (gpointer) this);
170  gtk_table_attach(GTK_TABLE(channels_table)
171  ,enabled_boxes[i]
172  ,3,4,i+1,i+2,GTK_FILL,GTK_SHRINK,0,0);
173  }
174 
175 
176  GtkWidget * scroll_window = gtk_scrolled_window_new(NULL,NULL);
177  gtk_container_border_width(GTK_CONTAINER(scroll_window),0);
178  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window),
179  GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
180 
181 
182  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll_window),channels_table);
183  gtk_widget_set_size_request(scroll_window,300,-1);
184  gtk_box_pack_start(GTK_BOX(channels_hbox), scroll_window, false, false, 0);
185 
186  gtk_box_pack_start(GTK_BOX(main_hbox), TabFrameCreate(channels_hbox, view->getString("RecordingStr9")), false, false, 0);
187 
188 
189 
190  //----------------------------------------
191  // Data Process Frame
192 
193  //MAKE TREE MODEL
194 
195  GtkListStore *store;
196  GtkTreeIter iter;
197  store = gtk_list_store_new(NUM_COLS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT);
198 
199  //REFERENCE
200  gtk_list_store_append(store, &iter);
201  gtk_list_store_set(store, &iter,
202  COL_CHECK, true,
203  COL_VALUE, view->getString("RecordingStr10"),
205  -1);
206 
207  //ENABLED
208  gtk_list_store_append(store, &iter);
209  gtk_list_store_set(store, &iter,
210  COL_CHECK, true,
211  COL_VALUE, view->getString("RecordingStr11"),
213  -1);
214 
215  //FILTER
216  gtk_list_store_append(store, &iter);
217  gtk_list_store_set(store, &iter,
218  COL_CHECK, false,
219  COL_VALUE, view->getString("RecordingStr12"),
221  -1);
222  //MAKE TREE
223  GtkCellRenderer *renderer;
224  GtkTreeModel *model;
225  GtkWidget *view;
226  GtkTreeViewColumn *col;
227  GtkTreeSelection *selection;
228 
229 
230  view = gtk_tree_view_new();
231 
232  //HANDLE SELECTION
233  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
234  gtk_tree_selection_set_select_function(selection, CB_SelectProcess, this, NULL);
235 
236 
237 
238  //COLUMN 1
239  col = gtk_tree_view_column_new();
240  gtk_tree_view_column_set_title(col, this->view->getString("RecordingStr13"));
241  gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
242  renderer = gtk_cell_renderer_toggle_new();
243  g_signal_connect(renderer, "toggled", (GCallback) CB_ToggleProcess, this);
244 
245  gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(renderer), true);
246  g_object_set(renderer, "activatable", TRUE, NULL);
247  gtk_tree_view_column_pack_start(col, renderer, TRUE);
248 
249  gtk_tree_view_column_set_attributes(col, renderer,
250  "active", COL_CHECK,
251  NULL);
252 
253  //COLUMN 2
254  col = gtk_tree_view_column_new();
255  gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
256  gtk_tree_view_column_set_title(col, this->view->getString("RecordingStr14"));
257  renderer = gtk_cell_renderer_text_new();
258  gtk_tree_view_column_pack_start(col, renderer, TRUE);
259  gtk_tree_view_column_set_attributes(col, renderer,
260  "text", COL_VALUE,
261  NULL);
262 
263  //APPLY MODEL
264  model = GTK_TREE_MODEL(store);
265  this->tree_model = model;
266  gtk_tree_view_set_model(GTK_TREE_VIEW(view),model);
267 
268 
269  g_object_unref(model);
270 
271  gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)),
272  GTK_SELECTION_BROWSE);
273  gtk_widget_show_all(GTK_WIDGET(view));
274 
275  //PANE
276  GtkWidget *process_pane = gtk_vpaned_new();
277  gtk_widget_show(process_pane);
278 
279  gtk_paned_pack1(GTK_PANED(process_pane),view, true,true);
280 
281 
282  //MAKE DESCRIPTION VIEWER
283  description_viewer = gtk_text_view_new();
284  gtk_text_view_set_editable(GTK_TEXT_VIEW(description_viewer),false);
285  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(description_viewer),false);
286  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(description_viewer),GTK_WRAP_WORD);
287  gtk_widget_set_size_request (description_viewer, 250, 110);
288 
289  GtkWidget * frame = TabFrameCreate(description_viewer,this->view->getString("RecordingStr15"));
290  gtk_paned_pack2(GTK_PANED(process_pane),frame,false,false);
291 
292 
293  //Add the box to the tab
294  gtk_box_pack_start(GTK_BOX(main_hbox), TabFrameCreate(process_pane, this->view->getString("RecordingStr16")), false,false, 0);
295 
296  //----------------------------------------
297  TabAdd(main_hbox,true,true,5);
298 
299 
300  //update view from model
301  updateView();
302 }
303 
304 //----------------------------------------------------------------------
305 // UPDATE WIDGETS
306 
308 {
309  suppress_channel_callbacks = true;
310  CEBLModel * model = getView()->getModel();
311  for(int i=0; i<num_channel_boxes; i++)
312  {
313  gtk_entry_set_text(GTK_ENTRY(entry_electrode_names[i]),
314  model->channelsGetElectrodeName(i).c_str());
315  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(reference_boxes[i]),
317  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enabled_boxes[i]),
318  model->channelsGetElectrodeEnabled(i));
319  }
320  string markup = getView()->getModel()->channelsGetConfigFilename();
321  gtk_label_set_markup(GTK_LABEL(label_filename),markup.c_str());
322 
323 
324  //update process
325  GtkTreeIter iter;
326  gtk_tree_model_get_iter_first(GTK_TREE_MODEL(tree_model),&iter);
327 
328  do
329  {
331  gtk_tree_model_get(tree_model, &iter, COL, &id, -1);
332 
333  switch(id)
334  {
335  case PROCESS_REFERENCE:
336  gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter,
337  COL_CHECK,
338  (getView()->getModel()->processGetReferenceEnabled()),
339  -1);
340  break;
341  case PROCESS_ENABLED:
342  gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter,
343  COL_CHECK,
344  (getView()->getModel()->processGetRemoveEnabled()),
345  -1);
346  break;
347  case PROCESS_FILTER:
348  gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter,
349  COL_CHECK,
350  (getView()->getModel()->processGetFilterEnabled()),
351  -1);
352  break;
353  default:
354  break;
355  }
356  }
357  while(gtk_tree_model_iter_next(GTK_TREE_MODEL(tree_model),&iter));
358 
359  suppress_channel_callbacks = false;
360 }
361 
362 //update model from view
364 {
365 
366 }
367 
368 //----------------------------------------------------------------------
369 // CALLBACKS
370 
371 
372 
373 void TabEEGRecording::CB_LoadChannelsFile(GtkWidget * w, gpointer data)
374 {
375  TabEEGRecording *tab = (TabEEGRecording*)(data);
376 
377  string filename = WidgetUtils::selectLoadFile();
378  if(filename != "")
379  {
380  try
381  {
382  tab->getView()->getModel()->channelsLoadFile(filename.c_str());
383  }
384  catch(FileException e)
385  {
386  WidgetUtils::AlertError(tab->view->getString("RecordingStr17"),
387  tab->view->getString("RecordingStr18"));
388  }
389  }
390  //update the channels widgets
391  tab->updateView();
392 }
393 
394 
395 void TabEEGRecording::CB_SaveChannelsFile(GtkWidget * w, gpointer data)
396 {
397  TabEEGRecording *tab = (TabEEGRecording*)(data);
398  string filename = WidgetUtils::selectSaveFile("conf");
399  if(filename != "")
400  {
401  try
402  {
403  tab->getView()->getModel()->channelsSaveFile(filename);
404  }
405  catch(FileException e)
406  {
407  WidgetUtils::AlertError(tab->view->getString("RecordingStr17"),
408  tab->view->getString("RecordingStr19"));
409  }
410  }
411 }
412 
413 
414 void TabEEGRecording::CB_ClearChannels(GtkWidget *w, gpointer data)
415 {
416  TabEEGRecording *tab = (TabEEGRecording*)(data);
417 
418  for(int i=0; i < tab->num_channel_boxes; i++)
419  {
420  gtk_entry_set_text(GTK_ENTRY(tab->entry_electrode_names[i]),"");
421  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tab->reference_boxes[i]),
422  false);
423  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tab->enabled_boxes[i]),
424  false);
425  tab->getView()->getModel()->channelsSetElectrodeName(i,"");
426  tab->getView()->getModel()->channelsSetElectrodeEnabled(i,false);
427  tab->getView()->getModel()->channelsSetElectrodeReference(i,false);
428  }
429 }
430 
431 
432 //toggle a process in the gui
433 void TabEEGRecording::CB_ToggleProcess(GtkCellRendererToggle *cell,
434  gchar *path,
435  gpointer userdata)
436 {
437  TabEEGRecording *tab = (TabEEGRecording*)(userdata);
438  //return if callback is suppressed
439  if(tab->suppress_channel_callbacks) return;
440 
441 
442  GtkTreeIter iter;
443  bool this_selected =
444  gtk_tree_model_get_iter_from_string(tab->tree_model, &iter, path);
445  if(this_selected)
446  {
447  gboolean selected = false;
449  gtk_tree_model_get(tab->tree_model, &iter, COL_CHECK, &selected, -1);
450  gtk_tree_model_get(tab->tree_model, &iter, COL, &id, -1);
451  gtk_list_store_set(GTK_LIST_STORE(tab->tree_model), &iter,
452  COL_CHECK, !selected,
453  -1);
454 
455  switch(id)
456  {
457  case PROCESS_REFERENCE:
458  tab->getView()->getModel()->processSetReferenceEnabled(!selected);
459  break;
460  case PROCESS_ENABLED:
461  tab->getView()->getModel()->processSetRemoveEnabled(!selected);
462  break;
463  case PROCESS_FILTER:
464  tab->getView()->getModel()->processSetFilterEnabled(!selected);
465  break;
466  default:
467  break;
468  }
469  }
470 }
471 
472 
473 //select a process
474 gboolean TabEEGRecording::CB_SelectProcess (GtkTreeSelection *selection,
475  GtkTreeModel *model,
476  GtkTreePath *path,
477  gboolean path_currently_selected,
478  gpointer userdata)
479 {
480 
481 
482 
483  //get tab pointer
484  TabEEGRecording *tab = (TabEEGRecording*)(userdata);
485 
486  //if this is already selected, ignore it
487  if(path_currently_selected)
488  return true;
489 
490  //get iterator
491  GtkTreeIter iter;
492  if(gtk_tree_model_get_iter(model, &iter, path))
493  {
494  int id = -1;
495  gtk_tree_model_get(model, &iter, COL, &id, -1);
496 
497  //SET DESCRIPTIONS
498  GtkTextBuffer * buffer;
499  GtkWidget *view = tab->description_viewer;
500  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
501  switch(id)
502  {
503  case PROCESS_ENABLED:
504  gtk_text_buffer_set_text(buffer,
505  tab->view->getString("RecordingStr20"), -1);
506 
507  break;
508  case PROCESS_REFERENCE:
509  gtk_text_buffer_set_text(buffer,
510  tab->view->getString("RecordingStr21"), -1);
511 
512  break;
513  case PROCESS_FILTER:
514  gtk_text_buffer_set_text(buffer,
515  tab->view->getString("RecordingStr22"), -1);
516  break;
517  default:
518  break;
519  }
520  }
521  return true;
522 }
523 
524 
525 
526 //update all the channel values in the model from gui
527 void TabEEGRecording::CB_ChangeChannel(GtkWidget *w, gpointer data)
528 {
529  TabEEGRecording *tab = (TabEEGRecording*)(data);
530  //return if callback is suppressed
531  if(tab->suppress_channel_callbacks) return;
532 
533  for(int i=0; i<tab->num_channel_boxes;i++)
534  {
535  tab->getView()->getModel()->channelsSetElectrodeName(i,gtk_entry_get_text(GTK_ENTRY(tab->entry_electrode_names[i])));
536  tab->getView()->getModel()->channelsSetElectrodeEnabled(i,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tab->enabled_boxes[i])));
537  tab->getView()->getModel()->channelsSetElectrodeReference(i,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tab->reference_boxes[i])));
538  }
539 }
540 
541