// src/resources_widget.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 "resources_widget.hh" #include #include #include #include #include #include #include #include #include #include #include #include "gettext.h" #include #include #include using namespace sgpem; using namespace Gtk; using namespace Glib; using Gnome::Glade::Xml; PropertyProxy_Base ResourcesWidget::CellRendererTextMarkup::_property_renderable() { return Glib::PropertyProxy_Base(this, "markup"); } ResourcesWidget::ResourcesWidget(BaseObjectType* cobject, const RefPtr& glade) : TreeView(cobject), _add_resource_dialog_glade(Xml::create(GLADEDIR "/add-resource-dialog.glade")) { _columns.add(_key_column); _columns.add(_main_column); _columns.add(_handles_column); _model = ListStore::create(_columns); set_model(_model); int idx = append_column(_("resources"), _cell_renderer) - 1; Gtk::TreeViewColumn* tvc = get_column(idx); tvc->set_cell_data_func(_cell_renderer, sigc::mem_fun(*this, &ResourcesWidget::_on_cell_name_data)); /** DIALOGS **/ _add_resource_dialog_glade->get_widget("AddResourceDialog", _add_resource_dialog); set_headers_visible(false); Simulation::get_instance().get_history().attach(*this); } ResourcesWidget::~ResourcesWidget() { Simulation::get_instance().get_history().detach(*this); } bool ResourcesWidget::get_selected_key(unsigned int& selection) { TreeModel::iterator it = get_selection()->get_selected(); if(it) { selection = (*it)[_key_column]; return true; } else return false; } Resource* ResourcesWidget::get_selected_resource() { TreeModel::iterator it = get_selection()->get_selected(); if(it) { const void* r_handle = (*it)[_handles_column]; return reinterpret_cast(const_cast(r_handle)); } else return NULL; } bool ResourcesWidget::on_button_press_event(GdkEventButton* event) { TreeView::on_button_press_event(event); if((Simulation::get_instance().get_state() == Simulation::state_stopped) && (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { RefPtr action_group = Gtk::ActionGroup::create(); action_group->add( Gtk::Action::create("AddResource", "Add Resource"), sigc::mem_fun(*this, &ResourcesWidget::_on_add_resource) ); action_group->add( Gtk::Action::create("EditResource", "Edit Resource"), sigc::mem_fun(*this, &ResourcesWidget::_on_edit_resource) ); action_group->add( Gtk::Action::create("RemoveResource", "Remove Resource"), sigc::mem_fun(*this, &ResourcesWidget::_on_remove_resource) ); RefPtr UIManager = Gtk::UIManager::create(); UIManager->insert_action_group(action_group); Glib::ustring ui_info = "" " " " "; if(get_selected_resource() != NULL) ui_info += " " " " " " " "; ui_info += " " ""; UIManager->add_ui_from_string(ui_info); Gtk::Menu* menu = dynamic_cast(UIManager->get_widget("/PopupMenu")); menu->popup(event->button, event->time); return true; //It has been handled. } else return false; } void ResourcesWidget::update(const History& history) { typedef Environment::Resources::const_iterator ResourceIt; const Environment::Resources& resources = history.get_last_environment().get_resources(); _model->clear(); for(Iseq it = iseq(resources); it; ++it) { Resource& r = *(it->second); TreeModel::Row row = *(_model->append()); row[_key_column] = it->first; row[_main_column] = r.get_name(); row[_handles_column] = &r; } } void ResourcesWidget::_on_add_resource() { add_edit_resource(true); } void ResourcesWidget::_on_edit_resource() { add_edit_resource(false); } void ResourcesWidget::add_edit_resource(bool adding) { Entry* name_entry; SpinButton* places_spin; Resource* resource = NULL; _add_resource_dialog_glade->get_widget("Name.Entry", name_entry); _add_resource_dialog_glade->get_widget("Places.Spin", places_spin); if(adding) { name_entry->set_text(""); places_spin->set_value(1.0); } else { resource = get_selected_resource(); name_entry->set_text(resource->get_name()); places_spin->set_value(static_cast(resource->get_places())); } if(_add_resource_dialog->run() == RESPONSE_OK) { if(adding) { Simulation::get_instance().get_history().add_resource(name_entry->get_text(), false, places_spin->get_value_as_int()); } else { Simulation::get_instance().get_history().edit_resource(*resource, name_entry->get_text(), false, places_spin->get_value_as_int()); } } _add_resource_dialog->hide(); } void ResourcesWidget::_on_remove_resource() { unsigned int selection; if(get_selected_key(selection)) Simulation::get_instance().get_history().remove(selection); /** Delete empty requests, they are useless with the current GUI **/ typedef Environment::Processes::const_iterator ProcessIt; using std::vector; const Environment& env = Simulation::get_instance().get_history().get_last_environment(); const Environment::Processes& processes = env.get_processes(); std::stack to_delete; for(ProcessIt pit = processes.begin(); pit != processes.end(); ++pit) { vector threads = (*pit)->get_threads(); for(vector::iterator tit = threads.begin(); tit != threads.end(); ++tit) { vector requests = (*tit)->get_requests(); for(vector::iterator rit = requests.begin(); rit != requests.end(); ++rit) { if((*rit)->get_subrequests().empty()) to_delete.push(*rit); } } } while(!to_delete.empty()) { Simulation::get_instance().get_history().remove(*to_delete.top()); to_delete.pop(); } } void ResourcesWidget::_on_cell_name_data(Gtk::CellRenderer* cr, const Gtk::TreeModel::iterator& it) { CellRendererTextMarkup& crtm = static_cast(*cr); unsigned int key = (*it)[_key_column]; Simulation& sim = Simulation::get_instance(); const Environment& env = sim.get_history().get_last_environment(); const void* r_handle = (*it)[_handles_column]; Resource& resource = *reinterpret_cast(const_cast(r_handle)); std::ostringstream oss; const Environment::SubRequestQueue& queue = env.get_request_queue(key); oss << "" << Markup::escape_text(resource.get_name()) << ""; oss << " (" << queue.size() << "/" << resource.get_places() << ")\n"; for(Iseq it = iseq(queue); it; ++it) { SubRequest& sr = *(*it); oss << " " << sr.get_request().get_thread().get_name() << "" << " (" << (sr.get_length() - sr.get_remaining_time()) << "/" << sr.get_length() << ")"; } oss << ""; crtm.property_markup() = oss.str(); }