1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 2, or (at your option)
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 General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
19 #include <QApplication>
21 #include <QHeaderView>
22 #include <QMessageBox>
23 #include <QProgressBar>
24 #include <QScrollArea>
25 #include <QTableWidget>
32 #include "repodlgs_common.h"
39 #include "qtg_cxxside.h"
43 /****************************************************************************
44 Compare unit_items (used for techs) by name
45 ****************************************************************************/
46 bool comp_less_than(const qlist_item
&q1
, const qlist_item
&q2
)
48 return (q1
.tech_str
< q2
.tech_str
);
51 /****************************************************************************
52 Constructor for research diagram
53 ****************************************************************************/
54 research_diagram::research_diagram(QWidget
*parent
): QWidget(parent
)
56 req
= create_reqtree(client_player(), true);
57 get_reqtree_dimensions(req
, &width
, &height
);
58 pcanvas
= qtg_canvas_create(width
, height
);
59 pcanvas
->map_pixmap
.fill(Qt::transparent
);
62 /****************************************************************************
63 Destructor for research diagram
64 ****************************************************************************/
65 research_diagram::~research_diagram()
67 qtg_canvas_free(pcanvas
);
71 /****************************************************************************
72 Recreates whole diagram and schedules update
73 ****************************************************************************/
74 void research_diagram::update_reqtree()
77 req
= create_reqtree(client_player(), true);
78 draw_reqtree(req
, pcanvas
, 0, 0, 0, 0, width
, height
);
82 /****************************************************************************
83 Mouse handler for research_diagram
84 ****************************************************************************/
85 void research_diagram::mousePressEvent(QMouseEvent
*event
)
87 Tech_type_id tech
= get_tech_on_reqtree(req
, event
->x(), event
->y());
89 if (event
->button() == Qt::LeftButton
&& can_client_issue_orders()) {
90 switch (player_invention_state(client_player(), tech
)) {
91 case TECH_PREREQS_KNOWN
:
92 dsend_packet_player_research(&client
.conn
, tech
);
95 dsend_packet_player_tech_goal(&client
.conn
, tech
);
103 /****************************************************************************
104 Paint event for research_diagram
105 ****************************************************************************/
106 void research_diagram::paintEvent(QPaintEvent
*event
)
111 painter
.drawPixmap(0, 0, width
, height
, pcanvas
->map_pixmap
);
115 /****************************************************************************
116 Returns size of research_diagram
117 ****************************************************************************/
118 QSize
research_diagram::size()
127 /****************************************************************************
128 Consctructor for science_report
129 ****************************************************************************/
130 science_report::science_report(): QWidget()
133 QSizePolicy
size_expanding_policy(QSizePolicy::Expanding
,
134 QSizePolicy::Expanding
);
135 QSizePolicy
size_fixed_policy(QSizePolicy::Minimum
, QSizePolicy::Minimum
);
137 goal_combo
= new QComboBox();
138 info_label
= new QLabel();
139 progress
= new QProgressBar();
140 progress_label
= new QLabel();
141 researching_combo
= new QComboBox();
142 sci_layout
= new QGridLayout();
143 res_diag
= new research_diagram();
144 scroll
= new QScrollArea();
148 progress
->setTextVisible(true);
149 progress_label
->setSizePolicy(size_fixed_policy
);
150 sci_layout
->addWidget(progress_label
, 0, 0, 1, 8);
151 sci_layout
->addWidget(researching_combo
, 1, 0, 1, 4);
152 researching_combo
->setSizePolicy(size_fixed_policy
);
153 sci_layout
->addWidget(progress
, 1, 5, 1, 4);
154 progress
->setSizePolicy(size_fixed_policy
);
155 sci_layout
->addWidget(goal_combo
, 2, 0, 1, 4);
156 goal_combo
->setSizePolicy(size_fixed_policy
);
157 sci_layout
->addWidget(info_label
, 2, 5, 1, 4);
158 info_label
->setSizePolicy(size_fixed_policy
);
160 size
= res_diag
->size();
161 res_diag
->setMinimumSize(size
);
162 scroll
->setAutoFillBackground(true);
163 scroll
->setPalette(QPalette(QColor(215,215,215)));
164 scroll
->setWidget(res_diag
);
165 scroll
->setSizePolicy(size_expanding_policy
);
166 sci_layout
->addWidget(scroll
, 4, 0, 1, 10);
168 QObject::connect(researching_combo
, SIGNAL(currentIndexChanged(int)),
169 SLOT(current_tech_changed(int)));
171 QObject::connect(goal_combo
, SIGNAL(currentIndexChanged(int)),
172 SLOT(goal_tech_changed(int)));
174 setLayout(sci_layout
);
178 /****************************************************************************
179 Destructor for science report
180 Removes "SCI" string marking it as closed
181 And frees given index on list marking it as ready for new widget
182 ****************************************************************************/
183 science_report::~science_report()
185 gui()->remove_repo_dlg("SCI");
186 gui()->remove_place(index
);
189 /****************************************************************************
190 Updates science_report and marks it as opened
191 It has to be called soon after constructor.
192 It could be in constructor but compiler will yell about not used variable
193 ****************************************************************************/
194 void science_report::init(bool raise
)
196 index
= gui()->gimme_place();
197 gui()->add_game_tab(this, _("Research"), index
);
198 if (raise
== false) {
199 gui()->game_tab_widget
->change_color(index
, Qt::red
);
201 gui()->game_tab_widget
->setCurrentIndex(index
);
203 gui()->add_repo_dlg("SCI");
207 /****************************************************************************
208 Schedules paint event in some qt queue
209 ****************************************************************************/
210 void science_report::redraw()
215 /****************************************************************************
216 Updates all important widgets on science_report
217 ****************************************************************************/
218 void science_report::update_report()
221 struct player_research
*research
= player_research_get(client_player());
224 int done
= research
->bulbs_researched
;
230 fc_assert_ret(NULL
!= research
);
240 if (research
->researching
!= A_UNSET
) {
241 total
= total_bulbs_required(client
.conn
.playing
);
246 curr_list
= new QList
<qlist_item
>;
247 goal_list
= new QList
<qlist_item
>;
248 progress_label
->setText(science_dialog_text());
249 progress_label
->setAlignment(Qt::AlignHCenter
);
250 info_label
->setAlignment(Qt::AlignHCenter
);
251 info_label
->setText(get_science_goal_text(research
->tech_goal
));
252 text
= get_science_target_text(¬_used
);
253 str
= QString::fromUtf8(text
);
254 progress
->setFormat(str
);
255 progress
->setMinimum(0);
256 progress
->setMaximum(total
);
259 progress
->setValue(done
);
262 progress
->setValue(done
);
265 /** Collect all techs which are reachable in the next step. */
266 advance_index_iterate(A_FIRST
, i
) {
267 if (TECH_PREREQS_KNOWN
== research
->inventions
[i
].state
) {
270 QString::fromUtf8(advance_name_translation(advance_by_number(i
)));
272 curr_list
->append(item
);
274 } advance_index_iterate_end
;
277 /** Collect all techs which are reachable in next 10 steps. */
278 advance_index_iterate(A_FIRST
, i
) {
279 if (player_invention_reachable(client_player(), i
, true)
280 && TECH_KNOWN
!= research
->inventions
[i
].state
281 && (i
== research
->tech_goal
282 || 10 >= research
->inventions
[i
].num_required_techs
)) {
284 = QString::fromUtf8(advance_name_translation(advance_by_number(i
)));
286 goal_list
->append(item
);
288 } advance_index_iterate_end
;
290 /** sort both lists */
291 qSort(goal_list
->begin(), goal_list
->end(), comp_less_than
);
292 qSort(curr_list
->begin(), curr_list
->end(), comp_less_than
);
294 /** fill combo boxes */
295 researching_combo
->blockSignals(true);
296 goal_combo
->blockSignals(true);
298 researching_combo
->clear();
300 for (int i
= 0; i
< curr_list
->count(); i
++) {
301 qvar
= curr_list
->at(i
).id
;
302 researching_combo
->insertItem(i
, curr_list
->at(i
).tech_str
, qvar
);
305 for (int i
= 0; i
< goal_list
->count(); i
++) {
306 qvar
= goal_list
->at(i
).id
;
307 goal_combo
->insertItem(i
, goal_list
->at(i
).tech_str
, qvar
);
310 /** set current tech and goal */
311 qres
= research
->researching
;
313 if (qres
== A_UNSET
) {
314 researching_combo
->insertItem(0, _("None"), A_UNSET
);
315 researching_combo
->setCurrentIndex(0);
317 for (int i
= 0; i
< researching_combo
->count(); i
++) {
318 qvar
= researching_combo
->itemData(i
);
321 researching_combo
->setCurrentIndex(i
);
326 qres
= research
->tech_goal
;
328 if (qres
== A_UNSET
) {
329 goal_combo
->insertItem(0, _("None"), A_UNSET
);
330 goal_combo
->setCurrentIndex(0);
332 for (int i
= 0; i
< goal_combo
->count(); i
++) {
333 qvar
= goal_combo
->itemData(i
);
336 goal_combo
->setCurrentIndex(i
);
341 researching_combo
->blockSignals(false);
342 goal_combo
->blockSignals(false);
347 /****************************************************************************
348 Calls update for research_diagram
349 ****************************************************************************/
350 void science_report::update_reqtree()
352 res_diag
->update_reqtree();
355 /****************************************************************************
356 Slot used when combo box with current tech changes
357 ****************************************************************************/
358 void science_report::current_tech_changed(int index
)
361 qvar
= researching_combo
->itemData(index
);
363 if (researching_combo
->hasFocus()) {
364 if (can_client_issue_orders()) {
365 dsend_packet_player_research(&client
.conn
, qvar
.toInt());
370 /****************************************************************************
371 Slot used when combo box with goal have been changed
372 ****************************************************************************/
373 void science_report::goal_tech_changed(int index
)
376 qvar
= goal_combo
->itemData(index
);
378 if (goal_combo
->hasFocus()) {
379 if (can_client_issue_orders()) {
380 dsend_packet_player_tech_goal(&client
.conn
, qvar
.toInt());
385 /**************************************************************************
386 Update the science report.
387 **************************************************************************/
388 void real_science_report_dialog_update(void)
391 science_report
*sci_rep
;
394 if (gui()->is_repo_dlg_open("SCI")) {
395 i
= gui()->gimme_index_of("SCI");
397 w
= gui()->game_tab_widget
->widget(i
);
398 sci_rep
= reinterpret_cast<science_report
*>(w
);
399 sci_rep
->update_report();
403 /**************************************************************************
404 Constructor for units report
405 **************************************************************************/
406 units_report::units_report(): QWidget()
408 QGridLayout
*units_layout
= new QGridLayout
;
409 units_widget
= new QTableWidget
;
410 find_button
= new QPushButton
;
411 upgrade_button
= new QPushButton
;
413 slist
<< _("Unit Type") << Q_("?Upgradable unit [short]:U") << _("In-Prog")
414 << _("Active") << _("Shield") << _("Food") << _("Gold");
415 units_widget
->setColumnCount(slist
.count());
416 units_widget
->setHorizontalHeaderLabels(slist
);
417 units_widget
->setProperty("showGrid", "false");
418 units_widget
->setProperty("selectionBehavior", "SelectRows");
419 units_widget
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
420 units_widget
->horizontalHeader()->resizeSections(QHeaderView::
422 units_widget
->verticalHeader()->setVisible(false);
423 units_widget
->setSelectionMode(QAbstractItemView::SingleSelection
);
424 find_button
->setText(_("Find _Nearest"));
425 find_button
->setEnabled(false);
426 upgrade_button
->setText(_("Upgrade"));
427 upgrade_button
->setEnabled(false);
428 units_layout
->addWidget(units_widget
, 1, 0, 5, 5);
429 units_layout
->addWidget(find_button
, 0, 0, 1, 1);
430 units_layout
->addWidget(upgrade_button
, 0, 1, 1, 1);
432 connect(find_button
, SIGNAL(pressed()), SLOT(find_units()));
433 connect(upgrade_button
, SIGNAL(pressed()), SLOT(upgrade_units()));
434 connect(units_widget
->selectionModel(),
435 SIGNAL(selectionChanged(const QItemSelection
&,
436 const QItemSelection
&)),
437 SLOT(selection_changed(const QItemSelection
&,
438 const QItemSelection
&)));
439 setLayout(units_layout
);
443 /****************************************************************************
444 Destructor for units report
445 ****************************************************************************/
446 units_report::~units_report()
448 gui()->remove_repo_dlg("UNI");
449 gui()->remove_place(index
);
452 /****************************************************************************
453 Updates units_report and marks it as opened
454 It has to be called soon after constructor.
455 ****************************************************************************/
456 void units_report::init()
459 index
= gui()->gimme_place();
460 gui()->add_game_tab(this, _("Units"), index
);
461 gui()->game_tab_widget
->setCurrentIndex(index
);
462 gui()->add_repo_dlg("UNI");
465 /**************************************************************************
466 Updates all widgets in units reports
467 **************************************************************************/
468 void units_report::update_report()
477 Unit_type_id utype_id
;
478 QTableWidgetItem
*unit_item
;
479 struct urd_info unit_array
[utype_count()];
480 struct urd_info unit_totals
;
481 struct urd_info
*info
;
484 units_widget
->setRowCount(0);
485 units_widget
->clearContents();
486 memset(unit_array
, '\0', sizeof(unit_array
));
487 memset(&unit_totals
, '\0', sizeof(unit_totals
));
489 players_iterate(pplayer
) {
490 if (client_has_player() && pplayer
!= client_player()) {
494 unit_list_iterate(pplayer
->units
, punit
) {
495 info
= unit_array
+ utype_index(unit_type(punit
));
497 if (0 != punit
->homecity
) {
498 for (output
= 0; output
< O_LAST
; output
++) {
499 info
->upkeep
[output
] += punit
->upkeep
[output
];
502 info
->active_count
++;
503 } unit_list_iterate_end
;
504 city_list_iterate(pplayer
->cities
, pcity
) {
505 if (VUT_UTYPE
== pcity
->production
.kind
) {
507 info
= unit_array
+ utype_index(pcity
->production
.value
.utype
);
508 /* Account for build slots in city */
509 (void) city_production_build_units(pcity
, true, &num_units
);
510 /* Unit is in progress even if it won't be done this turn */
511 num_units
= MAX(num_units
, 1);
512 info
->building_count
+= num_units
;
514 } city_list_iterate_end
;
515 } players_iterate_end
;
517 unit_type_iterate(utype
) {
518 utype_id
= utype_index(utype
);
519 info
= unit_array
+ utype_id
;
521 if (0 == info
->active_count
&& 0 == info
->building_count
) {
522 continue; /* We don't need a row for this type. */
524 units_widget
->setRowCount(row
+ 1);
525 for (column
= 0; column
< 7; column
++) {
526 unit_item
= new QTableWidgetItem
;
527 unit_item
->setTextAlignment(Qt::AlignHCenter
);
530 unit_item
->setTextAlignment(Qt::AlignLeft
);
531 unit_item
->setText(utype_name_translation(utype
));
533 unit_item
->setData(Qt::UserRole
, qvar
);
536 if ((client_has_player()
537 && NULL
!= can_upgrade_unittype(client_player(), utype
))) {
538 unit_item
->setCheckState(Qt::Checked
);
540 unit_item
->setCheckState(Qt::Unchecked
);
544 unit_item
->setText(QString::number(info
->building_count
));
547 unit_item
->setText(QString::number(info
->active_count
));
550 unit_item
->setText(QString::number(info
->upkeep
[O_SHIELD
]));
553 unit_item
->setText(QString::number(info
->upkeep
[O_FOOD
]));
556 unit_item
->setText(QString::number(info
->upkeep
[O_GOLD
]));
559 units_widget
->setItem(row
, column
, unit_item
);
562 unit_totals
.active_count
+= info
->active_count
;
563 for (output
= 0; output
< O_LAST
; output
++) {
564 unit_totals
.upkeep
[output
] += info
->upkeep
[output
];
566 unit_totals
.building_count
+= info
->building_count
;
569 } unit_type_iterate_end
;
571 units_widget
->setRowCount(row
);
572 for (column
= 0; column
< 7; column
++) {
573 unit_item
= new QTableWidgetItem
;
574 unit_item
->setTextAlignment(Qt::AlignHCenter
);
577 unit_item
->setTextAlignment(Qt::AlignLeft
);
578 unit_item
->setText(_("Totals:"));
581 unit_item
->setCheckState(Qt::Unchecked
);
584 unit_item
->setText(QString::number(unit_totals
.building_count
));
587 unit_item
->setText(QString::number(unit_totals
.active_count
));
590 unit_item
->setText(QString::number(unit_totals
.upkeep
[O_SHIELD
]));
593 unit_item
->setText(QString::number(unit_totals
.upkeep
[O_FOOD
]));
596 unit_item
->setText(QString::number(unit_totals
.upkeep
[O_GOLD
]));
599 units_widget
->setItem(row
- 1, column
, unit_item
);
601 units_widget
->resizeRowsToContents();
605 /**************************************************************************
607 **************************************************************************/
608 struct unit
*units_report::find_nearest_unit(const struct unit_type
*utype
,
611 struct unit
*best_candidate
= NULL
;
612 int best_dist
= FC_INFINITY
, dist
;
614 players_iterate(pplayer
) {
615 if (client_has_player() && pplayer
!= client_player()) {
619 unit_list_iterate(pplayer
->units
, punit
) {
620 if (utype
== unit_type(punit
)
621 && FOCUS_AVAIL
== punit
->client
.focus_status
622 && 0 < punit
->moves_left
623 && !punit
->done_moving
&& !punit
->ai_controlled
) {
624 dist
= sq_map_distance(unit_tile(punit
), ptile
);
625 if (dist
< best_dist
) {
626 best_candidate
= punit
;
630 } unit_list_iterate_end
;
631 } players_iterate_end
;
632 return best_candidate
;
635 /**************************************************************************
636 Action for button 'find units' in units report
637 **************************************************************************/
638 void units_report::find_units()
642 struct unit_type
*utype
;
644 utype
= utype_by_number(uid
);
645 ptile
= get_center_tile_mapcanvas();
646 if ((punit
= find_nearest_unit(utype
, ptile
))) {
647 center_tile_mapcanvas(unit_tile(punit
));
649 if (ACTIVITY_IDLE
== punit
->activity
650 || ACTIVITY_SENTRY
== punit
->activity
) {
651 if (can_unit_do_activity(punit
, ACTIVITY_IDLE
)) {
652 unit_focus_set_and_select(punit
);
658 /**************************************************************************
659 Upgrades selected units after clicking 'upgrade' button
660 **************************************************************************/
661 void units_report::upgrade_units()
664 struct unit_type
*utype
;
665 struct unit_type
*upgrade
;
666 utype
= utype_by_number(uid
);
674 upgrade
= can_upgrade_unittype(client_player(), utype
);
675 price
= unit_upgrade_price(client_player(), utype
, upgrade
);
676 fc_snprintf(buf
, ARRAY_SIZE(buf
), PL_("Treasury contains %d gold.",
677 "Treasury contains %d gold.",
678 client_player()->economic
.gold
),
679 client_player()->economic
.gold
);
680 fc_snprintf(buf2
, ARRAY_SIZE(buf2
),
681 PL_("Upgrade as many %s to %s as possible "
682 "for %d gold each?\n%s",
683 "Upgrade as many %s to %s as possible "
684 "for %d gold each?\n%s", price
),
685 utype_name_translation(utype
),
686 utype_name_translation(upgrade
), price
, buf
);
689 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
690 ask
.setDefaultButton(QMessageBox::Cancel
);
691 ask
.setWindowTitle(_("Upgrade Obsolete Units"));
695 case QMessageBox::Cancel
:
697 case QMessageBox::Ok
:
698 dsend_packet_unit_type_upgrade(&client
.conn
, utype_number(utype
));
703 /**************************************************************************
704 Action for changed selection in units report
705 **************************************************************************/
706 void units_report::selection_changed(const QItemSelection
& sl
,
707 const QItemSelection
& ds
)
709 QTableWidgetItem
*itm
;
712 struct unit_type
*utype
;
713 find_button
->setEnabled(false);
714 upgrade_button
->setEnabled(false);
720 curr_row
= sl
.indexes().at(0).row();
721 if (curr_row
>= 0 && curr_row
< max_row
) {
722 itm
= units_widget
->item(curr_row
, 0);
723 qvar
= itm
->data(Qt::UserRole
);
725 utype
= utype_by_number(uid
);
726 itm
= units_widget
->item(curr_row
, 3);
727 i
= itm
->text().toInt();
729 find_button
->setEnabled(true);
731 if (can_client_issue_orders()
732 && NULL
!= can_upgrade_unittype(client_player(), utype
)) {
733 upgrade_button
->setEnabled(true);
738 /**************************************************************************
739 Constructor for eceonmy report
740 **************************************************************************/
741 eco_report::eco_report(): QWidget()
743 QGridLayout
*eco_layout
= new QGridLayout
;
744 eco_widget
= new QTableWidget
;
745 disband_button
= new QPushButton
;
746 sell_button
= new QPushButton
;
747 sell_redun_button
= new QPushButton
;
748 eco_label
= new QLabel
;
751 slist
<< _("Type") << Q_("?Building or Unit type:Name") << _("Redundant")
752 << _("Count") << _("Cost") << _("U Total");
753 eco_widget
->setColumnCount(slist
.count());
754 eco_widget
->setHorizontalHeaderLabels(slist
);
755 eco_widget
->setProperty("showGrid", "false");
756 eco_widget
->setProperty("selectionBehavior", "SelectRows");
757 eco_widget
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
758 eco_widget
->horizontalHeader()->resizeSections(QHeaderView::Stretch
);
759 eco_widget
->verticalHeader()->setVisible(false);
760 eco_widget
->setSelectionMode(QAbstractItemView::SingleSelection
);
761 disband_button
->setText(_("_Disband"));
762 disband_button
->setEnabled(false);
763 sell_button
->setText(_("Sell _All"));
764 sell_button
->setEnabled(false);
765 sell_redun_button
->setText(_("Sell _Redundant"));
766 sell_redun_button
->setEnabled(false);
767 eco_layout
->addWidget(eco_widget
, 1, 0, 5, 5);
768 eco_layout
->addWidget(disband_button
, 0, 0, 1, 1);
769 eco_layout
->addWidget(sell_button
, 0, 1, 1, 1);
770 eco_layout
->addWidget(sell_redun_button
, 0, 2, 1, 1);
771 eco_layout
->addWidget(eco_label
, 6, 0, 1, 5);
773 connect(disband_button
, SIGNAL(pressed()), SLOT(disband_units()));
774 connect(sell_button
, SIGNAL(pressed()), SLOT(sell_buildings()));
775 connect(sell_redun_button
, SIGNAL(pressed()), SLOT(sell_redundant()));
776 connect(eco_widget
->selectionModel(),
777 SIGNAL(selectionChanged(const QItemSelection
&,
778 const QItemSelection
&)),
779 SLOT(selection_changed(const QItemSelection
&,
780 const QItemSelection
&)));
781 setLayout(eco_layout
);
784 /**************************************************************************
785 Destructor for economy report
786 **************************************************************************/
787 eco_report::~eco_report()
789 gui()->remove_repo_dlg("ECO");
790 gui()->remove_place(index
);
793 /**************************************************************************
794 Initializes place in tab for economy report
795 **************************************************************************/
796 void eco_report::init()
799 index
= gui()->gimme_place();
800 gui()->add_game_tab(this, _("Economy"), index
);
801 gui()->game_tab_widget
->setCurrentIndex(index
);
802 gui()->add_repo_dlg("ECO");
805 /**************************************************************************
806 Refresh all widgets for economy report
807 **************************************************************************/
808 void eco_report::update_report()
810 struct improvement_entry building_entries
[B_LAST
];
811 struct unit_entry unit_entries
[U_LAST
];
812 int entries_used
, building_total
, unit_total
, tax
, i
, j
;
814 QTableWidgetItem
*item
;
815 QFont f
= QApplication::font();
820 eco_widget
->setRowCount(0);
821 eco_widget
->clearContents();
822 get_economy_report_data(building_entries
, &entries_used
,
823 &building_total
, &tax
);
824 for (i
= 0; i
< entries_used
; i
++) {
825 struct improvement_entry
*pentry
= building_entries
+ i
;
826 struct impr_type
*pimprove
= pentry
->type
;
827 QPixmap
*pix
= get_building_sprite(tileset
, pimprove
)->pm
;
828 pix_scaled
= pix
->scaledToHeight(h
);
829 cid cid
= cid_encode_building(pimprove
);
831 eco_widget
->insertRow(i
);
832 for (j
= 0; j
< 6; j
++) {
833 item
= new QTableWidgetItem
;
834 item
->setTextAlignment(Qt::AlignHCenter
);
837 item
->setData(Qt::DecorationRole
, pix_scaled
);
838 item
->setData(Qt::UserRole
, cid
);
841 item
->setTextAlignment(Qt::AlignLeft
);
842 item
->setText(improvement_name_translation(pimprove
));
845 item
->setText(QString::number(pentry
->redundant
));
848 item
->setText(QString::number(pentry
->count
));
851 item
->setText(QString::number(pentry
->cost
));
854 item
->setText(QString::number(pentry
->total_cost
));
857 eco_widget
->setItem(i
, j
, item
);
861 get_economy_report_units_data(unit_entries
, &entries_used
, &unit_total
);
862 for (i
= 0; i
< entries_used
; i
++) {
863 struct unit_entry
*pentry
= unit_entries
+ i
;
864 struct unit_type
*putype
= pentry
->type
;
865 QPixmap
*pix
= get_unittype_sprite(tileset
, putype
,
866 direction8_invalid(), true)->pm
;
867 cid cid
= cid_encode_unit(putype
);
869 eco_widget
->insertRow(i
+ max_row
);
870 for (j
= 0; j
< 6; j
++) {
871 item
= new QTableWidgetItem
;
872 item
->setTextAlignment(Qt::AlignHCenter
);
875 item
->setData(Qt::DecorationRole
, *pix
);
876 item
->setData(Qt::UserRole
, cid
);
879 item
->setTextAlignment(Qt::AlignLeft
);
880 item
->setText(utype_name_translation(putype
));
883 item
->setText(QString::number(0));
886 item
->setText(QString::number(pentry
->count
));
889 item
->setText(QString::number(pentry
->cost
));
892 item
->setText(QString::number(pentry
->total_cost
));
895 eco_widget
->setItem(max_row
+ i
, j
, item
);
898 max_row
= max_row
+ i
;
899 fc_snprintf(buf
, sizeof(buf
), _("Income: %d Total Costs: %d"),
900 tax
, building_total
+ unit_total
);
901 eco_label
->setText(buf
);
904 /**************************************************************************
905 Action for selection changed in economy report
906 **************************************************************************/
907 void eco_report::selection_changed(const QItemSelection
& sl
,
908 const QItemSelection
& ds
)
910 QTableWidgetItem
*itm
;
913 struct universal selected
;
914 struct impr_type
*pimprove
;
915 disband_button
->setEnabled(false);
916 sell_button
->setEnabled(false);
917 sell_redun_button
->setEnabled(false);
923 curr_row
= sl
.indexes().at(0).row();
924 if (curr_row
>= 0 && curr_row
<= max_row
) {
925 itm
= eco_widget
->item(curr_row
, 0);
926 qvar
= itm
->data(Qt::UserRole
);
928 selected
= cid_decode(uid
);
929 switch (selected
.kind
) {
930 case VUT_IMPROVEMENT
:
931 pimprove
= selected
.value
.building
;
932 counter
= eco_widget
->item(curr_row
, 3)->text().toInt();
933 if (can_sell_building(pimprove
)) {
934 sell_button
->setEnabled(true);
936 itm
= eco_widget
->item(curr_row
, 2);
937 i
= itm
->text().toInt();
939 sell_redun_button
->setEnabled(true);
943 counter
= eco_widget
->item(curr_row
, 3)->text().toInt();
944 disband_button
->setEnabled(true);
947 log_error("Not supported type: %d.", selected
.kind
);
952 /**************************************************************************
953 Disband pointed units (in economy report)
954 **************************************************************************/
955 void eco_report::disband_units()
957 struct universal selected
;
963 selected
= cid_decode(uid
);
964 struct unit_type
*putype
= selected
.value
.utype
;
965 fc_snprintf(buf
, ARRAY_SIZE(buf
),
966 _("Do you really wish to disband "
967 "every %s (%d total)?"),
968 utype_name_translation(putype
), counter
);
972 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
973 ask
.setDefaultButton(QMessageBox::Cancel
);
974 ask
.setWindowTitle(_("Disband Units"));
977 case QMessageBox::Cancel
:
979 case QMessageBox::Ok
:
980 disband_all_units(putype
, false, buf
, sizeof(buf
));
985 ask
.setStandardButtons(QMessageBox::Ok
);
986 ask
.setWindowTitle(_("Disband Results"));
990 /**************************************************************************
991 Sell all pointed builings
992 **************************************************************************/
993 void eco_report::sell_buildings()
995 struct universal selected
;
1000 selected
= cid_decode(uid
);
1001 struct impr_type
*pimprove
= selected
.value
.building
;
1002 fc_snprintf(buf
, ARRAY_SIZE(buf
),
1003 _("Do you really wish to sell "
1004 "every %s (%d total)?"),
1005 improvement_name_translation(pimprove
), counter
);
1009 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
1010 ask
.setDefaultButton(QMessageBox::Cancel
);
1011 ask
.setWindowTitle(_("Sell Improvements"));
1014 case QMessageBox::Cancel
:
1016 case QMessageBox::Ok
:
1017 sell_all_improvements(pimprove
, false, buf
, sizeof(buf
));
1022 ask
.setStandardButtons(QMessageBox::Ok
);
1023 ask
.setWindowTitle(_("Sell-Off: Results"));
1027 /**************************************************************************
1028 Sells redundant buildings
1029 **************************************************************************/
1030 void eco_report::sell_redundant()
1032 struct universal selected
;
1037 selected
= cid_decode(uid
);
1038 struct impr_type
*pimprove
= selected
.value
.building
;
1039 fc_snprintf(buf
, ARRAY_SIZE(buf
),
1040 _("Do you really wish to sell "
1041 "every redundant %s (%d total)?"),
1042 improvement_name_translation(pimprove
), counter
);
1046 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
1047 ask
.setDefaultButton(QMessageBox::Cancel
);
1048 ask
.setWindowTitle(_("Sell Improvements"));
1051 case QMessageBox::Cancel
:
1053 case QMessageBox::Ok
:
1054 sell_all_improvements(pimprove
, true, buf
, sizeof(buf
));
1059 ask
.setStandardButtons(QMessageBox::Ok
);
1060 ask
.setWindowTitle(_("Sell-Off: Results"));
1064 /**************************************************************************
1065 Constructor for endgame report
1066 **************************************************************************/
1067 endgame_report::endgame_report(const struct packet_endgame_report
*packet
): QWidget()
1069 QGridLayout
*end_layout
= new QGridLayout
;
1070 end_widget
= new QTableWidget
;
1074 const size_t col_num
= packet
->category_num
+ 3;
1076 slist
<< _("Player") << _("Nation") << _("Score");
1077 for (i
= 0 ; i
< col_num
- 3; i
++) {
1078 slist
<< Q_(packet
->category_name
[i
]);
1080 end_widget
->setColumnCount(slist
.count());
1081 end_widget
->setHorizontalHeaderLabels(slist
);
1082 end_widget
->setProperty("showGrid", "false");
1083 end_widget
->setProperty("selectionBehavior", "SelectRows");
1084 end_widget
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
1085 end_widget
->verticalHeader()->setVisible(false);
1086 end_widget
->setSelectionMode(QAbstractItemView::SingleSelection
);
1087 end_layout
->addWidget(end_widget
, 1, 0, 5, 5);
1088 setLayout(end_layout
);
1092 /**************************************************************************
1093 Destructor for endgame report
1094 **************************************************************************/
1095 endgame_report::~endgame_report()
1097 gui()->remove_repo_dlg("END");
1098 gui()->remove_place(index
);
1101 /**************************************************************************
1102 Initializes place in tab for endgame report
1103 **************************************************************************/
1104 void endgame_report::init()
1106 index
= gui()->gimme_place();
1107 gui()->add_game_tab(this, _("Score"), index
);
1108 gui()->game_tab_widget
->setCurrentIndex(index
);
1109 gui()->add_repo_dlg("END");
1112 /**************************************************************************
1113 Refresh all widgets for economy report
1114 **************************************************************************/
1115 void endgame_report::update_report(const struct packet_endgame_player
*packet
)
1117 QTableWidgetItem
*item
;
1120 const struct player
*pplayer
= player_by_number(packet
->player_id
);
1121 const size_t col_num
= packet
->category_num
+ 3;
1122 end_widget
->insertRow(players
);
1123 for (i
= 0; i
< col_num
; i
++) {
1124 item
= new QTableWidgetItem
;
1127 item
->setText(player_name(pplayer
));
1130 pix
= get_nation_flag_sprite(tileset
, nation_of_player(pplayer
))->pm
;
1132 item
->setData(Qt::DecorationRole
, *pix
);
1136 item
->setText(QString::number(packet
->score
));
1137 item
->setTextAlignment(Qt::AlignHCenter
);
1140 item
->setText(QString::number(packet
->category_score
[i
-3]));
1141 item
->setTextAlignment(Qt::AlignHCenter
);
1144 end_widget
->setItem(players
, i
, item
);
1147 end_widget
->resizeRowsToContents();
1150 /**************************************************************************
1151 Display the science report. Optionally raise it.
1152 Typically triggered by F6.
1153 **************************************************************************/
1154 void science_report_dialog_popup(bool raise
)
1157 science_report
*sci_rep
;
1161 if (client_is_global_observer()){
1164 if (!gui()->is_repo_dlg_open("SCI")) {
1165 sci_rep
= new science_report
;
1166 sci_rep
->init(raise
);
1168 i
= gui()->gimme_index_of("SCI");
1170 if (gui()->game_tab_widget
->currentIndex() == i
) {
1173 w
= gui()->game_tab_widget
->widget(i
);
1174 sci_rep
= reinterpret_cast<science_report
*>(w
);
1175 if (raise
== false) {
1176 gui()->game_tab_widget
->change_color(i
, Qt::red
);
1178 gui()->game_tab_widget
->setCurrentWidget(sci_rep
);
1183 /**************************************************************************
1184 Update the economy report.
1185 **************************************************************************/
1186 void real_economy_report_dialog_update(void)
1189 eco_report
*eco_rep
;
1192 if (gui()->is_repo_dlg_open("ECO")) {
1193 i
= gui()->gimme_index_of("ECO");
1195 w
= gui()->game_tab_widget
->widget(i
);
1196 eco_rep
= reinterpret_cast<eco_report
*>(w
);
1197 eco_rep
->update_report();
1201 /**************************************************************************
1202 Display the economy report. Optionally raise it.
1203 Typically triggered by F5.
1204 **************************************************************************/
1205 void economy_report_dialog_popup(bool raise
)
1208 eco_report
*eco_rep
;
1210 if (!gui()->is_repo_dlg_open("ECO")) {
1211 eco_rep
= new eco_report
;
1213 eco_rep
->update_report();
1216 i
= gui()->gimme_index_of("ECO");
1218 w
= gui()->game_tab_widget
->widget(i
);
1219 eco_rep
= reinterpret_cast<eco_report
*>(w
);
1220 gui()->game_tab_widget
->setCurrentWidget(eco_rep
);
1224 /**************************************************************************
1225 Update the units report.
1226 **************************************************************************/
1227 void real_units_report_dialog_update(void)
1230 units_report
*units_rep
;
1233 if (gui()->is_repo_dlg_open("UNI")) {
1234 i
= gui()->gimme_index_of("UNI");
1236 w
= gui()->game_tab_widget
->widget(i
);
1237 units_rep
= reinterpret_cast<units_report
*>(w
);
1238 units_rep
->update_report();
1242 /**************************************************************************
1243 Display the units report. Optionally raise it.
1244 Typically triggered by F2.
1245 **************************************************************************/
1246 void units_report_dialog_popup(bool raise
)
1251 if (!gui()->is_repo_dlg_open("UNI")) {
1252 units_report
*units_rep
= new units_report
;
1254 units_rep
->update_report();
1256 i
= gui()->gimme_index_of("UNI");
1258 w
= gui()->game_tab_widget
->widget(i
);
1259 ur
= reinterpret_cast<units_report
*>(w
);
1260 gui()->game_tab_widget
->setCurrentWidget(ur
);
1264 /****************************************************************************
1265 Show a dialog with player statistics at endgame.
1266 ****************************************************************************/
1267 void endgame_report_dialog_start(const struct packet_endgame_report
*packet
)
1269 endgame_report
*end_rep
;
1270 end_rep
= new endgame_report(packet
);
1274 /****************************************************************************
1275 Received endgame report information about single player.
1276 ****************************************************************************/
1277 void endgame_report_dialog_player(const struct packet_endgame_player
*packet
)
1280 endgame_report
*end_rep
;
1283 if (gui()->is_repo_dlg_open("END")) {
1284 i
= gui()->gimme_index_of("END");
1286 w
= gui()->game_tab_widget
->widget(i
);
1287 end_rep
= reinterpret_cast<endgame_report
*>(w
);
1288 end_rep
->update_report(packet
);
1292 /****************************************************************************
1293 Resize and redraw the requirement tree.
1294 ****************************************************************************/
1295 void science_report_dialog_redraw(void)
1298 science_report
*sci_rep
;
1301 if (gui()->is_repo_dlg_open("SCI")) {
1302 i
= gui()->gimme_index_of("SCI");
1304 w
= gui()->game_tab_widget
->widget(i
);
1305 sci_rep
= reinterpret_cast<science_report
*>(w
);