- 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 Glib;
using Gnome::Glade::Xml;
using std::vector;
AddRequestDialog::AddRequestDialog(BaseObjectType* cobject, const RefPtr<Xml>& 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("Resource.Combo", _resource_combo);
_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 **/
@ -95,31 +99,89 @@ AddRequestDialog::AddRequestDialog(BaseObjectType* cobject, const RefPtr<Xml>& g
sigc::mem_fun(*this, &AddRequestDialog::_on_list_selection_changed));
}
Request&
AddRequestDialog::construct_request(Thread& owner)
Request*
AddRequestDialog::run_add(Thread& owner)
{
assert(_list_model->children());
update_combo();
SpinButton* instant_spin;
_glade->get_widget("Instant.Spin", instant_spin);
History& h = Simulation::get_instance().get_history();
Request* r = NULL;
Request& r = h.add_request(owner, instant_spin->get_value_as_int());
TreeNodeChildren sreq_container = _list_model->children();
// reset the dialog data
_list_model->clear();
_instant_spin->set_value(0.0);
_duration_spin->set_value(0.0);
for(Iseq<TreeIter> it = iseq(sreq_container); it; ++it)
h.add_subrequest(r, (*it)[_list_key_column], (*it)[_list_length_column]);
if(run() == RESPONSE_OK)
{
assert(_list_model->children());
History& h = Simulation::get_instance().get_history();
r = &h.add_request(owner, _instant_spin->get_value_as_int());
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;
}
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;
const Environment::Resources& resources =
@ -142,10 +204,6 @@ AddRequestDialog::_on_add()
{
TreeModel::iterator sel = _resource_combo->get_active();
SpinButton* duration_spin;
_glade->get_widget("Duration.Spin", duration_spin);
TreeModel::Row row = *(_list_model->append());
const unsigned int key = (*sel)[_combo_key_column];
@ -154,7 +212,7 @@ AddRequestDialog::_on_add()
const ustring resource = (*sel)[_combo_resource_column];
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;
}

View File

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

View File

@ -185,6 +185,15 @@ SchedulablesTreeWidget::on_button_press_event(GdkEventButton* event)
action_group->add( Gtk::Action::create("AddRequest", "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"),
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();
Glib::ustring ui_info =
"<ui>"
" <popup name='PopupMenu'>";
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'/>";
Glib::ustring adds;
Glib::ustring edits;
Glib::ustring removes;
Glib::ustring separator;
if(selection_type != htype_undefined)
ui_info +=
" <separator/>";
separator = "<separator/>";
switch(selection_type)
{
case htype_process:
ui_info +=
" <menuitem action='RemoveProcess'/>";
adds = "<menuitem action='AddThread'/>";
edits = "<menuitem action='EditProcess'/>";
removes = "<menuitem action='RemoveProcess'/>";
break;
case htype_thread:
ui_info +=
" <menuitem action='RemoveThread'/>";
adds = "<menuitem action='AddRequest'/>";
edits = "<menuitem action='EditThread'/>";
removes = "<menuitem action='RemoveThread'/>";
break;
case htype_request:
ui_info +=
" <menuitem action='RemoveRequest'/>";
edits = "<menuitem action='EditRequest'/>";
removes = "<menuitem action='RemoveRequest'/>";
break;
case htype_subrequest:
ui_info +=
" <menuitem action='RemoveSubrequest'/>";
removes = "<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 +=
" </popup>"
"</ui>";
@ -327,19 +335,63 @@ SchedulablesTreeWidget::update(const History& history)
void
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)
{
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);
Simulation::get_instance().get_history().add_process(name_entry->get_text(),
arrival_time_spin->get_value_as_int(),
base_priority_spin->get_value_as_int());
if(adding)
{
Simulation::get_instance().get_history().add_process(name_entry->get_text(),
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();
@ -348,27 +400,74 @@ SchedulablesTreeWidget::_on_add_process()
void
SchedulablesTreeWidget::_on_add_thread()
{
Process* p = get_selected<Process>();
if(p == NULL)
return;
add_edit_thread(true);
}
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)
{
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);
Simulation::get_instance().get_history().add_thread(name_entry->get_text(),
*p,
cpu_time_spin->get_value_as_int(),
arrival_time_spin->get_value_as_int(),
base_priority_spin->get_value_as_int());
if(adding)
{
Process* p = get_selected<Process>();
assert(p != NULL);
Simulation::get_instance().get_history().add_thread(name_entry->get_text(),
*p,
cpu_time_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_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>();
if(t == NULL)
return;
if(_add_request_dialog->run() == RESPONSE_OK)
_add_request_dialog->construct_request(*t);
assert(t != NULL);
_add_request_dialog->hide();
_add_request_dialog->run_add(*t);
}
void
SchedulablesTreeWidget::_on_edit_request()
{
Request* r = get_selected<Request>();
assert(r != NULL);
_add_request_dialog->run_edit(*r);
}
void

View File

@ -88,6 +88,13 @@ namespace sgpem
void _on_add_thread();
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_thread();
void _on_remove_request();