// -*- C++ -*- /* * Gnome Chemistry Utils * programs/gchemtable-elt.cc * * Copyright (C) 2005-2007 Jean Bréfort * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include "config.h" #include "gchemtable-elt.h" #include "gchemtable-app.h" #include #include #include #include extern void on_show_curve (GObject *obj, char const* name); static void on_focus_in (GChemTableElt *dlg) { dlg->OnFocusIn (); } GChemTableElt::GChemTableElt (GChemTableApp *App, int Z): Dialog (App, GLADEDIR"/eltpage.glade", "eltdlg") { Element *elt = Element::GetElement (Z); m_Z = Z; char *buf; gtk_window_set_title (dialog, elt->GetName ()); g_signal_connect_swapped (G_OBJECT (dialog), "focus-in-event", G_CALLBACK (on_focus_in), this); GtkWidget *w = glade_xml_get_widget (xml, "symbol"); buf = g_strconcat ("", elt->GetSymbol (), "", NULL); gtk_label_set_markup (GTK_LABEL (w), buf); g_free (buf); buf = g_strdup_printf ("%d", Z); w = glade_xml_get_widget (xml, "z"); gtk_label_set_text (GTK_LABEL (w), buf); g_free (buf); int prec; double weight = elt->GetWeight (prec); char *format = (prec > 0)? g_strdup_printf ("%%0.%df",prec): g_strdup ("(%.0f)"); buf = g_strdup_printf (format, weight); w = glade_xml_get_widget (xml, "weight"); gtk_label_set_text (GTK_LABEL (w), buf); g_free (format); g_free (buf); w = glade_xml_get_widget (xml, "elec-conf-lbl"); /* The markup at the end of the chain is there to ensure that things will be correcly aligned, add the same to the translated string */ gtk_label_set_markup (GTK_LABEL (w), _("Electronic configuration: ")); w = glade_xml_get_widget (xml, "elec-conf"); gtk_label_set_markup (GTK_LABEL (w), elt->GetElectronicConfiguration ().c_str ()); //Add composition list GtkListStore *pclist = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); GtkTreeView *tree = GTK_TREE_VIEW (glade_xml_get_widget (xml, "names")); gtk_tree_view_set_model (tree, GTK_TREE_MODEL (pclist)); g_object_unref (pclist); GtkCellRenderer *renderer; GtkTreeViewColumn *column; /* column for element */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Lang"), renderer, "text", 0, NULL); /* set this column to a minimum sizing (of 100 pixels) */ gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_GROW_ONLY); gtk_tree_view_column_set_min_width(GTK_TREE_VIEW_COLUMN (column), 100); gtk_tree_view_append_column (tree, column); /* column for x */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, "text", 1, NULL); g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL); /* set this column to a fixed sizing (of 100 pixels) */ gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 100); gtk_tree_view_append_column (tree, column); map Names = elt->GetNames (); map::iterator i, end = Names.end (); GtkTreeIter iter; for (i = Names.begin (); i != end; i++) { gtk_list_store_append (pclist, &iter); gtk_list_store_set (pclist, &iter, 0, (*i).first.c_str (), 1, (*i).second.c_str (), -1); } // electronic properties page w = glade_xml_get_widget (xml, "pauling-en"); GcuElectronegativity en; en.scale = "Pauling"; en.Z = elt->GetZ (); if (elt->GetElectronegativity (&en)) { buf = gcu_value_get_string (&en.value); gtk_label_set_text (GTK_LABEL (w), buf); g_free (buf); } else gtk_label_set_text (GTK_LABEL (w), _("n.a.")); w = glade_xml_get_widget (xml, "pauling-btn"); g_object_set_data (G_OBJECT (w), "app", App); g_signal_connect (G_OBJECT (w), "clicked", G_CALLBACK (on_show_curve), (void*) "en/Pauling"); // ionization energies int n = 1; GcuDimensionalValue const *value; GtkWidget *val, *button; GtkTable *table = GTK_TABLE (glade_xml_get_widget (xml, "ei-table")); while ((value = elt->GetIonizationEnergy (n))) { if (n > 1) { gtk_table_resize (table, 4, n); buf = g_strdup_printf (_("%d:"), n); w = gtk_label_new (buf); gtk_misc_set_padding (GTK_MISC (w), 8, 0); g_free (buf); gtk_table_attach (table, w, 0, 1, n - 1, n, (GtkAttachOptions) (GTK_SHRINK | GTK_FILL), (GtkAttachOptions) 0 , 0, 0); val = gtk_label_new (""); gtk_misc_set_alignment (GTK_MISC (val), 0., 0.); gtk_table_attach (table, val, 1, 2, n - 1, n, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) 0 , 0, 0); button = gtk_button_new_with_label (_("Show curve")); gtk_table_attach (table, button, 2, 3, n - 1, n, (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0 , 0, 0); } else { val = glade_xml_get_widget (xml, "ei-value"); button = glade_xml_get_widget (xml, "ei-btn"); } buf = gcu_dimensional_value_get_string (value); gtk_label_set_markup (GTK_LABEL (val), buf); g_free (buf); buf = g_strdup_printf ("ei/%d", n); g_object_set_data (G_OBJECT (button), "app", App); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_show_curve), (void*) buf); n++; } gtk_widget_show_all (GTK_WIDGET (table)); if (n == 1) { w = glade_xml_get_widget (xml, "ei-lbl"); gtk_label_set_text (GTK_LABEL (w), _("n.a.")); w = glade_xml_get_widget (xml, "ei-btn"); gtk_widget_hide (w); } // electronic affinities n = 1; table = GTK_TABLE (glade_xml_get_widget (xml, "ae-table")); while ((value = elt->GetElectronAffinity (n))) { if (n > 1) { gtk_table_resize (table, 4, n); buf = g_strdup_printf (_("%d:"), n); w = gtk_label_new (buf); gtk_misc_set_alignment (GTK_MISC (w), 0., 0.); g_free (buf); gtk_table_attach (table, w, 0, 1, n - 1, n, (GtkAttachOptions) (GTK_SHRINK | GTK_FILL), (GtkAttachOptions) 0 , 0, 0); val = gtk_label_new (""); gtk_table_attach (table, val, 1, 2, n - 1, n, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) 0 , 0, 0); button = NULL; // not enough values to draw a curve. } else { val = glade_xml_get_widget (xml, "ae-value"); button = glade_xml_get_widget (xml, "ae-btn"); g_object_set_data (G_OBJECT (button), "app", App); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_show_curve), (void*) "ae"); } buf = gcu_dimensional_value_get_string (value); gtk_label_set_markup (GTK_LABEL (val), buf); g_free (buf); n++; } gtk_widget_show_all (GTK_WIDGET (table)); if (n == 1) { w = glade_xml_get_widget (xml, "ae-lbl"); gtk_label_set_text (GTK_LABEL (w), _("n.a.")); w = glade_xml_get_widget (xml, "ae-btn"); gtk_widget_hide (w); } // Radii page // First covalent radius GcuAtomicRadius r; r.Z = Z; r.type = GCU_COVALENT; r.charge = 0; r.scale = NULL; r.cn = -1; r.spin = GCU_N_A_SPIN; button = glade_xml_get_widget (xml, "covalent-btn"); if (elt->GetRadius (&r)) { buf = gcu_dimensional_value_get_string (&r.value); w = glade_xml_get_widget (xml, "covalent-radius"); gtk_label_set_text (GTK_LABEL (w), buf); g_free (buf); g_object_set_data (G_OBJECT (button), "app", App); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_show_curve), (void*) "covalent"); } else { w = glade_xml_get_widget (xml, "covalent-radius"); gtk_label_set_text (GTK_LABEL (w), _("n.a.")); gtk_widget_hide (button); } r.type = GCU_VAN_DER_WAALS; button = glade_xml_get_widget (xml, "vdw-btn"); if (elt->GetRadius (&r)) { buf = gcu_dimensional_value_get_string (&r.value); w = glade_xml_get_widget (xml, "vdw-radius"); gtk_label_set_text (GTK_LABEL (w), buf); g_free (buf); g_object_set_data (G_OBJECT (button), "app", App); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_show_curve), (void*) "vdw"); } else { w = glade_xml_get_widget (xml, "vdw-radius"); gtk_label_set_text (GTK_LABEL (w), _("n.a.")); gtk_widget_hide (button); } r.type = GCU_METALLIC; button = glade_xml_get_widget (xml, "metallic-btn"); if (elt->GetRadius (&r)) { buf = gcu_dimensional_value_get_string (&r.value); w = glade_xml_get_widget (xml, "metallic-radius"); gtk_label_set_text (GTK_LABEL (w), buf); g_free (buf); g_object_set_data (G_OBJECT (button), "app", App); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_show_curve), (void*) "metallic"); } else { w = glade_xml_get_widget (xml, "metallic-radius"); gtk_label_set_text (GTK_LABEL (w), _("n.a.")); gtk_widget_hide (button); } GcuAtomicRadius const **radii = elt->GetRadii (); list radii_list; list ::iterator j, jend; int maxspin = 0; if (radii) while (*radii) { if (((*radii)->type == GCU_IONIC) && !strcmp ((*radii)->scale, "Shannon")) { j = radii_list.begin (); jend = radii_list.end (); while ((j != jend) && (((*j)->charge < (*radii)->charge) || (((*j)->charge == (*radii)->charge) && ((*j)->cn < (*radii)->cn) || (((*j)->cn == (*radii)->cn) && ((*j)->spin < (*radii)->spin))))) j++; radii_list.insert (j, *radii); if ((*radii)->spin > maxspin) maxspin = (*radii)->spin; } radii++; } if (radii_list.size () == 0) { w = gtk_label_new (_("n.a.")); gtk_widget_show (w); gtk_box_pack_start (GTK_BOX (glade_xml_get_widget (xml, "ionic-radii")), w, FALSE, FALSE, 0); gtk_widget_hide (glade_xml_get_widget (xml, "radii-scrolled")); } else { pclist = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); tree = GTK_TREE_VIEW (glade_xml_get_widget (xml, "radii-list")); gtk_tree_view_set_model (tree, GTK_TREE_MODEL (pclist)); g_object_unref (pclist); /* column for element */ renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Ion"), renderer, "markup", 0, NULL); /* set this column to a minimum sizing (of 80 pixels) */ gtk_tree_view_column_set_spacing (column, 5); gtk_tree_view_append_column (tree, column); /* column for x */ renderer = gtk_cell_renderer_text_new (); /* C.N. stands for coordination number */ column = gtk_tree_view_column_new_with_attributes (_("C.N."), renderer, "text", 1, NULL); g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL); /* set this column to a fixed sizing (of 50 pixels) */ gtk_tree_view_column_set_spacing (column, 5); gtk_tree_view_append_column (tree, column); column = gtk_tree_view_column_new_with_attributes (_("Spin"), renderer, "text", 2, NULL); if (maxspin == 0) g_object_set (G_OBJECT (column), "visible", false, NULL); g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL); /* set this column to a fixed sizing (of 50 pixels) */ gtk_tree_view_column_set_spacing (column, 5); gtk_tree_view_append_column (tree, column); column = gtk_tree_view_column_new_with_attributes (_("Value"), renderer, "text", 3, NULL); g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL); /* set this column to a fixed sizing (of 50 pixels) */ gtk_tree_view_column_set_spacing (column, 5); gtk_tree_view_append_column (tree, column); jend = radii_list.end (); char *ion, *cn, *spin; for (j = radii_list.begin (); j != jend; j++) { if ((*j)->charge > 1) ion = g_strdup_printf ("%s%d+ ",elt->GetSymbol (),(*j)->charge); else if ((*j)->charge < -1) ion = g_strdup_printf ("%s%d\xE2\x88\x92 ",elt->GetSymbol (),-(*j)->charge); else if ((*j)->charge == 1) ion = g_strdup_printf ("%s+ ",elt->GetSymbol ()); else ion = g_strdup_printf ("%s\xE2\x88\x92 ",elt->GetSymbol ()); cn = g_strdup_printf ("%d", (*j)->cn); switch ((*j)->spin) { case GCU_LOW_SPIN: spin = _("Low"); break; case GCU_HIGH_SPIN: spin = _("High"); break; default: spin = (char*) ""; break; } buf = gcu_dimensional_value_get_string (&(*j)->value); gtk_list_store_append (pclist, &iter); gtk_list_store_set (pclist, &iter, 0, ion, 1, cn, 2, spin, 3, buf, -1); g_free (ion); g_free (cn); g_free (buf); } } Value const *prop = elt->GetProperty ("meltingpoint"); button = glade_xml_get_widget (xml, "melting-btn"); if (prop) { w = glade_xml_get_widget (xml, "melting"); gtk_label_set_text (GTK_LABEL (w), prop->GetAsString ()); g_object_set_data (G_OBJECT (button), "app", App); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_show_curve), (void*) "mp"); } else gtk_widget_hide (w); prop = elt->GetProperty ("boilingpoint"); button = glade_xml_get_widget (xml, "boiling-btn"); if (prop) { w = glade_xml_get_widget (xml, "boiling"); gtk_label_set_text (GTK_LABEL (w), prop->GetAsString ()); g_object_set_data (G_OBJECT (button), "app", App); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_show_curve), (void*) "bp"); } else gtk_widget_hide (button); } GChemTableElt::~GChemTableElt () { reinterpret_cast (m_App)->ClearPage (m_Z); } void GChemTableElt::OnFocusIn () { reinterpret_cast (m_App)->SetCurZ (m_Z); }