Debian package version of polhemus's createcfgfile
Janis Streib
30.03.22 354d2bb9b7cb6169178e24450e56beebab927c44
commit | author | age
45edef 1     /*  CreateCfgFile.cpp */
JS 2
3 #include <gtk/gtk.h>
4 #include <glib/gprintf.h>
5 #include "G4SrcCfgIncl.h"
6 #include "tooltiptext.h"
7 #include "Quaternion.h"
8 #include "config.h"
9 #include <stdlib.h>
10 #include <string.h>
11
12
13     static void cb_checkbox(GtkToggleButton*,gpointer);
14     static void cb_open_cfg_file(GtkButton*,gpointer);
15     static void cb_ld_attr(GtkButton*,gpointer);
16     static void cb_create_cfg_file(GtkButton*,gpointer);
17     static void cb_about(GtkButton*,gpointer);
18     static void cb_pos_unit_chg(GtkToggleButton*,gpointer);
19     static void cb_att_unit_chg(GtkToggleButton*,gpointer);
20
21
22     gchar* browse4file();
23
24     const float IN2MET=0.02540f;
25     const char* app_version=VERSION;
26
27     typedef struct _CONTROL_STRUCT {
28       GtkWidget* chkSrcButton;
29       GtkWidget* srcPno[7];
30       GtkWidget* AttrLdButton;
31       GtkWidget* hemCombo;
32       GtkWidget* floorCompCombo;
33       GtkWidget* AttrLoaded;
34       GtkWidget* srcFreq;
35     }*LPCONTROL_STRUCT,CONTROL_STRUCT;
36
37
38     typedef struct _UNITS_STRUCT {
39       LPCONTROL_STRUCT pcs;
40       GtkWidget* label;
41       int* patt_units;
42       int* ppos_units;
43     }*LPUNITS_STRUCT,UNITS_STRUCT;
44
45     static void update_pos_vals(int,int,LPCONTROL_STRUCT);
46     static void update_att_vals(int,int,LPCONTROL_STRUCT);
47
48     const char* hemLab[6]={"POS X","POS Y","POS Z","NEG X","NEG Y","NEG Z"};
49     const char freqAlphaLab[MAX_SOURCES]={'A','B','C','D','E','F','G','H'};
50     const char* flrLab[4]={"None","50 cm","75 cm","100 cm"};
51
52
53
54     int main(int argc,char* argv[]){
55
56       CONTROL_STRUCT cs[MAX_SOURCES];
57       UNITS_STRUCT us;
58       G4_SRC_DATA_STRUCT sds;
59
60       GtkWidget *win,*table,*openButton,*create,*close;
61       GtkWidget *chkLab,*ldLab,*pnoLab,*hemLabel,*flrLabel,*freqLab;
62       GtkWidget* openImage,*saveImage,*about,*hsep,*vsep,*spacer;
63       GtkWidget* bottom_hbox,*but_table,*pos_table,*ori_box,*vbox,*unit_table;
64       GtkWidget *inches,*feet,*cm,*meters,*deg,*rads,*quats,*pos_frame,*ori_frame;
65
66       int pos_units,att_units;
67
68       int i,j,a;
69
70
71       gtk_init(&argc,&argv);
72
73       pos_units=G4_SRC_CFG_INCH;
74       att_units=G4_SRC_CFG_EULER_DEGREE;
75
76       g_object_set(gtk_settings_get_default(),"gtk_button_images",TRUE,NULL);  /*show images*/
77
78       win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
79       gtk_window_set_title(GTK_WINDOW(win),"Create G4 Source Configuration File");
80       gtk_widget_set_size_request(win,1100,600);
81         gtk_container_set_border_width(GTK_CONTAINER(win),5);
82         gtk_window_set_position(GTK_WINDOW(win),GTK_WIN_POS_CENTER);
83       //  gtk_window_set_default_icon_from_file("icon.png",NULL);
84
85       table=gtk_grid_new();
86       gtk_grid_set_column_homogeneous(GTK_GRID(table),FALSE);
87       gtk_grid_set_row_spacing(GTK_GRID(table),5);
88        /* create, add labels */
89       chkLab=gtk_label_new("System\nSources");
90       pnoLab=gtk_label_new("Location X Y Z A E R (inches and degrees)");
91       hemLabel=gtk_label_new("Startup\nHemisphere");
92       flrLabel=gtk_label_new("Floor\nCompensation");
93       ldLab=gtk_label_new("Calibration\nStatus");
94       freqLab=gtk_label_new("Source\nFreq");
95       gtk_grid_attach(GTK_GRID(table),chkLab,0,0,1,1);
96       gtk_grid_attach(GTK_GRID(table),pnoLab,1,0,7,1);
97       gtk_grid_attach(GTK_GRID(table),hemLabel,10,0,2,1);
98       gtk_grid_attach(GTK_GRID(table),flrLabel,12,0,2,1);
99       gtk_grid_attach(GTK_GRID(table),ldLab,14,0,2,1);
100       gtk_grid_attach(GTK_GRID(table),freqLab,16,0,1,1);
101       gtk_grid_set_column_spacing(GTK_GRID(table),10);
102
103
104        /* create, add ui widgets */
105       for (i=0;i<MAX_SOURCES;i++){
106         cs[i].chkSrcButton=gtk_check_button_new_with_label(NULL);
107         gtk_grid_attach(GTK_GRID(table),cs[i].chkSrcButton,0,i+1,1,1);
108         g_object_set_data(G_OBJECT(cs[i].chkSrcButton),"att_units",&att_units);
109         gtk_widget_set_tooltip_text(cs[i].chkSrcButton,tooltip_text[TT_SRC_CHKBOX]);
110         for (j=0;j<7;j++){
111           cs[i].srcPno[j]=gtk_entry_new();
112             gtk_entry_set_width_chars(GTK_ENTRY(cs[i].srcPno[j]),8);
113           gtk_grid_attach(GTK_GRID(table),cs[i].srcPno[j],j+1,i+1,1,1);
114           gtk_widget_set_sensitive(cs[i].srcPno[j],FALSE);
115           gtk_widget_set_tooltip_text(cs[i].srcPno[j],tooltip_text[TT_PNO_ENTRY]);
116         }
117         cs[i].AttrLdButton=gtk_button_new_with_label("Ld Src Calib...");
118         gtk_grid_attach(GTK_GRID(table),cs[i].AttrLdButton,8,i+1,2,1);
119         gtk_widget_set_sensitive(cs[i].AttrLdButton,FALSE);
120         g_object_set_data(G_OBJECT(cs[i].AttrLdButton),"src_data_struct",&sds);
121         g_object_set_data(G_OBJECT(cs[i].AttrLdButton),"if_data",&cs[i]);
122         gtk_widget_set_tooltip_text(cs[i].AttrLdButton,tooltip_text[TT_LD_CAL_BUTTON]);
123         cs[i].hemCombo=gtk_combo_box_text_new();
124         for (a=0;a<6;a++)
125           gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cs[i].hemCombo),hemLab[a]);
126         gtk_combo_box_set_active(GTK_COMBO_BOX(cs[i].hemCombo),0);
127         gtk_widget_set_sensitive(cs[i].hemCombo,FALSE);
128         gtk_widget_set_tooltip_text(cs[i].hemCombo,tooltip_text[TT_HEM_COMBO]);
129         gtk_grid_attach(GTK_GRID(table),cs[i].hemCombo,10,i+1,2,1);
130         cs[i].floorCompCombo=gtk_combo_box_text_new();
131
132         for (a=0;a<4;a++)
133           gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cs[i].floorCompCombo),flrLab[a]);
134         gtk_combo_box_set_active(GTK_COMBO_BOX(cs[i].floorCompCombo),0);
135         gtk_widget_set_sensitive(cs[i].floorCompCombo,FALSE);
136         gtk_widget_set_tooltip_text(cs[i].floorCompCombo,tooltip_text[TT_FLR_COMBO]);
137         gtk_grid_attach(GTK_GRID(table),cs[i].floorCompCombo,12,i+1,2,1);
138         cs[i].AttrLoaded=gtk_label_new("Not Loaded");
139         gtk_widget_set_tooltip_text(cs[i].AttrLoaded,tooltip_text[TT_CAL_STATUS]);
140         gtk_grid_attach(GTK_GRID(table),cs[i].AttrLoaded,14,i+1,2,1);
141         gtk_widget_set_sensitive(cs[i].AttrLoaded,FALSE);
142         cs[i].srcFreq=gtk_label_new("N/A");
143         gtk_widget_set_tooltip_text(cs[i].srcFreq,tooltip_text[TT_SRC_FREQ_LABEL]);
144         gtk_grid_attach(GTK_GRID(table),cs[i].srcFreq,16,i+1,2,1);
145
146
147         g_signal_connect(cs[i].chkSrcButton,"toggled",G_CALLBACK(cb_checkbox),cs+i);
148         g_signal_connect(cs[i].AttrLdButton,"clicked",G_CALLBACK(cb_ld_attr),(gpointer)(long)i);
149       }
150
151       hsep=gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
152       gtk_grid_attach(GTK_GRID(table),hsep,0,9,17,1);
153
154       openButton=gtk_button_new_with_label("Open Existing Configuration File...");
155       openImage=gtk_image_new_from_stock(GTK_STOCK_OPEN,GTK_ICON_SIZE_BUTTON);
156       gtk_widget_set_tooltip_text(openButton,tooltip_text[TT_OPEN_BUTTON]);
157       gtk_button_set_image(GTK_BUTTON(openButton),openImage);
158       g_object_set_data(G_OBJECT(openButton),"src_data_struct",&sds);
159       g_object_set_data(G_OBJECT(openButton),"pos_units",&pos_units);
160       g_object_set_data(G_OBJECT(openButton),"att_units",&att_units);
161       create=gtk_button_new_with_label("Create Source Configuration File...");
162       saveImage=gtk_image_new_from_stock(GTK_STOCK_SAVE,GTK_ICON_SIZE_BUTTON);
163       gtk_button_set_image(GTK_BUTTON(create),saveImage);
164       gtk_widget_set_tooltip_text(create,tooltip_text[TT_CREATE_BUTTON]);
165       g_object_set_data(G_OBJECT(create),"src_data_struct",&sds);
166       g_object_set_data(G_OBJECT(create),"pos_units",&pos_units);
167       g_object_set_data(G_OBJECT(create),"att_units",&att_units);
168       close=gtk_button_new_from_stock(GTK_STOCK_CLOSE);
169       about=gtk_button_new_from_stock(GTK_STOCK_ABOUT);
170
171       vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL,5);    // overall container
172
173       bottom_hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
174       but_table=gtk_grid_new();
175       gtk_grid_set_column_spacing(GTK_GRID(but_table),10);
176       gtk_grid_set_row_spacing(GTK_GRID(but_table),10);
177       gtk_container_set_border_width(GTK_CONTAINER(but_table),50);
178       gtk_grid_attach(GTK_GRID(but_table),openButton,0,1,4,2);
179       gtk_grid_attach(GTK_GRID(but_table),create,0,3,4,2);
180       gtk_grid_attach(GTK_GRID(but_table),close,0,5,2,2);
181       gtk_grid_attach(GTK_GRID(but_table),about,2,5,2,2);
182       spacer=gtk_label_new(NULL);
183       gtk_box_pack_start(GTK_BOX(bottom_hbox),spacer,FALSE,TRUE,20);
184       gtk_box_pack_start(GTK_BOX(bottom_hbox),but_table,FALSE,TRUE,0);
185       vsep=gtk_separator_new(GTK_ORIENTATION_VERTICAL);
186       gtk_box_pack_start(GTK_BOX(bottom_hbox),vsep,TRUE,TRUE,0);
187
188       // radio buttons
189       inches=gtk_radio_button_new_with_label_from_widget(NULL,"inches");
190       feet=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(inches),"feet");
191       cm=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(inches),"cm");
192       meters=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(inches),"meters");
193
194       g_object_set_data(G_OBJECT(inches),"pos_unit",(gpointer)(long)G4_SRC_CFG_INCH);
195       g_object_set_data(G_OBJECT(feet),"pos_unit",(gpointer)(long)G4_SRC_CFG_FOOT);
196       g_object_set_data(G_OBJECT(cm),"pos_unit",(gpointer)(long)G4_SRC_CFG_CM);
197       g_object_set_data(G_OBJECT(meters),"pos_unit",(gpointer)(long)G4_SRC_CFG_METER);
198
199       g_object_set_data(G_OBJECT(inches),"c_struct",(gpointer)&cs);
200       g_object_set_data(G_OBJECT(feet),"c_struct",(gpointer)&cs);
201       g_object_set_data(G_OBJECT(cm),"c_struct",(gpointer)&cs);
202       g_object_set_data(G_OBJECT(meters),"c_struct",(gpointer)&cs);
203
204       deg=gtk_radio_button_new_with_label_from_widget(NULL,"Euler Degrees");
205       rads=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(deg),"Euler Radians");
206       quats=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(deg),"Quaternions");
207
208       g_object_set_data(G_OBJECT(deg),"att_unit",(gpointer)(long)G4_SRC_CFG_EULER_DEGREE);
209       g_object_set_data(G_OBJECT(rads),"att_unit",(gpointer)(long)G4_SRC_CFG_EULER_RADIAN);
210       g_object_set_data(G_OBJECT(quats),"att_unit",(gpointer)(long)G4_SRC_CFG_QUATERNION);
211
212       g_object_set_data(G_OBJECT(deg),"c_struct",(gpointer)&cs);
213       g_object_set_data(G_OBJECT(rads),"c_struct",(gpointer)&cs);
214       g_object_set_data(G_OBJECT(quats),"c_struct",(gpointer)&cs);
215
216
217       unit_table=gtk_grid_new();
218       gtk_grid_set_column_homogeneous(GTK_GRID(unit_table),FALSE);
219       gtk_grid_set_column_spacing(GTK_GRID(unit_table),40);
220       gtk_container_set_border_width(GTK_CONTAINER(unit_table),50);
221
222       pos_table=gtk_grid_new();
223       gtk_grid_attach(GTK_GRID(pos_table),inches,0,0,1,1);
224       gtk_grid_attach(GTK_GRID(pos_table),feet,0,1,1,1);
225       gtk_grid_attach(GTK_GRID(pos_table),cm,1,0,1,1);
226       gtk_grid_attach(GTK_GRID(pos_table),meters,1,1,1,1);
227       pos_frame=gtk_frame_new("Position Units");
228       gtk_widget_set_tooltip_text(pos_frame,tooltip_text[TT_POS_UNITS]);
229       gtk_container_set_border_width(GTK_CONTAINER(pos_table),10);
230       gtk_container_add(GTK_CONTAINER(pos_frame),pos_table);
231       gtk_grid_attach(GTK_GRID(unit_table),pos_frame,0,1,1,2);
232
233
234       ori_box=gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
235       gtk_container_add(GTK_CONTAINER(ori_box),deg);
236       gtk_container_add(GTK_CONTAINER(ori_box),rads);
237       gtk_container_add(GTK_CONTAINER(ori_box),quats);
238       ori_frame=gtk_frame_new("Orientation Units");
239       gtk_widget_set_tooltip_text(ori_frame,tooltip_text[TT_ATT_UNITS]);
240       gtk_container_set_border_width(GTK_CONTAINER(ori_box),10);
241       gtk_container_add(GTK_CONTAINER(ori_frame),ori_box);
242       gtk_grid_attach(GTK_GRID(unit_table),ori_frame,2,1,3,2);
243
244
245       gtk_box_pack_start(GTK_BOX(bottom_hbox),unit_table,FALSE,FALSE,2);
246
247
248       gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,0);
249       gtk_box_pack_start(GTK_BOX(vbox),bottom_hbox,TRUE,TRUE,0);
250
251       gtk_container_add(GTK_CONTAINER(win),vbox);
252
253       us.pcs=cs;
254       us.label=pnoLab;
255       us.patt_units=&att_units;
256       us.ppos_units=&pos_units;
257
258
259       g_signal_connect(win,"destroy",G_CALLBACK(gtk_main_quit),NULL);
260       g_signal_connect(close,"clicked",G_CALLBACK(gtk_main_quit),NULL);
261       g_signal_connect(openButton,"clicked",G_CALLBACK(cb_open_cfg_file),cs);
262       g_signal_connect(create,"clicked",G_CALLBACK(cb_create_cfg_file),cs);
263       g_signal_connect(about,"clicked",G_CALLBACK(cb_about),NULL);
264
265       g_signal_connect(inches,"toggled",G_CALLBACK(cb_pos_unit_chg),&us);
266       g_signal_connect(feet,"toggled",G_CALLBACK(cb_pos_unit_chg),&us);
267       g_signal_connect(cm,"toggled",G_CALLBACK(cb_pos_unit_chg),&us);
268       g_signal_connect(meters,"toggled",G_CALLBACK(cb_pos_unit_chg),&us);
269
270       g_signal_connect(deg,"toggled",G_CALLBACK(cb_att_unit_chg),&us);
271       g_signal_connect(rads,"toggled",G_CALLBACK(cb_att_unit_chg),&us);
272       g_signal_connect(quats,"toggled",G_CALLBACK(cb_att_unit_chg),&us);
273
274       gtk_widget_show_all(win);
275
276       gtk_main();
277
278       return 0;
279
280
281     }
282
283
284     void cb_checkbox(GtkToggleButton* cb,gpointer data){
285
286       int i;
287       LPCONTROL_STRUCT pcs=(LPCONTROL_STRUCT)data;
288       gboolean ckd=gtk_toggle_button_get_active(cb);
289       int* patt_units=(int*)g_object_get_data(G_OBJECT(cb),"att_units");
290
291       int num_vals=*patt_units==G4_SRC_CFG_QUATERNION?7:6;
292
293       for (i=0;i<num_vals;i++){
294         gtk_widget_set_sensitive(pcs->srcPno[i],ckd);
295         gtk_entry_set_text(GTK_ENTRY(pcs->srcPno[i]),ckd?"0.00":"");
296       }
297       gtk_widget_set_sensitive(pcs->AttrLdButton,ckd);
298       gtk_widget_set_sensitive(pcs->AttrLoaded,ckd);
299       gtk_widget_set_sensitive(pcs->srcFreq,ckd);
300       gtk_widget_set_sensitive(pcs->hemCombo,ckd);
301       gtk_widget_set_sensitive(pcs->floorCompCombo,ckd);
302
303     }
304
305     void cb_open_cfg_file(GtkButton* b,gpointer p){
306
307       LPCONTROL_STRUCT pcs=(LPCONTROL_STRUCT)p;
308       LPG4_SRC_DATA_STRUCT pdata=(LPG4_SRC_DATA_STRUCT)g_object_get_data(G_OBJECT(b),"src_data_struct");
309       int rv,i,pos,len,a;
310       GtkWidget* dlg;
311       gchar* filename;
312       gchar str[100];
313       GtkFileFilter *all,*g4c;
314       int *ppos_units,*patt_units;
315       int num_vals;
316       char fstr[5];
317
318       ppos_units=(int*)g_object_get_data(G_OBJECT(b),"pos_units");
319       patt_units=(int*)g_object_get_data(G_OBJECT(b),"att_units");
320
321       if (*patt_units==G4_SRC_CFG_QUATERNION){
322         num_vals=7;
323         strcpy(fstr,"%.4f");
324       }
325       else {
326         num_vals=6;
327         strcpy(fstr,"%.3f");
328       }
329
330       // get file to read
331       all=gtk_file_filter_new();
332       g4c=gtk_file_filter_new();
333       gtk_file_filter_set_name(all,"All Files");
334       gtk_file_filter_set_name(g4c,"G4 Source Configuration Files (*.g4c)");
335       gtk_file_filter_add_pattern(all,"*");
336       gtk_file_filter_add_pattern(g4c,"*.g4c");
337       dlg=gtk_file_chooser_dialog_new("Select a Configuration File",NULL,
338                       GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,
339                       GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,NULL);
340
341       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg),g4c);
342       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg),all);
343       rv=gtk_dialog_run(GTK_DIALOG(dlg));
344       if (rv==GTK_RESPONSE_CANCEL){
345         gtk_widget_destroy(dlg);
346         return;
347       }
348
349       filename=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
350       gtk_widget_destroy(dlg);
351
352
353
354       // read the file
355       rv=g4_read_source_cfg_file(*ppos_units,*patt_units,pdata,filename);
356       if (rv){
357         dlg=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
358                        "Error reading Source Configuration File: %s",filename);
359         gtk_dialog_run(GTK_DIALOG(dlg));
360         gtk_widget_destroy(dlg);
361         return;
362       }
363       g_free(filename);
364
365       // update the interface
366       for (i=0;i<MAX_SOURCES;i++){
367         if (pdata->sourceMap & (0x01<<i)){
368           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcs[i].chkSrcButton),TRUE);
369           pos=0;
370           for (a=0;a<num_vals;a++){
371         len=g_sprintf(str,a<3?"%.4f":fstr,pdata->pos_ori[i][a]);
372         gtk_editable_delete_text(GTK_EDITABLE(pcs[i].srcPno[a]),0,-1);
373         gtk_editable_insert_text(GTK_EDITABLE(pcs[i].srcPno[a]),str,len,&pos);
374           }
375           gtk_combo_box_set_active(GTK_COMBO_BOX(pcs[i].hemCombo),pdata->start_hem[i]&0x07);
376           gtk_combo_box_set_active(GTK_COMBO_BOX(pcs[i].floorCompCombo),(pdata->start_hem[i]>>4)&0x07);
377           gtk_label_set_text(GTK_LABEL(pcs[i].AttrLoaded),"Loaded");
378           g_sprintf(str,"Freq %c",freqAlphaLab[pdata->freq[i]&0xff]);
379           gtk_label_set_text(GTK_LABEL(pcs[i].srcFreq),str);
380
381
382         }
383         else{
384           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pcs[i].chkSrcButton),FALSE);
385           for (a=0;a<num_vals;a++)
386         gtk_editable_delete_text(GTK_EDITABLE(pcs[i].srcPno[a]),0,-1);
387           gtk_label_set_text(GTK_LABEL(pcs[i].AttrLoaded),"Not Loaded");
388           gtk_label_set_text(GTK_LABEL(pcs[i].srcFreq),"N/A");
389
390
391         }
392       }
393
394     }
395
396     void cb_ld_attr(GtkButton* b,gpointer p){
397
398       LPCONTROL_STRUCT pcs=(LPCONTROL_STRUCT)g_object_get_data(G_OBJECT(b),"if_data");
399       LPG4_SRC_DATA_STRUCT pdata=(LPG4_SRC_DATA_STRUCT)g_object_get_data(G_OBJECT(b),"src_data_struct");
400       int index=(int)(long)p;
401       GtkWidget* dlg;
402       GtkFileFilter *all,*g4s;
403       int rv;
404       gchar* filename;
405       FILE* f;
406       int freq;
407       gchar str[20];
408
409       dlg=gtk_file_chooser_dialog_new("Choose the G4S file for this source",NULL,
410                       GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,
411                       GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,NULL);
412       g4s=gtk_file_filter_new();
413       gtk_file_filter_set_name(g4s,"G4 Attribute Files (*.g4s)");
414       gtk_file_filter_add_pattern(g4s,"*.g4s");
415       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg),g4s);
416
417       all=gtk_file_filter_new();
418       gtk_file_filter_set_name(all,"All Files");
419       gtk_file_filter_add_pattern(all,"*");
420       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg),all);
421
422       rv=gtk_dialog_run(GTK_DIALOG(dlg));
423       if (rv==GTK_RESPONSE_CANCEL){
424         gtk_widget_destroy(dlg);
425         return;
426       }
427
428       filename=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
429       gtk_widget_destroy(dlg);
430       f=fopen(filename,"r");
431       if (!f){
432         dlg=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
433                        "Error opening file: %s",filename);
434         gtk_dialog_run(GTK_DIALOG(dlg));
435         gtk_widget_destroy(dlg);
436         return;
437       }
438       g_free(filename);
439
440       rv=fread(pdata->attr[index],1,ATTR_LEN,f);
441       fclose(f);
442
443       if (rv!=ATTR_LEN){
444         dlg=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
445                        "Error reading file: %s",filename);
446         gtk_dialog_run(GTK_DIALOG(dlg));
447         gtk_widget_destroy(dlg);
448         return;
449       }
450
451       gtk_label_set_text(GTK_LABEL(pcs->AttrLoaded),"Loaded");
452       freq=g4_get_freq_sn_from_attr(pdata->attr[index],pdata->id[index]);
453       g_sprintf(str,"Freq %c",freqAlphaLab[freq]);
454       gtk_label_set_text(GTK_LABEL(pcs->srcFreq),str);
455       pdata->freq[index]=freq&0xff;
456
457
458     }
459
460     #include <string.h>
461     void cb_create_cfg_file(GtkButton* b,gpointer p){
462
463       LPCONTROL_STRUCT pcs=(LPCONTROL_STRUCT)p;
464       LPG4_SRC_DATA_STRUCT pdata=(LPG4_SRC_DATA_STRUCT)g_object_get_data(G_OBJECT(b),"src_data_struct");
465       int rv;
466       GtkWidget* dlg;
467       int i,a;
468       const gchar* buf;
469       gchar* file;
470       int num_vals;
471       int *ppos_units,*patt_units;
472
473
474       file=browse4file();
475       if (file==NULL)
476         return;
477
478       ppos_units=(int*)g_object_get_data(G_OBJECT(b),"pos_units");
479       patt_units=(int*)g_object_get_data(G_OBJECT(b),"att_units");
480
481       num_vals=*patt_units==G4_SRC_CFG_QUATERNION?7:6;
482
483       // set source map and start-up hem
484       pdata->sourceMap=0;
485       for (i=0;i<MAX_SOURCES;i++){
486         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pcs[i].chkSrcButton))){
487            pdata->sourceMap|=(0x01<<i);
488           // load up the pno
489            for (a=0;a<num_vals;a++){
490          buf=gtk_entry_get_text(GTK_ENTRY(pcs[i].srcPno[a]));
491          pdata->pos_ori[i][a]=strtod(buf,NULL);
492            }
493           // start-up hemisphere
494           pdata->start_hem[i]=gtk_combo_box_get_active(GTK_COMBO_BOX(pcs[i].hemCombo))&0x07;
495           // floor comp
496           pdata->start_hem[i]|=((gtk_combo_box_get_active(GTK_COMBO_BOX(pcs[i].floorCompCombo))&0x07)<<4);
497         }
498       }
499
500
501
502       rv=g4_create_source_cfg_file(*ppos_units,*patt_units,pdata,file);
503
504       if (rv)
505         dlg=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,
506                        "Failure creating source configuration file.  Error %d",rv);
507       else
508         dlg=gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,GTK_MESSAGE_INFO,GTK_BUTTONS_OK,
509                        "Source Configuration File Created Successfully:\n%s",file);
510
511       gtk_dialog_run(GTK_DIALOG(dlg));
512       gtk_widget_destroy(dlg);
513       g_free(file);
514
515     }
516
517     gchar* browse4file(){
518
519       GtkWidget* dlg;
520       int rv;
521       gchar* file;
522       gchar* ret_file=NULL;
523       GtkFileFilter *all,*g4c;
524
525       all=gtk_file_filter_new();
526       g4c=gtk_file_filter_new();
527       gtk_file_filter_set_name(all,"All Files");
528       gtk_file_filter_set_name(g4c,"G4 Source Configuration Files (*.g4c)");
529       gtk_file_filter_add_pattern(all,"*");
530       gtk_file_filter_add_pattern(g4c,"*.g4c");
531       dlg=gtk_file_chooser_dialog_new("Select a path and name for the Configuration file",NULL,
532                       GTK_FILE_CHOOSER_ACTION_SAVE,GTK_STOCK_SAVE,GTK_RESPONSE_ACCEPT,
533                       GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,NULL);
534
535       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg),g4c);
536       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg),all);
537       gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dlg),TRUE);
538
539       rv=gtk_dialog_run(GTK_DIALOG(dlg));
540       if (rv==GTK_RESPONSE_ACCEPT){
541         file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
542         ret_file=g_strdup(file);
543         g_free(file);
544       }
545
546       gtk_widget_destroy(dlg);
547       return ret_file;
548
549     }
550
551     void cb_about(GtkButton* b,gpointer p){
552
553       const gchar* author[]={"James C. Farr","<jimfarr@polhemus.com>",NULL};
554
555       gtk_show_about_dialog(NULL,"program-name","Create G4 Src Cfg File","version",app_version,"website",
556                 "http://www.polhemus.com/","copyright","Copyright © 2010-2013 by Polhemus","comments",
557                 "Program to create G4 Source Configuration files",
558                 "authors",author,NULL);
559
560     }
561
562
563     void cb_pos_unit_chg(GtkToggleButton* b,gpointer g){
564
565       LPUNITS_STRUCT pus=(LPUNITS_STRUCT)g;
566       LPCONTROL_STRUCT lcs;
567       int pos_unit;
568       char label[100];
569       char attLabel[50];
570
571       if (gtk_toggle_button_get_active(b)){
572         pos_unit=(int)(long)g_object_get_data(G_OBJECT(b),"pos_unit");
573         lcs=(LPCONTROL_STRUCT)g_object_get_data(G_OBJECT(b),"c_struct");
574         update_pos_vals(*pus->ppos_units,pos_unit,lcs);
575         *pus->ppos_units=pos_unit;
576         strcpy(label,"X Y Z ");
577
578         if (*pus->patt_units==G4_SRC_CFG_QUATERNION){
579           strcat(label,"q0 q1 q2 q3 ");
580           strcpy(attLabel," quaternions)");
581         }
582         else {
583           strcat(label,"A E R ");
584           if (*pus->patt_units==G4_SRC_CFG_EULER_DEGREE)
585         strcpy(attLabel," degrees)");
586           else
587         strcpy(attLabel," radians)");
588         }
589
590         switch (pos_unit){
591         case G4_SRC_CFG_INCH:
592           strcat(label,"(inches and");
593           break;
594         case G4_SRC_CFG_FOOT:
595           strcat(label,"(feet and");
596           break;
597         case G4_SRC_CFG_CM:
598           strcat(label,"(centimeters and");
599           break;
600         case G4_SRC_CFG_METER :
601           strcat(label,"(meters and");
602           break;
603         }
604         strcat(label,attLabel);
605
606         gtk_label_set_text(GTK_LABEL(pus->label),label);
607       }
608     }
609
610
611     void cb_att_unit_chg(GtkToggleButton* b,gpointer g){
612
613       LPUNITS_STRUCT pus=(LPUNITS_STRUCT)g;
614       int att_unit;
615       char label[100];
616       char attLabel[50];
617       int i;
618       LPCONTROL_STRUCT lcs;
619
620
621       if (gtk_toggle_button_get_active(b)){
622         att_unit=(int)(long)g_object_get_data(G_OBJECT(b),"att_unit");
623         lcs=(LPCONTROL_STRUCT)g_object_get_data(G_OBJECT(b),"c_struct");
624         update_att_vals(*pus->patt_units,att_unit,lcs);
625         *pus->patt_units=att_unit;
626         strcpy(label,"X Y Z ");
627
628         if (att_unit==G4_SRC_CFG_QUATERNION){
629           strcat(label,"q0 q1 q2 q3 ");
630           strcpy(attLabel," quaternions)");
631         }
632         else {
633           strcat(label,"A E R ");
634           if (att_unit==G4_SRC_CFG_EULER_DEGREE)
635         strcpy(attLabel," degrees)");
636           else
637         strcpy(attLabel," radians)");
638         }
639
640         switch (*pus->ppos_units){
641         case G4_SRC_CFG_INCH:
642           strcat(label,"(inches and");
643           break;
644         case G4_SRC_CFG_FOOT:
645           strcat(label,"(feet and");
646           break;
647         case G4_SRC_CFG_CM:
648           strcat(label,"(centimeters and");
649           break;
650         case G4_SRC_CFG_METER :
651           strcat(label,"(meters and");
652           break;
653         }
654         strcat(label,attLabel);
655
656         gtk_label_set_text(GTK_LABEL(pus->label),label);
657
658         // go thru and enable/disable 7th entry depending on att unit
659         for (i=0;i<MAX_SOURCES;i++){
660           if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(pus->pcs[i].chkSrcButton))){
661         if (att_unit==G4_SRC_CFG_QUATERNION)
662           gtk_widget_set_sensitive(pus->pcs[i].srcPno[6],TRUE);
663         else {
664           gtk_editable_delete_text(GTK_EDITABLE(pus->pcs[i].srcPno[6]),0,-1);
665           gtk_widget_set_sensitive(pus->pcs[i].srcPno[6],FALSE);
666         }
667           }
668         }
669       }
670
671     }
672
673
674     void update_pos_vals(int old_pos,int new_pos,LPCONTROL_STRUCT cs){
675
676       float factor=1.0f;
677       float f[MAX_SOURCES][3];
678
679       int i,a;
680       const gchar* text;
681       gchar str[20];
682
683       // first change to meters then to new val
684
685
686       if (old_pos!=new_pos){
687
688         switch (old_pos){
689         case G4_SRC_CFG_INCH:
690           factor=IN2MET;
691           break;
692         case G4_SRC_CFG_FOOT:
693           factor=IN2MET*12.0f;
694           break;
695         case G4_SRC_CFG_CM:
696           factor=0.01f;
697         }
698
699         for (i=0;i<MAX_SOURCES;i++){
700           if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cs[i].chkSrcButton))){
701         for (a=0;a<3;a++){
702           text=gtk_entry_get_text(GTK_ENTRY(cs[i].srcPno[a]));
703           f[i][a]=strtof(text,NULL);
704           f[i][a]*=factor;
705         }
706           }
707         }
708
709         factor=1.0f;
710         switch (new_pos){
711         case G4_SRC_CFG_INCH:
712           factor=1.0f/IN2MET;
713           break;
714         case G4_SRC_CFG_FOOT:
715           factor=1.0f/IN2MET/12.0f;
716           break;
717         case G4_SRC_CFG_CM:
718           factor=100.0f;
719         }
720
721         for (i=0;i<MAX_SOURCES;i++){
722           if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cs[i].chkSrcButton))){
723         for (a=0;a<3;a++){
724           f[i][a]*=factor;
725           sprintf(str,"%.4f",f[i][a]);
726           gtk_entry_set_text(GTK_ENTRY(cs[i].srcPno[a]),str);
727         }
728           }
729         }
730       }
731     }
732
733
734
735     void update_att_vals(int old_att,int new_att,LPCONTROL_STRUCT cs){
736
737       int i,a;
738       int deg;
739       float f[4];
740       const gchar* text;
741       char str[10];
742
743       if (old_att!=new_att){
744
745         CQuaternion q[MAX_SOURCES];
746
747         // - first change to quaternion
748         if (old_att==G4_SRC_CFG_QUATERNION){    // already quats
749
750           for (i=0;i<MAX_SOURCES;i++){
751         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cs[i].chkSrcButton))){
752           for (a=0;a<4;a++){
753             text=gtk_entry_get_text(GTK_ENTRY(cs[i].srcPno[a+3]));
754             f[a]=strtof(text,NULL);
755           }
756           q[i].SetQuatVals(f);
757         }
758           }
759         }
760
761
762         else {
763           deg=(old_att==G4_SRC_CFG_EULER_DEGREE);
764           for (i=0;i<MAX_SOURCES;i++){
765         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cs[i].chkSrcButton))){
766           for (a=0;a<3;a++){
767             text=gtk_entry_get_text(GTK_ENTRY(cs[i].srcPno[a+3]));
768             f[a]=strtof(text,NULL);
769           }
770           q[i].SetFromEulers(f,deg);
771         }
772           }
773         }
774
775         // change to new format
776         if (new_att==G4_SRC_CFG_QUATERNION){
777           for (i=0;i<MAX_SOURCES;i++){
778         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cs[i].chkSrcButton))){
779           q[i].GetQuatVal(f);
780           for (a=0;a<4;a++){
781             sprintf(str,"%.4f",f[a]);
782             gtk_entry_set_text(GTK_ENTRY(cs[i].srcPno[a+3]),str);
783           }
784         }
785           }
786         }
787         else {
788           deg=(new_att==G4_SRC_CFG_EULER_DEGREE);
789           for (i=0;i<MAX_SOURCES;i++){
790         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cs[i].chkSrcButton))){
791           q[i].GetEuler(f,deg);
792           for (a=0;a<3;a++){
793             sprintf(str,"%.3f",f[a]);
794             gtk_entry_set_text(GTK_ENTRY(cs[i].srcPno[a+3]),str);
795           } // end for a
796         } // end if
797           }// end for i
798         }// end else
799       }// end if
800     }
801
802
803