--- /dev/null
+#include <msp/core/maputils.h>
+#include <msp/gltk/grid.h>
+#include <msp/strings/format.h>
+#include "libr2c2/layout.h"
+#include "libr2c2/train.h"
+#include "libr2c2/zone.h"
+#include "departuresdialog.h"
+
+using namespace std;
+using namespace Msp;
+using namespace R2C2;
+
+DeparturesDialog::DeparturesDialog(const Layout &l, const string &group):
+ layout(l),
+ departures(0)
+{
+ Loader::WidgetMap widgets;
+ DataFile::load(*this, "data/departuresdialog.ui", widgets);
+
+ lbl_title = dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_title"));
+ drp_groups = dynamic_cast<GLtk::Dropdown *>(get_item(widgets, "drp_groups"));
+ drp_groups->set_data(groups);
+ drp_groups->signal_item_selected.connect(sigc::mem_fun(this, &DeparturesDialog::group_selected));
+ pnl_departures = dynamic_cast<GLtk::Panel *>(get_item(widgets, "pnl_departures"));
+
+ GLtk::Grid grid(*pnl_departures->get_layout(), 2);
+ rows.resize(8);
+ for(unsigned i=0; i<rows.size(); ++i)
+ {
+ Row &row = rows[i];
+ pnl_departures->add(*(row.lbl_time = new GLtk::Label));
+ row.lbl_time->set_style("digital_borderless");
+ pnl_departures->add(*(row.lbl_train = new GLtk::Label));
+ row.lbl_train->set_style("digital_borderless");
+ }
+
+ const set<Zone *> &zones = layout.get_all<Zone>();
+ set<string> group_set;
+ for(set<Zone *>::const_iterator i=zones.begin(); i!=zones.end(); ++i)
+ group_set.insert((*i)->get_group());
+
+ for(set<string>::const_iterator i=group_set.begin(); i!=group_set.end(); ++i)
+ {
+ groups.append(*i);
+ if(*i==group)
+ drp_groups->set_selected_index(groups.size()-1);
+ }
+}
+
+void DeparturesDialog::group_selected(unsigned index)
+{
+ const string &group = groups.get(index);
+ lbl_title->set_text("Departures from "+group);
+
+ for(vector<Row>::iterator i=rows.begin(); i!=rows.end(); ++i)
+ i->set_departure(0);
+
+ delete departures;
+ departures = new Departures(layout, group);
+ departures->signal_departure_added.connect(sigc::mem_fun(this, &DeparturesDialog::departure_added));
+ departures->signal_departure_removed.connect(sigc::mem_fun(this, &DeparturesDialog::departure_removed));
+
+ update_rows();
+}
+
+void DeparturesDialog::departure_added(const Departures::Departure &)
+{
+ update_rows();
+}
+
+void DeparturesDialog::departure_removed(const Departures::Departure &)
+{
+ update_rows();
+}
+
+void DeparturesDialog::update_rows()
+{
+ const list<Departures::Departure> &deps = departures->get_departures();
+ list<Departures::Departure>::const_iterator i = deps.begin();
+ for(unsigned j=0; j<rows.size(); ++j)
+ {
+ if(i!=deps.end())
+ rows[j].set_departure(&*i++);
+ else
+ rows[j].set_departure(0);
+ }
+}
+
+
+DeparturesDialog::Row::Row():
+ departure(0),
+ lbl_time(0),
+ lbl_train(0)
+{ }
+
+void DeparturesDialog::Row::set_departure(const Departures::Departure *d)
+{
+ departure = d;
+ if(departure)
+ {
+ unsigned secs = departure->time/Time::sec;
+ unsigned hour = secs/3600%24;
+ unsigned min = secs/60%60;
+ lbl_time->set_text(format("%2d:%02d", hour, min));
+ lbl_train->set_text(departure->train->get_name());
+ }
+ else
+ {
+ lbl_time->set_text(string());
+ lbl_train->set_text(string());
+ }
+}