d46f33d38df92b50cfc14ceec3d9d770a2cdb8b9
[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     {
80         sprintf(tmp, "%ctmp%cdialogXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR);
81         gmx_tmpnam(tmp);
82     }
83     else
84     {
85         fclose(tfil);
86     }
87     if ((tfil = fopen(tmp, "w")) == NULL)
88     {
89         gmx_fatal(FARGS, "Can not open tmp file %s", tmp);
90     }
91
92     fprintf(tfil, "%s\n", script);
93     fprintf(tfil, "sleep %d\n", nsleep);
94     fclose(tfil);
95
96     sprintf(command, "xterm -title %s -e sh %s", title, tmp);
97 #ifdef DEBUG
98     fprintf(stderr, "command: %s\n", command);
99 #endif
100
101 #ifdef GMX_NO_SYSTEM
102     printf("Warning-- No calls to system(3) supported on this platform.");
103     printf("Warning-- Skipping execution of 'system(\"%s\")'.", buf);
104 #else
105     if (0 != system(command))
106     {
107         gmx_fatal(FARGS, "Failed to execute command: %s", command);
108     }
109 #endif
110
111 #ifdef DEBUG
112     unlink(tmp)
113 #endif
114 }
115
116 void show_mb(t_gmx *gmx, int mb)
117 {
118     if (mb >= 0 && mb < emNR)
119     {
120         gmx->which_mb = mb;
121         ShowDlg(gmx->mboxes[mb]);
122     }
123 }
124
125 static void hide_mb(t_gmx *gmx)
126 {
127     if (gmx->which_mb >= 0 && gmx->which_mb < emNR)
128     {
129         HideDlg(gmx->mboxes[gmx->which_mb]);
130         gmx->which_mb = -1;
131     }
132 }
133
134 static void MBCallback(t_x11 *x11, int dlg_mess, int item_id,
135                        char *set, void *data)
136 {
137     t_gmx *gmx;
138
139     gmx = (t_gmx *)data;
140     if (dlg_mess == DLG_EXIT)
141     {
142         hide_mb(gmx);
143     }
144 }
145
146 static t_dlg *about_mb(t_x11 *x11, t_gmx *gmx)
147 {
148     char *lines[] = {
149         "         G R O M A C S",
150         " Machine for Simulating Chemistry",
151         "       Copyright (c) 1992-2000",
152         "  Dept. of Biophysical Chemistry",
153         "    University of Groningen"
154     };
155
156     return MessageBox(x11, gmx->wd->self, gmx->wd->text,
157                       asize(lines), lines, MB_OK | MB_ICONGMX | MBFLAGS,
158                       MBCallback, gmx);
159 }
160
161 static void QuitCB(t_x11 *x11, int dlg_mess, int item_id,
162                    char *set, void *data)
163 {
164     t_gmx  *gmx;
165     gmx = (t_gmx *)data;
166
167     hide_mb(gmx);
168     if (dlg_mess == DLG_EXIT)
169     {
170         if (gmx_strcasecmp("yes", set) == 0)
171         {
172             write_gmx(x11, gmx, IDTERM);
173         }
174     }
175 }
176
177 static t_dlg *quit_mb(t_x11 *x11, t_gmx *gmx)
178 {
179     char *lines[] = {
180         " Do you really want to Quit ?"
181     };
182
183     return MessageBox(x11, gmx->wd->self, gmx->wd->text,
184                       asize(lines), lines,
185                       MB_YESNO | MB_ICONSTOP | MBFLAGS,
186                       QuitCB, gmx);
187 }
188
189 static t_dlg *help_mb(t_x11 *x11, t_gmx *gmx)
190 {
191     char *lines[] = {
192         " Help will soon be added"
193     };
194
195     return MessageBox(x11, gmx->wd->self, gmx->wd->text,
196                       asize(lines), lines,
197                       MB_OK | MB_ICONINFORMATION | MBFLAGS,
198                       MBCallback, gmx);
199 }
200
201 static t_dlg *ni_mb(t_x11 *x11, t_gmx *gmx)
202 {
203     char *lines[] = {
204         " This feature has not been",
205         " implemented yet."
206     };
207
208     return MessageBox(x11, gmx->wd->self, gmx->wd->text,
209                       asize(lines), lines,
210                       MB_OK | MB_ICONEXCLAMATION | MBFLAGS,
211                       MBCallback, gmx);
212 }
213
214 enum {
215     eExE, eExGrom, eExPdb, eExConf, eExNR
216 };
217
218 static void ExportCB(t_x11 *x11, int dlg_mess, int item_id,
219                      char *set, void *data)
220 {
221     gmx_bool   bOk;
222     t_gmx     *gmx;
223     t_dlg     *dlg;
224
225     gmx = (t_gmx *)data;
226     dlg = gmx->dlgs[edExport];
227     switch (dlg_mess)
228     {
229         case DLG_SET:
230             switch (item_id)
231             {
232                 case eExGrom:
233                     gmx->ExpMode = eExpGromos;
234                     break;
235                 case eExPdb:
236                     gmx->ExpMode = eExpPDB;
237                     break;
238                 default:
239                     break;
240             }
241 #ifdef DEBUG
242             fprintf(stderr, "exportcb: item_id=%d\n", item_id);
243 #endif
244             break;
245         case DLG_EXIT:
246             if ((bOk = gmx_strcasecmp("ok", set)) == 0)
247             {
248                 strcpy(gmx->confout, EditText(dlg, eExConf));
249             }
250             HideDlg(dlg);
251             if (bOk)
252             {
253                 write_gmx(x11, gmx, IDDOEXPORT);
254             }
255             break;
256     }
257 }
258
259 enum {
260     eg0, egTOPOL, egCONFIN, egPARAM, eg1, eg1PROC, eg32PROC
261 };
262
263 static void Extract(t_dlg *dlg, int ID, char *buf)
264 {
265     char *et;
266
267     et = EditText(dlg, ID);
268     if (et)
269     {
270         strcpy(buf, et);
271     }
272 }
273
274 enum bond_set {
275     ebShowH = 11, ebDPlus, ebRMPBC, ebCue, ebSkip, ebWait
276 };
277
278 static void BondsCB(t_x11 *x11, int dlg_mess, int item_id,
279                     char *set, void *data)
280 {
281     static int ebond = -1;
282     static int ebox  = -1;
283     gmx_bool   bOk, bBond = FALSE;
284     int        nskip, nwait;
285     t_gmx     *gmx;
286
287     gmx = (t_gmx *)data;
288     if (ebond == -1)
289     {
290         ebond = gmx->man->molw->bond_type;
291         ebox  = gmx->man->molw->boxtype;
292     }
293     switch (dlg_mess)
294     {
295         case DLG_SET:
296             if (item_id <= eBNR)
297             {
298                 ebond = item_id-1;
299                 bBond = FALSE;
300             }
301             else if (item_id <= eBNR+esbNR+1)
302             {
303                 ebox  = item_id-eBNR-2;
304                 bBond = TRUE;
305             }
306             else
307             {
308
309 #define DO_NOT(b) (b) = (!(b))
310
311                 switch (item_id)
312                 {
313                     case ebShowH:
314                         toggle_hydrogen(x11, gmx->man->molw);
315                         break;
316                     case ebDPlus:
317                         DO_NOT(gmx->man->bPlus);
318 #ifdef DEBUG
319                         fprintf(stderr, "gmx->man->bPlus=%s\n", gmx_bool_names[gmx->man->bPlus]);
320 #endif
321                         break;
322                     /*case ebSBox:
323                        set_box_type(x11,gmx->man->molw,ebond);
324                        break;*/
325                     case ebRMPBC:
326                         toggle_pbc(gmx->man);
327                         break;
328                     case ebCue:
329                         DO_NOT(gmx->man->bSort);
330 #ifdef DEBUG
331                         fprintf(stderr, "gmx->man->bSort=%s\n", gmx_bool_names[gmx->man->bSort]);
332 #endif
333                         break;
334                     case ebSkip:
335                         sscanf(set, "%d", &nskip);
336 #ifdef DEBUG
337                         fprintf(stderr, "nskip: %d frames\n", nskip);
338 #endif
339                         if (nskip >= 0)
340                         {
341                             gmx->man->nSkip = nskip;
342                         }
343                         break;
344                     case ebWait:
345                         sscanf(set, "%d", &nwait);
346 #ifdef DEBUG
347                         fprintf(stderr, "wait: %d ms\n", nwait);
348 #endif
349                         if (nwait >= 0)
350                         {
351                             gmx->man->nWait = nwait;
352                         }
353                     default:
354 #ifdef DEBUG
355                         fprintf(stderr, "item_id: %d, set: %s\n", item_id, set);
356 #endif
357                         break;
358                 }
359             }
360             break;
361         case DLG_EXIT:
362             bOk = (gmx_strcasecmp("ok", set) == 0);
363             HideDlg(gmx->dlgs[edBonds]);
364             if (bOk)
365             {
366                 if (bBond)
367                 {
368                     switch (ebond)
369                     {
370                         case eBThin:
371                             write_gmx(x11, gmx, IDTHIN);
372                             break;
373                         case eBFat:
374                             write_gmx(x11, gmx, IDFAT);
375                             break;
376                         case eBVeryFat:
377                             write_gmx(x11, gmx, IDVERYFAT);
378                             break;
379                         case eBSpheres:
380                             write_gmx(x11, gmx, IDBALLS);
381                             break;
382                         default:
383                             gmx_fatal(FARGS, "Invalid bond type %d at %s, %d",
384                                       ebond, __FILE__, __LINE__);
385                     }
386                 }
387                 else
388                 {
389                     switch (ebox)
390                     {
391                         case esbNone:
392                             write_gmx(x11, gmx, IDNOBOX);
393                             break;
394                         case esbRect:
395                             write_gmx(x11, gmx, IDRECTBOX);
396                             break;
397                         case esbTri:
398                             write_gmx(x11, gmx, IDTRIBOX);
399                             break;
400                         case esbTrunc:
401                             write_gmx(x11, gmx, IDTOBOX);
402                             break;
403                         default:
404                             gmx_fatal(FARGS, "Invalid box type %d at %s, %d",
405                                       ebox, __FILE__, __LINE__);
406                     }
407                 }
408             }
409             break;
410     }
411 }
412
413 enum {
414     esFUNCT = 1, esBSHOW, esINFIL, esINDEXFIL, esLSQ, esSHOW, esPLOTFIL
415 };
416
417 static gmx_bool in_set(int i, int n, int set[])
418 {
419     int j;
420     for (j = 0; (j < n); j++)
421     {
422         if (set[j] == i)
423         {
424             return TRUE;
425         }
426     }
427     return FALSE;
428 }
429
430 typedef t_dlg *t_mmb (t_x11 *x11, t_gmx *gmx);
431
432 typedef struct {
433     eDialogs    ed;
434     const char  *dlgfile;
435     DlgCallback *cb;
436 } t_dlginit;
437
438 typedef struct {
439     eMBoxes     ed;
440     t_mmb       *mmb;
441     DlgCallback *cb;
442 } t_mbinit;
443
444 void init_dlgs(t_x11 *x11, t_gmx *gmx)
445 {
446     static t_dlginit di[] = {
447         { edExport,   "export.dlg",   ExportCB },
448         { edBonds,    "bonds.dlg",    BondsCB  }
449     };
450     static t_mbinit mi[emNR] = {
451         { emQuit,       quit_mb,    QuitCB     },
452         { emHelp,       help_mb,    MBCallback },
453         { emAbout,      about_mb,   MBCallback },
454         { emNotImplemented, ni_mb,      MBCallback }
455     };
456     int i;
457
458     snew(gmx->dlgs, edNR);
459     for (i = 0; (i < asize(di)); i++)
460     {
461         gmx->dlgs[i] = ReadDlg(x11, gmx->wd->self, di[i].dlgfile,
462                                x11->fg, x11->bg, di[i].dlgfile,
463                                0, 0, TRUE, FALSE, di[i].cb, gmx);
464     }
465
466     gmx->dlgs[edFilter] = select_filter(x11, gmx);
467
468     snew(gmx->mboxes, emNR);
469     for (i = 0; (i < emNR); i++)
470     {
471         gmx->mboxes[i] = mi[i].mmb(x11, gmx);
472     }
473     gmx->which_mb = -1;
474 }
475
476 void done_dlgs(t_gmx *gmx)
477 {
478     int i;
479
480     for (i = 0; (i < edNR); i++)
481     {
482         FreeDlg(gmx->dlgs[i]);
483     }
484     for (i = 0; (i < emNR); i++)
485     {
486         FreeDlg(gmx->mboxes[i]);
487     }
488 }
489
490 void edit_file(const char *fn)
491 {
492     if (fork() == 0)
493     {
494         char script[256];
495
496         sprintf(script, "vi  %s", fn);
497         shell_comm(fn, script, 0);
498         exit(0);
499     }
500 }