Update changelog date
[rateit.git] / rateit.c
1 #include <gtk/gtk.h>
2 #include <glade/glade.h>
3 #include <libxml/parser.h>
4 #include <libxml/tree.h>
5 #include <string.h>
6 #include <time.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <signal.h>
10 #include <sys/wait.h>
11
12 #define MAX_SAMPLES 10
13 #define MAX_TRIALS 80
14
15 #include "rateit_glade.h"
16
17 typedef struct {
18 char *name;
19 char *path;
20 int id;
21 int pos;
22 int score;
23 char *comment;
24 } Sample;
25
26 typedef struct Trial {
27 int id;
28 int nbSamples;
29 char *name;
30 int refID;
31 Sample *samp;
32 } Trial;
33
34 typedef struct {
35 int active;
36 char *basepath;
37 char *participant;
38 int nbSamples;
39 int nbTrials;
40 char *experiment_name;
41 char *savepath;
42 Trial *trials;
43 int curr_trial;
44 int last_played;
45 } Session;
46
47 Session *session = NULL;
48
49 GladeXML *main_window;
50
51 GtkWidget *vscales[MAX_SAMPLES];
52 GtkWidget *commentButtons[MAX_SAMPLES];
53 GtkWidget *playButtons[MAX_SAMPLES];
54
55 pid_t play_pid=0;
56
57 void chld_handler(int sig)
58 {
59 pid_t pid;
60 fprintf(stderr, "Got SIGCHLD\n");
61 while ((pid=waitpid(-1, NULL, WNOHANG))>0)
62 {
63 if (pid==play_pid)
64 play_pid = 0;
65 }
66 play_pid = 0;
67 }
68
69 int xmlGetInt(xmlNode *node, const char *prop, int def)
70 {
71 xmlChar *tmpStr;
72 int val = def;
73 tmpStr = xmlGetProp(node, (const xmlChar*)prop);
74 if (tmpStr)
75 {
76 val = atoi((char*)tmpStr);
77 xmlFree(tmpStr);
78 }
79 return val;
80 }
81
82 char *xmlGetString(xmlNode *node, const char *prop, char *def)
83 {
84 xmlChar *tmpStr;
85 char *val = def;
86 tmpStr = xmlGetProp(node, (const xmlChar*)prop);
87 if (tmpStr)
88 {
89 val = strdup((char*)tmpStr);
90 xmlFree(tmpStr);
91 }
92 return val;
93 }
94
95 void free_session()
96 {
97 /* FIXME: LEAK HERE -- Must delete a few here if we don't want to leak */
98 }
99
100 void destroy_session()
101 {
102 /* FIXME: BIG LEAK HERE -- Must delete lots of stuff here if we don't want to leak */
103 session=NULL;
104 }
105
106 /*int pos2ID(int pos)
107 {
108 int id, i;
109 Trial *tr = &session->trials[session->curr_trial];
110 for (i=0;i<session->nbSamples;i++)
111 {
112 if (tr->samp[i].pos == ID)
113 return tr->samp[i].id;
114 }
115 return -1;
116 }*/
117
118 void save_session()
119 {
120 int i,j;
121 xmlDocPtr doc = NULL; /* document pointer */
122 xmlNodePtr root_node = NULL, trial_node = NULL, sample_node = NULL; /* node pointers */
123 /*xmlDtdPtr dtd = NULL;*/ /* DTD pointer */
124 char buf[256];
125 printf ("Saving to %s\n", session->savepath);
126 doc = xmlNewDoc(BAD_CAST "1.0");
127 root_node = xmlNewNode(NULL, BAD_CAST "MUSHRAEval");
128 xmlDocSetRootElement(doc, root_node);
129
130 snprintf(buf, 256, "%d", session->curr_trial);
131 xmlNewProp(root_node, BAD_CAST "currTrial", BAD_CAST buf);
132 xmlNewProp(root_node, BAD_CAST "expName", BAD_CAST session->experiment_name);
133
134 for (i=0;i<session->nbTrials;i++)
135 {
136 trial_node = xmlNewChild(root_node, NULL, BAD_CAST "SessionTrial", NULL);
137 snprintf(buf, 256, "%d", i);
138 xmlNewProp(trial_node, BAD_CAST "id", BAD_CAST buf);
139 for (j=0;j<session->nbSamples;j++)
140 {
141 sample_node = xmlNewChild(trial_node, NULL, BAD_CAST "PlayedSample", BAD_CAST session->trials[i].samp[j].comment);
142 snprintf(buf, 256, "%d", session->trials[i].samp[j].id);
143 xmlNewProp(sample_node, BAD_CAST "id", BAD_CAST buf);
144 snprintf(buf, 256, "%d", session->trials[i].samp[j].pos);
145 xmlNewProp(sample_node, BAD_CAST "pos", BAD_CAST buf);
146 snprintf(buf, 256, "%d", session->trials[i].samp[j].score);
147 xmlNewProp(sample_node, BAD_CAST "score", BAD_CAST buf);
148 }
149 }
150 xmlSaveFormatFileEnc(session->savepath, doc, "UTF-8", 1);
151
152 /*free the document */
153 xmlFreeDoc(doc);
154 }
155
156 void on_save_as_activate (GtkWidget *widget, gpointer user_data)
157 {
158 GtkWidget *saveasDialog = glade_xml_get_widget (main_window, "SaveAsDialog");
159 /*
160 if (!session->savepath)
161 {
162 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (saveasDialog), ".");
163 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (saveasDialog), "Untitled session");
164 }
165 else
166 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (saveasDialog), session->savepath);
167 */
168 if (gtk_dialog_run (GTK_DIALOG (saveasDialog)) == GTK_RESPONSE_OK)
169 {
170 char *filename;
171 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (saveasDialog));
172 session->savepath = strdup(filename);
173 save_session();
174 g_free (filename);
175 } else {
176 printf ("Cancel open\n");
177 }
178 gtk_widget_hide(saveasDialog);
179 }
180
181 void updateGUI()
182 {
183 int i;
184 GtkWidget *w;
185 const char *expStr, *trialStr="";
186 if (session)
187 {
188 for (i=0;i<session->nbSamples;i++)
189 {
190 gtk_range_set_value (GTK_RANGE(vscales[session->trials[session->curr_trial].samp[i].pos]),
191 session->trials[session->curr_trial].samp[i].score);
192 /*gtk_widget_set_sensitive(vscales[session->trials[session->curr_trial].samp[i].pos],session->active);
193 gtk_widget_set_sensitive(commentButtons[session->trials[session->curr_trial].samp[i].pos],session->active);
194 gtk_widget_set_sensitive(playButtons[session->trials[session->curr_trial].samp[i].pos],session->active);*/
195 gtk_widget_set_sensitive(vscales[session->trials[session->curr_trial].samp[i].pos],session->last_played==session->trials[session->curr_trial].samp[i].id);
196 gtk_widget_set_sensitive(commentButtons[session->trials[session->curr_trial].samp[i].pos],session->last_played==session->trials[session->curr_trial].samp[i].id);
197 }
198 expStr = session->experiment_name;
199 if (session->active)
200 trialStr=session->trials[session->curr_trial].name;
201 } else {
202 expStr = "No experiment loaded";
203 }
204
205 w = glade_xml_get_widget (main_window, "labelExperiment");
206 gtk_label_set_text(GTK_LABEL(w), expStr);
207 w = glade_xml_get_widget (main_window, "labelTrial");
208 gtk_label_set_text(GTK_LABEL(w), trialStr);
209
210 w = glade_xml_get_widget (main_window, "new1");
211 gtk_widget_set_sensitive(w, session!=NULL);
212 w = glade_xml_get_widget (main_window, "open1");
213 gtk_widget_set_sensitive(w, session!=NULL);
214 w = glade_xml_get_widget (main_window, "save1");
215 gtk_widget_set_sensitive(w, session!=NULL && session->active);
216 w = glade_xml_get_widget (main_window, "save_as1");
217 gtk_widget_set_sensitive(w, session!=NULL && session->active);
218
219 w = glade_xml_get_widget (main_window, "table1");
220 gtk_widget_set_sensitive(w, session!=NULL && session->active);
221 w = glade_xml_get_widget (main_window, "buttonNext");
222 gtk_widget_set_sensitive(w, session!=NULL && session->active);
223 if (session!=NULL && session->active)
224 {
225 if (session->curr_trial == session->nbTrials-1)
226 {
227 w = glade_xml_get_widget (main_window, "labelNext");
228 gtk_label_set_markup(GTK_LABEL(w), "<b>Finish</b>");
229 } else {
230 w = glade_xml_get_widget (main_window, "labelNext");
231 gtk_label_set_markup(GTK_LABEL(w), "<b>Next trial</b>");
232 }
233 }
234 w = glade_xml_get_widget (main_window, "buttonPrev");
235 gtk_widget_set_sensitive(w, session!=NULL && session->active && session->curr_trial != 0);
236 w = glade_xml_get_widget (main_window, "buttonPlayRef");
237 gtk_widget_set_sensitive(w, session!=NULL && session->active);
238 w = glade_xml_get_widget (main_window, "buttonPause");
239 gtk_widget_set_sensitive(w, session!=NULL && session->active && play_pid);
240 w = glade_xml_get_widget (main_window, "buttonStop");
241 gtk_widget_set_sensitive(w, session!=NULL && session->active && play_pid);
242 }
243
244 void on_save_activate (GtkWidget *widget, gpointer user_data)
245 {
246 if (session->savepath)
247 save_session();
248 else
249 on_save_as_activate(NULL, NULL);
250 }
251
252
253 int close_request()
254 {
255 GtkWidget *dialog = glade_xml_get_widget (main_window, "CloseConfirm");
256 gint response = gtk_dialog_run (GTK_DIALOG (dialog));
257 gtk_widget_hide(dialog);
258 if (response == GTK_RESPONSE_YES)
259 {
260 on_save_activate(NULL, NULL);
261 return 1;
262 } else if (response == GTK_RESPONSE_NO)
263 {
264 return 1;
265 } else
266 {
267 return 0;
268 }
269 }
270
271 void new_session()
272 {
273 int i,j;
274 if (!session)
275 return;
276 if (session->active)
277 {
278 /* Close current session */
279 if (!close_request())
280 return;
281 free_session();
282 }
283 session->active = 1;
284 session->curr_trial = 0;
285 for (i=0;i<session->nbTrials;i++)
286 {
287 for (j=0;j<session->nbSamples;j++)
288 {
289 int unique;
290 session->trials[i].samp[j].score = 100;
291 do
292 {
293 unique = 1;
294 int k;
295 /* FIXME: Must randomize properly */
296 session->trials[i].samp[j].pos = rand()%session->nbSamples;
297 for (k=0;k<j;k++)
298 {
299 if (session->trials[i].samp[k].pos == session->trials[i].samp[j].pos)
300 {
301 unique = 0;
302 break;
303 }
304 }
305 } while (!unique);
306 }
307 }
308 printf ("New session\n");
309 updateGUI();
310 }
311
312 int create_session(xmlDocPtr current_experiment)
313 {
314 xmlNode *root;
315 xmlNode *trial_node;
316 xmlNode *sample_node;
317 xmlChar *tmpStr;
318 int i,j;
319 int corrupted = 0;
320
321 session = malloc(sizeof(Session));
322 session->active = 0;
323 root = xmlDocGetRootElement(current_experiment);
324
325 tmpStr = xmlGetProp(root, (const xmlChar*)"nbSamples");
326 if (tmpStr)
327 {
328 int i;
329 session->nbSamples = atoi((char*)tmpStr);
330 xmlFree(tmpStr);
331 } else {
332 session->nbSamples = 0;
333 }
334
335 tmpStr = xmlGetProp(root, (const xmlChar*)"nbTrials");
336 if (tmpStr)
337 {
338 session->nbTrials = atoi((char*)tmpStr);
339 xmlFree(tmpStr);
340 } else {
341 session->nbTrials = 0;
342 }
343 if (session->nbTrials < 1 || session->nbTrials>= MAX_TRIALS || session->nbSamples<1 || session->nbSamples>=MAX_SAMPLES)
344 {
345 fprintf (stderr, "Attempted to create a session with %d trials and %d samples\n", session->nbTrials, session->nbSamples);
346 free(session);
347 session = NULL;
348 return 0;
349 }
350 for (i=0;i<session->nbSamples;i++)
351 {
352 gtk_widget_show(vscales[i]);
353 gtk_widget_show(commentButtons[i]);
354 gtk_widget_show(playButtons[i]);
355 }
356 for (i=session->nbSamples;i<MAX_SAMPLES;i++)
357 {
358 gtk_widget_hide(vscales[i]);
359 gtk_widget_hide(commentButtons[i]);
360 gtk_widget_hide(playButtons[i]);
361 }
362
363 session->last_played = -1;
364 session->experiment_name = xmlGetString(root, "name", "unknown experiment");
365 session->trials = malloc(sizeof(Trial)*session->nbTrials);
366 session->participant = NULL;
367 session->savepath = NULL;
368 session->curr_trial = 0;
369 session->basepath = xmlGetString(root, "samplePath", "");
370 for (i=0;i<session->nbTrials;i++)
371 {
372 session->trials[i].samp = malloc(sizeof(Session)*session->nbSamples);
373 session->trials[i].id = i;
374 session->trials[i].refID = 0;
375 session->trials[i].name = NULL;
376 session->trials[i].nbSamples = session->nbSamples;
377 for (j=0;j<session->nbSamples;j++)
378 {
379 session->trials[i].samp[j].score = 100;
380 session->trials[i].samp[j].id = j;
381 session->trials[i].samp[j].pos = j;
382 session->trials[i].samp[j].comment = NULL;
383 session->trials[i].samp[j].name = NULL;
384 session->trials[i].samp[j].path = NULL;
385 }
386 }
387
388 trial_node = root->children;
389 while (trial_node)
390 {
391 if (trial_node->type == XML_ELEMENT_NODE)
392 {
393 int tid=0;
394 tid = xmlGetInt(trial_node, "id", 0);
395 if (tid >= session->nbTrials || tid <0)
396 {
397 fprintf (stderr, "Attempted to load trial %d of %d\n", tid, session->nbTrials);
398 trial_node = trial_node->next;
399 corrupted = 1;
400 continue;
401 }
402 /*fprintf (stderr, "tid = %d of %d\n", tid, session->nbTrials);*/
403 session->trials[tid].name = xmlGetString(trial_node, "name", NULL);
404 sample_node = trial_node->children;
405 while (sample_node)
406 {
407 if (trial_node->type == XML_ELEMENT_NODE && strcmp((char*)sample_node->name, "Sample")==0)
408 {
409 char *tmpStr;
410 int sid = xmlGetInt(sample_node, "id", 0);
411 if (sid >= session->nbSamples || sid <0)
412 {
413 fprintf (stderr, "Attempted to load sample %d of %d\n", sid, session->nbSamples);
414 sample_node = sample_node->next;
415 corrupted = 1;
416 continue;
417 }
418 session->trials[tid].samp[sid].name = xmlGetString(sample_node, "name", NULL);
419 /*session->trials[tid].samp[sid].path = xmlGetString(sample_node, "file", NULL);*/
420 tmpStr = (char*)xmlGetProp(sample_node, (xmlChar*)"file");
421 if (tmpStr)
422 {
423 session->trials[tid].samp[sid].path = malloc(strlen(tmpStr)+strlen(session->basepath)+2);
424 strcpy(session->trials[tid].samp[sid].path, session->basepath);
425 strcat(session->trials[tid].samp[sid].path, "/");
426 strcat(session->trials[tid].samp[sid].path, tmpStr);
427 }
428 tmpStr = xmlGetString(sample_node, "ref", NULL);
429 if (tmpStr && strcmp(tmpStr, "true")==0)
430 session->trials[tid].refID = sid;
431 free(tmpStr);
432 session->trials[tid].samp[sid].id = sid;
433 }
434 sample_node = sample_node->next;
435 }
436 }
437 trial_node = trial_node->next;
438 }
439 for (i=0;i<session->nbTrials;i++)
440 {
441 for (j=0;j<session->nbSamples;j++)
442 {
443 if (!session->trials[i].samp[j].path)
444 {
445 fprintf (stderr, "Sample has no path\n");
446 corrupted = 1;
447 break;
448 }
449 }
450 }
451 if (corrupted)
452 {
453 for (i=0;i<session->nbTrials;i++)
454 free(session->trials[i].samp);
455 fprintf (stderr, "Loading of experiment failed (bad file)\n");
456 free(session);
457 session = NULL;
458 return 0;
459 }
460 return 1;
461 }
462
463
464 void loadSession(const char *filename)
465 {
466 xmlDocPtr current_session;
467 xmlNode *session_root;
468 xmlNode *trial_node;
469 xmlChar *sname;
470 if (!session)
471 return;
472 if (session->active)
473 {
474 /* Close current session */
475 if (!close_request())
476 return;
477 free_session();
478 }
479 session->savepath = strdup(filename);
480 current_session = xmlReadFile(filename, NULL, 0);
481 if (current_session == NULL) {
482 fprintf(stderr, "Failed to parse %s\n", filename);
483 return;
484 } else {
485 fprintf(stderr, "Successfully loaded %s\n", filename);
486 }
487 session_root = xmlDocGetRootElement(current_session);
488 sname = xmlGetProp(session_root, (const xmlChar*)"expName");
489 if (!sname || strcmp((char*)sname, session->experiment_name) != 0)
490 {
491 fprintf(stderr, "Session name doesn't match: %s\n", filename);
492 if (sname)
493 xmlFree(sname);
494 xmlFreeDoc(current_session);
495 return;
496 }
497 xmlFree(sname);
498 session->curr_trial = xmlGetInt(session_root, "currTrial", 0);
499 trial_node = session_root->children;
500 while (trial_node)
501 {
502 if (trial_node->type == XML_ELEMENT_NODE)
503 {
504 int tid;
505 xmlNode *sample_node;
506 tid = xmlGetInt(trial_node, "id", 0);
507 sample_node = trial_node->children;
508 while (sample_node)
509 {
510 if (sample_node->type == XML_ELEMENT_NODE)
511 {
512 int sid;
513 sid = xmlGetInt(sample_node, "id", 0);
514 session->trials[tid].samp[sid].pos = xmlGetInt(sample_node, "pos", 0);
515 session->trials[tid].samp[sid].score = xmlGetInt(sample_node, "score", 0);
516 /*fprintf(stderr, "name: %s at %s\n", session->trials[tid].name, session->trials[tid].samp[sid].path);*/
517 }
518 sample_node = sample_node->next;
519 }
520 }
521 trial_node = trial_node->next;
522 }
523 xmlFreeDoc(current_session);
524 session->active = 1;
525 updateGUI();
526 }
527
528
529 void loadExperiment(const char *filename)
530 {
531 xmlDocPtr current_experiment;
532 xmlNode *root;
533 if (session)
534 {
535 if (!close_request())
536 return;
537 /* Close current session */
538 destroy_session();
539 }
540 current_experiment = xmlReadFile(filename, NULL, 0);
541 if (current_experiment == NULL) {
542 fprintf(stderr, "Failed to parse %s\n", filename);
543 return;
544 } else {
545 fprintf(stderr, "Successfully loaded %s\n", filename);
546 }
547 root = xmlDocGetRootElement(current_experiment);
548 if (strcmp((char*)root->name, "MUSHRA") != 0)
549 {
550 fprintf(stderr, "Failed validate %s\n", filename);
551 xmlFreeDoc(current_experiment);
552 current_experiment = NULL;
553 return;
554 }
555 create_session(current_experiment);
556 updateGUI();
557 xmlFreeDoc(current_experiment);
558 }
559
560 int getIDFromLabel(GtkWidget *label)
561 {
562 const char *name = gtk_label_get_text(GTK_LABEL(label));
563 if (strcmp(name, "Ref")==0)
564 return -1;
565 else
566 return name[0]-'A';
567 }
568
569
570 Sample *getSampleFromLabel(GtkWidget *label, int update_last_played)
571 {
572 int i;
573 Trial *tr;
574 int ID = getIDFromLabel(label);
575 /*printf ("pos = %d\n", ID);*/
576 tr = &session->trials[session->curr_trial];
577 for (i=0;i<session->nbSamples;i++)
578 {
579 if (tr->samp[i].pos == ID)
580 {
581 if (update_last_played)
582 session->last_played = i;
583 return &tr->samp[i];
584 }
585 }
586 return &tr->samp[tr->refID];
587 }
588
589 void on_new_activate (GtkWidget *widget, gpointer user_data)
590 {
591 new_session();
592 }
593
594 void on_open_activate (GtkWidget *widget, gpointer user_data)
595 {
596 GtkWidget *openDialog = glade_xml_get_widget (main_window, "OpenDialog");
597 gtk_widget_show(openDialog);
598 if (gtk_dialog_run (GTK_DIALOG (openDialog)) == GTK_RESPONSE_OK)
599 {
600 char *filename;
601 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (openDialog));
602 /*open_file (filename);*/
603 /*printf ("Opening %s\n", filename);*/
604 loadSession(filename);
605 g_free (filename);
606 }
607 gtk_widget_hide(openDialog);
608 }
609
610 void on_open_experiment (GtkWidget *widget, gpointer user_data)
611 {
612 GtkWidget *openDialog = glade_xml_get_widget (main_window, "OpenDialog");
613 gtk_widget_show(openDialog);
614 if (gtk_dialog_run (GTK_DIALOG (openDialog)) == GTK_RESPONSE_OK)
615 {
616 char *filename;
617 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (openDialog));
618 /*printf ("Opening %s\n", filename);*/
619 loadExperiment(filename);
620 g_free (filename);
621 }
622 gtk_widget_hide(openDialog);
623 }
624
625
626
627 void on_vscale_value_changed (GtkWidget *widget, gpointer user_data)
628 {
629 Sample *s = getSampleFromLabel(widget, 0);
630 s->score = gtk_range_get_value(GTK_RANGE(vscales[s->pos]));
631 /*printf ("%d -> %d\n", s->id, s->score);*/
632 }
633
634 void on_buttonPlay_clicked (GtkWidget *widget, gpointer user_data)
635 {
636 Sample *s = getSampleFromLabel(widget, 1);
637 /*snprintf(command, 256, "play \"%s\" >& /dev/null &", s->path);*/
638 /*printf ("%s\n", command);*/
639 /*system("killall play >& /dev/null; killall sox >& /dev/null");*/
640 /*system(command);*/
641 if (play_pid)
642 {
643 kill(play_pid, SIGINT);
644 waitpid(play_pid, NULL, 0);
645 }
646 if ((play_pid=fork())==0)
647 {
648 close(0);
649 close(1);
650 close(2);
651 execlp("sox", "sox", s->path, "-t", "ossdsp", "/dev/dsp", NULL);
652 perror("execlp");
653 _exit(0);
654 }
655 updateGUI();
656 }
657
658 void on_buttonPause_clicked (GtkWidget *widget, gpointer user_data)
659 {
660 /*system("killall play >& /dev/null; killall sox >& /dev/null");*/
661 if (play_pid)
662 {
663 kill(play_pid, SIGINT);
664 waitpid(play_pid, NULL, 0);
665 printf ("Pause!\n");
666 }
667 updateGUI();
668 }
669
670 void on_buttonStop_clicked (GtkWidget *widget, gpointer user_data)
671 {
672 /*system("killall play >& /dev/null; killall sox >& /dev/null");*/
673 if (play_pid)
674 {
675 kill(play_pid, SIGINT);
676 waitpid(play_pid, NULL, 0);
677 printf ("Stop!\n");
678 }
679 updateGUI();
680 }
681
682 void on_buttonNext_clicked (GtkWidget *widget, gpointer user_data)
683 {
684 if (session->curr_trial < session->nbTrials-1)
685 {
686 session->curr_trial++;
687 session->last_played=-1;
688 updateGUI();
689 on_buttonStop_clicked(NULL, NULL);
690 printf ("Next!\n");
691 } else {
692 on_save_activate(NULL, NULL);
693 printf ("Completed!\n");
694 }
695 }
696
697 void on_buttonPrev_clicked (GtkWidget *widget, gpointer user_data)
698 {
699 if (session->curr_trial > 0)
700 {
701 session->curr_trial--;
702 session->last_played=-1;
703 updateGUI();
704 printf ("Prev!\n");
705 } else {
706 printf ("Already at the beginning!\n");
707 }
708 }
709
710 void on_buttonComment_clicked (GtkWidget *widget, gpointer user_data)
711 {
712 GtkWidget *commentDialog;
713 GtkTextIter startIter, endIter;
714 GtkTextBuffer *buffer;
715
716 Sample *s = getSampleFromLabel(widget, 0);
717
718 commentDialog = glade_xml_get_widget (main_window, "CommentDialog");
719 GtkWidget *textview = glade_xml_get_widget (main_window, "textviewComments");
720 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
721 gtk_text_buffer_set_text(buffer, s->comment ? s->comment : "", -1);
722
723 if (gtk_dialog_run (GTK_DIALOG (commentDialog)) == GTK_RESPONSE_CLOSE)
724 {
725 char *commentStr;
726 gtk_text_buffer_get_start_iter(buffer, &startIter);
727 gtk_text_buffer_get_end_iter(buffer, &endIter);
728 commentStr = gtk_text_buffer_get_text(buffer, &startIter, &endIter, FALSE);
729 free(s->comment);
730 s->comment = strdup(commentStr);
731 g_free(commentStr);
732 } else {
733 printf ("Cancel open\n");
734 }
735 gtk_widget_hide(commentDialog);
736 }
737
738 void on_instructions_activate (GtkWidget *widget, gpointer user_data)
739 {
740 GtkWidget *dialog;
741 dialog = glade_xml_get_widget (main_window, "InstructionsDialog");
742 gtk_dialog_run (GTK_DIALOG (dialog));
743 gtk_widget_hide(dialog);
744 }
745
746 void on_hscale_value_changed (GtkWidget *widget, gpointer user_data)
747 {
748 }
749
750 void quit_request (GtkWidget *widget, gpointer user_data)
751 {
752 if (session && session->active)
753 {
754 if (!close_request())
755 return;
756 }
757 on_buttonStop_clicked(NULL, NULL);
758 gtk_main_quit();
759 }
760
761
762 void
763 on_about_activate (GtkWidget *widget, gpointer user_data)
764 {
765 GtkWidget *about = glade_xml_get_widget (main_window, "AboutDialog");
766 gtk_widget_show(about);
767 }
768
769 int
770 main (int argc, char *argv[])
771 {
772 int i;
773 srand(time(NULL));
774 gtk_init (&argc, &argv);
775 LIBXML_TEST_VERSION
776
777 signal (SIGCHLD, chld_handler);
778 /* load the interface */
779 /*main_window = glade_xml_new ("rateit.glade", NULL, NULL);*/
780 main_window = glade_xml_new_from_memory((char*)rateit_glade, 1+strlen((char*)rateit_glade), NULL, NULL);
781
782 /* connect the signals in the interface */
783 glade_xml_signal_autoconnect (main_window);
784
785 /* Extract widgets to a table */
786 for (i=0;i<MAX_SAMPLES;i++)
787 {
788 char widget_name[100];
789 snprintf(widget_name, 100, "vscale%c", 'A'+i);
790 vscales[i] = glade_xml_get_widget (main_window, widget_name);
791 snprintf(widget_name, 100, "buttonComment%c", 'A'+i);
792 commentButtons[i] = glade_xml_get_widget (main_window, widget_name);
793 snprintf(widget_name, 100, "buttonPlay%c", 'A'+i);
794 playButtons[i] = glade_xml_get_widget (main_window, widget_name);
795 }
796
797 if (argc>=2)
798 loadExperiment(argv[1]);
799 if (argc>=3)
800 loadSession(argv[2]);
801 updateGUI();
802 /* start the event loop */
803 gtk_main ();
804 xmlCleanupParser();
805 return 0;
806 }
This page took 0.046988 seconds and 4 git commands to generate.