- Added the editing feature to the schedulables tree widget

- Value of dialog is now resetted, so they no more show up with the last data that was given

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@938 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
elvez 2006-08-25 00:29:28 +00:00
parent 50929d9a94
commit 34c65f42d1
4 changed files with 261 additions and 84 deletions

View File

@ -38,6 +38,7 @@ using namespace sgpem;
using namespace Gtk; using namespace Gtk;
using namespace Glib; using namespace Glib;
using Gnome::Glade::Xml; using Gnome::Glade::Xml;
using std::vector;
AddRequestDialog::AddRequestDialog(BaseObjectType* cobject, const RefPtr<Xml>& glade) : AddRequestDialog::AddRequestDialog(BaseObjectType* cobject, const RefPtr<Xml>& glade) :
Dialog(cobject), _glade(glade) Dialog(cobject), _glade(glade)
@ -47,6 +48,9 @@ AddRequestDialog::AddRequestDialog(BaseObjectType* cobject, const RefPtr<Xml>& g
_glade->get_widget("Remove", _remove_button); _glade->get_widget("Remove", _remove_button);
_glade->get_widget("Resource.Combo", _resource_combo); _glade->get_widget("Resource.Combo", _resource_combo);
_glade->get_widget("OK.Button", _ok_button); _glade->get_widget("OK.Button", _ok_button);
_glade->get_widget("Instant.Spin", _instant_spin);
_glade->get_widget("Duration.Spin", _duration_spin);
/** ATTACH SIGNAL HANDLERS FOR BUTTONS **/ /** ATTACH SIGNAL HANDLERS FOR BUTTONS **/
@ -95,31 +99,89 @@ AddRequestDialog::AddRequestDialog(BaseObjectType* cobject, const RefPtr<Xml>& g
sigc::mem_fun(*this, &AddRequestDialog::_on_list_selection_changed)); sigc::mem_fun(*this, &AddRequestDialog::_on_list_selection_changed));
} }
Request& Request*
AddRequestDialog::construct_request(Thread& owner) AddRequestDialog::run_add(Thread& owner)
{ {
assert(_list_model->children()); update_combo();
SpinButton* instant_spin; Request* r = NULL;
_glade->get_widget("Instant.Spin", instant_spin);
History& h = Simulation::get_instance().get_history(); // reset the dialog data
_list_model->clear();
_instant_spin->set_value(0.0);
_duration_spin->set_value(0.0);
Request& r = h.add_request(owner, instant_spin->get_value_as_int()); if(run() == RESPONSE_OK)
{
assert(_list_model->children());
TreeNodeChildren sreq_container = _list_model->children(); History& h = Simulation::get_instance().get_history();
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it) r = &h.add_request(owner, _instant_spin->get_value_as_int());
h.add_subrequest(r, (*it)[_list_key_column], (*it)[_list_length_column]);
TreeNodeChildren sreq_container = _list_model->children();
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it)
h.add_subrequest(*r, (*it)[_list_key_column], (*it)[_list_length_column]);
}
hide();
return r; return r;
} }
void void
AddRequestDialog::on_show() AddRequestDialog::run_edit(Request& request)
{ {
//TODO is this a reasonable place where to fill the combo model? update_combo();
_list_model->clear();
History& history = Simulation::get_instance().get_history();
const Environment::Resources& resources = history.get_last_environment().get_resources();
_instant_spin->set_value(static_cast<double>(request.get_instant()));
// PLEASE KEEP THIS A COPY, WE *NEED* TO COPY IT
vector<SubRequest*> subrequests = request.get_subrequests();
for(Iseq<vector<SubRequest*>::iterator> it = iseq(subrequests); it; ++it)
{
SubRequest& sr = *(*it);
TreeModel::Row row = *(_list_model->append());
unsigned int key = sr.get_resource_key();
row[_list_key_column] = key;
const ustring name = resources.find(key)->second->get_name();
row[_list_resource_column] = name;
row[_list_length_column] = sr.get_length();
}
if(run() == RESPONSE_OK)
{
assert(_list_model->children());
// I know it's a bit hack-ish, but do you know an elegant alternative way?
for(Iseq<vector<SubRequest*>::iterator> it = iseq(subrequests); it; ++it)
history.remove(*(*it));
history.edit_request(request, _instant_spin->get_value_as_int());
TreeNodeChildren sreq_container = _list_model->children();
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it)
history.add_subrequest(request, (*it)[_list_key_column], (*it)[_list_length_column]);
}
hide();
}
void
AddRequestDialog::update_combo()
{
typedef Environment::Resources::const_iterator ResourceIt; typedef Environment::Resources::const_iterator ResourceIt;
const Environment::Resources& resources = const Environment::Resources& resources =
@ -142,10 +204,6 @@ AddRequestDialog::_on_add()
{ {
TreeModel::iterator sel = _resource_combo->get_active(); TreeModel::iterator sel = _resource_combo->get_active();
SpinButton* duration_spin;
_glade->get_widget("Duration.Spin", duration_spin);
TreeModel::Row row = *(_list_model->append()); TreeModel::Row row = *(_list_model->append());
const unsigned int key = (*sel)[_combo_key_column]; const unsigned int key = (*sel)[_combo_key_column];
@ -154,7 +212,7 @@ AddRequestDialog::_on_add()
const ustring resource = (*sel)[_combo_resource_column]; const ustring resource = (*sel)[_combo_resource_column];
row[_list_resource_column] = resource; row[_list_resource_column] = resource;
const unsigned int length = duration_spin->get_value_as_int(); const unsigned int length = _duration_spin->get_value_as_int();
row[_list_length_column] = length; row[_list_length_column] = length;
} }

View File

@ -33,6 +33,7 @@ namespace sgpem
#include <gtkmm/liststore.h> #include <gtkmm/liststore.h>
#include <gtkmm/dialog.h> #include <gtkmm/dialog.h>
#include <gtkmm/combobox.h> #include <gtkmm/combobox.h>
#include <gtkmm/spinbutton.h>
#include <libglademm/xml.h> #include <libglademm/xml.h>
namespace sgpem namespace sgpem
@ -43,17 +44,21 @@ namespace sgpem
AddRequestDialog(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade); AddRequestDialog(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& glade);
/** /**
\brief Attemts to build a request by using the data supplied \brief Attemts to show the dialog, and constructs a request
up to now. if response is OK
\note Must be called only after it has been shown at least \param owner The thread which will own the request
one time with an OK, otherwise expect undefined behaviour!
*/ */
Request& construct_request(Thread& t); Request* run_add(Thread& owner);
protected: /**
virtual void on_show(); \brief Attemts to show the dialog, and modify an existing request
if response is OK
\param resource The request to modify
*/
void run_edit(Request& resource);
private: private:
void update_combo();
void _on_add(); void _on_add();
void _on_remove(); void _on_remove();
void _on_list_selection_changed(); void _on_list_selection_changed();
@ -72,6 +77,8 @@ namespace sgpem
Gtk::Button* _add_button; Gtk::Button* _add_button;
Gtk::Button* _remove_button; Gtk::Button* _remove_button;
Gtk::Button* _ok_button; Gtk::Button* _ok_button;
Gtk::SpinButton* _instant_spin;
Gtk::SpinButton* _duration_spin;
Gtk::ComboBox* _resource_combo; Gtk::ComboBox* _resource_combo;
Glib::RefPtr<Gtk::ListStore> _combo_model; Glib::RefPtr<Gtk::ListStore> _combo_model;

View File

@ -186,6 +186,15 @@ SchedulablesTreeWidget::on_button_press_event(GdkEventButton* event)
action_group->add( Gtk::Action::create("AddRequest", "Add Request"), action_group->add( Gtk::Action::create("AddRequest", "Add Request"),
sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_add_request) ); sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_add_request) );
action_group->add( Gtk::Action::create("EditProcess", "Edit Process"),
sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_edit_process) );
action_group->add( Gtk::Action::create("EditThread", "Edit Thread"),
sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_edit_thread) );
action_group->add( Gtk::Action::create("EditRequest", "Edit Request"),
sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_edit_request) );
action_group->add( Gtk::Action::create("RemoveProcess", "Remove Process"), action_group->add( Gtk::Action::create("RemoveProcess", "Remove Process"),
sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_remove_process) ); sigc::mem_fun(*this, &SchedulablesTreeWidget::_on_remove_process) );
@ -203,43 +212,42 @@ SchedulablesTreeWidget::on_button_press_event(GdkEventButton* event)
const HandleType selection_type = get_selection_type(); const HandleType selection_type = get_selection_type();
Glib::ustring ui_info = Glib::ustring adds;
"<ui>" Glib::ustring edits;
" <popup name='PopupMenu'>"; Glib::ustring removes;
Glib::ustring separator;
if(selection_type == htype_process)
ui_info +=
" <menuitem action='AddThread'/>";
else if(selection_type == htype_thread)
ui_info +=
" <menuitem action='AddRequest'/>";
ui_info +=
" <menuitem action='AddProcess'/>";
if(selection_type != htype_undefined) if(selection_type != htype_undefined)
ui_info += separator = "<separator/>";
" <separator/>";
switch(selection_type) switch(selection_type)
{ {
case htype_process: case htype_process:
ui_info += adds = "<menuitem action='AddThread'/>";
" <menuitem action='RemoveProcess'/>"; edits = "<menuitem action='EditProcess'/>";
removes = "<menuitem action='RemoveProcess'/>";
break; break;
case htype_thread: case htype_thread:
ui_info += adds = "<menuitem action='AddRequest'/>";
" <menuitem action='RemoveThread'/>"; edits = "<menuitem action='EditThread'/>";
removes = "<menuitem action='RemoveThread'/>";
break; break;
case htype_request: case htype_request:
ui_info += edits = "<menuitem action='EditRequest'/>";
" <menuitem action='RemoveRequest'/>"; removes = "<menuitem action='RemoveRequest'/>";
break; break;
case htype_subrequest: case htype_subrequest:
ui_info += removes = "<menuitem action='RemoveSubrequest'/>";
" <menuitem action='RemoveSubrequest'/>";
} }
adds += "<menuitem action='AddProcess'/>";
Glib::ustring ui_info =
"<ui>"
" <popup name='PopupMenu'>";
ui_info += adds + separator + edits + ((edits.size() == 0) ? ustring() : separator) + removes;
ui_info += ui_info +=
" </popup>" " </popup>"
"</ui>"; "</ui>";
@ -327,19 +335,63 @@ SchedulablesTreeWidget::update(const History& history)
void void
SchedulablesTreeWidget::_on_add_process() SchedulablesTreeWidget::_on_add_process()
{ {
add_edit_process(true);
}
void
SchedulablesTreeWidget::_on_edit_process()
{
add_edit_process(false);
}
void
SchedulablesTreeWidget::add_edit_process(bool adding)
{
/** This is ugly, I know, we should be using derived widgets, but I also believe we
* have little time, and I'm not going to waste too much of it on the frontend */
Entry* name_entry;
SpinButton* arrival_time_spin;
SpinButton* base_priority_spin;
_add_process_dialog_glade->get_widget("Name.Entry", name_entry);
_add_process_dialog_glade->get_widget("ArrivalTime.Spin", arrival_time_spin);
_add_process_dialog_glade->get_widget("BasePriority.Spin", base_priority_spin);
Process* selection = NULL;
if(!adding)
{
selection = get_selected<Process>();
name_entry->set_text(selection->get_name());
arrival_time_spin->set_value(static_cast<double>(selection->get_arrival_time()));
base_priority_spin->set_value(static_cast<double>(selection->get_base_priority()));
}
else
{
name_entry->set_text("");
arrival_time_spin->set_value(0.0);
base_priority_spin->set_value(0.0);
}
if(_add_process_dialog->run() == RESPONSE_OK) if(_add_process_dialog->run() == RESPONSE_OK)
{ {
Entry* name_entry;
SpinButton* arrival_time_spin;
SpinButton* base_priority_spin;
_add_process_dialog_glade->get_widget("Name.Entry", name_entry); if(adding)
_add_process_dialog_glade->get_widget("ArrivalTime.Spin", arrival_time_spin); {
_add_process_dialog_glade->get_widget("BasePriority.Spin", base_priority_spin); Simulation::get_instance().get_history().add_process(name_entry->get_text(),
arrival_time_spin->get_value_as_int(),
Simulation::get_instance().get_history().add_process(name_entry->get_text(), base_priority_spin->get_value_as_int());
arrival_time_spin->get_value_as_int(), }
base_priority_spin->get_value_as_int()); else
{
Simulation::get_instance().get_history().edit_process(*selection,
name_entry->get_text(),
arrival_time_spin->get_value_as_int(),
base_priority_spin->get_value_as_int());
}
} }
_add_process_dialog->hide(); _add_process_dialog->hide();
@ -348,27 +400,74 @@ SchedulablesTreeWidget::_on_add_process()
void void
SchedulablesTreeWidget::_on_add_thread() SchedulablesTreeWidget::_on_add_thread()
{ {
Process* p = get_selected<Process>(); add_edit_thread(true);
if(p == NULL) }
return;
void
SchedulablesTreeWidget::_on_edit_thread()
{
add_edit_thread(false);
}
void
SchedulablesTreeWidget::add_edit_thread(bool adding)
{
/** This is ugly, I know, we should be using derived widgets, but I also believe we
* have little time, and I'm not going to waste too much of it on the frontend */
Entry* name_entry;
SpinButton* cpu_time_spin;
SpinButton* arrival_time_spin;
SpinButton* base_priority_spin;
_add_thread_dialog_glade->get_widget("Name.Entry", name_entry);
_add_thread_dialog_glade->get_widget("CpuTime.Spin", cpu_time_spin);
_add_thread_dialog_glade->get_widget("ArrivalTime.Spin", arrival_time_spin);
_add_thread_dialog_glade->get_widget("BasePriority.Spin", base_priority_spin);
Thread* t = NULL;
if(!adding)
{
t = get_selected<Thread>();
name_entry->set_text(t->get_name());
cpu_time_spin->set_value(static_cast<double>(t->get_total_cpu_time()));
arrival_time_spin->set_value(static_cast<double>(t->get_arrival_time()));
base_priority_spin->set_value(static_cast<double>(t->get_base_priority()));
}
else
{
name_entry->set_text("");
cpu_time_spin->set_value(1.0);
arrival_time_spin->set_value(0.0);
base_priority_spin->set_value(0.0);
}
if(_add_thread_dialog->run() == RESPONSE_OK) if(_add_thread_dialog->run() == RESPONSE_OK)
{ {
Entry* name_entry;
SpinButton* cpu_time_spin;
SpinButton* arrival_time_spin;
SpinButton* base_priority_spin;
_add_thread_dialog_glade->get_widget("Name.Entry", name_entry); if(adding)
_add_thread_dialog_glade->get_widget("CpuTime.Spin", cpu_time_spin); {
_add_thread_dialog_glade->get_widget("ArrivalTime.Spin", arrival_time_spin); Process* p = get_selected<Process>();
_add_thread_dialog_glade->get_widget("BasePriority.Spin", base_priority_spin); assert(p != NULL);
Simulation::get_instance().get_history().add_thread(name_entry->get_text(), Simulation::get_instance().get_history().add_thread(name_entry->get_text(),
*p, *p,
cpu_time_spin->get_value_as_int(), cpu_time_spin->get_value_as_int(),
arrival_time_spin->get_value_as_int(), arrival_time_spin->get_value_as_int(),
base_priority_spin->get_value_as_int()); base_priority_spin->get_value_as_int());
}
else
{
Simulation::get_instance().get_history().edit_thread(*t,
name_entry->get_text(),
cpu_time_spin->get_value_as_int(),
arrival_time_spin->get_value_as_int(),
base_priority_spin->get_value_as_int());
}
} }
@ -380,13 +479,19 @@ SchedulablesTreeWidget::_on_add_request()
{ {
Thread* t = get_selected<Thread>(); Thread* t = get_selected<Thread>();
if(t == NULL) assert(t != NULL);
return;
if(_add_request_dialog->run() == RESPONSE_OK) _add_request_dialog->run_add(*t);
_add_request_dialog->construct_request(*t); }
_add_request_dialog->hide(); void
SchedulablesTreeWidget::_on_edit_request()
{
Request* r = get_selected<Request>();
assert(r != NULL);
_add_request_dialog->run_edit(*r);
} }
void void

View File

@ -88,6 +88,13 @@ namespace sgpem
void _on_add_thread(); void _on_add_thread();
void _on_add_request(); void _on_add_request();
void _on_edit_process();
void _on_edit_thread();
void _on_edit_request();
void add_edit_process(bool adding);
void add_edit_thread(bool adding);
void _on_remove_process(); void _on_remove_process();
void _on_remove_thread(); void _on_remove_thread();
void _on_remove_request(); void _on_remove_request();