1 /* DeMonMolecule.c */
2 /**********************************************************************************************************
3 Copyright (c) 2002-2013 Abdul-Rahman Allouche. All rights reserved
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 documentation files (the Gabedit), to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
8 and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
10 The above copyright notice and this permission notice shall be included in all copies or substantial portions
11 of the Software.
12
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
14 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 DEALINGS IN THE SOFTWARE.
18 ************************************************************************************************************/
19
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <math.h>
23
24 #include "../../Config.h"
25 #include "../Common/Global.h"
26 #include "../DeMon/DeMonTypes.h"
27 #include "../DeMon/DeMonGlobal.h"
28 #include "../DeMon/DeMonKeywords.h"
29 #include "../Geometry/GeomGlobal.h"
30 #include "../Geometry/GeomConversion.h"
31 #include "../Geometry/GeomXYZ.h"
32 #include "../Geometry/Fragments.h"
33 #include "../Geometry/DrawGeom.h"
34 #include "../Utils/Utils.h"
35 #include "../Utils/UtilsInterface.h"
36 #include "../Utils/Constants.h"
37 #include "../Utils/GabeditTextEdit.h"
38 #include "../Geometry/InterfaceGeom.h"
39 #include "../Common/Windows.h"
40 #include "../Utils/Constants.h"
41 #include "../Utils/AtomsProp.h"
42
43 /************************************************************************************************************/
44 static gint totalCharge = 0;
45 static gint spinMultiplicity=1;
46 /************************************************************************************************************/
getDeMonMultiplicity()47 gint getDeMonMultiplicity()
48 {
49 return spinMultiplicity;
50 }
51 /************************************************************************************************************/
initDeMonMoleculeButtons()52 void initDeMonMoleculeButtons()
53 {
54 }
55 /************************************************************************************************************/
initDeMonMolecule()56 void initDeMonMolecule()
57 {
58 demonMolecule.listOfAtoms = NULL;
59 demonMolecule.totalNumberOfElectrons = 0;
60 demonMolecule.numberOfValenceElectrons = 0;
61 demonMolecule.numberOfAtoms = 0;
62 }
63 /************************************************************************************************************/
freeDeMonMolecule()64 void freeDeMonMolecule()
65 {
66 static gboolean first = TRUE;
67
68 if(first)
69 {
70 initDeMonMolecule();
71 first = FALSE;
72 return;
73 }
74
75 if(demonMolecule.listOfAtoms) g_free(demonMolecule.listOfAtoms);
76 initDeMonMolecule();
77 }
78 /************************************************************************************************************/
setDeMonMoleculeFromSXYZ(gint nAtoms,gchar ** symbols,gdouble * X,gdouble * Y,gdouble * Z)79 static gint setDeMonMoleculeFromSXYZ(gint nAtoms, gchar** symbols, gdouble* X, gdouble* Y, gdouble* Z)
80 {
81 gint n;
82 DeMonAtom* atomList = NULL;
83
84 demonMolecule.listOfAtoms = NULL;
85 demonMolecule.numberOfAtoms = 0;
86 if(nAtoms<1) return 1;
87
88 demonMolecule.listOfAtoms = (DeMonAtom*)g_malloc(sizeof(DeMonAtom)*(nAtoms));
89 if(demonMolecule.listOfAtoms==NULL) return -1;
90
91 demonMolecule.numberOfAtoms = nAtoms;
92
93 atomList = demonMolecule.listOfAtoms;
94 for(n=0; n<demonMolecule.numberOfAtoms; n++)
95 {
96 atomList->position[0] = X[n];
97 atomList->position[1] = Y[n];
98 atomList->position[2] = Z[n];
99 atomList->symbol = g_strdup(symbols[n]);
100 atomList++;
101 }
102
103 return 0;
104 }
105 /************************************************************************************************************/
setXYZFromGeomXYZ(gint i,gdouble * x,gdouble * y,gdouble * z)106 static void setXYZFromGeomXYZ(gint i, gdouble* x, gdouble* y, gdouble *z)
107 {
108 if(!test(GeomXYZ[i].X))
109 *x = get_value_variableXYZ(GeomXYZ[i].X);
110 else
111 *x = atof(GeomXYZ[i].X);
112 if(!test(GeomXYZ[i].Y))
113 *y = get_value_variableXYZ(GeomXYZ[i].Y);
114 else
115 *y = atof(GeomXYZ[i].Y);
116 if(!test(GeomXYZ[i].Z))
117 *z = get_value_variableXYZ(GeomXYZ[i].Z);
118 else
119 *z = atof(GeomXYZ[i].Z);
120
121 if(Units==0)
122 {
123 *x *= BOHR_TO_ANG;
124 *y *= BOHR_TO_ANG;
125 *z *= BOHR_TO_ANG;
126 }
127 }
128 /************************************************************************************************************/
setDeMonMoleculeFromGeomXYZ()129 static gboolean setDeMonMoleculeFromGeomXYZ()
130 {
131 gint i;
132 gchar** symbols = NULL;
133 gdouble* X = NULL;
134 gdouble* Y = NULL;
135 gdouble* Z = NULL;
136 gint numberOfAtoms = NcentersXYZ;
137
138 if(numberOfAtoms<1) return FALSE;
139
140 symbols = (gchar**)g_malloc(sizeof(gchar*)*(numberOfAtoms));
141
142 if(symbols == NULL) return FALSE;
143
144 X = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
145 if(X == NULL) return FALSE;
146 Y = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
147 if(Y == NULL) return FALSE;
148 Z = (gdouble*)g_malloc(sizeof(gdouble)*(numberOfAtoms));
149 if(Z == NULL) return FALSE;
150
151 demonMolecule.totalNumberOfElectrons = 0;
152 for(i=0; i<numberOfAtoms; i++)
153 {
154 SAtomsProp prop = prop_atom_get(GeomXYZ[i].Symb);
155
156 symbols[i] = g_strdup(GeomXYZ[i].Symb);
157 setXYZFromGeomXYZ(i, &X[i] , &Y[i] , &Z[i]);
158 demonMolecule.totalNumberOfElectrons += prop.atomicNumber;
159 }
160 demonMolecule.numberOfValenceElectrons = demonMolecule.totalNumberOfElectrons;
161 setDeMonMoleculeFromSXYZ(numberOfAtoms, symbols, X, Y, Z);
162
163 for (i=0;i<(gint)NcentersXYZ;i++) g_free( symbols[i]);
164 g_free( symbols);
165 g_free(X);
166 g_free(Y);
167 g_free(Z);
168 return TRUE;
169 }
170 /************************************************************************************************************/
setDeMonMoleculeFromGeomZMatrix()171 static gboolean setDeMonMoleculeFromGeomZMatrix()
172 {
173 iprogram=PROG_IS_DEMON;
174 if(!zmat_to_xyz()) return FALSE;
175 delete_dummy_atoms();
176 /* conversion_zmat_to_xyz();*/
177 return setDeMonMoleculeFromGeomXYZ();
178 }
179 /************************************************************************************************************/
setDeMonMolecule()180 gboolean setDeMonMolecule()
181 {
182 freeDeMonMolecule();
183 if(MethodeGeom==GEOM_IS_XYZ && setDeMonMoleculeFromGeomXYZ()) return TRUE;
184 if(setDeMonMoleculeFromGeomZMatrix()) return TRUE;
185 return FALSE;
186 }
187 /************************************************************************************************************/
setDeMonGeometryFromInputFile(gchar * fileName)188 void setDeMonGeometryFromInputFile(gchar* fileName)
189 {
190 read_geom_in_demon_input(fileName);
191 setDeMonMolecule();
192 }
193 /*************************************************************************************************************/
194 /*
195 static gdouble getMinDistance()
196 {
197 gdouble d=0;
198 gint i;
199 gint k;
200 DeMonAtom* atomList = demonMolecule.listOfAtoms;
201 for(i=0; i<demonMolecule.numberOfAtoms-1; i++)
202 {
203 gdouble dd = 0;
204 for(k=0;k<3;k++)
205 {
206 gdouble xx = atomList->position[k]-atomList->position[k+1];
207 dd += xx*xx;
208 }
209 if(i==0) d = dd;
210 else if(d>dd) d= dd;
211 atomList++;
212 }
213 d = sqrt(d);
214
215 return d;
216 }
217 */
218 /*************************************************************************************************************/
219 /*
220 static void setFirstAtomToXAxis(gint numberOfAtoms, gdouble* X, gdouble* Y, gdouble*Z)
221 {
222 gdouble d;
223 gdouble s;
224 gdouble c;
225 gint i;
226 gdouble positionTolerance = -1;
227
228 if(numberOfAtoms<1) return;
229 d = X[0]*X[0]+Y[0]*Y[0];
230 if(d<1e-10) return;
231 d = sqrt(d);
232 if(positionTolerance<0) positionTolerance= getMinDistance()/50;
233
234 s = -Y[0]/d;
235 c = +X[0]/d;
236
237 for (i=0;i<numberOfAtoms;i++)
238 {
239 gdouble x = X[i];
240 gdouble y = Y[i];
241 X[i] = c*x - s*y;
242 Y[i] = s*x + c*y;
243 if(fabs(Y[i])<positionTolerance) Y[i]=0.0;
244 }
245
246 }
247 */
248 /*************************************************************************************************************/
249 /*
250 static gint getRealNumberXYZVariables()
251 {
252 gint k=0;
253 gint i;
254 for(i=0;i<NcentersXYZ;i++)
255 {
256 if(test(GeomXYZ[i].X))k++;
257 if(test(GeomXYZ[i].Y))k++;
258 if(test(GeomXYZ[i].Z))k++;
259 }
260 return k;
261 }
262 */
263 /*************************************************************************************************************/
putDeMonMoleculeInTextEditor()264 static void putDeMonMoleculeInTextEditor()
265 {
266 gchar buffer[BSIZE];
267 gint i;
268 gint nV = 0;
269 gdouble x,y,z;
270
271 if(demonMolecule.numberOfAtoms<1) return;
272
273 sprintf(buffer,"Multiplicity %d\n",spinMultiplicity);
274 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &demonColorFore.keyWord, &demonColorBack.keyWord, buffer, -1);
275 sprintf(buffer,"Charge %d\n",totalCharge);
276 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &demonColorFore.keyWord, &demonColorBack.keyWord, buffer, -1);
277
278 if(MethodeGeom==GEOM_IS_XYZ)
279 {
280 sprintf(buffer,"Geometry Cartesian\n");
281 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &demonColorFore.keyWord, &demonColorBack.keyWord, buffer, -1);
282 for (i=0;i<demonMolecule.numberOfAtoms;i++)
283 {
284 gchar X[100];
285 gchar Y[100];
286 gchar Z[100];
287 setXYZFromGeomXYZ(i, &x, &y, &z);
288 sprintf(X,"%f",x);
289 sprintf(Y,"%f",y);
290 sprintf(Z,"%f",z);
291 if(!strcmp(demonMolecule.listOfAtoms[i].symbol,"X")) sprintf(buffer," %s %s %s %s\n","X", X,Y,Z);
292 else sprintf(buffer," %s%d %s %s %s\n",demonMolecule.listOfAtoms[i].symbol,i+1, X,Y,Z);
293 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
294 }
295 nV = 0;
296 if(NVariablesXYZ>0)
297 for(i=0;i<NVariablesXYZ;i++)
298 {
299 if(VariablesXYZ[i].Used)
300 {
301 nV++;
302 }
303 }
304 if(nV>0 && nV!= 3*demonMolecule.numberOfAtoms)
305 {
306 sprintf(buffer,"Variables\n");
307 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &demonColorFore.keyWord, &demonColorBack.keyWord, buffer, -1);
308 for (i=0;i<demonMolecule.numberOfAtoms;i++)
309 {
310 if(!test(GeomXYZ[i].X))
311 {
312 sprintf(buffer," %s%d X\n",demonMolecule.listOfAtoms[i].symbol,i+1);
313 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
314 }
315 if(!test(GeomXYZ[i].Y))
316 {
317 sprintf(buffer," %s%d Y\n",demonMolecule.listOfAtoms[i].symbol,i+1);
318 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
319 }
320 if(!test(GeomXYZ[i].Z))
321 {
322 sprintf(buffer," %s%d Z\n",demonMolecule.listOfAtoms[i].symbol,i+1);
323 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL, buffer, -1);
324 }
325 }
326 }
327 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &demonColorFore.keyWord, &demonColorBack.keyWord,"# End geometry\n",-1);
328 }
329 else
330 {
331 sprintf(buffer,"Geometry Z-Matrix Angstrom\n");
332 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &demonColorFore.keyWord, &demonColorBack.keyWord, buffer, -1);
333 for(i=0;i<NcentersZmat;i++)
334 {
335 SAtomsProp prop = prop_atom_get(Geom[i].Symb);
336 gchar symb[100];
337 if(!strcmp(Geom[i].Symb,"X")) sprintf(symb,"%s","X");
338 else sprintf(symb,"%s",Geom[i].Symb);
339 if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE)
340 {
341 gchar R[100];
342 gchar A[100];
343 gchar D[100];
344 sprintf(R,"%s",Geom[i].R);
345 sprintf(A,"%s",Geom[i].Angle);
346 sprintf(D,"%s",Geom[i].Dihedral);
347 if(!test(Geom[i].Dihedral)) sprintf(D,"%f",get_value_variableZmat(Geom[i].Dihedral));
348
349 sprintf(buffer," %s %s %s %s %s %s %s\n",
350 symb,
351 Geom[i].NR, R,
352 Geom[i].NAngle, A,
353 Geom[i].NDihedral, D
354 );
355 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
356 }
357 else
358 if(Geom[i].Nentry>NUMBER_ENTRY_R)
359 {
360 gchar R[100];
361 gchar A[100];
362 sprintf(R,"%s",Geom[i].R);
363 sprintf(A,"%s",Geom[i].Angle);
364 sprintf(buffer," %s %s %s %s %s\n",
365 symb,
366 Geom[i].NR, R,
367 Geom[i].NAngle, A
368 );
369 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
370 }
371 else
372 if(Geom[i].Nentry>NUMBER_ENTRY_0)
373 {
374 gchar R[100];
375 sprintf(R,"%s",Geom[i].R);
376 sprintf(buffer," %s %s %s\n",
377 symb,
378 Geom[i].NR,R
379 );
380 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
381 }
382 else
383 {
384 sprintf(buffer," %s\n",
385 symb
386 );
387 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, &prop.color, buffer, -1);
388 }
389 }
390 nV = 0;
391 if(NVariables>0)
392 for(i=0;i<NVariables;i++)
393 {
394 if(Variables[i].Used)
395 {
396 nV++;
397 break;
398 }
399 }
400 if(nV>0)
401 {
402 sprintf(buffer,"Variables\n");
403 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,buffer,-1);
404 for (i=0;i<NcentersZmat;i++)
405 {
406 if(Geom[i].Nentry>=NUMBER_ENTRY_R && !test(Geom[i].R))
407 {
408 sprintf(buffer,"%s %0.14f\n",Geom[i].R, get_value_variableZmat(Geom[i].R));
409 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,buffer,-1);
410 }
411 if(Geom[i].Nentry>=NUMBER_ENTRY_ANGLE && !test(Geom[i].Angle))
412 {
413 sprintf(buffer,"%s %0.14f\n",Geom[i].Angle, get_value_variableZmat(Geom[i].Angle));
414 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,buffer,-1);
415 }
416 if(Geom[i].Nentry>NUMBER_ENTRY_ANGLE && !test(Geom[i].Dihedral))
417 {
418 sprintf(buffer,"%s %0.14f\n",Geom[i].Dihedral, get_value_variableZmat(Geom[i].Dihedral));
419 gabedit_text_insert (GABEDIT_TEXT(text), NULL, NULL, NULL,buffer,-1);
420 }
421 }
422 }
423 gabedit_text_insert (GABEDIT_TEXT(text), NULL, &demonColorFore.keyWord, &demonColorBack.keyWord,"# End geometry\n",-1);
424 }
425
426 }
427 /************************************************************************************************************/
putDeMonMoleculeInfoInTextEditor()428 void putDeMonMoleculeInfoInTextEditor()
429 {
430 putDeMonMoleculeInTextEditor();
431 }
432 /************************************************************************************************************/
433 /*
434 static GtkWidget* addRadioButtonToATable(GtkWidget* table, GtkWidget* friendButton, gchar* label, gint i, gint j, gint k)
435 {
436 GtkWidget *newButton;
437
438 if(friendButton)
439 newButton = gtk_radio_button_new_with_label( gtk_radio_button_get_group (GTK_RADIO_BUTTON (friendButton)), label);
440 else
441 newButton = gtk_radio_button_new_with_label( NULL, label);
442
443 gtk_table_attach(GTK_TABLE(table),newButton,j,j+k,i,i+1,
444 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
445 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
446 2,2);
447
448 g_object_set_data(G_OBJECT (newButton), "Label",NULL);
449 g_object_set_data(G_OBJECT (newButton), "Type",NULL);
450 return newButton;
451 }
452 */
453 /********************************************************************************/
setSpinMultiplicityComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity,gint spin)454 static void setSpinMultiplicityComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity, gint spin)
455 {
456 GtkWidget *entry = NULL;
457 gchar* t = NULL;
458 if(!comboSpinMultiplicity) return;
459 entry = GTK_BIN (comboSpinMultiplicity)->child;
460 t = g_strdup_printf("%d",spin);
461 gtk_entry_set_text(GTK_ENTRY(entry),t);
462 g_free(t);
463 }
464 /************************************************************************************************************/
setComboSpinMultiplicity(GtkWidget * comboSpinMultiplicity)465 static void setComboSpinMultiplicity(GtkWidget *comboSpinMultiplicity)
466 {
467 GList *glist = NULL;
468 gint i;
469 gint nlist = 0;
470 gchar** list = NULL;
471 gint k;
472 gint kinc;
473 gint ne = demonMolecule.numberOfValenceElectrons - totalCharge;
474
475 if(ne%2==0) nlist = ne/2+1;
476 else nlist = (ne+1)/2;
477
478 if(nlist<1) return;
479 list = g_malloc(nlist*sizeof(gchar*));
480 if(!list) return;
481 for(i=0;i<nlist;i++)
482 list[i] = g_malloc(10*sizeof(gchar));
483
484
485 if(GTK_IS_WIDGET(comboSpinMultiplicity)) gtk_widget_set_sensitive(comboSpinMultiplicity, TRUE);
486 if(ne%2==0) k = 1;
487 else k = 2;
488
489 kinc = 2;
490 for(i=0;i<nlist;i++)
491 {
492 sprintf(list[i],"%d",k);
493 k+=kinc;
494 }
495
496 for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
497
498 gtk_combo_box_entry_set_popdown_strings( comboSpinMultiplicity, glist) ;
499 g_list_free(glist);
500 if( SpinMultiplicities[0]%2 == atoi(list[0])%2) setSpinMultiplicityComboSpinMultiplicity(comboSpinMultiplicity, SpinMultiplicities[0]);
501 else SpinMultiplicities[0] = atoi(list[0]);
502 if(list)
503 {
504 for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
505 g_free(list);
506 }
507 }
508 /********************************************************************************/
setChargeComboCharge(GtkWidget * comboCharge,gint charge)509 static void setChargeComboCharge(GtkWidget *comboCharge, gint charge)
510 {
511 GtkWidget *entry = NULL;
512 gchar* t = NULL;
513 if(!comboCharge) return;
514 entry = GTK_BIN (comboCharge)->child;
515 t = g_strdup_printf("%d",charge);
516 gtk_entry_set_text(GTK_ENTRY(entry),t);
517 g_free(t);
518 }
519 /********************************************************************************/
setComboCharge(GtkWidget * comboCharge)520 static void setComboCharge(GtkWidget *comboCharge)
521 {
522 GList *glist = NULL;
523 gint i;
524 gint nlist;
525 gchar** list = NULL;
526 gint k;
527
528 nlist = demonMolecule.numberOfValenceElectrons*2-2+1;
529
530 if(nlist<1) return;
531 list = g_malloc(nlist*sizeof(gchar*));
532 if(!list) return;
533 for(i=0;i<nlist;i++)
534 list[i] = g_malloc(10*sizeof(gchar));
535
536
537 sprintf(list[0],"0");
538 k = 1;
539 for(i=1;i<nlist-1;i+=2)
540 {
541 sprintf(list[i],"+%d",k);
542 sprintf(list[i+1],"%d",-k);
543 k += 1;
544 }
545
546 for(i=0;i<nlist;i++) glist = g_list_append(glist,list[i]);
547
548 gtk_combo_box_entry_set_popdown_strings( comboCharge, glist) ;
549 g_list_free(glist);
550 if(list)
551 {
552 for(i=0;i<nlist;i++) if(list[i]) g_free(list[i]);
553 g_free(list);
554 }
555 setChargeComboCharge(comboCharge, totalCharge);
556 }
557 /**********************************************************************/
changedEntrySpinMultiplicity(GtkWidget * entry,gpointer data)558 static void changedEntrySpinMultiplicity(GtkWidget *entry, gpointer data)
559 {
560 G_CONST_RETURN gchar* entryText = NULL;
561
562 if(!GTK_IS_WIDGET(entry)) return;
563
564 entryText = gtk_entry_get_text(GTK_ENTRY(entry));
565 if(strlen(entryText)<1)return;
566
567 spinMultiplicity=atoi(entryText);
568 if(spinMultiplicity==1)
569 {
570 /* OK RHF*/
571 setDeMonSCFMethod(TRUE);
572 }
573 else
574 {
575 /* remove RHF from list*/
576 setDeMonSCFMethod(FALSE);
577 }
578 }
579 /**********************************************************************/
changedEntryCharge(GtkWidget * entry,gpointer data)580 static void changedEntryCharge(GtkWidget *entry, gpointer data)
581 {
582 G_CONST_RETURN gchar* entryText = NULL;
583 GtkWidget* comboSpinMultiplicity = NULL;
584 GtkWidget* labelNumberOfElectrons = NULL;
585
586 if(!GTK_IS_WIDGET(entry)) return;
587
588 entryText = gtk_entry_get_text(GTK_ENTRY(entry));
589 if(strlen(entryText)<1)return;
590
591 totalCharge = atoi(entryText);
592 TotalCharges[0] = totalCharge;
593
594 comboSpinMultiplicity = g_object_get_data(G_OBJECT (entry), "ComboSpinMultiplicity");
595 if(GTK_IS_WIDGET(comboSpinMultiplicity)) setComboSpinMultiplicity(comboSpinMultiplicity);
596
597 labelNumberOfElectrons = g_object_get_data(G_OBJECT (entry), "LabelNumberOfElectrons");
598
599 if(GTK_IS_WIDGET(labelNumberOfElectrons))
600 {
601 gint ne = demonMolecule.numberOfValenceElectrons - totalCharge;
602 gchar buffer[BSIZE];
603 sprintf(buffer, "Number of electrons = %d",ne);
604 gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
605 }
606 }
607 /**********************************************************************/
addComboListToATable(GtkWidget * table,gchar ** list,gint nlist,gint i,gint j,gint k)608 static GtkWidget* addComboListToATable(GtkWidget* table,
609 gchar** list, gint nlist, gint i, gint j, gint k)
610 {
611 GtkWidget *entry = NULL;
612 GtkWidget *combo = NULL;
613
614 combo = create_combo_box_entry(list, nlist, TRUE, -1, -1);
615
616 gtk_table_attach(GTK_TABLE(table),combo,j,j+k,i,i+1,
617 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
618 (GtkAttachOptions) (GTK_FILL | GTK_SHRINK),
619 2,2);
620 entry = GTK_BIN (combo)->child;
621 g_object_set_data(G_OBJECT (entry), "Combo",combo);
622 gtk_widget_set_size_request(GTK_WIDGET(entry),(gint)(ScreenHeight*0.2),-1);
623
624 return entry;
625 }
626 /***********************************************************************************************/
addDeMonChargeToTable(GtkWidget * table,gint i)627 static GtkWidget *addDeMonChargeToTable(GtkWidget *table, gint i)
628 {
629 GtkWidget* entryCharge = NULL;
630 GtkWidget* comboCharge = NULL;
631 gint nlistCharge = 1;
632 gchar* listCharge[] = {"0"};
633
634 add_label_table(table,_("Charge"),(gushort)i,0);
635 add_label_table(table,":",(gushort)i,1);
636 entryCharge = addComboListToATable(table, listCharge, nlistCharge, i, 2, 1);
637 comboCharge = g_object_get_data(G_OBJECT (entryCharge), "Combo");
638 gtk_widget_set_sensitive(entryCharge, TRUE);
639 gtk_editable_set_editable(GTK_EDITABLE(entryCharge), FALSE);
640
641 return comboCharge;
642 }
643 /***********************************************************************************************/
addDeMonSpinToTable(GtkWidget * table,gint i)644 static GtkWidget *addDeMonSpinToTable(GtkWidget *table, gint i)
645 {
646 GtkWidget* entrySpinMultiplicity = NULL;
647 GtkWidget* comboSpinMultiplicity = NULL;
648 gint nlistspinMultiplicity = 1;
649 gchar* listspinMultiplicity[] = {"0"};
650
651 add_label_table(table,_("Spin multiplicity"),(gushort)i,0);
652 add_label_table(table,":",(gushort)i,1);
653 entrySpinMultiplicity = addComboListToATable(table, listspinMultiplicity, nlistspinMultiplicity, i, 2, 1);
654 comboSpinMultiplicity = g_object_get_data(G_OBJECT (entrySpinMultiplicity), "Combo");
655 gtk_widget_set_sensitive(entrySpinMultiplicity, TRUE);
656 gtk_editable_set_editable(GTK_EDITABLE(entrySpinMultiplicity), FALSE);
657
658 g_signal_connect(G_OBJECT(entrySpinMultiplicity),"changed", G_CALLBACK(changedEntrySpinMultiplicity),NULL);
659 return comboSpinMultiplicity;
660 }
661 /***********************************************************************************************/
addLabelNumberOfElectronsToTable(GtkWidget * table,gint i,GtkWidget * comboCharge)662 static GtkWidget *addLabelNumberOfElectronsToTable(GtkWidget *table, gint i, GtkWidget *comboCharge)
663 {
664 GtkWidget* labelNumberOfElectrons = NULL;
665 GtkWidget* hbox = NULL;
666 GtkWidget* entryCharge = GTK_BIN(comboCharge)->child;
667
668 labelNumberOfElectrons = gtk_label_new(" ");
669 hbox = gtk_hbox_new(0,FALSE);
670 gtk_box_pack_start (GTK_BOX (hbox), labelNumberOfElectrons, FALSE, FALSE, 0);
671 gtk_table_attach(GTK_TABLE(table),hbox,0,0+3,i,i+1,
672 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
673 (GtkAttachOptions) (GTK_FILL | GTK_SHRINK),
674 2,2);
675
676 g_object_set_data(G_OBJECT (entryCharge), "LabelNumberOfElectrons", labelNumberOfElectrons);
677 g_signal_connect(G_OBJECT(entryCharge),"changed", G_CALLBACK(changedEntryCharge),NULL);
678 return labelNumberOfElectrons;
679 }
680 /***********************************************************************************************/
createDeMonChargeMultiplicityFrame(GtkWidget * box)681 void createDeMonChargeMultiplicityFrame(GtkWidget *box)
682 {
683 GtkWidget* frame;
684 GtkWidget* sep;
685 GtkWidget* labelNumberOfElectrons;
686 GtkWidget* vboxFrame;
687 GtkWidget* comboSpinMultiplicity = NULL;
688 GtkWidget* comboCharge = NULL;
689 GtkWidget *table = NULL;
690 gint i;
691
692 totalCharge = TotalCharges[0];
693 spinMultiplicity=SpinMultiplicities[0];
694
695 table = gtk_table_new(3,5,FALSE);
696
697 frame = gtk_frame_new (_("Charge & Multiplicty"));
698 gtk_widget_show (frame);
699 gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 3);
700 gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5);
701
702 vboxFrame = gtk_vbox_new (FALSE, 3);
703 gtk_widget_show (vboxFrame);
704 gtk_container_add (GTK_CONTAINER (frame), vboxFrame);
705
706 gtk_box_pack_start (GTK_BOX (vboxFrame), table, TRUE, TRUE, 0);
707
708 i = 0;
709 comboCharge = addDeMonChargeToTable(table, i);
710 i = 1;
711 comboSpinMultiplicity = addDeMonSpinToTable(table, i);
712 i = 2;
713 sep = gtk_hseparator_new ();;
714 gtk_table_attach(GTK_TABLE(table),sep,0,0+3,i,i+1,
715 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
716 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
717 2,2);
718
719 i = 3;
720 labelNumberOfElectrons=addLabelNumberOfElectronsToTable(table, i, comboCharge);
721
722 if(GTK_IS_COMBO_BOX(comboCharge))
723 g_object_set_data(G_OBJECT (GTK_BIN(comboCharge)->child), "ComboSpinMultiplicity", comboSpinMultiplicity);
724 setComboCharge(comboCharge);
725 setComboSpinMultiplicity(comboSpinMultiplicity);
726 if(GTK_IS_WIDGET(labelNumberOfElectrons))
727 {
728 gint ne = demonMolecule.numberOfValenceElectrons - totalCharge;
729 gchar buffer[BSIZE];
730 sprintf(buffer, "Number of electrons = %d",ne);
731 gtk_label_set_text(GTK_LABEL(labelNumberOfElectrons),buffer);
732 }
733
734 /* activate sensitivity */
735 /*
736 if(GTK_IS_WIDGET(comboMethod)) setComboMethod(comboMethod);
737 g_object_set_data(G_OBJECT (box), "EntryMethod", GTK_BIN(comboMethod)->child);
738 */
739 }
740 /************************************************************************************************************/
741