2006-09-02 13:31:01 +02:00
|
|
|
// src/gui_builder.cc - Copyright 2005, 2006, University
|
2006-01-26 19:31:23 +01:00
|
|
|
// 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
|
|
|
|
|
2006-09-16 15:34:43 +02:00
|
|
|
|
2006-01-26 19:31:23 +01:00
|
|
|
#include "gettext.h"
|
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
#include "gui_builder.hh"
|
2006-09-02 13:31:01 +02:00
|
|
|
|
|
|
|
#include "configure_policy_dialog.hh"
|
2006-08-31 01:37:11 +02:00
|
|
|
#include "graphical_preferences_editor.hh"
|
2006-09-06 01:54:16 +02:00
|
|
|
#include "holt_container_window.hh"
|
2006-09-02 16:48:03 +02:00
|
|
|
#include "holt_widget.hh"
|
2006-09-06 16:51:53 +02:00
|
|
|
#include "ready_queue_widget.hh"
|
2006-08-12 17:49:37 +02:00
|
|
|
#include "schedulables_tree_widget.hh"
|
2006-09-14 12:58:54 +02:00
|
|
|
#include "schedulables_statistics_widget.hh"
|
2006-08-12 17:49:37 +02:00
|
|
|
#include "simulation_widget.hh"
|
2006-08-21 02:12:56 +02:00
|
|
|
#include "resources_widget.hh"
|
2006-09-07 04:08:00 +02:00
|
|
|
#include "jump_to_dialog.hh"
|
2006-08-11 02:45:41 +02:00
|
|
|
|
2006-09-07 02:43:00 +02:00
|
|
|
#include <sgpemv2/templates/sequences.tcc>
|
2006-09-01 15:17:53 +02:00
|
|
|
|
2006-09-07 02:43:00 +02:00
|
|
|
#include <sgpemv2/cpu_policy_exception.hh>
|
|
|
|
#include <sgpemv2/null_policy_exception.hh>
|
|
|
|
#include <sgpemv2/cpu_policies_gatekeeper.hh>
|
|
|
|
#include <sgpemv2/cpu_policy_manager.hh>
|
|
|
|
#include <sgpemv2/resource_policies_gatekeeper.hh>
|
|
|
|
#include <sgpemv2/resource_policy_manager.hh>
|
|
|
|
#include <sgpemv2/history.hh>
|
|
|
|
#include <sgpemv2/policy_parameters.hh>
|
|
|
|
#include <sgpemv2/simulation.hh>
|
|
|
|
#include <sgpemv2/serializers_gatekeeper.hh>
|
|
|
|
#include <sgpemv2/serializer.hh>
|
2006-08-18 09:27:00 +02:00
|
|
|
|
2006-08-21 00:15:02 +02:00
|
|
|
#include <gdkmm/pixbuf.h>
|
2006-08-30 17:53:26 +02:00
|
|
|
#include <glibmm/markup.h>
|
2006-07-05 17:16:58 +02:00
|
|
|
#include <glibmm/ustring.h>
|
|
|
|
#include <gtkmm/aboutdialog.h>
|
2006-09-12 22:15:55 +02:00
|
|
|
#include <gtkmm/button.h>
|
2006-08-18 09:27:00 +02:00
|
|
|
#include <gtkmm/messagedialog.h>
|
2006-08-31 01:37:11 +02:00
|
|
|
#include <gtkmm/menutoolbutton.h>
|
2006-08-18 09:27:00 +02:00
|
|
|
#include <gtkmm/filechooserdialog.h>
|
2006-01-26 19:31:23 +01:00
|
|
|
#include <gtkmm/main.h>
|
2006-09-02 13:31:01 +02:00
|
|
|
#include <gtkmm/menuitem.h>
|
2006-09-02 13:12:23 +02:00
|
|
|
#include <gtkmm/checkmenuitem.h>
|
2006-09-01 15:17:53 +02:00
|
|
|
#include <gtkmm/radiomenuitem.h>
|
|
|
|
#include <gtkmm/radiobuttongroup.h>
|
2006-08-12 17:49:37 +02:00
|
|
|
#include <gtkmm/scrolledwindow.h>
|
2006-09-12 22:15:55 +02:00
|
|
|
#include <gtkmm/spinbutton.h>
|
2006-08-28 23:48:55 +02:00
|
|
|
#include <gtkmm/statusbar.h>
|
2006-08-18 09:27:00 +02:00
|
|
|
#include <gtkmm/stock.h>
|
2006-09-14 12:58:54 +02:00
|
|
|
#include <gtkmm/window.h>
|
2006-07-05 16:37:11 +02:00
|
|
|
|
2006-08-28 22:15:05 +02:00
|
|
|
#include <cassert>
|
2006-07-06 11:49:35 +02:00
|
|
|
#include <iostream>
|
2006-01-26 19:31:23 +01:00
|
|
|
|
2006-07-06 14:23:29 +02:00
|
|
|
using namespace sgpem;
|
|
|
|
using Gnome::Glade::Xml;
|
2006-07-05 16:37:11 +02:00
|
|
|
|
2006-09-17 15:03:07 +02:00
|
|
|
|
2006-08-15 19:33:47 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::on_edit_preferences_activate()
|
|
|
|
{
|
2006-09-17 21:12:52 +02:00
|
|
|
PreferencesEditor(); // Will run the dialog inside the constructor.
|
2006-08-15 19:33:47 +02:00
|
|
|
}
|
|
|
|
|
2006-09-07 04:08:00 +02:00
|
|
|
void
|
2006-09-12 22:15:55 +02:00
|
|
|
GuiBuilder::on_simulation_jump_to_clicked()
|
2006-09-07 04:08:00 +02:00
|
|
|
{
|
|
|
|
using Gnome::Glade::Xml;
|
|
|
|
|
2006-09-12 22:15:55 +02:00
|
|
|
// JumpTo spinbox
|
|
|
|
Gtk::SpinButton* jump_to_spin;
|
|
|
|
_refXml->get_widget("BottomHBox.JumpToSpin", jump_to_spin);
|
|
|
|
int target_instant = jump_to_spin->get_value_as_int();
|
2006-09-17 15:21:21 +02:00
|
|
|
assert(target_instant >= 0);
|
2006-09-12 22:15:55 +02:00
|
|
|
|
2006-09-07 04:08:00 +02:00
|
|
|
Glib::RefPtr<Xml> jump_to_dialog_glade = Xml::create(GLADEDIR "/jump-to-dialog.glade");
|
|
|
|
JumpToDialog* jump_to_dialog = NULL;
|
|
|
|
jump_to_dialog_glade->get_widget_derived("JumpToDialog", jump_to_dialog);
|
2006-09-06 11:12:53 +02:00
|
|
|
|
2006-09-12 22:15:55 +02:00
|
|
|
jump_to_dialog->set_transient_for(get_initial_window());
|
|
|
|
jump_to_dialog->set_target_instant(target_instant);
|
2006-09-12 23:35:41 +02:00
|
|
|
jump_to_dialog->start();
|
2006-09-07 04:08:00 +02:00
|
|
|
}
|
2006-09-06 11:12:53 +02:00
|
|
|
|
2006-09-12 23:35:41 +02:00
|
|
|
|
2006-09-06 11:12:53 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::on_view_show_threads_activate()
|
|
|
|
{
|
|
|
|
_show_threads = !_show_threads;
|
|
|
|
_simulation_widget->set_show_threads(_show_threads);
|
2006-09-07 17:01:29 +02:00
|
|
|
_simulation_widget->resize_redraw();
|
2006-09-06 11:12:53 +02:00
|
|
|
_holt_container.get_holt_widget().set_show_threads(_show_threads);
|
2006-09-13 16:52:11 +02:00
|
|
|
_holt_container.get_holt_widget().update(Simulation::get_instance().get_history());
|
2006-09-06 11:12:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
GuiBuilder::on_view_show_holt_graph_activate()
|
|
|
|
{
|
|
|
|
if(_holt_container.is_visible())
|
|
|
|
{
|
|
|
|
_holt_container.hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_holt_container.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-14 12:58:54 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::on_view_show_statistics_activate()
|
|
|
|
{
|
2006-09-18 00:26:47 +02:00
|
|
|
if(_statistics_container.get_main_window()->is_visible())
|
|
|
|
{
|
|
|
|
_statistics_container.get_main_window()->hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_statistics_container.get_main_window()->show();
|
|
|
|
}
|
2006-09-14 12:58:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-06 11:12:53 +02:00
|
|
|
|
2006-09-11 23:14:08 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::on_file_new_activate()
|
|
|
|
{
|
|
|
|
Simulation& sim = Simulation::get_instance();
|
|
|
|
History& history = sim.get_history();
|
|
|
|
|
2006-09-17 00:27:34 +02:00
|
|
|
ask_save();
|
2006-09-11 23:14:08 +02:00
|
|
|
|
|
|
|
sim.stop();
|
|
|
|
history.clear();
|
2006-09-17 15:03:07 +02:00
|
|
|
set_filename();
|
2006-09-11 23:14:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-08-18 09:27:00 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::on_file_open_activate()
|
|
|
|
{
|
2006-09-17 00:27:34 +02:00
|
|
|
ask_save();
|
|
|
|
|
2006-08-18 09:27:00 +02:00
|
|
|
Glib::ustring msg;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::vector<Serializer*> serializers =
|
|
|
|
SerializersGatekeeper::get_instance().get_registered();
|
|
|
|
|
|
|
|
// FIXME using the first serializer available, this
|
|
|
|
// will need to be changed when multiple serializers will
|
|
|
|
// be made available
|
|
|
|
Serializer& serializer = *serializers.at(0);
|
2006-09-02 15:18:48 +02:00
|
|
|
|
|
|
|
Simulation& sim = Simulation::get_instance();
|
2006-08-18 09:27:00 +02:00
|
|
|
|
|
|
|
// open file dialog...
|
2006-09-18 00:26:47 +02:00
|
|
|
Gtk::FileChooserDialog dialog(_("Please choose a file"), Gtk::FILE_CHOOSER_ACTION_OPEN);
|
2006-08-18 09:27:00 +02:00
|
|
|
dialog.set_transient_for(get_initial_window());
|
2006-09-02 15:18:48 +02:00
|
|
|
if(!_filename.empty()) // Please test the following line extensively:
|
|
|
|
dialog.set_current_folder(Glib::path_get_dirname(_filename));
|
2006-08-18 09:27:00 +02:00
|
|
|
|
|
|
|
//Add response buttons the the dialog:
|
|
|
|
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
|
|
|
|
dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
|
|
|
|
|
|
|
|
//Add filters, so that only certain file types can be selected:
|
|
|
|
for(std::vector<Serializer*>::const_iterator iter=serializers.begin(); iter!=serializers.end(); iter++)
|
|
|
|
{
|
|
|
|
Serializer* ser = *iter;
|
|
|
|
Gtk::FileFilter filter_sgpem;
|
|
|
|
filter_sgpem.set_name(ser->get_filename_description());
|
2006-09-02 03:01:37 +02:00
|
|
|
filter_sgpem.add_pattern(Glib::ustring("*.") + ser->get_filename_extension());
|
2006-08-18 09:27:00 +02:00
|
|
|
dialog.add_filter(filter_sgpem);
|
|
|
|
}
|
|
|
|
|
|
|
|
Gtk::FileFilter filter_any;
|
2006-09-18 00:26:47 +02:00
|
|
|
filter_any.set_name(_("Any files"));
|
2006-08-18 09:27:00 +02:00
|
|
|
filter_any.add_pattern("*");
|
|
|
|
dialog.add_filter(filter_any);
|
|
|
|
|
|
|
|
//Show the dialog and wait for a user response:
|
|
|
|
int result = dialog.run();
|
|
|
|
if(result==Gtk::RESPONSE_OK)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
set_filename(dialog.get_filename());
|
2006-09-02 15:18:48 +02:00
|
|
|
sim.stop(); // It would work anyhow, but it'd look strange
|
|
|
|
History& history = sim.get_history();
|
|
|
|
serializer.restore_snapshot(_filename, history);
|
2006-09-18 00:26:47 +02:00
|
|
|
msg = _("File: ") + _filename + _(" loaded.");
|
2006-08-18 09:27:00 +02:00
|
|
|
} // end - if(result==Gtk::RESPONSE_OK)
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (std::out_of_range e)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
Gtk::MessageDialog error(get_initial_window(),
|
|
|
|
_("<b>No serializer available.</b>\nThere's no registered serializer. Please check the loaded plugins."),
|
|
|
|
true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
error.run();
|
|
|
|
msg = _("ERROR: No registered serializer available");
|
2006-08-18 09:27:00 +02:00
|
|
|
}
|
|
|
|
catch (SerializerError e)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
Gtk::MessageDialog error(get_initial_window(), e.what(), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
error.run();
|
2006-08-18 09:27:00 +02:00
|
|
|
msg = _("ERROR: ") + Glib::ustring(e.what());
|
2006-09-17 15:03:07 +02:00
|
|
|
set_filename();
|
2006-08-18 09:27:00 +02:00
|
|
|
}
|
|
|
|
if(!msg.empty())
|
|
|
|
{
|
2006-08-28 23:48:55 +02:00
|
|
|
Gtk::Statusbar* sbar = _refXml->get_widget("MainStatusBar", sbar);
|
|
|
|
sbar->push(msg);
|
2006-08-18 09:27:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
GuiBuilder::on_file_save_activate()
|
|
|
|
{
|
2006-09-02 15:18:48 +02:00
|
|
|
if(_filename.empty())
|
|
|
|
{
|
|
|
|
on_file_saveas_activate();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// else:
|
|
|
|
|
|
|
|
Glib::ustring msg;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::vector<Serializer*> serializers =
|
|
|
|
SerializersGatekeeper::get_instance().get_registered();
|
|
|
|
|
|
|
|
// FIXME using the first serializer available, this
|
|
|
|
// will need to be changed when multiple serializers will
|
|
|
|
// be made available
|
|
|
|
Serializer& serializer = *serializers.at(0);
|
|
|
|
History& history = Simulation::get_instance().get_history();
|
|
|
|
|
|
|
|
serializer.save_snapshot(_filename, history);
|
2006-09-18 00:26:47 +02:00
|
|
|
msg = _("File: ") + _filename + _(" saved.");
|
2006-09-02 15:18:48 +02:00
|
|
|
}
|
|
|
|
catch (std::out_of_range e)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
Gtk::MessageDialog error(get_initial_window(),
|
|
|
|
_("<b>No serializer available.</b>\nThere's no registered serializer. Please check the loaded plugins."),
|
|
|
|
true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
error.run();
|
2006-09-02 15:18:48 +02:00
|
|
|
msg = _("ERROR: No registered serializer available");
|
|
|
|
}
|
|
|
|
catch (SerializerError e)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
Gtk::MessageDialog error(get_initial_window(), e.what(), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
error.run();
|
|
|
|
msg = _("ERROR: ") + Glib::ustring(e.what());
|
2006-09-02 15:18:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!msg.empty())
|
|
|
|
{
|
|
|
|
Gtk::Statusbar* sbar = _refXml->get_widget("MainStatusBar", sbar);
|
|
|
|
sbar->push(msg);
|
|
|
|
}
|
2006-08-18 09:27:00 +02:00
|
|
|
}
|
|
|
|
|
2006-09-02 15:18:48 +02:00
|
|
|
|
2006-08-18 09:27:00 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::on_file_saveas_activate()
|
|
|
|
{
|
|
|
|
Glib::ustring msg;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::vector<Serializer*> serializers =
|
|
|
|
SerializersGatekeeper::get_instance().get_registered();
|
|
|
|
|
|
|
|
// FIXME using the first serializer available, this
|
|
|
|
// will need to be changed when multiple serializers will
|
|
|
|
// be made available
|
|
|
|
Serializer& serializer = *serializers.at(0);
|
|
|
|
History& history = Simulation::get_instance().get_history();
|
|
|
|
|
|
|
|
// open file dialog...
|
2006-09-18 00:26:47 +02:00
|
|
|
Gtk::FileChooserDialog dialog(_("Please choose a file"), Gtk::FILE_CHOOSER_ACTION_SAVE);
|
2006-08-18 09:27:00 +02:00
|
|
|
dialog.set_transient_for(get_initial_window());
|
|
|
|
|
|
|
|
//Add response buttons the the dialog:
|
|
|
|
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
|
|
|
|
dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
|
|
|
|
|
|
|
|
//Add filters, so that only certain file types can be selected:
|
|
|
|
Gtk::FileFilter filter_sgpem;
|
2006-09-02 03:01:37 +02:00
|
|
|
filter_sgpem.set_name(serializer.get_filename_description());
|
|
|
|
filter_sgpem.add_pattern(Glib::ustring("*.") + serializer.get_filename_extension());
|
2006-08-18 09:27:00 +02:00
|
|
|
dialog.add_filter(filter_sgpem);
|
|
|
|
|
|
|
|
Gtk::FileFilter filter_any;
|
2006-09-18 00:26:47 +02:00
|
|
|
filter_any.set_name(_("Any files"));
|
2006-08-18 09:27:00 +02:00
|
|
|
filter_any.add_pattern("*");
|
|
|
|
dialog.add_filter(filter_any);
|
|
|
|
|
|
|
|
//Show the dialog and wait for a user response:
|
|
|
|
int result = dialog.run();
|
|
|
|
if(result==Gtk::RESPONSE_OK)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
std::string filename = dialog.get_filename();
|
2006-09-02 15:35:14 +02:00
|
|
|
|
|
|
|
// Append standard extension if none (or a different one) is provided
|
|
|
|
std::string ext = std::string(".") + serializer.get_filename_extension();
|
2006-09-17 15:03:07 +02:00
|
|
|
if(filename.size() < ext.size() || filename.substr(filename.size() - ext.size()) != ext)
|
|
|
|
filename += ext;
|
|
|
|
|
|
|
|
set_filename(filename);
|
2006-09-02 15:35:14 +02:00
|
|
|
|
|
|
|
serializer.save_snapshot(_filename, history);
|
|
|
|
|
2006-09-18 00:26:47 +02:00
|
|
|
msg = _("File: ") + _filename + _(" saved.");
|
2006-08-18 09:27:00 +02:00
|
|
|
} // end - if(result==Gtk::RESPONSE_OK)
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (std::out_of_range e)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
Gtk::MessageDialog error(get_initial_window(),
|
|
|
|
_("<b>No serializer available.</b>\nThere's no registered serializer. Please check the loaded plugins."),
|
|
|
|
true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
error.run();
|
2006-08-18 09:27:00 +02:00
|
|
|
msg = _("ERROR: No registered serializer available");
|
|
|
|
}
|
|
|
|
catch (SerializerError e)
|
|
|
|
{
|
2006-09-17 15:03:07 +02:00
|
|
|
Gtk::MessageDialog error(get_initial_window(), e.what(), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
error.run();
|
2006-08-18 09:27:00 +02:00
|
|
|
msg = _("ERROR: ") + Glib::ustring(e.what());
|
2006-09-17 15:03:07 +02:00
|
|
|
set_filename();
|
2006-08-18 09:27:00 +02:00
|
|
|
}
|
2006-08-28 23:48:55 +02:00
|
|
|
|
2006-08-18 09:27:00 +02:00
|
|
|
if(!msg.empty())
|
|
|
|
{
|
2006-08-28 23:48:55 +02:00
|
|
|
Gtk::Statusbar* sbar = _refXml->get_widget("MainStatusBar", sbar);
|
|
|
|
sbar->push(msg);
|
2006-08-18 09:27:00 +02:00
|
|
|
}
|
|
|
|
}
|
2006-07-05 16:37:11 +02:00
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
GuiBuilder::on_configure_cpu_policy()
|
|
|
|
{
|
|
|
|
using namespace Gtk;
|
|
|
|
|
2006-09-06 18:33:39 +02:00
|
|
|
Simulation& sim = Simulation::get_instance();
|
|
|
|
CPUPolicy* policy = sim.get_policy();
|
2006-08-31 01:37:11 +02:00
|
|
|
|
|
|
|
if(policy == NULL)
|
|
|
|
{
|
2006-09-01 14:08:26 +02:00
|
|
|
MessageDialog warn(get_initial_window(),
|
|
|
|
_("<b>No CPU policy is currently selected.</b>\nPlease choose one before trying to configure it."),
|
2006-08-31 01:37:11 +02:00
|
|
|
true, MESSAGE_WARNING, BUTTONS_OK, true);
|
|
|
|
warn.run();
|
|
|
|
}
|
2006-09-06 18:33:39 +02:00
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
PolicyParameters& params = policy->get_parameters();
|
2006-09-01 14:08:26 +02:00
|
|
|
ConfigurePolicyDialog config_dialog(_("Configuring CPU Policy ") + policy->get_name(),
|
|
|
|
get_initial_window(), policy->get_description(), params);
|
2006-09-06 18:33:39 +02:00
|
|
|
|
|
|
|
if(config_dialog.run() == RESPONSE_OK)
|
|
|
|
{
|
|
|
|
sim.stop();
|
|
|
|
sim.get_history().reset();
|
|
|
|
}
|
2006-08-31 01:37:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
GuiBuilder::on_configure_resource_policy()
|
|
|
|
{
|
|
|
|
using namespace Gtk;
|
|
|
|
|
2006-09-06 18:33:39 +02:00
|
|
|
Simulation& sim = Simulation::get_instance();
|
|
|
|
ResourcePolicy* policy = sim.get_resource_policy();
|
2006-08-31 01:37:11 +02:00
|
|
|
|
|
|
|
if(policy == NULL)
|
|
|
|
{
|
2006-09-01 14:08:26 +02:00
|
|
|
MessageDialog warn(get_initial_window(),
|
|
|
|
_("<b>No CPU policy is currently selected.</b>\nPlease choose one before trying to configure it."),
|
2006-08-31 01:37:11 +02:00
|
|
|
true, MESSAGE_WARNING, BUTTONS_OK, true);
|
|
|
|
warn.run();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
PolicyParameters& params = policy->get_parameters();
|
2006-09-01 14:08:26 +02:00
|
|
|
ConfigurePolicyDialog config_dialog(_("Configuring CPU Policy ") + policy->get_name(),
|
|
|
|
get_initial_window(), policy->get_description(), params);
|
2006-09-06 18:33:39 +02:00
|
|
|
|
|
|
|
if(config_dialog.run() == RESPONSE_OK)
|
|
|
|
{
|
|
|
|
sim.stop();
|
|
|
|
sim.get_history().reset();
|
|
|
|
}
|
2006-08-31 01:37:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-01 15:17:53 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::populate_with_cpu_policies(Gtk::Menu& menu)
|
|
|
|
{
|
|
|
|
using namespace Gtk;
|
|
|
|
|
|
|
|
// NOTE: Please note that this code relies on the fact that a given
|
|
|
|
// policy never "disappears" at runtime. A *GatekeeperObserver should
|
|
|
|
// be needed to avoid dangling pointers if this behaviour changes.
|
|
|
|
|
|
|
|
typedef std::vector<CPUPolicyManager*> Managers;
|
|
|
|
typedef std::vector<CPUPolicy*> Policies;
|
|
|
|
|
|
|
|
RadioButtonGroup group;
|
|
|
|
|
|
|
|
CPUPoliciesGatekeeper& pgk = CPUPoliciesGatekeeper::get_instance();
|
|
|
|
const Managers& managers = pgk.get_registered();
|
|
|
|
|
2006-09-06 19:39:46 +02:00
|
|
|
for(Iseq<Managers::const_iterator> m_it = iseq(managers); m_it; ++m_it)
|
2006-09-01 15:17:53 +02:00
|
|
|
{
|
|
|
|
const Policies& policies = (*m_it)->get_avail_policies();
|
2006-09-06 19:39:46 +02:00
|
|
|
for(Iseq<Policies::const_iterator> p_it = iseq(policies); p_it; ++p_it)
|
2006-09-01 15:17:53 +02:00
|
|
|
{
|
|
|
|
RadioMenuItem& menuitem = *manage(new RadioMenuItem(group, (*p_it)->get_name()));
|
|
|
|
menuitem.signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &GuiBuilder::on_selected_cpu_policy), *p_it));
|
|
|
|
menu.append(menuitem);
|
|
|
|
menuitem.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Activate the first policy available if possible
|
|
|
|
Menu::MenuList& items = menu.items();
|
|
|
|
if(!items.empty())
|
|
|
|
menu.activate_item(items.front());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
GuiBuilder::on_selected_cpu_policy(CPUPolicy* pol)
|
|
|
|
{
|
|
|
|
using namespace Gtk;
|
|
|
|
|
|
|
|
Statusbar* sbar;
|
|
|
|
_refXml->get_widget("MainStatusBar", sbar);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Simulation::get_instance().set_policy(pol);
|
|
|
|
if(pol != NULL) {
|
|
|
|
sbar->push(_("Selected CPU policy ") + pol->get_name());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(CPUPolicyException& e)
|
|
|
|
{
|
|
|
|
Simulation::get_instance().set_policy(NULL);
|
|
|
|
MessageDialog error(get_initial_window(),
|
|
|
|
Glib::ustring(_("<b>Impossible to select this CPU Policy.</b>\n")) + e.what(),
|
|
|
|
true, MESSAGE_ERROR, BUTTONS_OK, true);
|
|
|
|
error.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we got here, no policy is selected.
|
|
|
|
sbar->push(_("No CPU policy selected. Please select one."));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
GuiBuilder::populate_with_resource_policies(Gtk::Menu& menu)
|
|
|
|
{
|
|
|
|
using namespace Gtk;
|
|
|
|
|
|
|
|
// NOTE: Please note that this code relies on the fact that a given
|
|
|
|
// policy never "disappears" at runtime. A *GatekeeperObserver should
|
|
|
|
// be needed to avoid dangling pointers if this behaviour changes.
|
|
|
|
|
|
|
|
typedef std::vector<ResourcePolicyManager*> Managers;
|
|
|
|
typedef std::vector<ResourcePolicy*> Policies;
|
|
|
|
|
|
|
|
RadioButtonGroup group;
|
|
|
|
|
|
|
|
ResourcePoliciesGatekeeper& pgk = ResourcePoliciesGatekeeper::get_instance();
|
|
|
|
const Managers& managers = pgk.get_registered();
|
|
|
|
|
2006-09-06 19:39:46 +02:00
|
|
|
for(Iseq<Managers::const_iterator> m_it = iseq(managers); m_it; ++m_it)
|
2006-09-01 15:17:53 +02:00
|
|
|
{
|
|
|
|
const Policies& policies = (*m_it)->get_avail_policies();
|
2006-09-06 19:39:46 +02:00
|
|
|
for(Iseq<Policies::const_iterator> p_it = iseq(policies); p_it; ++p_it)
|
2006-09-01 15:17:53 +02:00
|
|
|
{
|
|
|
|
RadioMenuItem& menuitem = *manage(new RadioMenuItem(group, (*p_it)->get_name()));
|
|
|
|
menuitem.signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &GuiBuilder::on_selected_resource_policy), *p_it));
|
|
|
|
menu.append(menuitem);
|
|
|
|
menuitem.show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Activate the first policy available if possible
|
|
|
|
Menu::MenuList& items = menu.items();
|
|
|
|
if(!items.empty())
|
|
|
|
menu.activate_item(items.front());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
GuiBuilder::on_selected_resource_policy(ResourcePolicy* pol)
|
|
|
|
{
|
|
|
|
using namespace Gtk;
|
|
|
|
Simulation::get_instance().set_resource_policy(pol);
|
|
|
|
Statusbar* sbar;
|
|
|
|
_refXml->get_widget("MainStatusBar", sbar);
|
|
|
|
if(pol == NULL)
|
|
|
|
sbar->push(_("Current resource policy deselected."));
|
|
|
|
else
|
|
|
|
sbar->push(_("Selected resource policy ") + pol->get_name());
|
|
|
|
}
|
|
|
|
|
2006-09-02 13:12:23 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::on_toggle_simulation_mode()
|
|
|
|
{
|
|
|
|
Gtk::CheckMenuItem* continuous_mode;
|
|
|
|
_refXml->get_widget("MenuItem.Simulation.ContinuousMode", continuous_mode);
|
|
|
|
if(continuous_mode->get_active() == true)
|
|
|
|
Simulation::get_instance().set_mode(Simulation::mode_continuous);
|
|
|
|
else
|
|
|
|
Simulation::get_instance().set_mode(Simulation::mode_step_by_step);
|
|
|
|
}
|
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
|
2006-09-17 00:27:34 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::ask_save()
|
|
|
|
{
|
|
|
|
History& history = Simulation::get_instance().get_history();
|
|
|
|
const Environment& env = history.get_environment_at(0);
|
|
|
|
|
|
|
|
if(!(_filename.empty() && env.get_processes().empty() && env.get_resources().empty()))
|
|
|
|
{
|
|
|
|
Gtk::MessageDialog want_to_save(get_initial_window(),
|
|
|
|
_("<b>Want to save?</b>\nYou'll lose your changes if you don't."),
|
|
|
|
true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
|
|
|
|
want_to_save.set_default_response(Gtk::RESPONSE_YES);
|
|
|
|
if(want_to_save.run() == Gtk::RESPONSE_YES)
|
|
|
|
on_file_save_activate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-17 15:03:07 +02:00
|
|
|
void
|
|
|
|
GuiBuilder::set_filename(const std::string& filename)
|
|
|
|
{
|
|
|
|
static const Glib::ustring default_title = get_initial_window().get_title();
|
|
|
|
Glib::ustring title;
|
|
|
|
_filename = filename;
|
|
|
|
if(!_filename.empty())
|
|
|
|
title = Glib::path_get_basename(_filename) + " - ";
|
|
|
|
title += default_title;
|
|
|
|
get_initial_window().set_title(title);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-06 14:23:29 +02:00
|
|
|
GuiBuilder::GuiBuilder(const std::string& gladefile)
|
2006-09-06 01:54:16 +02:00
|
|
|
: _refXml(Xml::create(gladefile)), _controller(Simulation::get_instance(), _refXml),
|
2006-09-06 11:12:53 +02:00
|
|
|
_holt_container(Simulation::get_instance()),
|
|
|
|
_show_threads(true)
|
2006-07-06 14:23:29 +02:00
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
using namespace Gtk;
|
|
|
|
|
2006-09-17 00:27:34 +02:00
|
|
|
Window& main_window = get_initial_window();
|
|
|
|
main_window.signal_delete_event().connect(sigc::bind_return(sigc::hide(sigc::mem_fun(*this, &GuiBuilder::ask_save)), false));
|
|
|
|
|
2006-09-11 23:14:08 +02:00
|
|
|
// ---------------- Menu items ------------------
|
|
|
|
|
|
|
|
// Note: the Play, Pause and Stop menu items are already managed by sgpem::SimulationController.
|
|
|
|
|
|
|
|
// file new dialog
|
|
|
|
MenuItem* file_new = NULL;
|
|
|
|
_refXml->get_widget("MenuItem.File.New", file_new);
|
|
|
|
file_new->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_new_activate));
|
|
|
|
|
2006-08-18 09:27:00 +02:00
|
|
|
// file open dialog
|
|
|
|
MenuItem* file_open = NULL;
|
|
|
|
_refXml->get_widget("MenuItem.File.Open", file_open);
|
|
|
|
file_open->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_open_activate));
|
|
|
|
|
|
|
|
// file save dialog
|
|
|
|
MenuItem* file_save = NULL;
|
|
|
|
_refXml->get_widget("MenuItem.File.Save", file_save);
|
|
|
|
file_save->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_save_activate));
|
|
|
|
|
|
|
|
// file save dialog
|
|
|
|
MenuItem* file_saveas = NULL;
|
|
|
|
_refXml->get_widget("MenuItem.File.SaveAs", file_saveas);
|
|
|
|
file_saveas->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_saveas_activate));
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
MenuItem* file_quit = NULL;
|
|
|
|
_refXml->get_widget("MenuItem.File.Quit", file_quit);
|
2006-09-17 00:27:34 +02:00
|
|
|
file_quit->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::ask_save));
|
2006-08-09 16:38:45 +02:00
|
|
|
file_quit->signal_activate().connect(sigc::ptr_fun(&Main::quit));
|
|
|
|
|
2006-08-15 19:33:47 +02:00
|
|
|
// preferences dialog
|
2006-08-21 00:15:02 +02:00
|
|
|
MenuItem* edit_preferences;
|
2006-08-15 19:33:47 +02:00
|
|
|
_refXml->get_widget("MenuItem.Edit.Preferences", edit_preferences);
|
|
|
|
edit_preferences->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_edit_preferences_activate));
|
|
|
|
|
2006-09-06 11:12:53 +02:00
|
|
|
// enable/disable show threads on widgets
|
|
|
|
MenuItem* show_threads;
|
|
|
|
_refXml->get_widget("MenuItem.View.ShowThreads", show_threads);
|
|
|
|
show_threads->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_view_show_threads_activate));
|
|
|
|
|
|
|
|
// show/hide holt graph window
|
|
|
|
MenuItem* show_holt_graph;
|
|
|
|
_refXml->get_widget("MenuItem.View.ShowHoltGraph", show_holt_graph);
|
|
|
|
show_holt_graph->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_view_show_holt_graph_activate));
|
|
|
|
|
2006-09-14 12:58:54 +02:00
|
|
|
// show/hide statistics window
|
|
|
|
MenuItem* show_statistics_graph;
|
|
|
|
_refXml->get_widget("MenuItem.View.ShowStatistics", show_statistics_graph);
|
|
|
|
show_statistics_graph->signal_activate().connect(sigc::mem_fun(*this, &GuiBuilder::on_view_show_statistics_activate));
|
2006-09-06 11:12:53 +02:00
|
|
|
|
|
|
|
|
2006-09-02 13:12:23 +02:00
|
|
|
CheckMenuItem* continuous_mode;
|
|
|
|
_refXml->get_widget("MenuItem.Simulation.ContinuousMode", continuous_mode);
|
|
|
|
continuous_mode->signal_toggled().connect(sigc::mem_fun(*this, &GuiBuilder::on_toggle_simulation_mode));
|
|
|
|
|
2006-08-15 19:33:47 +02:00
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
// ---------------- Toolbar buttons ------------------
|
|
|
|
|
|
|
|
// Note: the Play, Pause and Stop buttons are already managed by sgpem::SimulationController.
|
|
|
|
|
2006-09-02 15:18:48 +02:00
|
|
|
// Open file
|
|
|
|
ToolButton* toolb_open;
|
|
|
|
_refXml->get_widget("ToolBar.Open", toolb_open);
|
|
|
|
toolb_open->signal_clicked().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_open_activate));
|
|
|
|
|
|
|
|
// Save file
|
|
|
|
ToolButton* toolb_save;
|
|
|
|
_refXml->get_widget("ToolBar.Save", toolb_save);
|
|
|
|
toolb_save->signal_clicked().connect(sigc::mem_fun(*this, &GuiBuilder::on_file_save_activate));
|
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
// Configure CPU Policy
|
|
|
|
MenuToolButton* cpu_policies_tb_menu;
|
|
|
|
_refXml->get_widget("ToolBar.PolicySelector", cpu_policies_tb_menu);
|
|
|
|
cpu_policies_tb_menu->signal_clicked().connect(sigc::mem_fun(*this, &GuiBuilder::on_configure_cpu_policy));
|
2006-09-01 15:17:53 +02:00
|
|
|
cpu_policies_tb_menu->set_menu(*manage(new Menu()));
|
|
|
|
populate_with_cpu_policies(*cpu_policies_tb_menu->get_menu());
|
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
// Configure Resource Policy
|
|
|
|
MenuToolButton* res_policies_tb_menu;
|
|
|
|
_refXml->get_widget("ToolBar.ResourceScheduling", res_policies_tb_menu);
|
|
|
|
res_policies_tb_menu->signal_clicked().connect(sigc::mem_fun(*this, &GuiBuilder::on_configure_resource_policy));
|
2006-09-01 15:17:53 +02:00
|
|
|
res_policies_tb_menu->set_menu(*manage(new Menu()));
|
|
|
|
populate_with_resource_policies(*res_policies_tb_menu->get_menu());
|
2006-08-31 01:37:11 +02:00
|
|
|
|
|
|
|
// ---------------------------------------------------
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
// About dialog
|
2006-08-21 00:15:02 +02:00
|
|
|
MenuItem* help_about;
|
2006-08-09 16:38:45 +02:00
|
|
|
_refXml->get_widget("MenuItem.Help.About", help_about);
|
|
|
|
AboutDialog* about_dialog = NULL;
|
|
|
|
_refXml->get_widget("AboutDialog", about_dialog);
|
2006-08-15 19:33:47 +02:00
|
|
|
help_about->signal_activate().connect(sigc::mem_fun(*about_dialog, &Window::show));
|
2006-08-21 00:15:02 +02:00
|
|
|
about_dialog->set_wrap_license(true);
|
|
|
|
about_dialog->set_logo(Gdk::Pixbuf::create_from_file(GLADEDIR "/logo.png"));
|
2006-08-15 19:33:47 +02:00
|
|
|
|
|
|
|
|
2006-08-27 15:39:40 +02:00
|
|
|
// Insert the schedulables TreeView custom widget
|
2006-08-20 23:26:14 +02:00
|
|
|
ScrolledWindow* schedulables_sw = NULL;
|
|
|
|
_refXml->get_widget("SchedulablesScrolledWindow", schedulables_sw);
|
|
|
|
SchedulablesTreeWidget* scheds_tree = manage(new SchedulablesTreeWidget());
|
|
|
|
schedulables_sw->add(*scheds_tree);
|
2006-08-09 16:38:45 +02:00
|
|
|
// we have to remember to manually show custom added widgets:
|
2006-08-20 23:26:14 +02:00
|
|
|
scheds_tree->show();
|
2006-08-12 17:49:37 +02:00
|
|
|
|
2006-08-31 01:37:11 +02:00
|
|
|
// Resources ListView widget
|
2006-08-21 02:12:56 +02:00
|
|
|
ResourcesWidget* resources_widget = NULL;
|
|
|
|
_refXml->get_widget_derived("Resources.Tree", resources_widget);
|
|
|
|
resources_widget->show();
|
2006-08-15 19:33:47 +02:00
|
|
|
|
2006-08-27 15:39:40 +02:00
|
|
|
|
2006-08-20 23:26:14 +02:00
|
|
|
// Main simulation widget
|
2006-08-12 17:49:37 +02:00
|
|
|
ScrolledWindow* simulation_window = NULL;
|
|
|
|
_refXml->get_widget("SimulationScrolledWindow", simulation_window);
|
2006-09-06 11:12:53 +02:00
|
|
|
//SimulationWidget& simulation_widget = *manage(new SimulationWidget(Simulation::get_instance()));
|
|
|
|
_simulation_widget = manage(new SimulationWidget(Simulation::get_instance()));
|
|
|
|
simulation_window->add(*_simulation_widget);
|
|
|
|
_simulation_widget->set_show_threads(_show_threads);
|
|
|
|
_simulation_widget->show();
|
2006-09-02 16:48:03 +02:00
|
|
|
|
2006-09-06 01:54:16 +02:00
|
|
|
|
2006-09-06 16:51:53 +02:00
|
|
|
// ReadyQueue custom label widget
|
|
|
|
ReadyQueueWidget& rq_widget = *manage(new ReadyQueueWidget(Simulation::get_instance().get_history()));
|
2006-09-12 22:15:55 +02:00
|
|
|
HBox* bottomhbox;
|
|
|
|
_refXml->get_widget("BottomHBox", bottomhbox);
|
|
|
|
bottomhbox->pack_start(rq_widget);
|
2006-09-06 16:51:53 +02:00
|
|
|
rq_widget.show();
|
|
|
|
|
|
|
|
|
2006-09-12 22:15:55 +02:00
|
|
|
// JumpTo button
|
|
|
|
Button* simulation_jump_to = NULL;
|
|
|
|
_refXml->get_widget("BottomHBox.JumpToButton", simulation_jump_to);
|
|
|
|
simulation_jump_to->signal_clicked().connect(sigc::mem_fun(*this, &GuiBuilder::on_simulation_jump_to_clicked));
|
|
|
|
|
|
|
|
|
2006-09-06 16:51:53 +02:00
|
|
|
// HoltGraph container window
|
2006-09-12 23:48:45 +02:00
|
|
|
_holt_container.set_transient_for(main_window);
|
2006-09-06 11:12:53 +02:00
|
|
|
_holt_container.get_holt_widget().set_show_threads(_show_threads);
|
2006-09-11 03:32:05 +02:00
|
|
|
|
2006-09-14 12:58:54 +02:00
|
|
|
_statistics_container.get_main_window()->set_transient_for(main_window);
|
2006-07-06 14:23:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
GuiBuilder::~GuiBuilder()
|
|
|
|
{}
|
2006-07-06 14:23:29 +02:00
|
|
|
|
2006-07-06 11:49:35 +02:00
|
|
|
|
2006-07-06 14:23:29 +02:00
|
|
|
Gtk::Window&
|
|
|
|
GuiBuilder::get_initial_window() const
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
Gtk::Window* main_window = NULL;
|
|
|
|
_refXml->get_widget("MainWindow", main_window);
|
|
|
|
return *main_window;
|
2006-01-26 19:31:23 +01:00
|
|
|
}
|
2006-02-19 23:36:24 +01:00
|
|
|
|
2006-07-06 14:23:29 +02:00
|
|
|
|
2006-08-09 16:38:45 +02:00
|
|
|
void
|
2006-07-06 14:23:29 +02:00
|
|
|
GuiBuilder::open_file(const std::string& filename)
|
|
|
|
{
|
2006-08-09 16:38:45 +02:00
|
|
|
// FIXME: to be written.
|
|
|
|
// Debug line (erase me when done):
|
|
|
|
std::cout << _("Filename to open: ") << filename << std::endl;
|
2006-07-06 14:23:29 +02:00
|
|
|
}
|
2006-08-20 23:26:14 +02:00
|
|
|
|