Merge "Merge branch 'release-4-6'"
[alexxy/gromacs.git] / src / programs / view / filter.cpp
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-2013, 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 <string.h>
40 #include "sysstuff.h"
41 #include "futil.h"
42 #include "smalloc.h"
43 #include "macros.h"
44 #include "index.h"
45 #include "xdlghi.h"
46 #include "dialogs.h"
47 #include "index.h"
48 #include "gmx_fatal.h"
49
50 t_filter *init_filter(t_atoms *atoms, const char *fn, int natom_trx)
51 {
52     t_filter *f;
53     int       g, i;
54
55     snew(f, 1);
56     if (fn != NULL)
57     {
58         f->grps = init_index(fn, &f->grpnames);
59     }
60     else
61     {
62         snew(f->grps, 1);
63         snew(f->grps->index, 1);
64         analyse(atoms, f->grps, &f->grpnames, false, false);
65     }
66     snew(f->bDisable, f->grps->nr);
67     for (g = 0; g < f->grps->nr; g++)
68     {
69         for (i = f->grps->index[g]; i < f->grps->index[g+1] && !f->bDisable[g]; i++)
70         {
71             f->bDisable[g] = (f->grps->a[i] >= natom_trx);
72         }
73     }
74
75     snew(f->bShow, f->grps->nr);
76
77     return f;
78 }
79
80 static void FilterCB(t_x11 *x11, int dlg_mess, int item_id,
81                      char *set, void *data)
82 {
83     int       nset;
84     t_filter *f;
85     t_gmx    *gmx;
86     t_dlg    *dlg;
87
88     gmx = (t_gmx *)data;
89     dlg = gmx->dlgs[edFilter];
90     f   = gmx->filter;
91
92 #ifdef DEBUG
93     printf("item_id: %d, set: %s\n", item_id, set);
94 #endif
95     switch (dlg_mess)
96     {
97         case DLG_SET:
98             if (set)
99             {
100                 if (sscanf(set, "%10d", &nset) == 1)
101                 {
102                     f->bShow[nset] = !f->bShow[nset];
103                 }
104             }
105             break;
106         case DLG_EXIT:
107             HideDlg(dlg);
108             write_gmx(x11, gmx, IDDOFILTER);
109             break;
110     }
111 }
112
113 t_dlg *select_filter(t_x11 *x11, t_gmx *gmx)
114 {
115     static const char *title = "Group";
116     static const char *dummy = "\"FALSE\"";
117     static const char *ok    = "\"Ok\"";
118     FILE              *tmp;
119     t_dlg             *dlg;
120     char               tmpfile[STRLEN];
121     int                i, j, k, len, tlen, ht, ncol, nrow, x0;
122
123     len = strlen(title);
124     for (i = 0; (i < (int)gmx->filter->grps->nr); i++)
125     {
126         len = std::max(len, (int)strlen(gmx->filter->grpnames[i]));
127     }
128     len += 2;
129
130     ncol = 1+(gmx->filter->grps->nr / 15);
131     nrow = gmx->filter->grps->nr/ncol;
132     if (nrow*ncol < gmx->filter->grps->nr)
133     {
134         nrow++;
135     }
136     if (ncol > 1)
137     {
138         ht = 1+(nrow+1)*2+3;
139     }
140     else
141     {
142         ht = 1+(gmx->filter->grps->nr+1)*2+3;
143     }
144     strcpy(tmpfile, "filterXXXXXX");
145     gmx_tmpnam(tmpfile);
146 #ifdef DEBUG
147     fprintf(stderr, "file: %s\n", tmpfile);
148 #endif
149     if ((tmp = fopen(tmpfile, "w")) == NULL)
150     {
151         sprintf(tmpfile, "%ctmp%cfilterXXXXXX", DIR_SEPARATOR, DIR_SEPARATOR);
152         gmx_tmpnam(tmpfile);
153         if ((tmp = fopen(tmpfile, "w")) == NULL)
154         {
155             gmx_fatal(FARGS, "Can not open tmp file %s", tmpfile);
156         }
157     }
158     tlen = 1+ncol*(1+len);
159     fprintf(tmp, "grid %d %d {\n\n", tlen, ht);
160
161     for (k = j = 0, x0 = 1; (j < ncol); j++, x0 += len+1)
162     {
163         fprintf(tmp, "group \"%s-%d\" %d 1 %d %d {\n", title, j+1, x0, len, ht-5);
164         for (i = 0; (i < nrow) && (k < gmx->filter->grps->nr); i++, k++)
165         {
166             if (!gmx->filter->bDisable[k])
167             {
168                 fprintf(tmp, "checkbox \"%s\" \"%d\" %s %s %s\n",
169                         gmx->filter->grpnames[k], k, dummy, dummy, dummy);
170             }
171             else
172             {
173                 fprintf(tmp, "statictext { \"  %s\" } \"%d\" %s %s %s\n",
174                         gmx->filter->grpnames[k], k, dummy, dummy, dummy);
175             }
176         }
177         fprintf(tmp, "}\n\n");
178     }
179     fprintf(tmp, "simple 1 %d %d 2 {\n", ht-3, tlen-2);
180     fprintf(tmp, "defbutton %s %s %s %s %s\n", ok, ok, dummy, dummy, dummy);
181     fprintf(tmp, "}\n\n}\n");
182     fclose(tmp);
183
184     dlg = ReadDlg(x11, gmx->wd->self, title, tmpfile,
185                   0, 0, true, false, FilterCB, gmx);
186
187     remove(tmpfile);
188
189     return dlg;
190 }