Redefine the default boolean type to gmx_bool.
[alexxy/gromacs.git] / src / ngmx / dialogs.c
1 /*
2  * 
3  *                This source code is part of
4  * 
5  *                 G   R   O   M   A   C   S
6  * 
7  *          GROningen MAchine for Chemical Simulations
8  * 
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  * 
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  * 
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "smalloc.h"
40 #include "sysstuff.h"
41 #include "macros.h"
42 #include "string2.h"
43 #include "x11.h"
44 #include "xdlghi.h"
45 #include "xmb.h"
46 #include "dialogs.h"
47 #include "names.h"
48 #include "nmol.h"
49 #include "manager.h"
50 #include "futil.h"
51 #include "gmx_fatal.h"
52
53 #define MBFLAGS /* MB_APPLMODAL | */ MB_DONTSHOW
54
55 void write_gmx(t_x11 *x11,t_gmx *gmx,int mess)
56 {
57   XEvent letter;
58
59   letter.type=ClientMessage;
60   letter.xclient.display=x11->disp;
61   letter.xclient.window=gmx->wd->self;
62   letter.xclient.message_type=0;
63   letter.xclient.format=32;
64   letter.xclient.data.l[0]=mess;
65   letter.xclient.data.l[1]=Button1;
66   XSendEvent(x11->disp,letter.xclient.window,True,0,&letter);
67 }
68
69 static void shell_comm(const char *title,const char *script,int nsleep)
70 {
71   FILE *tfil;
72   char command[STRLEN];
73   char tmp[32];
74
75   strcpy(tmp,"dialogXXXXXX");
76   gmx_tmpnam(tmp);
77   
78   if ((tfil = fopen(tmp,"w")) == NULL) {
79     sprintf(tmp,"%ctmp%cdialogXXXXXX",DIR_SEPARATOR,DIR_SEPARATOR);
80     gmx_tmpnam(tmp);
81   }
82   if ((tfil = fopen(tmp,"w")) == NULL) 
83     gmx_fatal(FARGS,"Can not open tmp file %s",tmp);
84   
85   fprintf(tfil,"%s\n",script);
86   fprintf(tfil,"sleep %d\n",nsleep);
87   fclose(tfil);
88
89   sprintf(command,"xterm -title %s -e sh %s",title,tmp);
90 #ifdef DEBUG
91   fprintf(stderr,"command: %s\n",command);
92 #endif
93
94 #ifdef GMX_NO_SYSTEM
95   printf("Warning-- No calls to system(3) supported on this platform.");
96   printf("Warning-- Skipping execution of 'system(\"%s\")'.", buf);
97 #else
98   if(0 != system(command))
99   {
100       gmx_fatal(FARGS,"Failed to execute command: %s",command);
101   }
102 #endif
103
104 #ifdef DEBUG
105   unlink(tmp)
106 #endif
107 }
108
109 void show_mb(t_gmx *gmx,int mb)
110 {
111   if (mb >=0 && mb < emNR) {
112     gmx->which_mb=mb;
113     ShowDlg(gmx->mboxes[mb]);
114   }
115 }
116
117 static void hide_mb(t_gmx *gmx)
118 {
119   if (gmx->which_mb >= 0 && gmx->which_mb < emNR) {
120     HideDlg(gmx->mboxes[gmx->which_mb]);
121     gmx->which_mb = -1;
122   }
123 }
124
125 static void MBCallback(t_x11 *x11,int dlg_mess,int item_id,
126                        char *set,void *data)
127 {
128   t_gmx *gmx;
129
130   gmx=(t_gmx *)data;
131   if (dlg_mess==DLG_EXIT) 
132     hide_mb(gmx);
133 }
134
135 static t_dlg *about_mb(t_x11 *x11,t_gmx *gmx)
136 {
137   char *lines[]={
138     "         G R O M A C S",
139     " Machine for Simulating Chemistry",
140     "       Copyright (c) 1992-2000",
141     "  Dept. of Biophysical Chemistry",
142     "    University of Groningen"
143     };
144   
145   return MessageBox(x11,gmx->wd->self,gmx->wd->text,
146                     asize(lines),lines,MB_OK | MB_ICONGMX | MBFLAGS,
147                     MBCallback,gmx);
148 }
149
150 static void QuitCB(t_x11 *x11,int dlg_mess,int item_id,
151                    char *set,void *data)
152 {
153   t_gmx  *gmx;
154   gmx=(t_gmx *)data;
155
156   hide_mb(gmx);
157   if (dlg_mess==DLG_EXIT) {
158     if (gmx_strcasecmp("yes",set)==0) 
159       write_gmx(x11,gmx,IDTERM);
160   }
161 }
162
163 static t_dlg *quit_mb(t_x11 *x11,t_gmx *gmx)
164 {
165   char *lines[]={
166     " Do you really want to Quit ?"
167     };
168
169   return MessageBox(x11,gmx->wd->self,gmx->wd->text,
170                     asize(lines),lines,
171                     MB_YESNO | MB_ICONSTOP | MBFLAGS,
172                     QuitCB,gmx);
173 }
174
175 static t_dlg *help_mb(t_x11 *x11,t_gmx *gmx)
176 {
177   char *lines[]={
178     " Help will soon be added"
179     };
180   
181   return MessageBox(x11,gmx->wd->self,gmx->wd->text,
182                     asize(lines),lines,
183                     MB_OK | MB_ICONINFORMATION | MBFLAGS,
184                     MBCallback,gmx);
185 }
186
187 static t_dlg *ni_mb(t_x11 *x11,t_gmx *gmx)
188 {
189   char *lines[]={
190     " This feature has not been",
191     " implemented yet."
192     };
193   
194   return MessageBox(x11,gmx->wd->self,gmx->wd->text,
195                     asize(lines),lines,
196                     MB_OK | MB_ICONEXCLAMATION | MBFLAGS,
197                     MBCallback,gmx);
198 }
199
200 enum { eExE, eExGrom, eExPdb, eExConf, eExNR };
201
202 static void ExportCB(t_x11 *x11,int dlg_mess,int item_id,
203                      char *set,void *data)
204 {
205   gmx_bool   bOk;
206   t_gmx  *gmx;
207   t_dlg  *dlg;
208
209   gmx=(t_gmx *)data;
210   dlg=gmx->dlgs[edExport];
211   switch (dlg_mess) {
212   case DLG_SET:
213     switch (item_id) {
214     case eExGrom:
215       gmx->ExpMode=eExpGromos;
216       break;
217     case eExPdb:
218       gmx->ExpMode=eExpPDB;
219       break;
220     default:
221       break;
222     }
223 #ifdef DEBUG
224     fprintf(stderr,"exportcb: item_id=%d\n",item_id);
225 #endif
226     break;
227   case DLG_EXIT:
228     if ((bOk=(gmx_strcasecmp("ok",set))==0)) 
229       strcpy(gmx->confout,EditText(dlg,eExConf));
230     HideDlg(dlg);
231     if (bOk)
232       write_gmx(x11,gmx,IDDOEXPORT);
233     break;
234   }
235 }
236
237 enum { eg0, egTOPOL, egCONFIN, egPARAM, eg1, eg1PROC, eg32PROC };
238
239 static void Extract(t_dlg *dlg,int ID,char *buf)
240 {
241   char *et;
242   
243   et=EditText(dlg,ID);
244   if (et)
245     strcpy(buf,et);
246 }
247
248 enum bond_set { ebShowH=11, ebDPlus, ebRMPBC, ebCue, ebSkip, ebWait };
249
250 static void BondsCB(t_x11 *x11,int dlg_mess,int item_id,
251                     char *set,void *data)
252 {
253   static int ebond=-1;
254   static int ebox=-1;
255   gmx_bool   bOk,bBond=FALSE;
256   int    nskip,nwait;
257   t_gmx  *gmx;
258
259   gmx=(t_gmx *)data;
260   if (ebond==-1) {
261     ebond = gmx->man->molw->bond_type;
262     ebox  = gmx->man->molw->boxtype;
263   }
264   switch (dlg_mess) {
265   case DLG_SET:
266     if (item_id <= eBNR) {
267       ebond=item_id-1;
268       bBond=FALSE;
269     }
270     else if (item_id <= eBNR+esbNR+1) {
271       ebox = item_id-eBNR-2;
272       bBond=TRUE;
273     }
274     else {
275
276 #define DO_NOT(b) (b) = (!(b))
277
278       switch (item_id) {
279       case ebShowH:
280         toggle_hydrogen(x11,gmx->man->molw);
281         break;
282       case ebDPlus:
283         DO_NOT(gmx->man->bPlus);
284 #ifdef DEBUG
285         fprintf(stderr,"gmx->man->bPlus=%s\n",gmx_bool_names[gmx->man->bPlus]);
286 #endif
287         break;
288         /*case ebSBox:
289         set_box_type(x11,gmx->man->molw,ebond);
290         break;*/
291       case ebRMPBC:
292         toggle_pbc(gmx->man);
293         break;
294       case ebCue:
295         DO_NOT(gmx->man->bSort);
296 #ifdef DEBUG
297         fprintf(stderr,"gmx->man->bSort=%s\n",gmx_bool_names[gmx->man->bSort]);
298 #endif
299         break;
300       case ebSkip:
301         sscanf(set,"%d",&nskip);
302 #ifdef DEBUG
303         fprintf(stderr,"nskip: %d frames\n",nskip);
304 #endif
305         if (nskip >= 0)
306           gmx->man->nSkip=nskip;
307         break;
308       case ebWait:
309         sscanf(set,"%d",&nwait);
310 #ifdef DEBUG
311         fprintf(stderr,"wait: %d ms\n",nwait);
312 #endif
313         if (nwait >= 0)
314           gmx->man->nWait=nwait;
315       default:
316 #ifdef DEBUG
317         fprintf(stderr,"item_id: %d, set: %s\n",item_id,set);
318 #endif
319         break;
320       }
321     }
322     break;
323   case DLG_EXIT:
324     bOk=(gmx_strcasecmp("ok",set)==0);
325     HideDlg(gmx->dlgs[edBonds]);
326     if (bOk) {
327       if (bBond) {
328         switch (ebond) {
329         case eBThin:
330           write_gmx(x11,gmx,IDTHIN);
331           break;
332         case eBFat:
333           write_gmx(x11,gmx,IDFAT);
334           break;
335         case eBVeryFat:
336           write_gmx(x11,gmx,IDVERYFAT);
337           break;
338         case eBSpheres:
339           write_gmx(x11,gmx,IDBALLS);
340           break;
341         default:
342           gmx_fatal(FARGS,"Invalid bond type %d at %s, %d",
343                       ebond,__FILE__,__LINE__);
344         }
345       }
346       else {
347         switch(ebox) {
348         case esbNone:
349           write_gmx(x11,gmx,IDNOBOX);
350           break;
351         case esbRect:
352           write_gmx(x11,gmx,IDRECTBOX);
353           break;
354         case esbTri:
355           write_gmx(x11,gmx,IDTRIBOX);
356           break;
357         case esbTrunc:
358           write_gmx(x11,gmx,IDTOBOX);
359           break;
360         default:
361           gmx_fatal(FARGS,"Invalid box type %d at %s, %d",
362                       ebox,__FILE__,__LINE__);
363         }
364       }
365     }
366     break;
367   }
368 }
369
370 enum { esFUNCT=1, esBSHOW, esINFIL, esINDEXFIL, esLSQ, esSHOW, esPLOTFIL };
371
372 static gmx_bool in_set(int i,int n,int set[])
373 {
374   int j;
375   for(j=0; (j<n); j++)
376     if (set[j]==i)
377       return TRUE;
378   return FALSE;
379 }
380
381 typedef t_dlg *t_mmb(t_x11 *x11,t_gmx *gmx);
382
383 typedef struct {
384   eDialogs    ed;
385   const char  *dlgfile;
386   DlgCallback *cb;
387 } t_dlginit;
388
389 typedef struct {
390   eMBoxes     ed;
391   t_mmb       *mmb;
392   DlgCallback *cb;
393 } t_mbinit;
394
395 void init_dlgs(t_x11 *x11,t_gmx *gmx)
396 {
397   static t_dlginit di[] = {
398     { edExport,   "export.dlg",   ExportCB },
399     { edBonds,    "bonds.dlg",    BondsCB  }
400   };
401   static t_mbinit mi[emNR] = {
402     { emQuit,           quit_mb,        QuitCB     },
403     { emHelp,           help_mb,        MBCallback },
404     { emAbout,          about_mb,       MBCallback },
405     { emNotImplemented, ni_mb,          MBCallback }
406   };
407   int i;
408
409   snew(gmx->dlgs,edNR);
410   for(i=0; (i<asize(di)); i++)
411     gmx->dlgs[i]=ReadDlg(x11,gmx->wd->self,di[i].dlgfile,
412                          x11->fg,x11->bg,di[i].dlgfile, 
413                          0,0,TRUE,FALSE,di[i].cb,gmx);
414
415   gmx->dlgs[edFilter]=select_filter(x11,gmx);
416   
417   snew(gmx->mboxes,emNR);
418   for(i=0; (i<emNR); i++)
419     gmx->mboxes[i]=mi[i].mmb(x11,gmx);
420   gmx->which_mb = -1;
421 }
422
423 void done_dlgs(t_gmx *gmx)
424 {
425   int i;
426
427   for(i=0; (i<edNR); i++)
428     FreeDlg(gmx->dlgs[i]);
429   for(i=0; (i<emNR); i++)
430     FreeDlg(gmx->mboxes[i]);
431 }
432
433 void edit_file(const char *fn)
434 {
435   if (fork()==0) {
436     char script[256];
437
438     sprintf(script,"vi  %s",fn);
439     shell_comm(fn,script,0);
440     exit(0);
441   }
442 }