Reset parser in grace_set_project().
[grace.git] / src / fileswin.c
blobee7327480000c34744cb26a3bc0780a35538bf78
1 /*
2 * Grace - GRaphing, Advanced Computation and Exploration of data
3 *
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
5 *
6 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7 * Copyright (c) 1996-2003 Grace Development Team
8 *
9 * Maintained by Evgeny Stambulchik
12 * All Rights Reserved
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * read/write data/parameter files
35 #include <config.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <string.h>
41 #if defined(HAVE_SYS_PARAM_H)
42 # include <sys/param.h>
43 #endif
45 #include <Xm/Xm.h>
46 #include <Xm/DialogS.h>
47 #include <Xm/RowColumn.h>
48 #include <Xm/List.h>
50 #include "globals.h"
51 #include "core_utils.h"
52 #include "utils.h"
53 #include "files.h"
54 #include "motifinc.h"
55 #include "protos.h"
57 static int open_proc(FSBStructure *fsb, char *filename, void *data);
58 static int save_proc(FSBStructure *fsb, char *filename, void *data);
60 static int read_sets_proc(FSBStructure *fsb, char *filename, void *data);
61 static void set_load_proc(OptionStructure *opt, int value, void *data);
62 static void set_src_proc(Widget w, XtPointer client_data, XtPointer call_data);
63 static int write_sets_proc(FSBStructure *fsb, char *filename, void *data);
65 void create_saveproject_popup(void)
67 static FSBStructure *fsb = NULL;
69 set_wait_cursor();
71 if (fsb == NULL) {
72 fsb = CreateFileSelectionBox(app_shell, "Save project");
73 AddFileSelectionBoxCB(fsb, save_proc, NULL);
74 ManageChild(fsb->FSB);
77 RaiseWindow(fsb->dialog);
79 unset_wait_cursor();
83 * save project to a file
85 static int save_proc(FSBStructure *fsb, char *filename, void *data)
87 if (save_project(grace->project, filename) == RETURN_SUCCESS) {
88 update_all();
89 return TRUE;
90 } else {
91 return FALSE;
95 void create_openproject_popup(void)
97 static FSBStructure *fsb = NULL;
99 set_wait_cursor();
101 if (fsb == NULL) {
102 fsb = CreateFileSelectionBox(app_shell, "Open project");
103 AddFileSelectionBoxCB(fsb, open_proc, NULL);
104 ManageChild(fsb->FSB);
106 RaiseWindow(fsb->dialog);
108 unset_wait_cursor();
112 * open project from a file
114 static int open_proc(FSBStructure *fsb, char *filename, void *data)
116 if (load_project(grace, filename) == RETURN_SUCCESS) {
117 update_all();
118 xdrawgraph(grace->project, FALSE);
119 return TRUE;
120 } else {
121 return FALSE;
126 typedef struct {
127 StorageStructure *graph_item; /* graph choice item */
128 OptionStructure *ftype_item; /* set type choice item */
129 OptionStructure *load_item; /* load as single/nxy/block */
130 OptionStructure *auto_item; /* autoscale on read */
131 OptionStructure *datehint;
132 } rdataGUI;
134 void create_file_popup(Widget but, void *data)
136 static FSBStructure *rdata_dialog = NULL;
138 set_wait_cursor();
140 if (rdata_dialog == NULL) {
141 int i;
142 Widget lab, rc, rc2, fr, rb, w[2];
143 rdataGUI *gui;
144 OptionItem option_items[3];
145 OptionItem opitems[4] = {
146 {FMT_iso, "ISO" },
147 {FMT_european, "European"},
148 {FMT_us, "US" },
149 {FMT_nohint, "None" }
152 gui = xmalloc(sizeof(rdataGUI));
154 rdata_dialog = CreateFileSelectionBox(app_shell, "Read sets");
155 AddFileSelectionBoxCB(rdata_dialog, read_sets_proc, (void *) gui);
157 fr = CreateFrame(rdata_dialog->rc, NULL);
158 rc = CreateVContainer(fr);
160 gui->graph_item = CreateGraphChoice(rc,
161 "Read to graph:", LIST_TYPE_SINGLE);
163 rc2 = CreateHContainer(rc);
165 option_items[0].value = LOAD_SINGLE;
166 option_items[0].label = "Single set";
167 option_items[1].value = LOAD_NXY;
168 option_items[1].label = "NXY";
169 option_items[2].value = LOAD_BLOCK;
170 option_items[2].label = "Block data";
171 gui->load_item = CreateOptionChoice(rc2, "Load as:", 1, 3, option_items);
172 AddOptionChoiceCB(gui->load_item, set_load_proc, (void *) gui);
173 gui->ftype_item = CreateSetTypeChoice(rc2, "Set type:");
175 rc2 = CreateHContainer(rc);
176 lab = CreateLabel(rc2, "Data source:");
177 rb = XmCreateRadioBox(rc2, "radio_box_2", NULL, 0);
178 XtVaSetValues(rb, XmNorientation, XmHORIZONTAL, NULL);
179 w[0] = CreateToggleButton(rb, "Disk");
180 w[1] = CreateToggleButton(rb, "Pipe");
181 for (i = 0; i < 2; i++) {
182 XtAddCallback(w[i],
183 XmNvalueChangedCallback, set_src_proc, (XtPointer) i);
185 ManageChild(rb);
186 ManageChild(w[0]);
187 ManageChild(w[1]);
188 SetToggleButtonState(w[0], TRUE);
190 rc2 = CreateHContainer(rc);
191 gui->auto_item = CreateASChoice(rc2, "Autoscale on read:");
192 gui->datehint = CreateOptionChoice(rc2, "Date hint:", 0, 4, opitems);
193 SetOptionChoice(gui->datehint, get_date_hint());
195 ManageChild(rdata_dialog->FSB);
199 RaiseWindow(rdata_dialog->dialog);
201 unset_wait_cursor();
204 static int read_sets_proc(FSBStructure *fsb, char *filename, void *data)
206 Quark *gr;
207 int load;
209 rdataGUI *gui = (rdataGUI *) data;
211 load = GetOptionChoice(gui->load_item);
212 if (GetSingleStorageChoice(gui->graph_item, &gr) != RETURN_SUCCESS) {
213 errmsg("Please select a single graph");
214 } else {
215 if (load == LOAD_SINGLE) {
216 grace->rt->curtype = GetOptionChoice(gui->ftype_item);
219 grace->rt->autoscale_onread = GetOptionChoice(gui->auto_item);
220 set_date_hint(GetOptionChoice(gui->datehint));
222 getdata(grace->project, filename, grace->rt->cursource, load);
224 if (load == LOAD_BLOCK) {
225 create_eblock_frame(gr);
226 } else {
227 update_all();
228 xdrawgraph(grace->project, FALSE);
231 /* never close the popup */
232 return FALSE;
235 static void set_src_proc(Widget w, XtPointer client_data, XtPointer call_data)
237 int which = (int) client_data;
238 XmToggleButtonCallbackStruct *state = (XmToggleButtonCallbackStruct *) call_data;
240 if (state->set) {
241 grace->rt->cursource = which;
245 static void set_load_proc(OptionStructure *opt, int value, void *data)
247 rdataGUI *gui = (rdataGUI *) data;
249 if (value == LOAD_SINGLE) {
250 SetSensitive(gui->ftype_item->menu, True);
251 } else {
252 SetOptionChoice(gui->ftype_item, SET_XY);
253 SetSensitive(gui->ftype_item->menu, False);
258 typedef struct {
259 GraphSetStructure *sel;
260 Widget format_item;
261 } wdataGUI;
263 void create_write_popup(Widget but, void *data)
265 static FSBStructure *fsb = NULL;
267 set_wait_cursor();
269 if (fsb == NULL) {
270 Widget fr, rc;
271 wdataGUI *gui;
273 gui = xmalloc(sizeof(wdataGUI));
275 fsb = CreateFileSelectionBox(app_shell, "Write sets");
276 AddFileSelectionBoxCB(fsb, write_sets_proc, (void *) gui);
278 fr = CreateFrame(fsb->rc, NULL);
279 rc = CreateVContainer(fr);
280 gui->sel = CreateGraphSetSelector(rc, NULL, LIST_TYPE_MULTIPLE);
281 gui->format_item = CreateTextItem2(rc, 15, "Format: ");
282 xv_setstr(gui->format_item, project_get_sformat(grace->project));
284 ManageChild(fsb->FSB);
286 RaiseWindow(fsb->dialog);
288 unset_wait_cursor();
292 * write a set or sets to a file
294 static int write_sets_proc(FSBStructure *fsb, char *filename, void *data)
296 wdataGUI *gui = (wdataGUI *) data;
297 int cd, i;
298 Quark *pset, **selset;
299 char format[32];
300 FILE *cp;
302 cp = grace_openw(grace, filename);
303 if (cp == NULL) {
304 return FALSE;
307 cd = GetStorageChoices(gui->sel->set_sel, &selset);
308 if (cd < 1) {
309 errmsg("No set selected");
310 } else {
311 strncpy(format, xv_getstr(gui->format_item), 31);
312 for (i = 0; i < cd; i++) {
313 pset = selset[i];
314 write_set(pset, cp, format);
316 xfree(selset);
318 grace_close(cp);
320 /* never close the popup */
321 return FALSE;
325 #ifdef HAVE_NETCDF
327 #include <netcdf.h>
331 * netcdf reader
335 static Widget netcdf_frame = (Widget) NULL;
337 static Widget netcdf_listx_item;
338 static Widget netcdf_listy_item;
339 static Widget netcdf_file_item;
341 void create_netcdffiles_popup(Widget w, XtPointer client_data, XtPointer call_data);
343 static void do_netcdfquery_proc(Widget w, XtPointer client_data, XtPointer call_data);
345 void update_netcdfs(void);
347 int getnetcdfvars(void);
349 static void do_netcdf_proc(Widget w, XtPointer client_data, XtPointer call_data)
351 char fname[256];
352 char xvar[256], yvar[256];
353 XmString *s, cs;
354 int *pos_list;
355 int j, pos_cnt, cnt, retval;
356 char *cstr;
358 set_wait_cursor();
361 * setno == -1, then next set
363 strcpy(fname, xv_getstr(netcdf_file_item));
364 if (XmListGetSelectedPos(netcdf_listx_item, &pos_list, &pos_cnt)) {
365 XtVaGetValues(netcdf_listx_item,
366 XmNselectedItemCount, &cnt,
367 XmNselectedItems, &s,
368 NULL);
369 cs = XmStringCopy(*s);
370 if ((cstr = GetStringSimple(cs))) {
371 strcpy(xvar, cstr);
372 XtFree(cstr);
374 XmStringFree(cs);
375 } else {
376 errmsg("Need to select X, either variable name or INDEX");
377 unset_wait_cursor();
378 return;
380 if (XmListGetSelectedPos(netcdf_listy_item, &pos_list, &pos_cnt)) {
381 j = pos_list[0];
382 XtVaGetValues(netcdf_listy_item,
383 XmNselectedItemCount, &cnt,
384 XmNselectedItems, &s,
385 NULL);
386 cs = XmStringCopy(*s);
387 if ((cstr = GetStringSimple(cs))) {
388 strcpy(yvar, cstr);
389 XtFree(cstr);
391 XmStringFree(cs);
392 } else {
393 errmsg("Need to select Y");
394 unset_wait_cursor();
395 return;
397 if (strcmp(xvar, "INDEX") == 0) {
398 retval = readnetcdf(NULL, fname, NULL, yvar, -1, -1, 1);
399 } else {
400 retval = readnetcdf(NULL, fname, xvar, yvar, -1, -1, 1);
402 if (retval) {
403 xdrawgraph(grace->project, FALSE);
405 unset_wait_cursor();
408 void update_netcdfs(void)
410 int i;
411 char buf[256], fname[512];
412 XmString xms;
413 int cdfid; /* netCDF id */
414 int ndims, nvars, ngatts, recdim;
415 int var_id;
416 char varname[256];
417 nc_type datatype = 0;
418 int dim[100], natts;
419 long dimlen[100];
420 long len;
422 ncopts = 0; /* no crash on error */
424 if (netcdf_frame != NULL) {
425 strcpy(fname, xv_getstr(netcdf_file_item));
426 set_wait_cursor();
427 XmListDeleteAllItems(netcdf_listx_item);
428 XmListDeleteAllItems(netcdf_listy_item);
429 xms = XmStringCreateLocalized("INDEX");
430 XmListAddItemUnselected(netcdf_listx_item, xms, 0);
431 XmStringFree(xms);
433 if (strlen(fname) < 2) {
434 unset_wait_cursor();
435 return;
437 if ((cdfid = ncopen(fname, NC_NOWRITE)) == -1) {
438 errmsg("Can't open file.");
439 unset_wait_cursor();
440 return;
442 ncinquire(cdfid, &ndims, &nvars, &ngatts, &recdim);
443 for (i = 0; i < ndims; i++) {
444 ncdiminq(cdfid, i, NULL, &dimlen[i]);
446 for (i = 0; i < nvars; i++) {
447 ncvarinq(cdfid, i, varname, &datatype, &ndims, dim, &natts);
448 if ((var_id = ncvarid(cdfid, varname)) == -1) {
449 char ebuf[256];
450 sprintf(ebuf, "update_netcdfs(): No such variable %s", varname);
451 errmsg(ebuf);
452 continue;
454 if (ndims != 1) {
455 continue;
457 ncdiminq(cdfid, dim[0], (char *) NULL, &len);
458 sprintf(buf, "%s", varname);
459 xms = XmStringCreateLocalized(buf);
460 XmListAddItemUnselected(netcdf_listx_item, xms, 0);
461 XmListAddItemUnselected(netcdf_listy_item, xms, 0);
462 XmStringFree(xms);
464 ncclose(cdfid);
466 unset_wait_cursor();
470 static void do_netcdfupdate_proc(Widget w, XtPointer client_data, XtPointer call_data)
472 set_wait_cursor();
473 update_netcdfs();
474 unset_wait_cursor();
477 void create_netcdfs_popup(Widget but, void *data)
479 static Widget top, dialog;
480 Widget lab;
481 Arg args[3];
483 set_wait_cursor();
484 if (top == NULL) {
485 char *label1[5];
486 Widget but1[5];
488 label1[0] = "Accept";
489 label1[1] = "Files...";
490 label1[2] = "Update";
491 label1[3] = "Query";
492 label1[4] = "Close";
493 top = XmCreateDialogShell(app_shell, "netCDF", NULL, 0);
494 handle_close(top);
495 dialog = CreateVContainer(top);
497 XtSetArg(args[0], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE);
498 XtSetArg(args[1], XmNvisibleItemCount, 5);
500 lab = CreateLabel(dialog, "Select set X:");
501 netcdf_listx_item = XmCreateScrolledList(dialog, "list", args, 2);
502 ManageChild(netcdf_listx_item);
504 lab = CreateLabel(dialog, "Select set Y:");
505 netcdf_listy_item = XmCreateScrolledList(dialog, "list", args, 2);
506 ManageChild(netcdf_listy_item);
508 netcdf_file_item = CreateTextItem2(dialog, 30, "netCDF file:");
510 CreateSeparator(dialog);
512 CreateCommandButtons(dialog, 5, but1, label1);
513 XtAddCallback(but1[0], XmNactivateCallback, (XtCallbackProc) do_netcdf_proc,
514 (XtPointer) NULL);
515 XtAddCallback(but1[1], XmNactivateCallback, (XtCallbackProc) create_netcdffiles_popup,
516 (XtPointer) NULL);
517 XtAddCallback(but1[2], XmNactivateCallback, (XtCallbackProc) do_netcdfupdate_proc,
518 (XtPointer) NULL);
519 XtAddCallback(but1[3], XmNactivateCallback, (XtCallbackProc) do_netcdfquery_proc,
520 (XtPointer) NULL);
521 XtAddCallback(but1[4], XmNactivateCallback, (XtCallbackProc) destroy_dialog,
522 (XtPointer) top);
524 ManageChild(dialog);
525 netcdf_frame = top;
527 update_netcdfs();
528 RaiseWindow(top);
529 unset_wait_cursor();
532 static int do_netcdffile_proc(FSBStructure *fsb, char *filename, void *data)
534 xv_setstr(netcdf_file_item, filename);
535 update_netcdfs();
537 return TRUE;
540 void create_netcdffiles_popup(Widget w, XtPointer client_data, XtPointer call_data)
542 static FSBStructure *fsb = NULL;
544 set_wait_cursor();
546 if (fsb == NULL) {
547 fsb = CreateFileSelectionBox(app_shell, "Select netCDF file");
548 AddFileSelectionBoxCB(fsb, do_netcdffile_proc, NULL);
549 ManageChild(fsb->FSB);
552 RaiseWindow(fsb->dialog);
554 unset_wait_cursor();
557 char *getcdf_type(nc_type datatype)
559 switch (datatype) {
560 case NC_SHORT:
561 return "NC_SHORT";
562 break;
563 case NC_LONG:
564 return "NC_LONG";
565 break;
566 case NC_FLOAT:
567 return "NC_FLOAT";
568 break;
569 case NC_DOUBLE:
570 return "NC_DOUBLE";
571 break;
572 default:
573 return "UNKNOWN (can't read this)";
574 break;
578 static void do_netcdfquery_proc(Widget w, XtPointer client_data, XtPointer call_data)
580 char xvar[256], yvar[256];
581 char buf[256], fname[512];
582 XmString *s, cs;
583 int *pos_list;
584 int i, pos_cnt, cnt;
585 char *cstr;
587 int cdfid; /* netCDF id */
588 nc_type datatype = 0;
589 float f;
590 double d;
592 int x_id, y_id;
593 nc_type xdatatype = 0;
594 nc_type ydatatype = 0;
595 int xndims, xdim[10], xnatts;
596 int yndims, ydim[10], ynatts;
597 long nx, ny;
599 int atlen;
600 char attname[256];
601 char atcharval[256];
603 ncopts = 0; /* no crash on error */
605 set_wait_cursor();
607 strcpy(fname, xv_getstr(netcdf_file_item));
609 if ((cdfid = ncopen(fname, NC_NOWRITE)) == -1) {
610 errmsg("Can't open file.");
611 unset_wait_cursor();
612 return;
614 if (XmListGetSelectedPos(netcdf_listx_item, &pos_list, &pos_cnt)) {
615 XtVaGetValues(netcdf_listx_item,
616 XmNselectedItemCount, &cnt,
617 XmNselectedItems, &s,
618 NULL);
619 cs = XmStringCopy(*s);
620 if ((cstr = GetStringSimple(cs))) {
621 strcpy(xvar, cstr);
622 XtFree(cstr);
624 XmStringFree(cs);
625 } else {
626 errmsg("Need to select X, either variable name or INDEX");
627 goto out1;
629 if (XmListGetSelectedPos(netcdf_listy_item, &pos_list, &pos_cnt)) {
630 XtVaGetValues(netcdf_listy_item,
631 XmNselectedItemCount, &cnt,
632 XmNselectedItems, &s,
633 NULL);
634 cs = XmStringCopy(*s);
635 if ((cstr = GetStringSimple(cs))) {
636 strcpy(yvar, cstr);
637 XtFree(cstr);
639 XmStringFree(cs);
640 } else {
641 errmsg("Need to select Y");
642 goto out1;
644 if (strcmp(xvar, "INDEX") == 0) {
645 stufftext("X is the index of the Y variable\n");
646 } else {
647 if ((x_id = ncvarid(cdfid, xvar)) == -1) {
648 char ebuf[256];
649 sprintf(ebuf, "do_query(): No such variable %s for X", xvar);
650 errmsg(ebuf);
651 goto out1;
653 ncvarinq(cdfid, x_id, NULL, &xdatatype, &xndims, xdim, &xnatts);
654 ncdiminq(cdfid, xdim[0], NULL, &nx);
655 sprintf(buf, "X is %s, data type %s \t length [%ld]\n", xvar, getcdf_type(xdatatype), nx);
656 stufftext(buf);
657 sprintf(buf, "\t%d Attributes:\n", xnatts);
658 stufftext(buf);
659 for (i = 0; i < xnatts; i++) {
660 atcharval[0] = 0;
661 ncattname(cdfid, x_id, i, attname);
662 ncattinq(cdfid, x_id, attname, &datatype, &atlen);
663 switch (datatype) {
664 case NC_CHAR:
665 ncattget(cdfid, x_id, attname, (void *) atcharval);
666 atcharval[atlen] = 0;
667 sprintf(buf, "\t\t%s: %s\n", attname, atcharval);
668 stufftext(buf);
669 break;
670 case NC_FLOAT:
671 ncattget(cdfid, x_id, attname, (void *) &f);
672 sprintf(buf, "\t\t%s: %f\n", attname, f);
673 stufftext(buf);
674 break;
675 case NC_DOUBLE:
676 ncattget(cdfid, x_id, attname, (void *) &d);
677 sprintf(buf, "\t\t%s: %f\n", attname, d);
678 stufftext(buf);
679 break;
680 default:
681 break;
685 if ((y_id = ncvarid(cdfid, yvar)) == -1) {
686 char ebuf[256];
687 sprintf(ebuf, "do_query(): No such variable %s for Y", yvar);
688 errmsg(ebuf);
689 goto out1;
691 ncvarinq(cdfid, y_id, NULL, &ydatatype, &yndims, ydim, &ynatts);
692 ncdiminq(cdfid, ydim[0], NULL, &ny);
693 sprintf(buf, "Y is %s, data type %s \t length [%ld]\n", yvar, getcdf_type(ydatatype), ny);
694 stufftext(buf);
695 sprintf(buf, "\t%d Attributes:\n", ynatts);
696 stufftext(buf);
697 for (i = 0; i < ynatts; i++) {
698 atcharval[0] = 0;
699 ncattname(cdfid, y_id, i, attname);
700 ncattinq(cdfid, y_id, attname, &datatype, &atlen);
701 switch (datatype) {
702 case NC_CHAR:
703 ncattget(cdfid, y_id, attname, (void *) atcharval);
704 atcharval[atlen] = 0;
705 sprintf(buf, "\t\t%s: %s\n", attname, atcharval);
706 stufftext(buf);
707 break;
708 case NC_FLOAT:
709 ncattget(cdfid, y_id, attname, (void *) &f);
710 sprintf(buf, "\t\t%s: %f\n", attname, f);
711 stufftext(buf);
712 break;
713 case NC_DOUBLE:
714 ncattget(cdfid, y_id, attname, (void *) &d);
715 sprintf(buf, "\t\t%s: %f\n", attname, d);
716 stufftext(buf);
717 break;
718 default:
719 break;
723 out1:;
724 ncclose(cdfid);
725 stufftext("\n");
726 unset_wait_cursor();
729 #endif