// src/configure_policy_dialog.cc - Copyright 2005, 2006, University // of Padova, dept. of Pure and Applied // Mathematics // // This file is part of SGPEMv2. // // This 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. // // SGPEMv2 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 SGPEMv2; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "gettext.h" #include "sequences.tcc" #include "configure_policy_dialog.hh" #include #include #include #include #include #include #include #include #include using namespace sgpem; using namespace Gtk; // WARNING: Note that we make strong assumptions on the number of columns // of the table. If you change it, you've to edit all the other methods // to reflect it, expecially "on_okay()" ConfigurePolicyDialog::ConfigurePolicyDialog(const Glib::ustring title, PolicyParameters& parameters) : Gtk::Dialog(title, true, true), _parameters(parameters), _table_int(NULL), _table_float(NULL), _table_string(NULL) { typedef std::map > IntParams; typedef std::map > FloatParams; typedef std::map > StringParams; VBox& main_vbox = *get_vbox(); guint row_n; // Integer parameters const IntParams intpars = _parameters.get_registered_int_parameters(); if(!intpars.empty()) { Frame& intframe = *manage(create_category(_("Integer values"))); main_vbox.pack_end(intframe); _table_int = manage(new Table(intpars.size(), 2)); _table_int->set_row_spacings(2); _table_int->set_col_spacings(2); _table_int->set_border_width(3); intframe.add(*_table_int); row_n = 0; for(Iseq it = const_iseq(intpars); it; ++it, ++row_n) parameter_int(it->second, row_n); } // Float parameters const FloatParams floatpars = _parameters.get_registered_float_parameters(); if(!floatpars.empty()) { Frame& floatframe = *manage(create_category(_("Floating point values"))); main_vbox.pack_end(floatframe); _table_float = manage(new Table(floatpars.size(), 2)); _table_float->set_row_spacings(2); _table_float->set_col_spacings(2); _table_float->set_border_width(3); floatframe.add(*_table_float); row_n = 0; for(Iseq it = const_iseq(floatpars); it; ++it, ++row_n) parameter_float(it->second, row_n); } // String parameters const StringParams stringpars = _parameters.get_registered_string_parameters(); if(!stringpars.empty()) { Frame& stringframe = *manage(create_category(_("Alphanumerical values"))); main_vbox.pack_end(stringframe); _table_string = manage(new Table(stringpars.size(), 2)); _table_string->set_row_spacings(2); _table_string->set_col_spacings(2); _table_string->set_border_width(3); stringframe.add(*_table_string); row_n = 0; for(Iseq it = const_iseq(stringpars); it; ++it, ++row_n) parameter_string(it->second, row_n); } if(_table_int == NULL && _table_float == NULL && _table_string == NULL) { Label& message = *manage(new Label(_("No options to configure for this policy"))); main_vbox.pack_end(message); } // Add final buttons, and we're done. add_button(Stock::CANCEL, RESPONSE_CANCEL); HButtonBox& bbox = *get_action_area(); Button& okay_bt = *manage(new Button(Stock::OK)); okay_bt.set_flags(CAN_DEFAULT); set_default(okay_bt); bbox.pack_end(okay_bt); okay_bt.signal_clicked().connect(sigc::mem_fun(*this, &ConfigurePolicyDialog::on_okay)); main_vbox.show_all(); } Gtk::Frame* ConfigurePolicyDialog::create_category(const Glib::ustring& type_name) const { Frame& frame = *new Frame("" + type_name + ""); frame.set_border_width(3); static_cast(frame.get_label_widget())->set_use_markup(true); return &frame; } void ConfigurePolicyDialog::parameter_int(const PolicyParameters::Parameter& param, guint row) { Label& desc = *manage(new Label(param.get_name(), ALIGN_LEFT)); _table_int->attach(desc, 0, 1, row, row + 1); Adjustment& adj = *manage(new Adjustment(param.get_value(), param.get_lower_bound(), param.get_upper_bound())); SpinButton& spin = *manage(new SpinButton(adj)); _table_int->attach(spin, 1, 2, row, row + 1); } void ConfigurePolicyDialog::parameter_float(const PolicyParameters::Parameter& param, guint row) { Label& desc = *manage(new Label(param.get_name(), ALIGN_LEFT)); _table_float->attach(desc, 0, 1, row, row + 1); Adjustment& adj = *manage(new Adjustment(param.get_value(), param.get_lower_bound(), param.get_upper_bound())); SpinButton& spin = *manage(new SpinButton(adj, 0, 3)); _table_float->attach(spin, 1, 2, row, row + 1); } void ConfigurePolicyDialog::parameter_string(const PolicyParameters::Parameter& param, guint row) { Label& desc = *manage(new Label(param.get_name(), ALIGN_LEFT)); _table_string->attach(desc, 0, 1, row, row + 1); Entry& entry = *manage(new Entry()); entry.set_text(param.get_value()); _table_string->attach(entry, 1, 2, row, row + 1); } void ConfigurePolicyDialog::on_okay() { // Save all values if(_table_int != NULL) { const Table::TableList list = _table_int->children(); // (cannot) fixme: Using a reverse iterator makes me feel REALLY uneasy... // what if the implementation changes between different gtk+ versions? for(Iseq it = const_riseq(list); it; ++it) { Widget* w; w = it->get_widget(); // First column assert(dynamic_cast(w) != NULL); Glib::ustring name = static_cast(w)->get_text(); w = (++it)->get_widget(); // Pass to the second column assert(dynamic_cast(w) != NULL); int value = static_cast(w)->get_value_as_int(); _parameters.set_int(name, value); } } //~ if _table_int if(_table_float != NULL) { const Table::TableList list = _table_float->children(); // (cannot) fixme: Using a reverse iterator makes me feel REALLY uneasy... // what if the implementation changes between different gtk+ versions? for(Iseq it = const_riseq(list); it; ++it) { Widget* w; w = it->get_widget(); // First column assert(dynamic_cast(w) != NULL); Glib::ustring name = static_cast(w)->get_text(); w = (++it)->get_widget(); // Pass to the second column assert(dynamic_cast(w) != NULL); double value = static_cast(w)->get_value(); _parameters.set_float(name, static_cast(value)); } } //~ if _table_float if(_table_string != NULL) { const Table::TableList list = _table_string->children(); // (cannot) fixme: Using a reverse iterator makes me feel REALLY uneasy... // what if the implementation changes between different gtk+ versions? for(Iseq it = const_riseq(list); it; ++it) { Widget* w; w = it->get_widget(); // First column assert(dynamic_cast(w) != NULL); Glib::ustring name = static_cast(w)->get_text(); w = (++it)->get_widget(); // Pass to the second column assert(dynamic_cast(w) != NULL); Glib::ustring value = static_cast(w)->get_text(); _parameters.set_string(name, value); } } //~ if _table_string // We're done. response(RESPONSE_OK); }