1 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <sigc++/functors/mem_fun.h>
23 #include "report-dialog.h"
25 #include "glade-helpers.h"
26 #include "image-helpers.h"
27 #include "input-helpers.h"
28 #include "bar-chart.h"
29 #include "ucompose.hpp"
33 #include "playerlist.h"
37 #include "GraphicsCache.h"
38 #include "armyprodbase.h"
39 #include "armysetlist.h"
41 ReportDialog::ReportDialog(Player *player, ReportType type)
44 Glib::RefPtr<Gtk::Builder> xml
45 = Gtk::Builder::create_from_file(get_glade_path() + "/report-dialog.ui");
47 xml->get_widget("dialog", dialog);
49 window_closed.connect(sigc::mem_fun(dialog, &Gtk::Dialog::hide));
51 xml->get_widget("map_image", map_image);
52 citymap = new CityMap();
53 citymap->map_changed.connect
54 (sigc::mem_fun(this, &ReportDialog::on_city_map_changed));
55 armymap = new ArmyMap();
56 armymap->map_changed.connect
57 (sigc::mem_fun(this, &ReportDialog::on_army_map_changed));
58 City *c = Citylist::getInstance()->getFirstCity(d_player);
59 vectormap = new VectorMap(c, VectorMap::SHOW_ALL_VECTORING, false);
60 vectormap->map_changed.connect
61 (sigc::mem_fun(this, &ReportDialog::on_vector_map_changed));
63 xml->get_widget("army_label", army_label);
64 xml->get_widget("city_label", city_label);
65 xml->get_widget("gold_label", gold_label);
66 xml->get_widget("production_label", production_label);
67 xml->get_widget("winning_label", winning_label);
70 xml->get_widget("report_notebook", report_notebook);
71 report_notebook->set_current_page(type);
72 report_notebook->signal_switch_page().connect(
73 sigc::mem_fun(*this, &ReportDialog::on_switch_page));
75 armies_list = Gtk::ListStore::create(armies_columns);
76 xml->get_widget("treeview", armies_treeview);
77 armies_treeview->set_model(armies_list);
78 armies_treeview->append_column("", armies_columns.image);
79 armies_treeview->append_column("", armies_columns.desc);
81 //loop through the action list looking for production actions
82 std::list<Action*> actions = player->getReportableActions();
84 std::list<Action*>::const_iterator it;
85 for (it = actions.begin(); it != actions.end(); it++)
87 if ((*it)->getType() == Action::PRODUCE_UNIT ||
88 (*it)->getType() == Action::PRODUCE_VECTORED_UNIT)
92 armies_treeview->get_selection()->signal_changed().connect
93 (sigc::mem_fun(*this, &ReportDialog::on_army_selected));
96 s = String::ucompose(ngettext("You produced %1 army this turn!",
97 "You produced %1 armies this turn!",
99 production_label->set_text(s);
101 Gtk::Button *close_button;
102 xml->get_widget("close_button", close_button);
103 close_button->signal_clicked().connect
104 (sigc::mem_fun(*this, &ReportDialog::on_close_button));
105 xml->get_widget("army_alignment", army_alignment);
106 xml->get_widget("city_alignment", city_alignment);
107 xml->get_widget("gold_alignment", gold_alignment);
108 xml->get_widget("winning_alignment", winning_alignment);
112 updateWinningChart();
117 ReportDialog::~ReportDialog()
124 void ReportDialog::on_close_button()
127 //FIXME: find out why the page_switch events with crap data,
128 //and then remove this function, and the closing variable too.
131 void ReportDialog::set_parent_window(Gtk::Window &parent)
133 dialog->set_transient_for(parent);
134 //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
137 void ReportDialog::hide()
142 void ReportDialog::run()
145 citymap->draw(Playerlist::getActiveplayer());
147 vectormap->draw(Playerlist::getActiveplayer());
149 armymap->draw(Playerlist::getActiveplayer());
155 void ReportDialog::on_army_map_changed(Glib::RefPtr<Gdk::Pixmap> map)
157 if (report_notebook->get_current_page() == ARMY)
158 map_image->property_pixmap() = map;
161 void ReportDialog::on_city_map_changed(Glib::RefPtr<Gdk::Pixmap> map)
163 if (report_notebook->get_current_page() == CITY ||
164 report_notebook->get_current_page() == GOLD ||
165 report_notebook->get_current_page() == WINNING)
166 map_image->property_pixmap() = map;
169 void ReportDialog::on_vector_map_changed(Glib::RefPtr<Gdk::Pixmap> map)
171 if (report_notebook->get_current_page() == PRODUCTION)
172 map_image->property_pixmap() = map;
175 void ReportDialog::on_switch_page(GtkNotebookPage *page, guint number)
182 map_image->property_pixmap() = armymap->get_surface();
187 map_image->property_pixmap() = citymap->get_surface();
190 map_image->property_pixmap() = vectormap->get_surface();
196 void ReportDialog::fill_in_info()
198 switch (report_notebook->get_current_page())
201 set_title(_("Army Report"));
204 set_title(_("City Report"));
207 set_title(_("Gold Report"));
210 set_title(_("Production Report"));
213 set_title(_("Winning Report"));
218 void ReportDialog::updateArmyChart()
220 std::list<guint32> bars;
221 std::list<Gdk::Color> colours;
225 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
227 Player *p = Playerlist::getInstance()->getPlayer(i);
230 if (p == Playerlist::getInstance()->getNeutral())
233 total = p->countArmies();
234 bars.push_back(total);
235 colour = p->getColor();
236 colours.push_back(colour);
239 s = String::ucompose(ngettext("You have %1 army!",
240 "You have %1 armies!",
242 army_label->set_text(s);
246 army_chart = new BarChart(bars, colours, 0);
247 army_alignment->add(*manage(army_chart));
250 void ReportDialog::updateCityChart()
252 std::list<guint32> bars;
253 std::list<Gdk::Color> colours;
257 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
259 Player *p = Playerlist::getInstance()->getPlayer(i);
262 if (p == Playerlist::getInstance()->getNeutral())
264 total = Citylist::getInstance()->countCities(p);
266 bars.push_back(total);
267 colour = p->getColor();
268 colours.push_back(colour);
271 s = String::ucompose(ngettext("You have %1 city!",
272 "You have %1 cities!",
274 city_label->set_text(s);
278 city_chart = new BarChart(bars, colours, Citylist::getInstance()->size());
279 city_alignment->add(*manage(city_chart));
282 void ReportDialog::updateGoldChart()
284 std::list<guint32> bars;
285 std::list<Gdk::Color> colours;
290 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
292 Player *p = Playerlist::getInstance()->getPlayer(i);
295 if (p == Playerlist::getInstance()->getNeutral())
297 total = p->getGold();
298 bars.push_back(total);
299 colour = p->getColor();
300 colours.push_back(colour);
303 s = String::ucompose(ngettext("You have %1 gold piece!",
304 "You have %1 gold pieces!",
306 gold_label->set_text(s);
309 gold_chart = new BarChart(bars, colours, 0);
310 gold_alignment->add(*manage(gold_chart));
313 std::string ReportDialog::calculateRank(std::list<guint32> scores, guint32 score)
315 char* rank_strings[MAX_PLAYERS] =
317 _("first"), _("second"), _("third"), _("fourth"), _("fifth"),
318 _("sixth"), _("seventh"), _("eighth"),
321 std::list<guint32>::iterator it = scores.begin();
322 for (; it != scores.end(); it++)
327 Glib::ustring s = String::ucompose(_("%1"), rank_strings[rank]);
331 void ReportDialog::updateWinningChart()
333 std::list<guint32> bars;
334 std::list<Gdk::Color> colours;
338 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
340 Player *p = Playerlist::getInstance()->getPlayer(i);
343 if (p == Playerlist::getInstance()->getNeutral())
345 score = p->getScore();
346 bars.push_back(score);
347 colour = p->getColor();
348 colours.push_back(colour);
350 s = String::ucompose(_("You are coming %1"), calculateRank(bars, d_player->getScore()));
351 winning_label->set_text(s);
352 winning_chart = new BarChart(bars, colours, 100);
353 winning_alignment->add(*manage(winning_chart));
356 void ReportDialog::addProduction(const Action *action)
358 GraphicsCache *gc = GraphicsCache::getInstance();
359 Player *p = d_player;
364 Glib::ustring s = "";
365 if (action->getType() == Action::PRODUCE_UNIT)
367 const Action_Produce *act;
368 act = dynamic_cast<const Action_Produce*>(action);
369 army_type = act->getArmy()->getTypeId();
370 Citylist::iterator cit = Citylist::getInstance()->begin();
371 for (; cit != Citylist::getInstance()->end(); ++cit)
372 if ((*cit)->getId() == act->getCityId())
374 s += (*cit)->getName();
377 if (act->getVectored())
379 city_id = act->getCityId();
381 else if (action->getType() == Action::PRODUCE_VECTORED_UNIT)
383 const Action_ProduceVectored *act;
384 act = dynamic_cast<const Action_ProduceVectored*>(action);
385 army_type = act->getArmy()->getTypeId();
386 Vector<int> pos = act->getDestination();
387 City *c = GameMap::getCity(pos);
393 city_id = GameMap::getCity(act->getOrigination())->getId();
395 else if (action->getType() == Action::CITY_DESTITUTE)
397 const Action_CityTooPoorToProduce *act;
398 act = dynamic_cast<const Action_CityTooPoorToProduce*>(action);
399 army_type = act->getArmyType();
400 City *c = Citylist::getInstance()->getById(act->getCityId());
402 s += " stops production!";
403 city_id = act->getCityId();
406 a = Armysetlist::getInstance()->getArmy(p->getArmyset(), army_type);
407 Gtk::TreeIter i = armies_list->append();
408 (*i)[armies_columns.city_id] = city_id;
409 (*i)[armies_columns.image] = gc->getArmyPic(p->getArmyset(), army_type, p,
411 (*i)[armies_columns.desc] = s;
414 void ReportDialog::on_army_selected()
416 Gtk::TreeIter i = armies_treeview->get_selection()->get_selected();
420 Citylist::getInstance()->getById((*i)[armies_columns.city_id]);
422 vectormap->setCity(c);