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