Freeciv-3.3
Loading...
Searching...
No Matches
citydlg.cpp
Go to the documentation of this file.
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)
6 any later version.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18// Qt
19#include <QApplication>
20#include <QCheckBox>
21#include <QGroupBox>
22#include <QHeaderView>
23#include <QImage>
24#include <QMenu>
25#include <QMessageBox>
26#include <QPainter>
27#include <QRadioButton>
28#include <QRect>
29#include <QScreen>
30#include <QScrollArea>
31#include <QScrollBar>
32#include <QSplitter>
33#include <QToolTip>
34#include <QVBoxLayout>
35#include <QWheelEvent>
36#include <QWidgetAction>
37
38// utility
39#include "support.h"
40
41// common
42#include "citizens.h"
43#include "city.h"
44#include "game.h"
45
46//agents
47#include "cma_core.h"
48#include "cma_fec.h"
49
50// client
51#include "citydlg_common.h"
52#include "client_main.h"
53#include "climisc.h"
54#include "control.h"
55#include "global_worklist.h"
56#include "helpdata.h"
57#include "mapview_common.h"
58#include "movement.h"
59#include "sprite.h"
60#include "text.h"
61#include "tilespec.h"
62
63// gui-qt
64#include "citydlg.h"
65#include "colors.h"
66#include "fc_client.h"
67#include "gui_main.h"
68#include "hudwidget.h"
69
70static bool city_dlg_created = false;
75extern QString split_text(QString text, bool cut);
76extern QString cut_helptext(QString text);
77
78/************************************************************************/
82{
83 m_timer.start();
84 startTimer(50);
86 sfont = new QFont;
88 pix = nullptr;
89}
90
91/************************************************************************/
95{
96 if (pix != nullptr) {
97 delete pix;
98 }
99 delete sfont;
100}
101
102/************************************************************************/
109
110/************************************************************************/
114{
115 struct sprite *sprite;
117 QImage img;
119 QRect crop;
120
121 if (VUT_UTYPE == target->kind) {
124 } else {
126 }
127 if (pix != nullptr) {
128 delete pix;
129 }
130 if (sprite == nullptr) {
131 pix = nullptr;
132 return;
133 }
134 img = sprite->pm->toImage();
136 cropped_img = img.copy(crop);
137 tpix = QPixmap::fromImage(cropped_img);
138 pix = new QPixmap(tpix.width(), tpix.height());
139 pix->fill(Qt::transparent);
140 pixmap_copy(pix, &tpix, 0 , 0, 0, 0, tpix.width(), tpix.height());
141}
142
143/************************************************************************/
147{
148 struct sprite *sprite;
149
152 } else {
153 sprite = nullptr;
154 }
155 if (pix != nullptr) {
156 delete pix;
157 }
158 if (sprite == nullptr) {
159 pix = nullptr;
160 return;
161 }
162 pix = new QPixmap(sprite->pm->width(),
163 sprite->pm->height());
164 pix->fill(Qt::transparent);
165 pixmap_copy(pix, sprite->pm, 0 , 0, 0, 0,
166 sprite->pm->width(), sprite->pm->height());
167 if (isVisible()) {
168 update();
169 }
170}
171
172/************************************************************************/
176{
177 if ((value() != minimum() && value() < maximum())
178 || (0 == minimum() && 0 == maximum())) {
179 m_animate_step = m_timer.elapsed() / 50;
180 update();
181 }
182}
183
184/************************************************************************/
188{
189 QPainter p;
191 QColor c;
192 QRect r, rx, r2;
193 int max;
194 int f_pixel_size;
195 int pix_width = 0;
196 int pixel_size = sfont->pixelSize();
197 int pbw, pbh;
198
199 if (pix != nullptr) {
200 pix_width = height() - 4;
201 }
202
203 if (pixel_size > 0) {
205 } else {
207
208 f_pixel_size = fm.height();
209 }
210
211 pbw = width();
212 pbh = height();
213
214 rx.setX(0);
215 rx.setY(0);
216 rx.setWidth(pbw);
217 rx.setHeight(pbh);
218 p.begin(this);
219 p.drawLine(rx.topLeft(), rx.topRight());
220 p.drawLine(rx.bottomLeft(), rx.bottomRight());
221
222 max = maximum();
223
224 if (max == 0) {
225 max = 1;
226 }
227
228 r = QRect(0, 0, pbw * value() / max, pbh);
229
230 gx = QLinearGradient(0 , 0, 0, pbh);
231 c = QColor(palette().color(QPalette::Highlight));
232 gx.setColorAt(0, c);
233 gx.setColorAt(0.5, QColor(40, 40, 40));
234 gx.setColorAt(1, c);
235 p.fillRect(r, QBrush(gx));
236 p.setClipRegion(reg.translated(m_animate_step % 32, 0));
237
238 g = QLinearGradient(0 , 0, pbw, pbh);
239 c.setAlphaF(0.1);
240 g.setColorAt(0, c);
241 c.setAlphaF(0.9);
242 g.setColorAt(1, c);
243 p.fillRect(r, QBrush(g));
244
245 p.setClipping(false);
246 r2 = QRect(pbw * value() / max, 0, pbw, pbh);
247 c = palette().color(QPalette::Window);
248 p.fillRect(r2, c);
249
250 // Draw icon
251 if (pix != nullptr) {
252 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
253 p.drawPixmap(2 , 2, pix_width
254 * static_cast<float>(pix->width()) / pix->height(),
255 pix_width, *pix, 0, 0, pix->width(), pix->height());
256 }
257
258 // Draw text
259 c = palette().color(QPalette::Text);
260 p.setPen(c);
261 sfont->setCapitalization(QFont::AllUppercase);
262 sfont->setBold(true);
263
264 if (text().contains('\n')) {
265 QString s1, s2;
266 int i, j;
267 QFont tmp_font = *sfont; // Don't make changes to font to be kept
268
269 i = text().indexOf('\n');
270 s1 = text().left(i);
271 s2 = text().right(text().length() - i);
272
273 if (2 * f_pixel_size >= 3 * pbh / 2) {
274 tmp_font.setPixelSize(pbh / 3);
275 }
276
277 p.setFont(tmp_font);
278
279 j = pbh - 2 * f_pixel_size;
280 p.setCompositionMode(QPainter::CompositionMode_ColorDodge);
282
283 if (fm.horizontalAdvance(s1) > rx.width()) {
284 s1 = fm.elidedText(s1, Qt::ElideRight, rx.width());
285 }
286
287 i = rx.width() - fm.horizontalAdvance(s1) + pix_width;
288 i = qMax(0, i);
289 p.drawText(i / 2, j / 3 + f_pixel_size, s1);
290
291 if (fm.horizontalAdvance(s2) > rx.width()) {
292 s2 = fm.elidedText(s2, Qt::ElideRight, rx.width());
293 }
294
295 i = rx.width() - fm.horizontalAdvance(s2) + pix_width;
296 i = qMax(0, i);
297
298 p.drawText(i / 2, pbh - j / 3, s2);
299 } else {
300 QString s;
301 int i, j;
302
303 p.setFont(*sfont);
304
305 s = text();
306 j = pbh - f_pixel_size;
307 p.setCompositionMode(QPainter::CompositionMode_ColorDodge);
309
310 if (fm.horizontalAdvance(s) > rx.width()) {
311 s = fm.elidedText(s, Qt::ElideRight, rx.width());
312 }
313
314 i = rx.width() - fm.horizontalAdvance(s) + pix_width;
315 i = qMax(0, i);
316 p.drawText(i / 2, j / 2 + f_pixel_size, s);
317 }
318
319 p.end();
320}
321
322/************************************************************************/
326{
327 int offset;
328 QRect r(-50, 0, width() + 50, height());
329 int chunk_width = 16;
330 int size = width() + 50;
331 reg = QRegion();
332
333 for (offset = 0; offset < (size * 2); offset += (chunk_width * 2)) {
334 QPolygon a;
335
336 a.setPoints(4, r.x(), r.y() + offset,
337 r.x() + r.width(), (r.y() + offset) - size,
338 r.x() + r.width(),
339 (r.y() + offset + chunk_width) - size,
340 r.x(), r.y() + offset + chunk_width);
341 reg += QRegion(a);
342 }
343
344}
345
346/************************************************************************/
349static void pixmap_put_x(QPixmap *pix)
350{
351 QPen pen(QColor(0, 0, 0));
352 QPainter p;
353
354 pen.setWidth(2);
355 p.begin(pix);
356 p.setRenderHint(QPainter::Antialiasing);
357 p.setPen(pen);
358 p.drawLine(0, 0, pix->width(), pix->height());
359 p.drawLine(pix->width(), 0, 0, pix->height());
360 p.end();
361}
362
363/************************************************************************/
366impr_item::impr_item(QWidget *parent, const impr_type *building,
367 struct city *pcity): QLabel(parent)
368{
370 dlgcity = pcity;
371 impr = building;
372 impr_pixmap = nullptr;
373 struct sprite *sprite;
374 sprite = get_building_sprite(tileset , building);
375
376 if (sprite != nullptr) {
378 sprite->pm->height());
379 impr_pixmap->map_pixmap.fill(Qt::transparent);
380 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
381 sprite->pm->width(), sprite->pm->height());
382 } else {
384 impr_pixmap->map_pixmap.fill(Qt::red);
385 }
386
389 setToolTip(get_tooltip_improvement(building, pcity, true).trimmed());
390}
391
392/************************************************************************/
396{
397 if (impr_pixmap) {
399 }
400}
401
402/************************************************************************/
406{
408 update();
409}
410
411/************************************************************************/
414#ifndef FC_QT5_MODE
416#else // FC_QT5_MODE
417void impr_item::enterEvent(QEvent *event)
418#endif // FC_QT5_MODE
419{
420 struct sprite *sprite;
421 QPainter p;
422
423 if (impr_pixmap) {
424 canvas_free(impr_pixmap);
425 }
426
428 if (impr && sprite) {
429 impr_pixmap = qtg_canvas_create(sprite->pm->width(),
430 sprite->pm->height());
431 impr_pixmap->map_pixmap.fill(QColor(palette().color(QPalette::Highlight)));
432 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
433 sprite->pm->width(), sprite->pm->height());
434 } else {
435 impr_pixmap = qtg_canvas_create(10, 10);
436 impr_pixmap->map_pixmap.fill(QColor(palette().color(QPalette::Highlight)));
437 }
438
439 init_pix();
440}
441
442/************************************************************************/
446{
447 struct sprite *sprite;
448
449 if (impr_pixmap) {
451 }
452
454 if (impr && sprite) {
456 sprite->pm->height());
457 impr_pixmap->map_pixmap.fill(Qt::transparent);
458 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
459 sprite->pm->width(), sprite->pm->height());
460 } else {
462 impr_pixmap->map_pixmap.fill(Qt::red);
463 }
464
465 init_pix();
466}
467
468/************************************************************************/
472{
474 layout = new QHBoxLayout(this);
475 init_layout();
476}
477
478/************************************************************************/
482{
483 QSizePolicy size_fixed_policy(QSizePolicy::Fixed,
484 QSizePolicy::MinimumExpanding,
485 QSizePolicy::Slider);
486
489}
490
491/************************************************************************/
495{
496
497}
498
499/************************************************************************/
503{
504 impr_list.append(item);
505}
506
507/************************************************************************/
511{
512 int i = impr_list.count();
513 impr_item *ui;
514 int j;
515 setUpdatesEnabled(false);
516 setMouseTracking(false);
517
518 for (j = 0; j < i; j++) {
519 ui = impr_list[j];
520 layout->removeWidget(ui);
521 delete ui;
522 }
523
524 while (!impr_list.empty()) {
525 impr_list.removeFirst();
526 }
527
528 setMouseTracking(true);
529 setUpdatesEnabled(true);
530}
531
532/************************************************************************/
536{
537 QPoint p;
538
539 p = parentWidget()->parentWidget()->pos();
540 p = mapToGlobal(p);
541
542 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
543 event->angleDelta(),
544 event->buttons(),
545 event->modifiers(),
546 event->phase(), false, event->source());
547
548 QApplication::sendEvent(parentWidget(), &new_event);
549}
550
551/************************************************************************/
555{
556 int i = impr_list.count();
557 int j;
558 int h = 0;
559 impr_item *ui;
560
561 setUpdatesEnabled(false);
562 hide();
563
564 for (j = 0; j < i; j++) {
565 ui = impr_list[j];
566 h = ui->height();
567 layout->addWidget(ui, 0, Qt::AlignVCenter);
568 }
569
570 if (impr_list.count() > 0) {
571 parentWidget()->parentWidget()->setFixedHeight(city_dlg->scroll_height
572 + h + 6);
573 } else {
574 parentWidget()->parentWidget()->setFixedHeight(0);
575 }
576
577 show();
578 setUpdatesEnabled(true);
579 layout->update();
581}
582
583/************************************************************************/
587{
588 QPoint p;
589
590 p = parentWidget()->parentWidget()->pos();
591 p = mapToGlobal(p);
592
593 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
594 event->angleDelta(),
595 event->buttons(),
596 event->modifiers(),
597 event->phase(), false, event->source());
598
599 QApplication::sendEvent(parentWidget()->parentWidget(),
600 &new_event);
601}
602
603/************************************************************************/
607{
609 return;
610 }
611
612 if (event->button() == Qt::LeftButton) {
613 char buf[256];
614 int price;
615 const int impr_id = improvement_number(impr);
616 const int city_id = dlgcity->id;
618
620 impr) != TR_SUCCESS) {
621 return;
622 }
623
625
628 PL_("Sell %s for %d gold?",
629 "Sell %s for %d gold?", price),
631
632 ask->set_text_title(buf, (_("Sell improvement?")));
633 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
634 ask->setAttribute(Qt::WA_DeleteOnClose);
635 connect(ask, &hud_message_box::accepted, [=]() {
636 struct city *pcity = game_city_by_number(city_id);
637
638 if (pcity == nullptr) {
639 return;
640 }
642 });
643 ask->show();
644 }
645}
646
647/************************************************************************/
651 bool supp, int hppy_cost) : QLabel()
652{
655 QImage img;
656 QRect crop;
657 qunit = punit;
658 struct canvas *unit_pixmap;
659 struct tileset *tmp;
660 float isosize;
661
663 supported = supp;
664
665 tmp = nullptr;
666 if (unscaled_tileset) {
667 tmp = tileset;
669 }
670 isosize = 0.6;
672 isosize = 0.45;
673 }
674
675 if (punit) {
676 if (supported) {
679 } else {
682 }
683
684 unit_pixmap->map_pixmap.fill(Qt::transparent);
685 put_unit(punit, unit_pixmap, 1.0, 0, 0);
686
687 if (supported) {
691 }
692 } else {
694 unit_pixmap->map_pixmap.fill(Qt::transparent);
695 }
696
697 img = unit_pixmap->map_pixmap.toImage();
699 cropped_img = img.copy(crop);
702 * isosize, Qt::SmoothTransformation);
703 } else {
705 Qt::SmoothTransformation);
706 }
708 if (tmp != nullptr) {
709 tileset = tmp;
710 }
711
713 setFixedWidth(unit_img.width() + 4);
714 setFixedHeight(unit_img.height());
716}
717
718/************************************************************************/
722{
723 setPixmap(QPixmap::fromImage(unit_img));
724 update();
725}
726
727/************************************************************************/
733
734/************************************************************************/
738{
739 QMenu *menu;
740
742 return;
743 }
744
745 if (unit_owner(qunit) != client_player()) {
746 return;
747 }
748
749 menu = new QMenu(gui()->central_wdg);
750 menu->addAction(activate);
751 menu->addAction(activate_and_close);
752
753 if (sentry) {
754 menu->addAction(sentry);
755 }
756
757 if (fortify) {
758 menu->addAction(fortify);
759 }
760
761 if (change_home) {
762 menu->addAction(change_home);
763 }
764
765 if (load) {
766 menu->addAction(load);
767 }
768
769 if (unload) {
770 menu->addAction(unload);
771 }
772
773 if (unload_trans) {
774 menu->addAction(unload_trans);
775 }
776
777 if (disband_action) {
778 menu->addAction(disband_action);
779 }
780
781 if (upgrade) {
782 menu->addAction(upgrade);
783 }
784
785 menu->popup(event->globalPos());
786}
787
788/************************************************************************/
792{
793 struct unit_list *qunits;
794
796 return;
797 }
798
801 activate = new QAction(_("Activate unit"), this);
802 connect(activate, &QAction::triggered, this, &unit_item::activate_unit);
803 activate_and_close = new QAction(_("Activate and close dialog"), this);
804 connect(activate_and_close, &QAction::triggered, this,
806
808 sentry = new QAction(_("Sentry unit"), this);
809 connect(sentry, &QAction::triggered, this, &unit_item::sentry_unit);
810 } else {
811 sentry = nullptr;
812 }
813
815 fortify = new QAction(_("Fortify unit"), this);
816 connect(fortify, &QAction::triggered, this, &unit_item::fortify_unit);
817 } else {
818 fortify = nullptr;
819 }
821 disband_action = new QAction(_("Disband unit"), this);
822 connect(disband_action, &QAction::triggered, this, &unit_item::disband);
823 } else {
824 disband_action = nullptr;
825 }
826
829 this);
830 connect(change_home, &QAction::triggered, this, &unit_item::change_homecity);
831 } else {
832 change_home = nullptr;
833 }
834
835 if (units_can_load(qunits)) {
836 load = new QAction(_("Load"), this);
837 connect(load, &QAction::triggered, this, &unit_item::load_unit);
838 } else {
839 load = nullptr;
840 }
841
842 if (units_can_unload(&(wld.map), qunits)) {
843 unload = new QAction(_("Unload"), this);
844 connect(unload, &QAction::triggered, this, &unit_item::unload_unit);
845 } else {
846 unload = nullptr;
847 }
848
850 unload_trans = new QAction(_("Unload All From Transporter"), this);
851 connect(unload_trans, &QAction::triggered, this, &unit_item::unload_all);
852 } else {
853 unload_trans = nullptr;
854 }
855
856 if (units_can_upgrade(&(wld.map), qunits)) {
857 upgrade = new QAction(_("Upgrade Unit"), this);
858 connect(upgrade, &QAction::triggered, this, &unit_item::upgrade_unit);
859 } else {
860 upgrade = nullptr;
861 }
862
864}
865
866/************************************************************************/
870{
871 struct unit_list *punits;
873
874 if (punit == nullptr) {
875 return;
876 }
877
882}
883
884/************************************************************************/
891
892/************************************************************************/
899
900/************************************************************************/
907
908/************************************************************************/
919
920/************************************************************************/
929
930/************************************************************************/
940
941/************************************************************************/
945{
946 if (qunit) {
948 }
949}
950
951/************************************************************************/
955{
956 if (qunit) {
958 }
959}
960
961/************************************************************************/
964#ifndef FC_QT5_MODE
966#else // FC_QT5_MODE
967void unit_item::enterEvent(QEvent *event)
968#endif // FC_QT5_MODE
969{
970 QImage temp_img(unit_img.size(), QImage::Format_ARGB32_Premultiplied);
971 QPainter p;
972
973 p.begin(&temp_img);
974 p.fillRect(0, 0, unit_img.width(), unit_img.height(),
975 QColor(palette().color(QPalette::Highlight)));
976 p.drawImage(0, 0, unit_img);
977 p.end();
978
979 setPixmap(QPixmap::fromImage(temp_img));
980 update();
981}
982
983/************************************************************************/
987{
988 init_pix();
989}
990
991/************************************************************************/
995{
996 QPoint p;
997
998 p = parentWidget()->parentWidget()->pos();
999 p = mapToGlobal(p);
1000
1001 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1002 event->angleDelta(),
1003 event->buttons(),
1004 event->modifiers(),
1005 event->phase(), false, event->source());
1006
1007 QApplication::sendEvent(parentWidget()->parentWidget(),
1008 &new_event);
1009}
1010
1011/************************************************************************/
1015{
1016 if (event->button() == Qt::LeftButton) {
1017 if (qunit) {
1020 }
1021 }
1022}
1023
1024/************************************************************************/
1028{
1029 if (qunit) {
1031 }
1032}
1033
1034/************************************************************************/
1038{
1039 layout = new QHBoxLayout(this);
1040 init_layout();
1041 supports = supp;
1042}
1043
1044/************************************************************************/
1048{
1050 unit_list.clear();
1051}
1052
1053/************************************************************************/
1057{
1058 unit_list.append(item);
1059}
1060
1061/************************************************************************/
1065{
1066 QSizePolicy size_fixed_policy(QSizePolicy::Fixed,
1067 QSizePolicy::MinimumExpanding,
1068 QSizePolicy::Slider);
1071}
1072
1073/************************************************************************/
1077{
1078 QPoint p;
1079
1080 p = parentWidget()->parentWidget()->pos();
1081 p = mapToGlobal(p);
1082
1083 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1084 event->angleDelta(),
1085 event->buttons(),
1086 event->modifiers(),
1087 event->phase(), false, event->source());
1088
1089 QApplication::sendEvent(parentWidget(), &new_event);
1090}
1091
1092/************************************************************************/
1096{
1097 int i = unit_list.count();
1098 int j;
1099 int h;
1100 float hexfix;
1101 unit_item *ui;
1102
1103 setUpdatesEnabled(false);
1104 hide();
1105
1106 for (j = 0; j < i; j++) {
1107 ui = unit_list[j];
1108 layout->addWidget(ui, 0, Qt::AlignVCenter);
1109 }
1110
1111 hexfix = 1.0;
1113 hexfix = 0.75;
1114 }
1115
1117 h = tileset_unit_width(get_tileset()) * 0.7 * hexfix + 6;
1118 } else {
1120 }
1121 if (unit_list.count() > 0) {
1122 parentWidget()->parentWidget()->setFixedHeight(city_dlg->scroll_height
1123 + h);
1124 } else {
1125 parentWidget()->parentWidget()->setFixedHeight(0);
1126 }
1127 show();
1128 setUpdatesEnabled(true);
1129 layout->update();
1131}
1132
1133/************************************************************************/
1137{
1138 int i = unit_list.count();
1139 unit_item *ui;
1140 int j;
1141 setUpdatesEnabled(false);
1142 setMouseTracking(false);
1143
1144 for (j = 0; j < i; j++) {
1145 ui = unit_list[j];
1146 layout->removeWidget(ui);
1147 delete ui;
1148 }
1149
1150 while (!unit_list.empty()) {
1151 unit_list.removeFirst();
1152 }
1153
1154 setMouseTracking(true);
1155 setUpdatesEnabled(true);
1156}
1157
1158/************************************************************************/
1162city_label::city_label(int t, QWidget *parent) : QLabel(parent)
1163{
1164 type = t;
1165}
1166
1167/************************************************************************/
1171{
1172 int citnum, i;
1173 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
1174 int num_citizens = pcity->size;
1175
1176 if (cma_is_city_under_agent(pcity, nullptr)) {
1177 return;
1178 }
1179
1180 i = 1 + (num_citizens * 5 / 200);
1181 w = w / i;
1182 citnum = event->pos().x() / w;
1183
1184 if (!can_client_issue_orders()) {
1185 return;
1186 }
1187
1189}
1190
1191/************************************************************************/
1195{
1196 pcity = pciti;
1197}
1198
1199/************************************************************************/
1203{
1205 radius = 0;
1211 view->map_pixmap.fill(Qt::black);
1213 miniview->map_pixmap.fill(Qt::black);
1214 delta_x = 0;
1215 delta_y = 0;
1216 setContextMenuPolicy(Qt::CustomContextMenu);
1217 connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
1218 this, SLOT(context_menu(const QPoint &)));
1219}
1220
1221/************************************************************************/
1229
1230/************************************************************************/
1234{
1236 QString str;
1237
1238 painter.begin(this);
1239 painter.drawPixmap(0, 0, zoomed_pixmap);
1240
1241 if (cma_is_city_under_agent(mcity, nullptr)) {
1242 painter.fillRect(0, 0, zoomed_pixmap.width(), zoomed_pixmap.height(),
1243 QBrush(QColor(60, 60 , 60 , 110)));
1244 painter.setPen(QColor(255, 255, 255));
1245 // TRANS: %1 is custom string choosen by player.
1246 str = QString(_("Governor %1"))
1248 painter.drawText(5, zoomed_pixmap.height() - 10, str);
1249 }
1250
1251 painter.end();
1252}
1253
1254/************************************************************************/
1257void city_map::set_pixmap(struct city *pcity, float z)
1258{
1259 int r, max_r;
1260 QSize size;
1261
1262 zoom = z;
1263 r = sqrt(city_map_radius_sq_get(pcity));
1264
1265 if (radius != r) {
1267 radius = r;
1269 cutted_width = wdth * (r + 1) / max_r;
1270 cutted_height = hight * (r + 1) / max_r;
1273 delta_x = (wdth - cutted_width) / 2;
1274 delta_y = (hight - cutted_height) / 2;
1276 miniview->map_pixmap.fill(Qt::black);
1277 }
1278
1282 size = miniview->map_pixmap.size();
1284 Qt::KeepAspectRatio,
1285 Qt::SmoothTransformation);
1287 mcity = pcity;
1288}
1289
1290/************************************************************************/
1294{
1295 return zoomed_pixmap.size();
1296}
1297
1298/************************************************************************/
1302{
1303 return zoomed_pixmap.size();
1304}
1305
1306/************************************************************************/
1310{
1312 QPoint pos;
1313
1314 if (!can_client_issue_orders() || event->button() != Qt::LeftButton) {
1315 return;
1316 }
1317
1318 pos = event->pos();
1319 canvas_x = pos.x() / zoom + delta_x;
1320 canvas_y = pos.y() / zoom + delta_y;
1321
1323 canvas_x, canvas_y)) {
1325 }
1326}
1327
1328/************************************************************************/
1332{
1334 QAction *con_cultivate = nullptr;
1335 QAction *con_irrig = nullptr;
1336 QAction *con_plant = nullptr;
1337 QAction *con_mine = nullptr;
1338 QAction *con_road = nullptr;
1339 QAction *con_trfrm = nullptr;
1340 QAction *con_clean = nullptr;
1341 QAction *con_clear = nullptr;
1342 QMenu *con_menu;
1344 struct terrain *pterr;
1345 struct tile *ptile;
1346 struct universal for_terr;
1347 struct worker_task *ptask;
1348 int city_id = mcity->id;
1349
1350 if (!can_client_issue_orders()) {
1351 return;
1352 }
1353
1354 canvas_x = point.x() / zoom + delta_x;
1355 canvas_y = point.y() / zoom + delta_y;
1356
1358 canvas_x, canvas_y)) {
1359 return;
1360 }
1361
1363 city_x, city_y);
1364 pterr = tile_terrain(ptile);
1365 for_terr.kind = VUT_TERRAIN;
1366 for_terr.value.terrain = pterr;
1368
1369 wid_act = new QWidgetAction(this);
1370 wid_act->setDefaultWidget(new QLabel(_("Autoworker activity:")));
1371
1372 con_menu = new QMenu(this);
1373 con_menu->addAction(wid_act);
1374
1375 if (pterr->plant_result != nullptr
1377 con_plant = con_menu->addAction(_("Plant"));
1378 }
1380 con_mine = con_menu->addAction(Q_("?act:Mine"));
1381 }
1382
1383 if (pterr->cultivate_result != nullptr
1385 con_cultivate = con_menu->addAction(_("Cultivate"));
1386 }
1388 con_irrig = con_menu->addAction(_("Irrigate"));
1389 }
1390
1391 if (pterr->transform_result != pterr && pterr->transform_result != nullptr
1393 nullptr, &for_terr)) {
1394 con_trfrm = con_menu->addAction(_("Transform"));
1395 }
1396
1397 if (next_extra_for_tile(ptile, EC_ROAD, city_owner(mcity), nullptr) != nullptr) {
1398 con_road = con_menu->addAction(_("Road"));
1399 }
1400
1401 if (prev_extra_in_tile(ptile, ERM_CLEAN,
1402 city_owner(mcity), nullptr) != nullptr) {
1403 con_clean = con_menu->addAction(_("Clean"));
1404 }
1405
1406 if (ptask != nullptr) {
1407 con_clear = con_menu->addAction(_("Clear"));
1408 }
1409
1410 con_menu->setAttribute(Qt::WA_DeleteOnClose);
1411 connect(con_menu, &QMenu::triggered,
1413 bool target = false;
1414 struct packet_worker_task task;
1415
1416 if (!act) {
1417 return;
1418 }
1419
1420 task.city_id = city_id;
1421
1422 if (act == con_road) {
1424 target = TRUE;
1425 } else if (act == con_mine) {
1426 task.activity = ACTIVITY_MINE;
1427 target = TRUE;
1428 } else if (act == con_plant) {
1429 task.activity = ACTIVITY_PLANT;
1430 } else if (act == con_irrig) {
1432 target = TRUE;
1433 } else if (act == con_cultivate) {
1435 } else if (act == con_trfrm) {
1437 } else if (act == con_clean) {
1438 task.activity = ACTIVITY_CLEAN;
1439 target = TRUE;
1440 } else if (act == con_clear) {
1441 task.activity = ACTIVITY_LAST;
1442 } else {
1443 // Closed dialog without selecting any activity entry.
1444 return;
1445 }
1446
1447 task.want = 100;
1448
1449 if (target) {
1450 enum extra_cause cause = activity_to_extra_cause(task.activity);
1452 struct extra_type *tgt;
1453
1454 if (cause != EC_NONE) {
1455 tgt = next_extra_for_tile(ptile, cause, city_owner(mcity), nullptr);
1456 } else if (rmcause != ERM_NONE) {
1457 tgt = prev_extra_in_tile(ptile, rmcause, city_owner(mcity), nullptr);
1458 } else {
1459 tgt = nullptr;
1460 }
1461
1462 if (tgt != nullptr) {
1463 task.tgt = extra_index(tgt);
1464 } else {
1465 task.tgt = -1;
1466 }
1467 } else {
1468 task.tgt = -1;
1469 }
1470
1471 task.tile_id = ptile->index;
1473 });
1474
1475 con_menu->popup(mapToGlobal(point));
1476}
1477
1478/************************************************************************/
1482{
1483 QFont f = QApplication::font();
1484 QFont *small_font;
1485 QFontMetrics fm(f);
1491 QHeaderView *header;
1492 QLabel *lab2, *label, *ql, *some_label;
1493 QPushButton *qpush2;
1495 QSizePolicy size_expanding_policy(QSizePolicy::Expanding,
1496 QSizePolicy::Expanding);
1497 QSlider *slider;
1498 QStringList info_list, str_list;
1503 int list_size;
1504 int h = 2 * fm.height() + 2;
1505
1507 zoom = 1.0;
1508
1509 happiness_shown = false;
1511 central_splitter->setOpaqueResize(false);
1513 central_left_splitter->setOpaqueResize(false);
1515 prod_unit_splitter->setOpaqueResize(false);
1516
1517 setMouseTracking(true);
1518 selected_row_p = -1;
1519 dlgcity = nullptr;
1520 lcity_name = new QPushButton(this);
1521 lcity_name->setToolTip(_("Click to change city name"));
1522
1524 single_page_layout->setContentsMargins(0, 0 ,0 ,0);
1525 size_expanding_policy.setHorizontalStretch(0);
1526 size_expanding_policy.setVerticalStretch(0);
1528 current_building = 0;
1529
1530 // Map view
1531 map_box = new QGroupBox(this);
1532
1533 // City information widget texts about surpluses and so on
1534 info_wdg = new QWidget(this);
1535
1536 // Fill info_wdg with labels
1538
1539 info_wdg->setFont(*small_font);
1540 info_grid_layout->setSpacing(0);
1541 info_grid_layout->setContentsMargins(0, 0, 0, 0);
1542
1543
1544 for (enum city_info info_field = city_info_begin();
1547
1548 ql = new QLabel(_(city_info_name(info_field)), info_wdg);
1549 ql->setFont(*small_font);
1550 ql->setProperty(fonts::notify_label, "true");
1551 info_grid_layout->addWidget(ql, info_field, 0);
1552 qlt[info_field] = new QLabel(info_wdg);
1553 qlt[info_field]->setFont(*small_font);
1554 qlt[info_field]->setProperty(fonts::notify_label, "true");
1555 info_grid_layout->addWidget(qlt[info_field], info_field, 1);
1556 info_grid_layout->setRowStretch(info_field, 0);
1557 }
1558
1559 info_wdg->setLayout(info_grid_layout);
1560
1561 // Buy button
1562 buy_button = new QPushButton();
1563 buy_button->setIcon(fc_icons::instance()->get_icon("help-donate"));
1564 connect(buy_button, &QAbstractButton::clicked, this, &city_dialog::buy);
1565
1566 connect(lcity_name, &QAbstractButton::clicked, this, &city_dialog::city_rename);
1568 citizen_pixmap = nullptr;
1569 view = new city_map(this);
1570
1571 zoom_vbox = new QVBoxLayout();
1572 zoom_in_button = new QPushButton();
1573 zoom_in_button->setIcon(fc_icons::instance()->get_icon("plus"));
1574 zoom_in_button->setIconSize(QSize(16, 16));
1575 zoom_in_button->setFixedSize(QSize(20, 20));
1576 zoom_in_button->setToolTip(_("Zoom in"));
1577 connect(zoom_in_button, &QAbstractButton::clicked, this, &city_dialog::zoom_in);
1578 zoom_out_button = new QPushButton();
1579 zoom_out_button->setIcon(fc_icons::instance()->get_icon("minus"));
1580 zoom_out_button->setIconSize(QSize(16, 16));
1581 zoom_out_button->setFixedSize(QSize(20, 20));
1582 zoom_out_button->setToolTip(_("Zoom out"));
1583 connect(zoom_out_button, &QAbstractButton::clicked, this, &city_dialog::zoom_out);
1584 zoom_vbox->addWidget(zoom_in_button);
1585 zoom_vbox->addWidget(zoom_out_button);
1586
1587 // City map group box
1590 hbox_layout->addStretch(100);
1591 hbox_layout->addWidget(view);
1592 hbox_layout->addStretch(100);
1593 hbox_layout->addLayout(zoom_vbox);
1594 vbox_layout->addLayout(hbox_layout);
1595 vbox_layout->addWidget(lcity_name);
1596 map_box->setLayout(vbox_layout);
1597 map_box->setTitle(_("City map"));
1598
1599 // Current/supported units/improvements widgets
1600 supp_units = new QLabel();
1601 curr_units = new QLabel();
1602 curr_impr = new QLabel();
1603 curr_units->setAlignment(Qt::AlignLeft);
1604 curr_impr->setAlignment(Qt::AlignLeft);
1605 supp_units->setAlignment(Qt::AlignLeft);
1606 supported_units = new unit_info(true);
1607 scroll = new QScrollArea;
1608 scroll->setWidgetResizable(true);
1609 scroll->setMaximumHeight(tileset_unit_with_upkeep_height(get_tileset()) + 6
1610 + scroll->horizontalScrollBar()->height());
1611 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1612 scroll->setWidget(supported_units);
1613 current_units = new unit_info(false);
1614 scroll2 = new QScrollArea;
1615 scroll2->setWidgetResizable(true);
1616 scroll2->setMaximumHeight(tileset_unit_height(get_tileset()) + 6
1617 + scroll2->horizontalScrollBar()->height());
1618 scroll2->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1619 scroll2->setWidget(current_units);
1620 scroll_height = scroll2->horizontalScrollBar()->height();
1621 city_buildings = new impr_info(this);
1622 scroll3 = new QScrollArea;
1623 scroll3->setWidgetResizable(true);
1624 scroll3->setMaximumHeight(tileset_unit_height(tileset) + 6
1625 + scroll3->horizontalScrollBar()->height());
1626 scroll3->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1627 scroll3->setWidget(city_buildings);
1628 scroll->setProperty("city_scroll", true);
1629 scroll2->setProperty("city_scroll", true);
1630 scroll3->setProperty("city_scroll", true);
1631
1634 right_layout = new QVBoxLayout();
1636 units_layout = new QVBoxLayout();
1637 left_layout = new QVBoxLayout();
1638
1639 /* Checkboxes to show units/wonders/imrovements
1640 * on production list */
1643 show_buildings->setToolTip(_("Show buildings"));
1644 show_buildings->setChecked(true);
1645 label = new QLabel();
1646 label->setPixmap(*fc_icons::instance()->get_pixmap("building"));
1647 label->setToolTip(_("Show buildings"));
1648 prod_option_layout->addWidget(show_buildings, Qt::AlignLeft);
1649 prod_option_layout->addWidget(label, Qt::AlignLeft);
1650 prod_option_layout->addStretch(100);
1651 label = new QLabel();
1652 label->setPixmap(*fc_icons::instance()->get_pixmap("cunits"));
1653 label->setToolTip(_("Show units"));
1654 show_units = new QCheckBox;
1655 show_units->setToolTip(_("Show units"));
1656 show_units->setChecked(true);
1657 prod_option_layout->addWidget(show_units, Qt::AlignHCenter);
1658 prod_option_layout->addWidget(label, Qt::AlignHCenter);
1659 prod_option_layout->addStretch(100);
1660 label = new QLabel();
1661 label->setPixmap(*fc_icons::instance()->get_pixmap("wonder"));
1662 label->setToolTip(_("Show wonders"));
1663 show_wonders = new QCheckBox;
1664 show_wonders->setToolTip(_("Show wonders"));
1665 show_wonders->setChecked(true);
1666 prod_option_layout->addWidget(show_wonders);
1667 prod_option_layout->addWidget(label);
1668 prod_option_layout->addStretch(100);
1669 label = new QLabel();
1670 label->setPixmap(*fc_icons::instance()->get_pixmap("future"));
1671 label->setToolTip(_("Show future targets"));
1673 future_targets->setToolTip(_("Show future targets"));
1674 future_targets->setChecked(false);
1676 prod_option_layout->addWidget(label, Qt::AlignRight);
1677 prod_options = new QGroupBox(this);
1678 prod_options->setLayout(prod_option_layout);
1679 prod_options->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
1680
1681 // Prev/next and close buttons
1682 button = new QPushButton;
1683 button->setIcon(fc_icons::instance()->get_icon("city-close"));
1684 button->setIconSize(QSize(56, 56));
1685 button->setToolTip(_("Close city dialog"));
1686 connect(button, &QAbstractButton::clicked, this, &QWidget::hide);
1687
1688 next_city_but = new QPushButton();
1689 next_city_but->setIcon(fc_icons::instance()->get_icon("city-right"));
1690 next_city_but->setIconSize(QSize(56, 56));
1691 next_city_but->setToolTip(_("Show next city"));
1692 connect(next_city_but, &QAbstractButton::clicked, this, &city_dialog::next_city);
1693
1694 prev_city_but = new QPushButton();
1695 connect(prev_city_but, &QAbstractButton::clicked, this, &city_dialog::prev_city);
1696 prev_city_but->setIcon(fc_icons::instance()->get_icon("city-left"));
1697 prev_city_but->setIconSize(QSize(56, 56));
1698 prev_city_but->setToolTip(_("Show previous city"));
1699
1700 happiness_button = new QPushButton();
1701 happiness_button->setIcon(fc_icons::instance()->get_icon("city-switch"));
1702 happiness_button->setIconSize(QSize(56, 28));
1703 connect(happiness_button, &QAbstractButton::clicked, this, &city_dialog::show_happiness);
1705
1706 button->setFixedSize(64, 64);
1707 prev_city_but->setFixedSize(64, 64);
1708 next_city_but->setFixedSize(64, 64);
1709 happiness_button->setFixedSize(64, 32);
1711 vbox_layout->addWidget(prev_city_but);
1712 vbox_layout->addWidget(next_city_but);
1713 vbox_layout->addWidget(button);
1714 vbox_layout->addWidget(happiness_button, Qt::AlignHCenter);
1716
1717 hbox_layout->addLayout(vbox_layout, Qt::AlignLeft);
1718 hbox_layout->addWidget(info_wdg, Qt::AlignLeft);
1719 hbox_layout->addWidget(map_box, Qt::AlignCenter);
1720
1721 // Layout with city view and buttons
1722 lefttop_layout->addWidget(citizens_label, Qt::AlignHCenter);
1723 lefttop_layout->addStretch(0);
1724 lefttop_layout->addLayout(hbox_layout);
1725 lefttop_layout->addStretch(50);
1726
1727 // Layout for units/buildings
1728 curr_unit_wdg = new QWidget();
1729 supp_unit_wdg = new QWidget();
1730 curr_impr_wdg = new QWidget();
1731 v_layout = new QVBoxLayout;
1732 v_layout->addWidget(curr_impr);
1733 v_layout->addWidget(scroll3);
1734 v_layout->setContentsMargins(0 , 0 , 0, 0);
1735 v_layout->setSpacing(0);
1736 curr_impr_wdg->setLayout(v_layout);
1737 v_layout = new QVBoxLayout;
1738 v_layout->addWidget(curr_units);
1739 v_layout->addWidget(scroll2);
1740 v_layout->setContentsMargins(0 , 0 , 0, 0);
1741 v_layout->setSpacing(0);
1742 curr_unit_wdg->setLayout(v_layout);
1743 v_layout = new QVBoxLayout;
1744 v_layout->addWidget(supp_units);
1745 v_layout->addWidget(scroll);
1746 v_layout->setContentsMargins(0 , 0 , 0, 0);
1747 v_layout->setSpacing(0);
1748 supp_unit_wdg->setLayout(v_layout);
1749
1750 units_layout->addWidget(curr_unit_wdg);
1751 units_layout->addWidget(supp_unit_wdg);
1752 units_layout->addWidget(curr_impr_wdg);
1753 units_layout->setSpacing(0);
1754 units_layout->setContentsMargins(0 , 0 , 0, 0);
1755
1756 vbox = new QVBoxLayout;
1758 qgbprod = new QGroupBox;
1759 group_box = new QGroupBox(_("Worklist Option"));
1761 work_next_but = new QPushButton(fc_icons::instance()->get_icon(
1762 "go-down"), "");
1763 work_prev_but = new QPushButton(fc_icons::instance()->get_icon(
1764 "go-up"), "");
1765 work_add_but = new QPushButton(fc_icons::instance()->get_icon(
1766 "list-add"), "");
1767 work_rem_but = new QPushButton(style()->standardIcon(
1768 QStyle::SP_DialogDiscardButton), "");
1769 work_but_layout->addWidget(work_add_but);
1770 work_but_layout->addWidget(work_next_but);
1771 work_but_layout->addWidget(work_prev_but);
1772 work_but_layout->addWidget(work_rem_but);
1774 production_combo_p->setToolTip(_("Click to change current production"));
1775 p_table_p = new QTableWidget;
1776
1777 r1 = new QRadioButton(_("Change"));
1778 r2 = new QRadioButton(_("Insert Before"));
1779 r3 = new QRadioButton(_("Insert After"));
1780 r4 = new QRadioButton(_("Add Last"));
1781 r4->setChecked(true);
1782 group_box->setLayout(vbox);
1783
1784
1785 p_table_p->setColumnCount(3);
1786 p_table_p->setProperty("showGrid", "false");
1787 p_table_p->setProperty("selectionBehavior", "SelectRows");
1788 p_table_p->setEditTriggers(QAbstractItemView::NoEditTriggers);
1789 p_table_p->verticalHeader()->setVisible(false);
1790 p_table_p->horizontalHeader()->setVisible(false);
1791 p_table_p->setSelectionMode(QAbstractItemView::SingleSelection);
1792 production_combo_p->setFixedHeight(h);
1793 p_table_p->setMinimumWidth(200);
1794 p_table_p->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
1795 p_table_p->setContextMenuPolicy(Qt::CustomContextMenu);
1796 p_table_p->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
1797 header = p_table_p->horizontalHeader();
1798 header->setStretchLastSection(true);
1799
1800 qgbprod->setTitle(_("Worklist"));
1801 vbox_layout->setSpacing(0);
1802 vbox_layout->addWidget(prod_options);
1803 vbox_layout->addWidget(buy_button);
1804 vbox_layout->addWidget(production_combo_p);
1805 vbox_layout->addLayout(work_but_layout);
1806 vbox_layout->addWidget(p_table_p);
1807 qgbprod->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1808 qgbprod->setLayout(vbox_layout);
1809
1810 worklist_layout->setSpacing(0);
1811 worklist_layout->addWidget(qgbprod);
1812 connect(p_table_p,
1813 &QWidget::customContextMenuRequested, this,
1816 connect(work_add_but, &QAbstractButton::clicked, this, &city_dialog::show_targets_worklist);
1817 connect(work_prev_but, &QAbstractButton::clicked, this, &city_dialog::worklist_up);
1818 connect(work_next_but, &QAbstractButton::clicked, this, &city_dialog::worklist_down);
1819 connect(work_rem_but, &QAbstractButton::clicked, this, &city_dialog::worklist_del);
1820 connect(p_table_p,
1821 &QTableWidget::itemDoubleClicked,
1823 connect(p_table_p->selectionModel(),
1825 const QItemSelection &)),
1827 const QItemSelection &)));
1828 happiness_group = new QGroupBox(_("Happiness"));
1829 gridl = new QGridLayout;
1830
1831 nationality_table = new QTableWidget;
1832 nationality_table->setColumnCount(3);
1833 nationality_table->setProperty("showGrid", "false");
1834 nationality_table->setProperty("selectionBehavior", "SelectRows");
1835 nationality_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1836 nationality_table->verticalHeader()->setVisible(false);
1837 nationality_table->horizontalHeader()->setStretchLastSection(true);
1838
1839 info_list.clear();
1840 info_list << _("Cities:") << _("Luxuries:") << _("Buildings:")
1841 << _("Nationality:") << _("Units:") << _("Wonders:");
1842
1843 for (int i = 0; i < info_list.count(); i++) {
1844 lab_table[i] = new city_label(1 + i, this);
1845 gridl->addWidget(lab_table[i], i, 1, 1, 1);
1846 lab2 = new QLabel(this);
1847 lab2->setFont(*small_font);
1848 lab2->setProperty(fonts::notify_label, "true");
1849 lab2->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1850 lab2->setText(info_list.at(i));
1851 gridl->addWidget(lab2, i, 0, 1, 1);
1852 }
1853
1854 gridl->setSpacing(0);
1855 happiness_group->setLayout(gridl);
1856
1857
1861 happiness_layout->setStretch(0, 10);
1862 happiness_widget = new QWidget();
1864 qgbox = new QGroupBox(_("Presets:"));
1865 qsliderbox = new QGroupBox(_("Governor settings"));
1866 result_box = new QGroupBox(_("Results:"));
1867 hbox = new QHBoxLayout;
1868 gridl = new QGridLayout;
1870
1871 qpush2
1872 = new QPushButton(style()->standardIcon(QStyle::SP_DialogSaveButton),
1873 _("Save"));
1874 connect(qpush2, &QAbstractButton::pressed, this, &city_dialog::save_cma);
1875
1876 cma_info_text = new QLabel;
1877 cma_info_text->setFont(*small_font);
1878 cma_info_text->setAlignment(Qt::AlignCenter);
1879 cma_table = new QTableWidget;
1880 cma_table->setColumnCount(1);
1881 cma_table->setProperty("showGrid", "false");
1882 cma_table->setProperty("selectionBehavior", "SelectRows");
1883 cma_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1884 cma_table->setSelectionMode(QAbstractItemView::SingleSelection);
1885 cma_table->setContextMenuPolicy(Qt::CustomContextMenu);
1886 cma_table->verticalHeader()->setVisible(false);
1887 cma_table->horizontalHeader()->setVisible(false);
1888 cma_table->horizontalHeader()->setSectionResizeMode(
1889 QHeaderView::Stretch);
1890
1891 connect(cma_table->selectionModel(),
1893 const QItemSelection &)),
1895 const QItemSelection &)));
1896 connect(cma_table,
1897 &QWidget::customContextMenuRequested, this,
1899 connect(cma_table, &QTableWidget::cellDoubleClicked, this,
1901 gridl->addWidget(cma_table, 0, 0, 1, 2);
1902 qgbox->setLayout(gridl);
1903 hbox->addWidget(cma_info_text);
1904 result_box->setLayout(hbox);
1905 str_list << _("Food") << _("Shield") << _("Trade") << _("Gold")
1906 << _("Luxury") << _("Science") << _("Celebrate")
1907 << _("Maximize growth");
1908 some_label = new QLabel(_("Minimal Surplus"));
1910 some_label->setAlignment(Qt::AlignRight);
1911 slider_grid->addWidget(some_label, 0, 0, 1, 3);
1912 some_label = new QLabel(_("Priority"));
1914 some_label->setAlignment(Qt::AlignCenter);
1915 slider_grid->addWidget(some_label, 0, 3, 1, 2);
1916
1917 list_size = str_list.count();
1918 for (int i = 0; i < list_size; i++) {
1919 some_label = new QLabel(str_list.at(i));
1920 slider_grid->addWidget(some_label, i + 1, 0, 1, 1);
1921 some_label = new QLabel("0");
1922 some_label->setMinimumWidth(25);
1923
1924 if (i < list_size - 2) {
1925 slider = new QSlider(Qt::Horizontal);
1926 slider->setPageStep(1);
1927 slider->setFocusPolicy(Qt::TabFocus);
1928 slider_tab[2 * i] = slider;
1929 slider->setRange(-20, 20);
1930 slider->setSingleStep(1);
1931 slider_grid->addWidget(some_label, i + 1, 1, 1, 1);
1932 slider_grid->addWidget(slider, i + 1, 2, 1, 1);
1933 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1934
1935 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1936 } else if (i == list_size - 2) {
1938 slider_grid->addWidget(cma_celeb_checkbox, i + 1, 2 , 1 , 1);
1939 connect(cma_celeb_checkbox,
1940 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1941 } else {
1942 fc_assert(i == list_size - 1);
1943
1945 slider_grid->addWidget(cma_max_growth, i + 1, 2 , 1 , 1);
1946 connect(cma_max_growth,
1947 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1948 }
1949
1950 if (i <= list_size - 2) {
1951 some_label = new QLabel("0");
1952 some_label->setMinimumWidth(25);
1953 slider = new QSlider(Qt::Horizontal);
1954 slider->setFocusPolicy(Qt::TabFocus);
1955 slider->setRange(0, 25);
1956 slider_tab[2 * i + 1] = slider;
1957 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1958 slider_grid->addWidget(some_label, i + 1, 3, 1, 1);
1959 slider_grid->addWidget(slider, i + 1, 4, 1, 1);
1960 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1961 }
1962 }
1963
1964 cma_enable_but = new QPushButton();
1965 cma_enable_but->setFocusPolicy(Qt::TabFocus);
1966 connect(cma_enable_but, &QAbstractButton::pressed, this, &city_dialog::cma_enable);
1967 slider_grid->addWidget(cma_enable_but, O_LAST + 4, 0, 1, 3);
1968 slider_grid->addWidget(qpush2, O_LAST + 4, 3, 1, 2);
1969
1970 qsliderbox->setLayout(slider_grid);
1971 cma_result = new QLabel;
1972 cma_result_pix = new QLabel;
1973
1974 hbox = new QHBoxLayout;
1975 hbox->addWidget(cma_result_pix);
1976 hbox->addWidget(cma_result);
1977 hbox->addStretch(10);
1978 right_layout->addWidget(qgbox);
1979 right_layout->addLayout(hbox);
1980 right_layout->addWidget(qsliderbox);
1981
1982 split_widget1 = new QWidget;
1983 split_widget1->setLayout(worklist_layout);
1984 split_widget2 = new QWidget;
1985 split_widget2->setLayout(units_layout);
1988 prod_unit_splitter->setStretchFactor(0, 3);
1989 prod_unit_splitter->setStretchFactor(1, 97);
1990 prod_unit_splitter->setOrientation(Qt::Horizontal);
1992 top_widget = new QWidget;
1993 top_widget->setLayout(lefttop_layout);
1994 top_widget->setSizePolicy(QSizePolicy::Minimum,
1995 QSizePolicy::Minimum);
1996 scroll_info = new QScrollArea();
1997 scroll_info->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
1998 scroll_unit = new QScrollArea();
1999 scroll_info->setWidget(top_widget);
2000 scroll_info->setWidgetResizable(true);
2001 prod_happ_widget = new QWidget;
2002 prod_happ_widget->setLayout(leftbot_layout);
2003 prod_happ_widget->setSizePolicy(QSizePolicy::MinimumExpanding,
2004 QSizePolicy::MinimumExpanding);
2005 scroll_unit->setWidget(prod_happ_widget);
2006 scroll_unit->setWidgetResizable(true);
2009 central_left_splitter->setStretchFactor(0, 40);
2010 central_left_splitter->setStretchFactor(1, 60);
2011 central_left_splitter->setOrientation(Qt::Vertical);
2013
2014 split_widget1 = new QWidget(this);
2015 split_widget2 = new QWidget(this);
2016 split_widget1->setLayout(left_layout);
2017 split_widget2->setLayout(right_layout);
2018 central_splitter->addWidget(split_widget1);
2019 central_splitter->addWidget(split_widget2);
2020 central_splitter->setStretchFactor(0, 99);
2021 central_splitter->setStretchFactor(1, 1);
2022 central_splitter->setOrientation(Qt::Horizontal);
2024 setSizeGripEnabled(true);
2026
2027 installEventFilter(this);
2028
2029 ::city_dlg_created = true;
2030}
2031
2032/************************************************************************/
2036{
2037
2038 cid cprod;
2039 int i, pos;
2040 int item, targets_used;
2042 QString str;
2043 struct item items[MAX_NUM_PRODUCTION_TARGETS];
2044 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
2045 struct universal univ;
2046
2047 pos = 0;
2050 name_and_sort_items(targets, targets_used, items, false, dlgcity);
2051
2052 for (item = 0; item < targets_used; item++) {
2053 if (can_city_build_now(dlgcity, &items[item].item)) {
2054 prod_list << cid_encode(items[item].item);
2055 }
2056 }
2057
2058 for (i = 0; i < prod_list.size(); i++) {
2059 if (prod_list.at(i) == cprod) {
2060 if (next) {
2061 pos = i + 1;
2062 } else {
2063 pos = i - 1;
2064 }
2065 }
2066 }
2067 if (pos == prod_list.size()) {
2068 pos = 0;
2069 }
2070 if (pos == - 1) {
2071 pos = prod_list.size() - 1;
2072 }
2073 univ = cid_decode(static_cast<cid>(prod_list.at(pos)));
2075}
2076
2077/************************************************************************/
2081{
2082 if (happiness_shown) {
2083 happiness_button->setToolTip(_("Show city production"));
2084 } else {
2085 happiness_button->setToolTip(_("Show happiness information"));
2086 }
2087}
2088
2089/************************************************************************/
2093{
2094 setUpdatesEnabled(false);
2095
2096 if (!happiness_shown) {
2097 leftbot_layout->replaceWidget(prod_unit_splitter,
2099 Qt::FindDirectChildrenOnly);
2100 prod_unit_splitter->hide();
2101 happiness_widget->show();
2102 happiness_widget->updateGeometry();
2103 } else {
2104 leftbot_layout->replaceWidget(happiness_widget,
2106 Qt::FindDirectChildrenOnly);
2107 prod_unit_splitter->show();
2108 prod_unit_splitter->updateGeometry();
2109 happiness_widget->hide();
2110 }
2111
2112 setUpdatesEnabled(true);
2113 update();
2116}
2117
2118/************************************************************************/
2122{
2123 struct player *pplayer = client_player();
2124
2125 if (pplayer == nullptr
2126 || city_owner(dlgcity) != pplayer) {
2127 prev_city_but->setDisabled(true);
2128 next_city_but->setDisabled(true);
2129 buy_button->setDisabled(true);
2130 cma_enable_but->setDisabled(true);
2131 production_combo_p->setDisabled(true);
2132 current_units->setDisabled(true);
2133 supported_units->setDisabled(true);
2134 view->setDisabled(true);
2135 } else {
2136 prev_city_but->setEnabled(true);
2137 next_city_but->setEnabled(true);
2138 buy_button->setEnabled(true);
2139 cma_enable_but->setEnabled(true);
2140 production_combo_p->setEnabled(true);
2141 current_units->setEnabled(true);
2142 supported_units->setEnabled(true);
2143 view->setEnabled(true);
2144 }
2145
2147 cma_enable_but->setEnabled(true);
2148 } else {
2149 cma_enable_but->setDisabled(true);
2150 }
2151
2153}
2154
2155/************************************************************************/
2159{
2160 struct player *pplayer = client_player();
2161
2162 work_next_but->setDisabled(true);
2163 work_prev_but->setDisabled(true);
2164 work_add_but->setDisabled(true);
2165 work_rem_but->setDisabled(true);
2166
2167 if (pplayer != nullptr
2168 && city_owner(dlgcity) == pplayer) {
2169 work_add_but->setEnabled(true);
2170
2171 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount()) {
2172 work_rem_but->setEnabled(true);
2173 }
2174
2175 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount() - 1) {
2176 work_next_but->setEnabled(true);
2177 }
2178
2179 if (selected_row_p > 0 && selected_row_p < p_table_p->rowCount()) {
2180 work_prev_but->setEnabled(true);
2181 }
2182 }
2183}
2184
2185/************************************************************************/
2189{
2190 if (citizen_pixmap) {
2191 citizen_pixmap->detach();
2192 delete citizen_pixmap;
2193 }
2194
2195 cma_table->clear();
2196 p_table_p->clear();
2197 nationality_table->clear();
2199 supported_units->clear_layout();
2200 removeEventFilter(this);
2201 ::city_dlg_created = false;
2202
2203 // Delete the one widget that currently does NOT have a parent
2204 if (happiness_shown) {
2205 delete prod_unit_splitter;
2206 } else {
2207 delete happiness_widget;
2208 }
2209}
2210
2211/************************************************************************/
2215{
2216 gui()->qt_settings.city_geometry = saveGeometry();
2217 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2218 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2219 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2220}
2221
2222/************************************************************************/
2226{
2227 if (!gui()->qt_settings.city_geometry.isNull()) {
2228 restoreGeometry(gui()->qt_settings.city_geometry);
2229 prod_unit_splitter->restoreState(gui()->qt_settings.city_splitter1);
2230 central_left_splitter->restoreState(gui()->qt_settings.city_splitter2);
2231 central_splitter->restoreState(gui()->qt_settings.city_splitter3);
2232 } else {
2233 QRect rect = QApplication::primaryScreen()->availableGeometry();
2234
2235 resize((rect.width() * 4) / 5, (rect.height() * 5) / 6);
2236 }
2237}
2238
2239/************************************************************************/
2243{
2244 gui()->qt_settings.city_geometry = saveGeometry();
2245 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2246 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2247 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2248}
2249
2250/************************************************************************/
2253bool city_dialog::eventFilter(QObject *obj, QEvent *event)
2254{
2255
2256 if (obj == this) {
2257 if (event->type() == QEvent::KeyPress) {
2258 }
2259
2260 if (event->type() == QEvent::ShortcutOverride) {
2261 QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
2262 if (key_event->key() == Qt::Key_Right) {
2263 next_city();
2264 event->setAccepted(true);
2265 return true;
2266 }
2267 if (key_event->key() == Qt::Key_Left) {
2268 prev_city();
2269 event->setAccepted(true);
2270 return true;
2271 }
2272 if (key_event->key() == Qt::Key_Up) {
2273 change_production(true);
2274 event->setAccepted(true);
2275 return true;
2276 }
2277 if (key_event->key() == Qt::Key_Down) {
2278 change_production(false);
2279 event->setAccepted(true);
2280 return true;
2281 }
2282 }
2283 }
2284 return QObject::eventFilter(obj, event);
2285}
2286
2287/************************************************************************/
2291{
2293 const int city_id = dlgcity->id;
2294
2295 if (!can_client_issue_orders()) {
2296 return;
2297 }
2298
2299 ask = new hud_input_box(gui()->central_wdg);
2300 ask->set_text_title_definput(_("What should we rename the city to?"),
2301 _("Rename City"), city_name_get(dlgcity));
2302 ask->setAttribute(Qt::WA_DeleteOnClose);
2303 connect(ask, &hud_message_box::accepted, this, [=]() {
2304 struct city *pcity = game_city_by_number(city_id);
2306
2307 if (!pcity) {
2308 return;
2309 }
2310
2311 ask_bytes = ask->input_edit.text().toUtf8();
2312 ::city_rename(pcity, ask_bytes.data());
2313 });
2314 ask->show();
2315}
2316
2317/************************************************************************/
2321{
2322 zoom = zoom * 1.2;
2323 if (dlgcity) {
2324 view->set_pixmap(dlgcity, zoom);
2325 }
2327 left_layout->update();
2328}
2329
2330/************************************************************************/
2334{
2335 zoom = zoom / 1.2;
2336 if (dlgcity) {
2337 view->set_pixmap(dlgcity, zoom);
2338 }
2340 left_layout->update();
2341}
2342
2343/************************************************************************/
2347{
2348 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
2349
2350 ask->set_text_title_definput(_("What should we name the preset?"),
2351 _("Name new preset"),
2352 _("new preset"));
2353 ask->setAttribute(Qt::WA_DeleteOnClose);
2354 connect(ask, &hud_message_box::accepted, this,
2356 struct cm_parameter param;
2357 QByteArray ask_bytes = ask->input_edit.text().toUtf8();
2358 QString text = ask_bytes.data();
2359 if (!text.isEmpty()) {
2360 param.allow_disorder = false;
2361 param.allow_specialists = true;
2362 param.require_happy = cma_celeb_checkbox->isChecked();
2363 param.max_growth = cma_max_growth->isChecked();
2364 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2365
2366 for (int i = O_FOOD; i < O_LAST; i++) {
2367 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2368 param.factor[i] = slider_tab[2 * i + 1]->value();
2369 }
2370
2371 ask_bytes = text.toUtf8();
2372 cmafec_preset_add(ask_bytes.data(), &param);
2374 }
2375 });
2376 ask->show();
2377}
2378
2379/************************************************************************/
2383{
2384 if (cma_is_city_under_agent(dlgcity, nullptr)) {
2386
2387 return;
2388 }
2389
2390 cma_changed();
2392}
2393
2394/************************************************************************/
2398{
2399 struct cm_parameter param;
2400
2401 param.allow_disorder = false;
2402 param.allow_specialists = true;
2403 param.require_happy = cma_celeb_checkbox->isChecked();
2404 param.max_growth = cma_max_growth->isChecked();
2405 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2406
2407 for (int i = O_FOOD; i < O_LAST; i++) {
2408 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2409 param.factor[i] = slider_tab[2 * i + 1]->value();
2410 }
2411
2413}
2414
2415/************************************************************************/
2419{
2420 const struct cm_parameter *param;
2421
2422 if (!can_client_issue_orders()) {
2423 return;
2424 }
2426 if (cma_is_city_under_agent(dlgcity, nullptr)) {
2428 }
2429
2432}
2433
2434/************************************************************************/
2438 const QItemSelection &ds)
2439{
2440 const struct cm_parameter *param;
2441 QModelIndex index;
2442 QModelIndexList indexes = sl.indexes();
2443
2444 if (indexes.isEmpty() || cma_table->signalsBlocked()) {
2445 return;
2446 }
2447
2448 index = indexes.at(0);
2449 int ind = index.row();
2450
2451 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2452 return;
2453 }
2454
2457
2458 if (cma_is_city_under_agent(dlgcity, nullptr)) {
2461 }
2462}
2463
2464/************************************************************************/
2468{
2469 struct cm_parameter param;
2470 const struct cm_parameter *cparam;
2471 int output;
2472 QVariant qvar;
2473 QLabel *label;
2474
2475 if (!cma_is_city_under_agent(dlgcity, &param)) {
2476 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2477 return;
2478 }
2480 cm_copy_parameter(&param, cparam);
2481 }
2482
2483 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2484 slider_tab[output]->blockSignals(true);
2485 }
2486
2487 for (output = O_FOOD; output < O_LAST; output++) {
2488 qvar = slider_tab[2 * output + 1]->property("FC");
2489 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2490 label->setText(QString::number(param.factor[output]));
2491 slider_tab[2 * output + 1]->setValue(param.factor[output]);
2492 qvar = slider_tab[2 * output]->property("FC");
2493 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2494 label->setText(QString::number(param.minimal_surplus[output]));
2495 slider_tab[2 * output]->setValue(param.minimal_surplus[output]);
2496 }
2497
2498 slider_tab[2 * O_LAST + 1]->blockSignals(true);
2499 qvar = slider_tab[2 * O_LAST + 1]->property("FC");
2500 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2501 label->setText(QString::number(param.happy_factor));
2502 slider_tab[2 * O_LAST + 1]->setValue(param.happy_factor);
2503 slider_tab[2 * O_LAST + 1]->blockSignals(false);
2504 cma_celeb_checkbox->blockSignals(true);
2505 cma_celeb_checkbox->setChecked(param.require_happy);
2506 cma_celeb_checkbox->blockSignals(false);
2507 cma_max_growth->blockSignals(true);
2508 cma_max_growth->setChecked(param.max_growth);
2509 cma_max_growth->blockSignals(false);
2510
2511 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2512 slider_tab[output]->blockSignals(false);
2513 }
2514}
2515
2516/************************************************************************/
2520{
2521 QString s;
2523 struct cm_parameter param;
2524 QPixmap pix;
2525 int i;
2526
2527 cma_table->clear();
2528 cma_table->setRowCount(0);
2529
2530 for (i = 0; i < cmafec_preset_num(); i++) {
2531 item = new QTableWidgetItem;
2532 item->setText(cmafec_preset_get_descr(i));
2533 cma_table->insertRow(i);
2534 cma_table->setItem(i, 0, item);
2535 }
2536
2537 if (cmafec_preset_num() == 0) {
2538 cma_table->insertRow(0);
2539 item = new QTableWidgetItem;
2540 item->setText(_("No governor defined"));
2541 cma_table->setItem(0, 0, item);
2542 }
2543
2544 if (cma_is_city_under_agent(dlgcity, nullptr)) {
2545 view->update();
2547 pix = style()->standardPixmap(QStyle::SP_DialogApplyButton);
2548 pix = pix.scaled(2 * pix.width(), 2 * pix.height(),
2549 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2550 cma_result_pix->setPixmap(pix);
2551 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2552 // TRANS: %1 is custom string chosen by player
2553 cma_result->setText(QString(_("<h3>Governor Enabled<br>(%1)</h3>"))
2554 .arg(s.toHtmlEscaped()));
2555 cma_result->setAlignment(Qt::AlignCenter);
2556 } else {
2557 pix = style()->standardPixmap(QStyle::SP_DialogCancelButton);
2558 pix = pix.scaled(1.6 * pix.width(), 1.6 * pix.height(),
2559 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2560 cma_result_pix->setPixmap(pix);
2561 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2562 cma_result->setText(QString(_("<h3>Governor Disabled</h3>")));
2563 cma_result->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
2564 }
2565
2566 if (cma_is_city_under_agent(dlgcity, nullptr)) {
2569 cm_parameter *const >(&param));
2570 if (i >= 0 && i < cma_table->rowCount()) {
2571 cma_table->blockSignals(true);
2572 cma_table->setCurrentCell(i, 0);
2573 cma_table->blockSignals(false);
2574 }
2575
2576 cma_enable_but->setText(_("Disable"));
2577 } else {
2578 cma_enable_but->setText(_("Enable"));
2579 }
2581}
2582
2583/************************************************************************/
2587{
2588 int i;
2590
2591 i = cma_table->currentRow();
2592
2593 if (i == -1 || cmafec_preset_num() == 0) {
2594 return;
2595 }
2596
2598 ask->set_text_title(_("Remove this preset?"), cmafec_preset_get_descr(i));
2599 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
2600 ask->setDefaultButton(QMessageBox::Cancel);
2601 ask->setAttribute(Qt::WA_DeleteOnClose);
2602 connect(ask, &hud_message_box::accepted, this,
2606 });
2607 ask->show();
2608}
2609
2610/************************************************************************/
2614{
2615 if (cma_is_city_under_agent(dlgcity, nullptr)) {
2616 cma_changed();
2618 }
2619}
2620
2621/************************************************************************/
2625{
2626 QVariant qvar;
2627 QSlider *slider;
2628 QLabel *label;
2629
2631 qvar = slider->property("FC");
2632
2633 if (qvar.isNull() || !qvar.isValid()) {
2634 return;
2635 }
2636
2637 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2638 label->setText(QString::number(value));
2639
2640 if (cma_is_city_under_agent(dlgcity, nullptr)) {
2641 cma_changed();
2643 }
2644}
2645
2646/************************************************************************/
2665
2666/************************************************************************/
2670{
2671 QMenu *cma_menu = new QMenu(this);
2673
2674 cma_menu->setAttribute(Qt::WA_DeleteOnClose);
2675 cma_del_item = cma_menu->addAction(_("Remove Governor"));
2676 connect(cma_menu, &QMenu::triggered, this,
2678 if (act == cma_del_item) {
2679 cma_remove();
2680 }
2681 });
2682
2683 cma_menu->popup(QCursor::pos());
2684}
2685
2686/************************************************************************/
2690{
2691 QAction *action;
2692 QAction *disband;
2697 QMap<QString, cid>::const_iterator map_iter;
2698 QMenu *change_menu;
2699 QMenu *insert_menu;
2700 QMenu *list_menu;
2701 QMenu *options_menu;
2702 int city_id = dlgcity->id;
2703
2704 if (!can_client_issue_orders()) {
2705 return;
2706 }
2707 list_menu = new QMenu(this);
2708 change_menu = list_menu->addMenu(_("Change worklist"));
2709 insert_menu = list_menu->addMenu(_("Insert worklist"));
2710 wl_clear = list_menu->addAction(_("Clear"));
2711 connect(wl_clear, &QAction::triggered, this, &city_dialog::clear_worklist);
2712 list.clear();
2713
2717
2718 if (list.count() == 0) {
2719 wl_empty = change_menu->addAction(_("(no worklists defined)"));
2720 insert_menu->addAction(wl_empty);
2721 }
2722
2723 map_iter = list.constBegin();
2724
2725 while (map_iter != list.constEnd()) {
2726 action = change_menu->addAction(map_iter.key());
2727 action->setData(map_iter.value());
2728
2729 action = insert_menu->addAction(map_iter.key());
2730 action->setData(map_iter.value());
2731
2732 map_iter++;
2733 }
2734
2735 wl_save = list_menu->addAction(_("Save worklist"));
2736 connect(wl_save, &QAction::triggered, this, &city_dialog::save_worklist);
2737 options_menu = list_menu->addMenu(_("Options"));
2738 disband = options_menu->addAction(_("Allow disbanding city"));
2739 disband->setCheckable(true);
2740 disband->setChecked(is_city_option_set(dlgcity, CITYO_DISBAND));
2741 connect(disband, &QAction::triggered, this,
2743
2744 connect(change_menu, &QMenu::triggered, this, [=](QAction *act) {
2745 QVariant id = act->data();
2746 struct city *pcity = game_city_by_number(city_id);
2747 const struct worklist *worklist;
2748
2749 if (!pcity) {
2750 return;
2751 }
2752
2753#ifndef FC_QT5_MODE
2754 fc_assert_ret(id.typeId() == QMetaType::Int);
2755#else // FC_QT5_MODE
2756 fc_assert_ret(id.type() == QVariant::Int);
2757#endif // FC_QT5_MODE
2758
2761 });
2762
2763 connect(insert_menu, &QMenu::triggered, this,
2765 QVariant id = act->data();
2766 struct city *pcity = game_city_by_number(city_id);
2767 const struct worklist *worklist;
2768
2769 if (!pcity) {
2770 return;
2771 }
2772
2773#ifndef FC_QT5_MODE
2774 fc_assert_ret(id.typeId() == QMetaType::Int);
2775#else // FC_QT5_MODE
2776 fc_assert_ret(id.type() == QVariant::Int);
2777#endif // FC_QT5_MODE
2778
2781 });
2782
2783 list_menu->popup(QCursor::pos());
2784}
2785
2786/************************************************************************/
2790{
2791 QString str;
2792 int value;
2793 struct player *pplayer = client_player();
2794
2795 buy_button->setDisabled(true);
2796
2797 if (!client_is_observer() && pplayer != nullptr) {
2798 value = dlgcity->client.buy_cost;
2799 str = QString(PL_("Buy (%1 gold)", "Buy (%1 gold)",
2800 value)).arg(QString::number(value));
2801
2802 if (pplayer->economic.gold >= value && value != 0) {
2803 buy_button->setEnabled(true);
2804 }
2805 } else {
2806 str = QString(_("Buy"));
2807 }
2808
2809 buy_button->setText(str);
2810}
2811
2812/************************************************************************/
2816{
2817 enum citizen_category categories[MAX_CITY_SIZE];
2818 int i, j, width, height;
2819 QPainter p;
2820 QPixmap *pix;
2822 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
2823 int h = tileset_small_sprite_height(tileset) / gui()->map_scale;
2824
2825 i = 1 + (num_citizens * 5 / 200);
2826 w = w / i;
2827 QRect source_rect(0, 0, w, h);
2828 QRect dest_rect(0, 0, w, h);
2829 width = w * num_citizens;
2830 height = h;
2831
2832 if (citizen_pixmap) {
2833 citizen_pixmap->detach();
2834 delete citizen_pixmap;
2835 }
2836
2838
2839 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2840 dest_rect.moveTo(i * w, 0);
2841 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2842 p.begin(citizen_pixmap);
2843 p.drawPixmap(dest_rect, *pix, source_rect);
2844 p.end();
2845 }
2846
2848 citizens_label->setPixmap(*citizen_pixmap);
2849
2852
2853 for (int k = 0; k < FEELING_LAST - 1; k++) {
2856 static_cast<citizen_feeling>(k),
2857 categories);
2858
2859 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2860 dest_rect.moveTo(i * w, 0);
2861 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2862 p.begin(citizen_pixmap);
2863 p.drawPixmap(dest_rect, *pix, source_rect);
2864 p.end();
2865 }
2866
2867 lab_table[k]->setPixmap(*citizen_pixmap);
2868
2869 switch (k) {
2870 case FEELING_BASE:
2871 lab_table[k]->setToolTip(text_happiness_cities(dlgcity));
2872 break;
2873
2874 case FEELING_LUXURY:
2875 lab_table[k]->setToolTip(text_happiness_luxuries(dlgcity));
2876 break;
2877
2878 case FEELING_EFFECT :
2880 break;
2881
2884 break;
2885
2886 case FEELING_MARTIAL:
2887 lab_table[k]->setToolTip(text_happiness_units(dlgcity));
2888 break;
2889
2890 default:
2891 break;
2892 }
2893 }
2894}
2895
2896/************************************************************************/
2900{
2901 setUpdatesEnabled(false);
2902 production_combo_p->blockSignals(true);
2903
2904 if (dlgcity) {
2905 view->set_pixmap(dlgcity, zoom);
2906 view->update();
2907 update_title();
2913 update_units();
2917 } else {
2919 }
2920
2921 production_combo_p->blockSignals(false);
2922 setUpdatesEnabled(true);
2924 update();
2925}
2926
2927
2928/************************************************************************/
2932{
2933 QFont f = QApplication::font();
2934 QFontMetrics fm(f);
2935 QPixmap *pix = nullptr;
2937 QString str;
2940 char buf[8];
2942 int h;
2943 int i = 0;
2944 struct sprite *sprite;
2945
2946 h = fm.height() + 6;
2947 nationality_table->clear();
2948 nationality_table->setRowCount(0);
2949 info_list.clear();
2950 info_list << _("#") << _("Flag") << _("Nation");
2951 nationality_table->setHorizontalHeaderLabels(info_list);
2952
2953 citizens_iterate(dlgcity, pslot, nationality) {
2954 nationality_table->insertRow(i);
2955
2956 for (int j = 0; j < nationality_table->columnCount(); j++) {
2957 item = new QTableWidgetItem;
2958
2959 switch (j) {
2960 case 0:
2962
2963 if (nationality_i == 0) {
2964 str = "-";
2965 } else {
2966 fc_snprintf(buf, sizeof(buf), "%d", nationality_i);
2967 str = QString(buf);
2968 }
2969
2970 item->setText(str);
2971 break;
2972
2973 case 1:
2976 (player_slot_get_player(pslot)));
2977
2978 if (sprite != nullptr) {
2979 pix = sprite->pm;
2980 pix_scaled = pix->scaledToHeight(h);
2981 item->setData(Qt::DecorationRole, pix_scaled);
2982 } else {
2983 item->setText("FLAG MISSING");
2984 }
2985 break;
2986
2987 case 2:
2989 (player_slot_get_player(pslot)));
2990 break;
2991
2992 default:
2993 break;
2994 }
2995 nationality_table->setItem(i, j, item);
2996 }
2997 i++;
2999 nationality_table->horizontalHeader()->setStretchLastSection(false);
3000 nationality_table->resizeColumnsToContents();
3001 nationality_table->resizeRowsToContents();
3002 nationality_table->horizontalHeader()->setStretchLastSection(true);
3003}
3004
3005/************************************************************************/
3009{
3010 int illness = 0;
3011 char buffer[512];
3012 char buf_info[NUM_INFO_FIELDS][512];
3013 char buf_tooltip[NUM_INFO_FIELDS][512];
3014 int granaryturns;
3015 int spec;
3016
3017 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3018 buf_info[i][0] = '\0';
3019 buf_tooltip[i][0] = '\0';
3020 }
3021
3022 // Fill the buffers with the necessary info
3023 spec = city_specialists(dlgcity);
3025 "%3d (%4d)", dlgcity->size, spec);
3027 _("Population: %d, Specialists: %d"),
3028 dlgcity->size, spec);
3029 fc_snprintf(buf_info[INFO_FOOD], sizeof(buf_info[INFO_FOOD]), "%3d (%+4d)",
3032 "%3d (%+4d)", dlgcity->prod[O_SHIELD] + dlgcity->waste[O_SHIELD],
3034 fc_snprintf(buf_info[INFO_TRADE], sizeof(buf_info[INFO_TRADE]), "%3d (%+4d)",
3037 fc_snprintf(buf_info[INFO_GOLD], sizeof(buf_info[INFO_GOLD]), "%3d (%+4d)",
3044 "%4d/%-4d", dlgcity->food_stock,
3046
3048 sizeof(buf_tooltip[INFO_FOOD]));
3050 sizeof(buf_tooltip[INFO_SHIELD]));
3052 sizeof(buf_tooltip[INFO_TRADE]));
3054 sizeof(buf_tooltip[INFO_GOLD]));
3056 sizeof(buf_tooltip[INFO_SCIENCE]));
3058 sizeof(buf_tooltip[INFO_LUXURY]));
3060 sizeof(buf_tooltip[INFO_CULTURE]));
3062 sizeof(buf_tooltip[INFO_POLLUTION]));
3064 sizeof(buf_tooltip[INFO_ILLNESS]));
3065
3067
3068 if (granaryturns == 0) {
3069 // TRANS: city growth is blocked. Keep short.
3070 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("blocked"));
3071 } else if (granaryturns == FC_INFINITY) {
3072 // TRANS: city is not growing. Keep short.
3073 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("never"));
3074 } else {
3075 /* A negative value means we'll have famine in that many turns.
3076 But that's handled down below. */
3077 // TRANS: city growth turns. Keep short.
3079 PL_("%d turn", "%d turns", abs(granaryturns)),
3080 abs(granaryturns));
3081 }
3082
3084 "%4d", dlgcity->waste[O_TRADE]);
3091
3092 if (!game.info.illness_on) {
3094 " -.-");
3095 } else {
3096 illness = city_illness_calc(dlgcity, nullptr, nullptr, nullptr, nullptr);
3097 // Illness is in tenth of percent
3099 "%5.1f%%", (float) illness / 10.0);
3100 }
3101 if (dlgcity->steal) {
3103 PL_("%d time", "%d times", dlgcity->steal), dlgcity->steal);
3104 } else {
3106 _("Not stolen"));
3107 }
3108
3110 sizeof(buf_info[INFO_AIRLIFT]));
3112 sizeof(buf_tooltip[INFO_AIRLIFT]));
3113
3114 get_city_dialog_output_text(dlgcity, O_FOOD, buffer, sizeof(buffer));
3115
3116 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3117 qlt[i]->setText(QString(buf_info[i]));
3118
3119 if (buf_tooltip[i][0]) {
3120 qlt[i]->setToolTip("<pre>" + QString(buf_tooltip[i]).toHtmlEscaped()
3121 + "</pre>");
3122 }
3123 }
3124}
3125
3126/************************************************************************/
3130{
3133
3134 setContentsMargins(0, 0 ,0 ,0);
3136 dlgcity = qcity;
3137 production_combo_p->blockSignals(true);
3138 refresh();
3139 production_combo_p->blockSignals(false);
3140}
3141
3142/************************************************************************/
3146{
3147 struct worklist queue;
3148
3149 city_get_queue(dlgcity, &queue);
3150
3152 return;
3153 }
3154
3156 city_set_queue(dlgcity, &queue);
3157}
3158
3159/************************************************************************/
3163{
3164 unit_item *ui;
3165 struct unit_list *units;
3166 char buf[256];
3167 int n;
3168 int happy_cost;
3170 struct player *pplayer = client_player();
3171
3172 supported_units->setUpdatesEnabled(false);
3173 supported_units->clear_layout();
3174
3175 if (pplayer != nullptr
3176 && city_owner(dlgcity) != pplayer) {
3178 } else {
3179 units = dlgcity->units_supported;
3180 }
3181
3182 unit_list_iterate(units, punit) {
3184 ui = new unit_item(this, punit, true, happy_cost);
3185 ui->init_pix();
3186 supported_units->add_item(ui);
3188 n = unit_list_size(units);
3189 fc_snprintf(buf, sizeof(buf), _("Supported units %d"), n);
3190 supp_units->setText(QString(buf));
3191 supported_units->update_units();
3192 supported_units->setUpdatesEnabled(true);
3193 current_units->setUpdatesEnabled(true);
3195
3196 if (pplayer != nullptr
3197 && city_owner(dlgcity) != pplayer) {
3199 } else {
3200 units = dlgcity->tile->units;
3201 }
3202
3203 unit_list_iterate(units, punit) {
3204 ui = new unit_item(this , punit, false);
3205 ui->init_pix();
3208
3209 n = unit_list_size(units);
3210 fc_snprintf(buf, sizeof(buf), _("Present units %d"), n);
3211 curr_units->setText(QString(buf));
3212
3214 current_units->setUpdatesEnabled(true);
3215}
3216
3217/************************************************************************/
3221 const QItemSelection &ds)
3222{
3223 QModelIndex index;
3224 QModelIndexList indexes = sl.indexes();
3225
3226 if (indexes.isEmpty()) {
3227 return;
3228 }
3229
3230 index = indexes.at(0);
3231 selected_row_p = index.row();
3233}
3234
3235/************************************************************************/
3239{
3240 int size, i;
3241 struct city *other_pcity = nullptr;
3242 struct player *pplayer = client_player();
3243
3244 if (pplayer == nullptr) {
3245 return;
3246 }
3247
3248 size = city_list_size(pplayer->cities);
3249
3250 if (size <= 1) {
3251 return;
3252 }
3253
3254 for (i = 0; i < size; i++) {
3255 if (dlgcity == city_list_get(pplayer->cities, i)) {
3256 break;
3257 }
3258 }
3259
3260 if (i >= size - 1) {
3261 // Current city last in the list (size - 1) or disappeared (size)
3262 other_pcity = city_list_get(pplayer->cities, 0);
3263 } else {
3264 other_pcity = city_list_get(pplayer->cities, i + 1);
3265 }
3266
3269}
3270
3271/************************************************************************/
3275{
3276 int size, i;
3277 struct city *other_pcity = nullptr;
3278 struct player *pplayer = client_player();
3279
3280 if (pplayer == nullptr) {
3281 return;
3282 }
3283
3284 size = city_list_size(pplayer->cities);
3285
3286 if (size <= 1) {
3287 return;
3288 }
3289
3290 for (i = 0; i < size; i++) {
3291 if (dlgcity == city_list_get(pplayer->cities, i)) {
3292 break;
3293 }
3294 }
3295
3296 if (i == 0 || i == size) {
3297 // Current city in the beginning of the list or disappeared
3298 other_pcity = city_list_get(pplayer->cities, size - 1);
3299 } else {
3300 other_pcity = city_list_get(pplayer->cities, i - 1);
3301 }
3302
3305}
3306
3307/************************************************************************/
3311{
3312 char buf[32];
3313 QString str;
3315
3317 production_combo_p->setRange(0, cost);
3319 if (dlgcity->shield_stock >= cost) {
3320 production_combo_p->setValue(cost);
3321 } else {
3323 }
3324 production_combo_p->setAlignment(Qt::AlignCenter);
3325 str = QString(buf);
3326 str = str.simplified();
3327
3328 production_combo_p->setFormat(QString("(%p%) %2\n%1")
3330 str));
3331
3332 production_combo_p->updateGeometry();
3333
3334}
3335
3336/************************************************************************/
3340{
3341 char buf[1024], buf2[1024];
3343 int value = dlgcity->client.buy_cost;
3345 int city_id = dlgcity->id;
3346
3347 if (!can_client_issue_orders()) {
3348 return;
3349 }
3350
3352 fc_snprintf(buf2, ARRAY_SIZE(buf2), PL_("Treasury contains %d gold.",
3353 "Treasury contains %d gold.",
3354 client_player()->economic.gold),
3355 client_player()->economic.gold);
3356 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Buy %s for %d gold?",
3357 "Buy %s for %d gold?", value),
3358 name, value);
3359 ask->set_text_title(buf, buf2);
3360 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
3361 ask->setDefaultButton(QMessageBox::Cancel);
3362 ask->setAttribute(Qt::WA_DeleteOnClose);
3363 connect(ask, &hud_message_box::accepted, this, [=]() {
3364 struct city *pcity = game_city_by_number(city_id);
3365
3366 if (!pcity) {
3367 return;
3368 }
3369
3371 });
3372 ask->show();
3373}
3374
3375/************************************************************************/
3379{
3380 QFont f = QApplication::font();
3381 QFontMetrics fm(f);
3382 QPixmap *pix = nullptr;
3386 struct sprite *sprite;
3387 int h, cost, item, targets_used, col, upkeep;
3388 struct item items[MAX_NUM_PRODUCTION_TARGETS];
3389 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
3390 struct worklist queue;
3391 impr_item *ui;
3392
3393 upkeep = 0;
3394 city_buildings->setUpdatesEnabled(false);
3396
3397 h = fm.height() + 6;
3399 name_and_sort_items(targets, targets_used, items, false, dlgcity);
3400
3401 for (item = 0; item < targets_used; item++) {
3402 struct universal target = items[item].item;
3403
3404 ui = new impr_item(this, target.value.building, dlgcity);
3405 ui->init_pix();
3407
3408 fc_assert_action(VUT_IMPROVEMENT == target.kind, continue);
3410 upkeep = upkeep + city_improvement_upkeep(dlgcity, target.value.building);
3411 if (sprite != nullptr) {
3412 pix = sprite->pm;
3413 pix_scaled = pix->scaledToHeight(h);
3414 }
3415 }
3416
3417 city_get_queue(dlgcity, &queue);
3418 p_table_p->setRowCount(worklist_length(&queue));
3419
3420 for (int i = 0; i < worklist_length(&queue); i++) {
3421 struct universal target = queue.entries[i];
3422
3423 tooltip = "";
3424
3425 if (VUT_UTYPE == target.kind) {
3427 cost = utype_build_shield_cost(dlgcity, nullptr, target.value.utype);
3428 tooltip = get_tooltip_unit(target.value.utype, true).trimmed();
3432 } else {
3436 dlgcity, true).trimmed();
3437
3439 cost = -1;
3440 } else {
3442 }
3443 }
3444
3445 for (col = 0; col < 3; col++) {
3446 qitem = new QTableWidgetItem();
3447 qitem->setToolTip(tooltip);
3448
3449 switch (col) {
3450 case 0:
3451 if (sprite) {
3452 pix = sprite->pm;
3453 pix_scaled = pix->scaledToHeight(h);
3454 qitem->setData(Qt::DecorationRole, pix_scaled);
3455 }
3456 break;
3457
3458 case 1:
3459 if (str.contains('[') && str.contains(']')) {
3460 int ii, ij;
3461
3462 ii = str.lastIndexOf('[');
3463 ij = str.lastIndexOf(']');
3464 if (ij > ii) {
3465 str = str.remove(ii, ij - ii + 1);
3466 }
3467 }
3468 qitem->setText(str);
3469 break;
3470
3471 case 2:
3472 qitem->setTextAlignment(Qt::AlignRight);
3473 qitem->setText(QString::number(cost));
3474 break;
3475 }
3476 p_table_p->setItem(i, col, qitem);
3477 }
3478 }
3479
3480 p_table_p->horizontalHeader()->setStretchLastSection(false);
3481 p_table_p->resizeColumnsToContents();
3482 p_table_p->resizeRowsToContents();
3483 p_table_p->horizontalHeader()->setStretchLastSection(true);
3484
3486 city_buildings->setUpdatesEnabled(true);
3487 city_buildings->setUpdatesEnabled(true);
3488
3489 curr_impr->setText(QString(_("Improvements - upkeep %1")).arg(upkeep));
3490}
3491
3492/************************************************************************/
3496{
3497 cid id;
3498 QVariant qvar;
3499
3501 struct universal univ;
3502
3503 id = qvar.toInt();
3504 univ = cid_production(id);
3506 }
3507}
3508
3509/************************************************************************/
3514{
3516 int when = 1;
3517
3518 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3519 when, selected_row_p, show_units->isChecked(),
3520 false, show_wonders->isChecked(),
3521 show_buildings->isChecked());
3522 pw->show();
3523}
3524
3525/************************************************************************/
3530{
3532 int when = 4;
3533
3534 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3535 when, selected_row_p, show_units->isChecked(),
3536 false, show_wonders->isChecked(),
3537 show_buildings->isChecked());
3538 pw->show();
3539}
3540
3541/************************************************************************/
3545{
3546 struct worklist empty;
3547
3548 if (!can_client_issue_orders()) {
3549 return;
3550 }
3551
3554}
3555
3556/************************************************************************/
3560{
3561 QModelIndex index;
3562 struct worklist queue;
3563 struct universal *target;
3564
3566 return;
3567 }
3568
3569 target = new universal;
3570 city_get_queue(dlgcity, &queue);
3571 worklist_peek_ith(&queue, target, selected_row_p);
3573 worklist_insert(&queue, target, selected_row_p - 1);
3574 city_set_queue(dlgcity, &queue);
3575 index = p_table_p->model()->index(selected_row_p - 1, 0);
3576 p_table_p->setCurrentIndex(index);
3577 delete target;
3578
3579}
3580
3581/************************************************************************/
3585{
3587
3588 if (selected_row_p < 0
3589 || selected_row_p >= p_table_p->rowCount()) {
3590 return;
3591 }
3592
3596}
3597
3598/************************************************************************/
3602{
3603 QModelIndex index;
3604 struct worklist queue;
3605 struct universal *target;
3606
3608 return;
3609 }
3610
3611 target = new universal;
3612 city_get_queue(dlgcity, &queue);
3613 worklist_peek_ith(&queue, target, selected_row_p);
3615 worklist_insert(&queue, target, selected_row_p + 1);
3616 city_set_queue(dlgcity, &queue);
3617 index = p_table_p->model()->index(selected_row_p + 1, 0);
3618 p_table_p->setCurrentIndex(index);
3619 delete target;
3620}
3621
3622/************************************************************************/
3626{
3627 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
3628 int city_id = dlgcity->id;
3629
3630 ask->set_text_title_definput(_("What should we name new worklist?"),
3631 _("Save current worklist"),
3632 _("New worklist"));
3633 ask->setAttribute(Qt::WA_DeleteOnClose);
3634 connect(ask, &hud_message_box::accepted, [=]() {
3635 struct global_worklist *gw;
3636 struct worklist queue;
3638 QString text;
3639 struct city *pcity = game_city_by_number(city_id);
3640
3641 ask_bytes = ask->input_edit.text().toUtf8();
3642 text = ask_bytes.data();
3643 if (!text.isEmpty()) {
3644 ask_bytes = text.toUtf8();
3646 city_get_queue(pcity, &queue);
3647 global_worklist_set(gw, &queue);
3648 }
3649 });
3650 ask->show();
3651}
3652
3653/************************************************************************/
3657{
3658 QString buf;
3659
3660 // Defeat keyboard shortcut mnemonics
3662 .replace("&", "&&"));
3663
3664 if (city_unhappy(dlgcity)) {
3665 // TRANS: city dialog title
3666 buf = QString(_("%1 - %2 citizens - DISORDER")).arg(city_name_get(dlgcity),
3668 } else if (city_celebrating(dlgcity)) {
3669 // TRANS: city dialog title
3670 buf = QString(_("%1 - %2 citizens - celebrating")).arg(city_name_get(dlgcity),
3672 } else if (city_happy(dlgcity)) {
3673 // TRANS: city dialog title
3674 buf = QString(_("%1 - %2 citizens - happy")).arg(city_name_get(dlgcity),
3676 } else {
3677 // TRANS: city dialog title
3678 buf = QString(_("%1 - %2 citizens")).arg(city_name_get(dlgcity),
3680 }
3681
3683}
3684
3685/************************************************************************/
3690{
3691 if (!::city_dlg_created) {
3692 ::city_dlg = new city_dialog(gui()->mapview_wdg);
3693 }
3694
3695 city_dlg->setup_ui(pcity);
3696 city_dlg->show();
3697 city_dlg->activateWindow();
3698 city_dlg->raise();
3699}
3700
3701/************************************************************************/
3705{
3706 if (!::city_dlg_created) {
3707 return;
3708 }
3709
3710 city_dlg->close();
3711 ::city_dlg_created = false;
3712}
3713
3714/************************************************************************/
3718{
3719 if (!::city_dlg_created) {
3720 return;
3721 }
3722
3724}
3725
3726/************************************************************************/
3733
3734/************************************************************************/
3738{
3739 if (!::city_dlg_created) {
3740 return;
3741 }
3742
3743 if (qtg_city_dialog_is_open(pcity)) {
3744 city_dlg->refresh();
3745 }
3746}
3747
3748/************************************************************************/
3752{
3754 QFont *f;
3755
3756 if (!::city_dlg_created) {
3757 return;
3758 }
3759
3760 l = city_dlg->findChildren<QLabel *>();
3761
3763
3764 for (int i = 0; i < l.size(); ++i) {
3765 if (l.at(i)->property(fonts::notify_label).isValid()) {
3766 l.at(i)->setFont(*f);
3767 }
3768 }
3769}
3770
3771/************************************************************************/
3788
3789/************************************************************************/
3793{
3794 if (!::city_dlg_created) {
3795 return false;
3796 }
3797
3798 if (city_dlg->dlgcity == pcity && city_dlg->isVisible()) {
3799 return true;
3800 }
3801
3802 return false;
3803}
3804
3805/************************************************************************/
3808bool fc_tooltip::eventFilter(QObject *obj, QEvent *ev)
3809{
3812 QRect rect;
3813
3814 if (ev->type() == QEvent::ToolTip) {
3816
3817 if (!view) {
3818 return false;
3819 }
3820
3821 help_event = static_cast<QHelpEvent *>(ev);
3822 QPoint pos = help_event->pos();
3823 QModelIndex index = view->indexAt(pos);
3824 QPoint hpos;
3825
3826 if (!index.isValid()) {
3827 return false;
3828 }
3829
3830 item_tooltip = view->model()->data(index, Qt::ToolTipRole).toString();
3831 rect = view->visualRect(index);
3832
3833 hpos = help_event->globalPos();
3834
3835 rect.setX(rect.x() + hpos.x());
3836 rect.setY(rect.y() + hpos.y());
3837
3838 if (!item_tooltip.isEmpty()) {
3839 QToolTip::showText(help_event->globalPos(), item_tooltip, view, rect);
3840 } else {
3841 QToolTip::hideText();
3842 }
3843
3844 return true;
3845 }
3846
3847 return false;
3848}
3849
3850/************************************************************************/
3854{
3855 return QString("<b>" + text + "</b>");
3856}
3857
3858/************************************************************************/
3862QString get_tooltip_improvement(const impr_type *building, struct city *pcity,
3863 bool ext)
3864{
3866 QString upkeep;
3867 QString s1, s2, str;
3868 const char *req = skip_intl_qualifier_prefix(_("?tech:None"));
3869 struct player *pplayer = client_player();
3870
3871 if (pcity != nullptr) {
3872 upkeep = QString::number(city_improvement_upkeep(pcity, building));
3873 } else {
3874 upkeep = QString::number(building->upkeep);
3875 }
3877 if (pobs->source.kind == VUT_ADVANCE) {
3878 req = advance_name_translation(pobs->source.value.advance);
3879 break;
3880 }
3882 s2 = QString(req);
3883 str = _("Obsolete by:");
3884 str = str + " " + s2;
3885 def_str = "<p style='white-space:pre'><b>"
3886 + QString(improvement_name_translation(building)).toHtmlEscaped()
3887 + "</b>\n";
3888 if (pcity != nullptr) {
3889 def_str += QString(_("Cost: %1, Upkeep: %2\n"))
3890 .arg(impr_build_shield_cost(pcity, building))
3891 .arg(upkeep).toHtmlEscaped();
3892 } else {
3894 nullptr, building);
3895
3896 def_str += QString(_("Cost Estimate: %1, Upkeep: %2\n"))
3897 .arg(cost_est)
3898 .arg(upkeep).toHtmlEscaped();
3899 }
3900 if (s1.compare(s2) != 0) {
3901 def_str = def_str + str.toHtmlEscaped() + "\n";
3902 }
3903 def_str = def_str + "\n";
3904 if (ext) {
3905 char buffer[8192];
3906
3907 str = helptext_building(buffer, sizeof(buffer), pplayer,
3908 nullptr, building);
3909 str = cut_helptext(str);
3910 str = split_text(str, true);
3911 str = str.trimmed();
3912 def_str = def_str + str.toHtmlEscaped();
3913 }
3914 return def_str;
3915}
3916
3917/************************************************************************/
3921QString get_tooltip_unit(const struct unit_type *utype, bool ext)
3922{
3925 QString str;
3926 const struct unit_type *obsolete;
3927 struct advance *tech;
3928
3929 def_str = "<b>"
3930 + QString(utype_name_translation(utype)).toHtmlEscaped()
3931 + "</b>\n";
3932 obsolete = utype->obsoleted_by;
3933 if (obsolete) {
3934 // FIXME: Don't give the impression that primary tech is (always) the only one.
3936 obsolete_str = QString("</td></tr><tr><td colspan=\"3\">");
3937 if (tech && tech != advance_by_number(A_NONE)) {
3938 /* TRANS: this and nearby literal strings are interpreted
3939 * as (Qt) HTML */
3940 obsolete_str = obsolete_str + QString(_("Obsoleted by %1 (%2)."))
3942 .arg(advance_name_translation(tech)).toHtmlEscaped();
3943 } else {
3944 obsolete_str = obsolete_str + QString(_("Obsoleted by %1."))
3945 .arg(utype_name_translation(obsolete)).toHtmlEscaped();
3946 }
3947 }
3948 def_str += "<table width=\"100\%\"><tr><td>"
3949 + bold(QString(_("Attack:"))) + " "
3950 + QString::number(utype->attack_strength).toHtmlEscaped()
3951 + QString("</td><td>") + bold(QString(_("Defense:"))) + " "
3952 + QString::number(utype->defense_strength).toHtmlEscaped()
3953 + QString("</td><td>") + bold(QString(_("Move:"))) + " "
3954 + QString(move_points_text(utype->move_rate, TRUE)).toHtmlEscaped()
3955 + QString("</td></tr><tr><td>")
3956 + bold(QString(_("Cost:"))) + " "
3957 + QString::number(utype_build_shield_cost_base(utype))
3958 .toHtmlEscaped()
3959 + QString("</td><td colspan=\"2\">")
3960 + bold(QString(_("Basic Upkeep:")))
3961 + " " + QString(helptext_unit_upkeep_str(utype)).toHtmlEscaped()
3962 + QString("</td></tr><tr><td>")
3963 + bold(QString(_("Hitpoints:"))) + " "
3964 + QString::number(utype->hp).toHtmlEscaped()
3965 + QString("</td><td>") + bold(QString(_("Firepower:"))) + " "
3966 + QString::number(utype->firepower).toHtmlEscaped()
3967 + QString("</td><td>") + bold(QString(_("Vision:"))) + " "
3968 + QString::number((int) sqrt((double) utype->vision_radius_sq))
3969 .toHtmlEscaped()
3970 + obsolete_str
3971 + QString("</td></tr></table><p style='white-space:pre'>");
3972 if (ext) {
3973 char buffer[8192];
3974 char buf2[1];
3975
3976 buf2[0] = '\0';
3977 str = helptext_unit(buffer, sizeof(buffer), client_player(),
3978 buf2, utype);
3979 str = cut_helptext(str);
3980 str = split_text(str, true);
3981 str = str.trimmed().toHtmlEscaped();
3982 def_str = def_str + str;
3983 }
3984
3985 return def_str;
3986};
3987
3988/************************************************************************/
3992{
3995 char buffer[8192];
3996 char buf2[1];
3997 struct universal *target;
3998 struct player *pplayer = client_player();
3999
4000 buf2[0] = '\0';
4001 target = reinterpret_cast<universal *>(qvar.value<void *>());
4002
4003 if (target == nullptr) {
4004 } else if (VUT_UTYPE == target->kind) {
4006 str = helptext_unit(buffer, sizeof(buffer), pplayer,
4007 buf2, target->value.utype);
4008 } else {
4009 if (!is_convert_improvement(target->value.building)) {
4011 }
4012
4013 str = helptext_building(buffer, sizeof(buffer), pplayer,
4014 nullptr, target->value.building);
4015 }
4016
4017 // Remove all lines from help which has '*' in first 3 chars
4019 ret_str = split_text(ret_str, true);
4020 ret_str = ret_str.trimmed();
4021 ret_str = def_str + ret_str.toHtmlEscaped();
4022
4023 return ret_str;
4024}
4025
4026/************************************************************************/
4030 QObject *parent,
4031 struct city *city)
4032 : QItemDelegate(parent)
4033{
4034 pd = sh;
4035 item_height = sh.y();
4036 pcity = city;
4037}
4038
4039/************************************************************************/
4044 const QModelIndex &index) const
4045{
4046 struct universal *target;
4047 QString name;
4048 QVariant qvar;
4049 QPixmap *pix;
4051 QRect rect1;
4052 QRect rect2;
4053 struct sprite *sprite;
4054 bool useless = false;
4055 bool is_coinage = false;
4056 bool is_neutral = false;
4057 bool is_sea = false;
4058 bool is_flying = false;
4059 bool is_unit = true;
4060 QPixmap pix_dec(option.rect.width(), option.rect.height());
4062 color col;
4063 QIcon icon = current_app()->style()->standardIcon(QStyle::SP_DialogCancelButton);
4064 bool free_sprite = false;
4065 struct unit_class *pclass;
4066
4067 if (!option.rect.isValid()) {
4068 return;
4069 }
4070
4071 qvar = index.data();
4072
4073 if (!qvar.isValid()) {
4074 return;
4075 }
4076
4077 target = reinterpret_cast<universal *>(qvar.value<void *>());
4078
4079 if (target == nullptr) {
4080 col.qcolor = Qt::white;
4081 sprite = qtg_create_sprite(100, 100, &col);
4082 free_sprite = true;
4083 *sprite->pm = icon.pixmap(100, 100);
4084 name = _("Cancel");
4085 is_unit = false;
4086 } else if (VUT_UTYPE == target->kind) {
4089 pclass = utype_class(target->value.utype);
4093 is_sea = true;
4094 }
4095
4096 if ((utype_fuel(target->value.utype)
4101 /* FIXME: Assumed to be flying since only missiles can do suicide
4102 * attacks in classic-like rulesets. This isn't true for all
4103 * rulesets. Not a high priority to fix since all is_flying and
4104 * is_sea is used for is to set a color. */
4106 target->value.utype)) {
4107 if (is_sea) {
4108 is_sea = false;
4109 }
4110 is_flying = true;
4111 }
4112
4116 } else {
4117 is_unit = false;
4122 }
4123
4124 if (sprite != nullptr) {
4125 pix = sprite->pm;
4126 pix_scaled = pix->scaledToHeight(item_height - 2, Qt::SmoothTransformation);
4127
4128 if (useless) {
4130 }
4131 }
4132
4133 opt = QItemDelegate::setOptions(index, option);
4134 painter->save();
4135 opt.displayAlignment = Qt::AlignLeft;
4136 opt.textElideMode = Qt::ElideMiddle;
4137 QItemDelegate::drawBackground(painter, opt, index);
4138 rect1 = option.rect;
4139 rect1.setWidth(pix_scaled.width() + 4);
4140 rect2 = option.rect;
4141 rect2.setLeft(option.rect.left() + rect1.width());
4142 rect2.setTop(rect2.top() + (rect2.height()
4143 - painter->fontMetrics().height()) / 2);
4144 QItemDelegate::drawDisplay(painter, opt, rect2, name);
4145
4146 if (is_unit) {
4147 if (is_sea) {
4148 pix_dec.fill(QColor(0, 0, 255, 80));
4149 } else if (is_flying) {
4150 pix_dec.fill(QColor(220, 0, 0, 80));
4151 } else if (is_neutral) {
4152 pix_dec.fill(QColor(0, 120, 0, 40));
4153 } else {
4154 pix_dec.fill(QColor(0, 0, 150, 40));
4155 }
4156
4157 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4158 }
4159
4160 if (is_coinage) {
4161 pix_dec.fill(QColor(255, 255, 0, 70));
4162 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4163 }
4164
4165 if (!pix_scaled.isNull()) {
4166 QItemDelegate::drawDecoration(painter, opt, rect1, pix_scaled);
4167 }
4168
4169 drawFocus(painter, opt, option.rect);
4170
4171 painter->restore();
4172
4173 if (free_sprite) {
4175 }
4176}
4177
4178/************************************************************************/
4183 const QRect &rect) const
4184{
4185 QPixmap pix(option.rect.width(), option.rect.height());
4186
4187 if ((option.state & QStyle::State_MouseOver) == 0 || !rect.isValid()) {
4188 return;
4189 }
4190
4191 pix.fill(QColor(50, 50, 50, 50));
4192 QItemDelegate::drawDecoration(painter, option, option.rect, pix);
4193}
4194
4195/************************************************************************/
4199 const QModelIndex &index) const
4200{
4201 QSize s;
4202
4203 s.setWidth(pd.x());
4204 s.setHeight(pd.y());
4205 return s;
4206}
4207
4208/************************************************************************/
4212 QObject *parent): QObject()
4213{
4215 target = ptarget;
4216}
4217
4218/************************************************************************/
4222{
4223 // Allocated as renegade in model
4224 if (target != nullptr) {
4225 delete target;
4226 }
4227}
4228
4229/************************************************************************/
4233{
4234 return QVariant::fromValue((void *)target);
4235}
4236
4237/************************************************************************/
4241{
4242 return false;
4243}
4244
4245/************************************************************************/
4249 bool su, bool sw, bool sb,
4250 QObject *parent)
4251 : QAbstractListModel(parent)
4252{
4253 show_units = su;
4254 show_wonders = sw;
4256 mcity = pcity;
4257 future_t = f;
4258 populate();
4259}
4260
4261/************************************************************************/
4269
4270/************************************************************************/
4274{
4275 if (!index.isValid()) {
4276 return QVariant();
4277 }
4278
4279 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4280 && index.column() < columnCount()
4281 && (index.column() + index.row() * 3 < city_target_list.count())) {
4282 int r, c, t, new_index;
4283
4284 r = index.row();
4285 c = index.column();
4286 t = r * 3 + c;
4287 new_index = t / 3 + rowCount() * c;
4288 // Exception, shift whole column
4289 if ((c == 2) && city_target_list.count() % 3 == 1) {
4290 new_index = t / 3 + rowCount() * c - 1;
4291 }
4292 if (role == Qt::ToolTipRole) {
4294 }
4295
4296 return city_target_list[new_index]->data();
4297 }
4298
4299 return QVariant();
4300}
4301
4302/************************************************************************/
4306{
4308 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
4309 struct item items[MAX_NUM_PRODUCTION_TARGETS];
4310 struct universal *renegade;
4311 int item, targets_used;
4312 QString str;
4314 QFontMetrics fm(f);
4315
4316 sh.setY(fm.height() * 2);
4317 sh.setX(0);
4318
4320 city_target_list.clear();
4321
4323 future_t);
4324 name_and_sort_items(targets, targets_used, items, false, mcity);
4325
4326 for (item = 0; item < targets_used; item++) {
4327 if (future_t || can_city_build_now(mcity, &items[item].item)) {
4328 renegade = new universal(items[item].item);
4329
4330 // Renagade deleted in production_item destructor
4331 if (VUT_UTYPE == renegade->kind) {
4332 str = utype_name_translation(renegade->value.utype);
4333 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4334
4335 if (show_units) {
4336 pi = new production_item(renegade, this);
4338 } else {
4339 delete renegade;
4340 }
4341 } else {
4342 str = improvement_name_translation(renegade->value.building);
4343 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4344
4345 if ((is_wonder(renegade->value.building) && show_wonders)
4346 || (is_improvement(renegade->value.building) && show_buildings)
4347 || (is_convert_improvement(renegade->value.building))
4348 || (is_special_improvement(renegade->value.building)
4349 && show_buildings)) {
4350 pi = new production_item(renegade, this);
4352 } else {
4353 delete renegade;
4354 }
4355 }
4356 }
4357 }
4358
4359 pi = new production_item(nullptr, this);
4361 sh.setX(2 * sh.y() + sh.x());
4362 sh.setX(qMin(sh.x(), 250));
4363}
4364
4365/************************************************************************/
4369 const QVariant &value, int role)
4370{
4371 if (!index.isValid() || role != Qt::DisplayRole || role != Qt::ToolTipRole)
4372 return false;
4373
4374 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4375 && index.column() < columnCount()) {
4376 bool change = city_target_list[index.row()]->setData();
4377 return change;
4378 }
4379
4380 return false;
4381}
4382
4383/************************************************************************/
4392 bool future, int when, int curr,
4393 bool show_units, bool buy,
4394 bool show_wonders,
4395 bool show_buildings): QTableView()
4396{
4397 QPoint pos, sh;
4398 QRect rect = QApplication::primaryScreen()->availableGeometry();
4399 int desk_width = rect.width();
4400 int desk_height = rect.height();
4401 fc_tt = new fc_tooltip(this);
4402 setAttribute(Qt::WA_DeleteOnClose);
4403 setWindowFlags(Qt::Popup);
4404 verticalHeader()->setVisible(false);
4405 horizontalHeader()->setVisible(false);
4406 setProperty("showGrid", false);
4408 sh_units = show_units;
4409 pw_city = pcity;
4410 buy_it = buy;
4411 when_change = when;
4412 list_model = new city_production_model(pw_city, future, show_units,
4413 show_wonders, show_buildings, this);
4414 sh = list_model->sh;
4415 c_p_d = new city_production_delegate(sh, this, pw_city);
4418 viewport()->installEventFilter(fc_tt);
4419 installEventFilter(this);
4421 const QItemSelection &)),
4423 const QItemSelection &)));
4426 setFixedWidth(3 * sh.x() + 6);
4427 setFixedHeight(list_model->rowCount()*sh.y() + 6);
4428
4429 if (width() > desk_width) {
4431 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4432 } else {
4433 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4434 }
4435
4436 if (height() > desk_height) {
4438 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4439 } else {
4440 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4441 }
4442
4443 pos = QCursor::pos();
4444
4445 if (pos.x() + width() > desk_width) {
4446 pos.setX(desk_width - width());
4447 } else if (pos.x() - width() < 0) {
4448 pos.setX(0);
4449 }
4450
4451 if (pos.y() + height() > desk_height) {
4452 pos.setY(desk_height - height());
4453 } else if (pos.y() - height() < 0) {
4454 pos.setY(0);
4455 }
4456
4457 move(pos);
4458 setMouseTracking(true);
4459 setFocus();
4460}
4461
4462/************************************************************************/
4466{
4467 if (event->button() == Qt::RightButton) {
4468 close();
4469 return;
4470 }
4471
4472 QAbstractItemView::mousePressEvent(event);
4473}
4474
4475/************************************************************************/
4479{
4480 QRect pw_rect;
4481 QPoint br;
4482
4483 if (obj != this)
4484 return false;
4485
4486 if (ev->type() == QEvent::MouseButtonPress) {
4487 pw_rect.setTopLeft(pos());
4488 br.setX(pos().x() + width());
4489 br.setY(pos().y() + height());
4490 pw_rect.setBottomRight(br);
4491
4492 if (!pw_rect.contains(QCursor::pos())) {
4493 close();
4494 }
4495 }
4496
4497 return false;
4498}
4499
4500/************************************************************************/
4504 const QItemSelection &ds)
4505{
4506 QModelIndexList indexes = selectionModel()->selectedIndexes();
4507 QModelIndex index;
4508 QVariant qvar;
4509 struct worklist queue;
4510 struct universal *target;
4511
4512 if (indexes.isEmpty() || client_is_observer()) {
4513 return;
4514 }
4515 index = indexes.at(0);
4516 qvar = index.data(Qt::UserRole);
4517 if (!qvar.isValid()) {
4518 return;
4519 }
4520 target = reinterpret_cast<universal *>(qvar.value<void *>());
4521 if (target != nullptr) {
4522 city_get_queue(pw_city, &queue);
4523 switch (when_change) {
4524 case 0: // Change current target
4526 if (city_can_buy(pw_city) && buy_it) {
4528 }
4529 break;
4530
4531 case 1: // Change current (selected on list)
4534 } else {
4536 worklist_insert(&queue, target, curr_selection);
4537 city_set_queue(pw_city, &queue);
4538 }
4539 break;
4540
4541 case 2: // Insert before
4543 curr_selection = 0;
4544 }
4547 worklist_insert(&queue, target, curr_selection);
4548 city_set_queue(pw_city, &queue);
4549 break;
4550
4551 case 3: // Insert after
4553 city_queue_insert(pw_city, -1, target);
4554 break;
4555 }
4557 worklist_insert(&queue, target, curr_selection);
4558 city_set_queue(pw_city, &queue);
4559 break;
4560
4561 case 4: // Add last
4562 city_queue_insert(pw_city, -1, target);
4563 break;
4564
4565 default:
4566 break;
4567 }
4568 }
4569 close();
4570 destroy();
4571}
4572
4573/************************************************************************/
4577{
4578 delete c_p_d;
4579 delete list_model;
4580 viewport()->removeEventFilter(fc_tt);
4581 removeEventFilter(this);
4582}
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1225
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:688
#define str
Definition astring.c:76
#define n
Definition astring.c:77
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_CLR(bv, bit)
Definition bitvector.h:86
QRect zealous_crop_rect(QImage &p)
Definition canvas.cpp:419
void qtg_canvas_free(struct canvas *store)
Definition canvas.cpp:48
struct canvas * qtg_canvas_create(int width, int height)
Definition canvas.cpp:36
void qtg_canvas_copy(struct canvas *dest, struct canvas *src, int src_x, int src_y, int dest_x, int dest_y, int width, int height)
Definition canvas.cpp:79
void pixmap_copy(QPixmap *dest, QPixmap *src, int src_x, int src_y, int dest_x, int dest_y, int width, int height)
Definition canvas.cpp:101
static QFont * get_font(enum client_font font)
Definition canvas.cpp:379
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int canvas_y
Definition canvas_g.h:43
struct canvas int canvas_x
Definition canvas_g.h:43
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
citizens citizens_nation_get(const struct city *pcity, const struct player_slot *pslot)
Definition citizens.c:74
#define citizens_iterate_end
Definition citizens.h:54
#define citizens_iterate(_pcity, _pslot, _nationality)
Definition citizens.h:48
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:663
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:737
int city_granary_size(int city_size)
Definition city.c:2129
bool can_city_build_now(const struct city *pcity, const struct universal *target)
Definition city.c:1011
int city_unit_unhappiness(struct unit *punit, int *free_unhappy)
Definition city.c:3046
struct tile * city_map_to_tile(const struct civ_map *nmap, const struct tile *city_center, int city_radius_sq, int city_map_x, int city_map_y)
Definition city.c:305
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Definition city.c:1251
bool is_city_option_set(const struct city *pcity, enum city_options option)
Definition city.c:3384
int city_population(const struct city *pcity)
Definition city.c:1187
bool city_unhappy(const struct city *pcity)
Definition city.c:1622
bool city_celebrating(const struct city *pcity)
Definition city.c:1641
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2867
bool city_happy(const struct city *pcity)
Definition city.c:1610
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
int rs_max_city_radius_sq(void)
Definition city.c:159
citizens city_specialists(const struct city *pcity)
Definition city.c:3313
int city_turns_to_grow(const struct city *pcity)
Definition city.c:1992
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:700
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
citizen_category
Definition city.h:267
#define city_owner(_pcity_)
Definition city.h:563
#define MAX_CITY_SIZE
Definition city.h:106
citizen_feeling
Definition city.h:278
@ FEELING_EFFECT
Definition city.h:281
@ FEELING_LUXURY
Definition city.h:280
@ FEELING_FINAL
Definition city.h:284
@ FEELING_LAST
Definition city.h:285
@ FEELING_BASE
Definition city.h:279
@ FEELING_NATIONALITY
Definition city.h:282
@ FEELING_MARTIAL
Definition city.h:283
void qtg_popdown_city_dialog(struct city *pcity)
Definition citydlg.cpp:3717
void qtg_real_city_dialog_refresh(struct city *pcity)
Definition citydlg.cpp:3737
QString split_text(QString text, bool cut)
Definition optiondlg.cpp:62
void city_font_update()
Definition citydlg.cpp:3751
bool qtg_city_dialog_is_open(struct city *pcity)
Definition citydlg.cpp:3792
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:3991
void qtg_popdown_all_city_dialogs()
Definition citydlg.cpp:3729
static city_dialog * city_dlg
Definition citydlg.cpp:74
void qtg_refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.cpp:3776
static QString bold(QString text)
Definition citydlg.cpp:3853
void qtg_real_city_dialog_popup(struct city *pcity)
Definition citydlg.cpp:3689
QString get_tooltip_improvement(const impr_type *building, struct city *pcity, bool ext)
Definition citydlg.cpp:3862
static bool city_dlg_created
Definition citydlg.cpp:70
static void pixmap_put_x(QPixmap *pix)
Definition citydlg.cpp:349
QString cut_helptext(QString text)
QString get_tooltip_unit(const struct unit_type *utype, bool ext)
Definition citydlg.cpp:3921
void destroy_city_dialog()
Definition citydlg.cpp:3704
void get_city_dialog_output_text(const struct city *pcity, Output_type_id otype, char *buf, size_t bufsz)
void get_city_dialog_production(struct city *pcity, char *buffer, size_t buffer_len)
int city_set_worklist(struct city *pcity, const struct worklist *pworklist)
int get_city_citizen_types(struct city *pcity, enum citizen_feeling idx, enum citizen_category *categories)
int city_buy_production(struct city *pcity)
bool city_queue_insert(struct city *pcity, int position, struct universal *item)
bool city_queue_insert_worklist(struct city *pcity, int position, const struct worklist *worklist)
int city_toggle_worker(struct city *pcity, int city_x, int city_y)
void get_city_dialog_airlift_text(const struct city *pcity, char *buf, size_t bufsz)
bool city_set_queue(struct city *pcity, const struct worklist *pqueue)
int city_change_production(struct city *pcity, struct universal *target)
void city_rotate_specialist(struct city *pcity, int citizen_index)
int get_citydlg_canvas_width(void)
bool canvas_to_city_pos(int *city_x, int *city_y, int city_radius_sq, int canvas_x, int canvas_y)
void get_city_dialog_airlift_value(const struct city *pcity, char *buf, size_t bufsz)
void city_get_queue(struct city *pcity, struct worklist *pqueue)
void city_dialog_redraw_map(struct city *pcity, struct canvas *pcanvas)
int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
void get_city_dialog_pollution_text(const struct city *pcity, char *buf, size_t bufsz)
void get_city_dialog_culture_text(const struct city *pcity, char *buf, size_t bufsz)
bool city_can_buy(const struct city *pcity)
int get_citydlg_canvas_height(void)
void get_city_dialog_illness_text(const struct city *pcity, char *buf, size_t bufsz)
void set_city(struct city *pcity)
Definition citydlg.cpp:1194
struct city * pcity
Definition citydlg.h:426
city_label(int type, QWidget *parent=nullptr)
Definition citydlg.cpp:1162
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1170
int wdth
Definition citydlg.h:287
int cutted_height
Definition citydlg.h:290
QSize sizeHint() const
Definition citydlg.cpp:1293
void paintEvent(QPaintEvent *event)
Definition citydlg.cpp:1233
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1309
void set_pixmap(struct city *pcity, float z)
Definition citydlg.cpp:1257
void context_menu(QPoint point)
Definition citydlg.cpp:1331
canvas * miniview
Definition citydlg.h:274
int hight
Definition citydlg.h:288
struct city * mcity
Definition citydlg.h:284
QSize minimumSizeHint() const
Definition citydlg.cpp:1301
float zoom
Definition citydlg.h:286
QPixmap zoomed_pixmap
Definition citydlg.h:275
city_map(QWidget *parent)
Definition citydlg.cpp:1202
int cutted_width
Definition citydlg.h:289
int radius
Definition citydlg.h:285
int delta_y
Definition citydlg.h:292
int delta_x
Definition citydlg.h:291
city_production_delegate(QPoint sh, QObject *parent, struct city *city)
Definition citydlg.cpp:4029
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4042
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4198
struct city * pcity
Definition citydlg.h:318
void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
Definition citydlg.cpp:4181
int rowCount(const QModelIndex &index=QModelIndex()) const
Definition citydlg.h:356
QList< production_item * > city_target_list
Definition citydlg.h:372
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole)
Definition citydlg.cpp:4368
int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition citydlg.h:360
city_production_model(struct city *pcity, bool f, bool su, bool sw, bool sb, QObject *parent=nullptr)
Definition citydlg.cpp:4248
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition citydlg.cpp:4273
struct city * mcity
Definition citydlg.h:373
static fc_font * instance()
Definition fonts.cpp:41
QFont * get_font(QString name)
Definition fonts.cpp:63
static fc_icons * instance()
bool eventFilter(QObject *obj, QEvent *event)
Definition citydlg.cpp:3808
void update_buildings()
Definition citydlg.cpp:554
QHBoxLayout * layout
Definition citydlg.h:260
void add_item(impr_item *item)
Definition citydlg.cpp:502
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:535
impr_info(QWidget *parent)
Definition citydlg.cpp:471
void clear_layout()
Definition citydlg.cpp:510
void init_layout()
Definition citydlg.cpp:481
QList< impr_item * > impr_list
Definition citydlg.h:261
void mouseDoubleClickEvent(QMouseEvent *event)
Definition citydlg.cpp:606
impr_item(QWidget *parent, const struct impr_type *building, struct city *pcity)
Definition citydlg.cpp:366
void init_pix()
Definition citydlg.cpp:405
void enterEvent(QEnterEvent *event)
Definition citydlg.cpp:415
struct canvas * impr_pixmap
Definition citydlg.h:232
struct city * dlgcity
Definition citydlg.h:233
const struct impr_type * impr
Definition citydlg.h:231
void leaveEvent(QEvent *event)
Definition citydlg.cpp:445
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:586
struct universal * target
Definition citydlg.h:342
QVariant data() const
Definition citydlg.cpp:4232
production_item(struct universal *ptarget, QObject *parent)
Definition citydlg.cpp:4211
bool eventFilter(QObject *obj, QEvent *ev)
Definition citydlg.cpp:4478
void prod_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:4503
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:4465
city_production_model * list_model
Definition citydlg.h:387
struct city * pw_city
Definition citydlg.h:404
fc_tooltip * fc_tt
Definition citydlg.h:409
city_production_delegate * c_p_d
Definition citydlg.h:388
production_widget(QWidget *parent, struct city *pcity, bool future, int when, int curr, bool show_units, bool buy=false, bool show_wonders=true, bool show_buildings=true)
Definition citydlg.cpp:4391
progress_bar(QWidget *parent)
Definition citydlg.cpp:81
void paintEvent(QPaintEvent *event)
Definition citydlg.cpp:187
int m_animate_step
Definition citydlg.h:132
void resizeEvent(QResizeEvent *event)
Definition citydlg.cpp:105
QRegion reg
Definition citydlg.h:134
void set_pixmap(struct universal *target)
Definition citydlg.cpp:113
void create_region()
Definition citydlg.cpp:325
QElapsedTimer m_timer
Definition citydlg.h:113
void timerEvent(QTimerEvent *event)
Definition citydlg.cpp:175
QPixmap * pix
Definition citydlg.h:133
QFont * sfont
Definition citydlg.h:135
void clicked()
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:1076
void init_layout()
Definition citydlg.cpp:1064
unit_info(bool supp)
Definition citydlg.cpp:1037
void add_item(unit_item *item)
Definition citydlg.cpp:1056
QHBoxLayout * layout
Definition citydlg.h:208
void update_units()
Definition citydlg.cpp:1095
void clear_layout()
Definition citydlg.cpp:1136
QList< unit_item * > unit_list
Definition citydlg.h:209
bool supports
Definition citydlg.h:212
QAction * activate
Definition citydlg.h:146
QAction * disband_action
Definition citydlg.h:144
void enterEvent(QEnterEvent *event)
Definition citydlg.cpp:965
void contextMenuEvent(QContextMenuEvent *ev)
Definition citydlg.cpp:737
QAction * sentry
Definition citydlg.h:148
struct unit * qunit
Definition citydlg.h:163
QAction * activate_and_close
Definition citydlg.h:147
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1014
int happy_cost
Definition citydlg.h:167
void change_homecity()
Definition citydlg.cpp:923
QAction * unload
Definition citydlg.h:151
QAction * upgrade
Definition citydlg.h:152
bool supported
Definition citydlg.h:168
void fortify_unit()
Definition citydlg.cpp:954
void sentry_unit()
Definition citydlg.cpp:1027
QAction * unload_trans
Definition citydlg.h:153
void load_unit()
Definition citydlg.cpp:887
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:994
QAction * load
Definition citydlg.h:150
void activate_unit()
Definition citydlg.cpp:944
QAction * change_home
Definition citydlg.h:145
QAction * fortify
Definition citydlg.h:149
QImage unit_img
Definition citydlg.h:164
void create_actions()
Definition citydlg.cpp:791
void unload_all()
Definition citydlg.cpp:903
void disband()
Definition citydlg.cpp:869
void upgrade_unit()
Definition citydlg.cpp:911
void init_pix()
Definition citydlg.cpp:721
void leaveEvent(QEvent *event)
Definition citydlg.cpp:986
unit_item(QWidget *parent, struct unit *punit, bool supp=false, int happy_cost=0)
Definition citydlg.cpp:650
void unload_unit()
Definition citydlg.cpp:895
void activate_and_close_dialog()
Definition citydlg.cpp:933
bool client_is_observer(void)
struct civclient client
bool can_client_issue_orders(void)
#define client_player()
int collect_eventually_buildable_targets(struct universal *targets, struct city *pcity, bool advanced_tech)
Definition climisc.c:809
void name_and_sort_items(struct universal *targets, int num_targets, struct item *items, bool show_cost, struct city *pcity)
Definition climisc.c:640
cid cid_encode(struct universal target)
Definition climisc.c:482
int collect_already_built_targets(struct universal *targets, struct city *pcity)
Definition climisc.c:902
struct universal cid_decode(cid id)
Definition climisc.c:525
#define MAX_NUM_PRODUCTION_TARGETS
Definition climisc.h:87
#define cid_production
Definition climisc.h:71
int cid
Definition climisc.h:31
static struct fc_sockaddr_list * list
Definition clinet.c:102
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Definition cm.c:2171
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:551
void cma_put_city_under_agent(struct city *pcity, const struct cm_parameter *const parameter)
Definition cma_core.c:523
void cma_release_city(struct city *pcity)
Definition cma_core.c:541
char * cmafec_preset_get_descr(int idx)
Definition cma_fec.c:169
const char * cmafec_get_short_descr_of_city(const struct city *pcity)
Definition cma_fec.c:221
const struct cm_parameter * cmafec_preset_get_parameter(int idx)
Definition cma_fec.c:182
void cmafec_preset_add(const char *descr_name, struct cm_parameter *pparam)
Definition cma_fec.c:136
int cmafec_preset_get_index_of_parameter(const struct cm_parameter *const parameter)
Definition cma_fec.c:196
void cmafec_preset_remove(int idx)
Definition cma_fec.c:153
int cmafec_preset_num(void)
Definition cma_fec.c:213
void cmafec_get_fe_parameter(struct city *pcity, struct cm_parameter *dest)
Definition cma_fec.c:115
char * incite_cost
Definition comments.c:74
void request_unit_fortify(struct unit *punit)
Definition control.c:2326
struct unit * request_unit_unload_all(struct unit *punit)
Definition control.c:1485
void unit_focus_set(struct unit *punit)
Definition control.c:501
void request_unit_change_homecity(struct unit *punit)
Definition control.c:2067
void request_unit_unload(struct unit *pcargo)
Definition control.c:2167
void request_unit_sentry(struct unit *punit)
Definition control.c:2315
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:41
bool qtg_request_transport(struct unit *pcargo, struct tile *ptile)
Definition dialogs.cpp:4872
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
int int id
Definition editgui_g.h:28
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
enum event_type event
Definition events.c:81
struct extra_type * next_extra_for_tile(const struct tile *ptile, enum extra_cause cause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:779
struct extra_type * prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause, const struct player *pplayer, const struct unit *punit)
Definition extras.c:804
enum extra_cause activity_to_extra_cause(enum unit_activity act)
Definition extras.c:1090
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
Definition extras.c:1111
#define extra_index(_e_)
Definition extras.h:183
unsigned char citizens
Definition fc_types.h:392
#define EC_NONE
Definition fc_types.h:1093
@ TR_SUCCESS
Definition fc_types.h:1226
#define ERM_NONE
Definition fc_types.h:1116
@ O_SHIELD
Definition fc_types.h:101
@ O_FOOD
Definition fc_types.h:101
@ O_TRADE
Definition fc_types.h:101
@ O_SCIENCE
Definition fc_types.h:101
@ O_LUXURY
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
@ O_LAST
Definition fc_types.h:101
const char * skip_intl_qualifier_prefix(const char *str)
Definition fcintl.c:48
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * population_to_text(int thousand_citizen)
Definition game.c:737
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
struct city * game_city_by_number(int id)
Definition game.c:106
struct global_worklist * global_worklist_by_id(int id)
bool global_worklist_set(struct global_worklist *pgwl, const struct worklist *pwl)
const char * global_worklist_name(const struct global_worklist *pgwl)
int global_worklist_id(const struct global_worklist *pgwl)
const struct worklist * global_worklist_get(const struct global_worklist *pgwl)
struct global_worklist * global_worklist_new(const char *name)
#define global_worklists_iterate(pgwl)
#define global_worklists_iterate_end
void canvas_free(struct canvas *store)
Definition canvas.c:44
@ INFO_LUXURY
Definition citydlg.c:120
@ INFO_STEAL
Definition citydlg.c:122
@ INFO_CORRUPTION
Definition citydlg.c:121
@ NUM_INFO_FIELDS
Definition citydlg.c:123
@ INFO_ILLNESS
Definition citydlg.c:122
@ INFO_WASTE
Definition citydlg.c:121
@ INFO_GROWTH
Definition citydlg.c:120
@ INFO_SHIELD
Definition citydlg.c:119
@ INFO_CULTURE
Definition citydlg.c:121
@ INFO_GOLD
Definition citydlg.c:119
@ INFO_SCIENCE
Definition citydlg.c:120
@ INFO_POLLUTION
Definition citydlg.c:121
@ INFO_TRADE
Definition citydlg.c:119
@ INFO_AIRLIFT
Definition citydlg.c:122
@ INFO_GRANARY
Definition citydlg.c:120
@ INFO_FOOD
Definition citydlg.c:119
void popup_upgrade_dialog(struct unit_list *punits)
Definition dialogs.c:1435
void popup_disband_dialog(struct unit_list *punits)
Definition dialogs.c:1473
static struct tile * pos
Definition finddlg.c:53
const char * tooltip
Definition repodlgs.c:1315
GType type
Definition repodlgs.c:1313
void free_sprite(struct sprite *s)
Definition sprite.c:278
static GMenu * change_menu
Definition cityrep.c:126
static GMenu * options_menu
Definition menu.c:83
QString get_tooltip_improvement(const impr_type *building, struct city *pcity=nullptr, bool ext=false)
Definition citydlg.cpp:3862
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:3991
#define CAPTURE_DEFAULT_THIS
Definition gui_main.h:31
#define show(id)
Definition widget.h:235
#define hide(id)
Definition widget.h:238
QApplication * current_app()
Definition gui_main.cpp:226
char * helptext_unit_upkeep_str(const struct unit_type *utype)
Definition helpdata.c:4966
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1381
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype)
Definition helpdata.c:1865
int impr_sell_gold(const struct impr_type *pimprove)
enum test_result test_player_sell_building_now(struct player *pplayer, struct city *pcity, const struct impr_type *pimprove)
bool is_special_improvement(const struct impr_type *pimprove)
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
bool is_improvement(const struct impr_type *pimprove)
Impr_type_id improvement_number(const struct impr_type *pimprove)
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
bool is_convert_improvement(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
int impr_estimate_build_shield_cost(const struct player *pplayer, const struct tile *ptile, const struct impr_type *pimprove)
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_action(condition, action)
Definition log.h:187
void put_unit(const struct unit *punit, struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y)
void put_unit_city_overlays(struct unit *punit, struct canvas *pcanvas, int canvas_x, int canvas_y, int *upkeep_cost, int happy_cost)
void center_tile_mapcanvas(const struct tile *ptile)
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1016
static mpgui * gui
Definition mpgui_qt.cpp:52
const char *const default_font
Definition fonts.h:27
const char *const notify_label
Definition fonts.h:28
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
int send_packet_worker_task(struct connection *pc, const struct packet_worker_task *packet)
int dsend_packet_city_options_req(struct connection *pc, int city_id, bv_city_options options)
const char * text_happiness_cities(const struct city *pcity)
Definition text.c:1913
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
struct player * player_slot_get_player(const struct player_slot *pslot)
Definition player.c:437
void qtg_free_sprite(struct sprite *s)
Definition sprite.cpp:172
struct sprite * qtg_create_sprite(int width, int height, struct color *pcolor)
Definition sprite.cpp:181
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
#define ARRAY_SIZE(x)
Definition shared.h:85
#define FC_INFINITY
Definition shared.h:36
size_t size
Definition specvec.h:72
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
QPixmap map_pixmap
Definition canvas.h:25
void setup_ui(struct city *qcity)
Definition citydlg.cpp:3129
int current_building
Definition citydlg.h:506
void worklist_up()
Definition citydlg.cpp:3559
city_label * citizens_label
Definition citydlg.h:451
QPushButton * lcity_name
Definition citydlg.h:492
void show_happiness()
Definition citydlg.cpp:2092
void closeEvent(QCloseEvent *event)
Definition citydlg.cpp:2242
void update_nation_table()
Definition citydlg.cpp:2931
void hideEvent(QHideEvent *event)
Definition citydlg.cpp:2214
QPushButton * work_next_but
Definition citydlg.h:481
void next_city()
Definition citydlg.cpp:3238
progress_bar * production_combo_p
Definition citydlg.h:465
QTableWidget * nationality_table
Definition citydlg.h:467
QRadioButton * r3
Definition citydlg.h:475
QTableWidget * cma_table
Definition citydlg.h:468
void showEvent(QShowEvent *event)
Definition citydlg.cpp:2225
QPushButton * happiness_button
Definition citydlg.h:485
void cma_double_clicked(int row, int column)
Definition citydlg.cpp:2418
void display_worklist_menu(const QPoint &p)
Definition citydlg.cpp:2689
void update_disabled()
Definition citydlg.cpp:2121
QLabel * supp_units
Definition citydlg.h:462
QPushButton * next_city_but
Definition citydlg.h:479
QLabel * qlt[NUM_INFO_FIELDS]
Definition citydlg.h:458
QPushButton * work_prev_but
Definition citydlg.h:482
QHBoxLayout * single_page_layout
Definition citydlg.h:441
void update_buy_button()
Definition citydlg.cpp:2789
int selected_row_p
Definition citydlg.h:493
QHBoxLayout * leftbot_layout
Definition citydlg.h:446
void update_building()
Definition citydlg.cpp:3310
QPushButton * zoom_in_button
Definition citydlg.h:486
void save_worklist()
Definition citydlg.cpp:3625
void worklist_del()
Definition citydlg.cpp:3584
QGridLayout * info_grid_layout
Definition citydlg.h:453
void clear_worklist()
Definition citydlg.cpp:3544
bool happiness_shown
Definition citydlg.h:440
impr_info * city_buildings
Definition citydlg.h:491
QLabel * curr_impr
Definition citydlg.h:464
city_label * lab_table[6]
Definition citydlg.h:452
int scroll_height
Definition citydlg.h:502
QLabel * curr_units
Definition citydlg.h:463
unit_info * current_units
Definition citydlg.h:489
void zoom_out()
Definition citydlg.cpp:2333
void zoom_in()
Definition citydlg.cpp:2320
struct unit_node_vector supported_units
Definition citydlg.c:163
QPushButton * zoom_out_button
Definition citydlg.h:487
struct city * pcity
Definition citydlg.c:138
void update_info_label()
Definition citydlg.cpp:3008
QPushButton * work_add_but
Definition citydlg.h:483
QSplitter * central_left_splitter
Definition citydlg.h:444
void disband_state_changed(bool allow_disband)
Definition citydlg.cpp:2649
void update_citizens()
Definition citydlg.cpp:2815
QRadioButton * r1
Definition citydlg.h:475
void cma_slider(int val)
Definition citydlg.cpp:2624
QCheckBox * cma_celeb_checkbox
Definition citydlg.h:469
QCheckBox * show_units
Definition citydlg.h:472
void worklist_down()
Definition citydlg.cpp:3601
void update_title()
Definition citydlg.cpp:3656
QLabel * cma_info_text
Definition citydlg.h:459
void dbl_click_p(QTableWidgetItem *item)
Definition citydlg.cpp:3145
QPushButton * cma_enable_but
Definition citydlg.h:478
QLabel * cma_result
Definition citydlg.h:460
void cma_remove()
Definition citydlg.cpp:2586
QSlider * slider_tab[2 *O_LAST+2]
Definition citydlg.h:494
QPushButton * button
Definition citydlg.h:476
bool eventFilter(QObject *obj, QEvent *event)
Definition citydlg.cpp:2253
QSplitter * prod_unit_splitter
Definition citydlg.h:443
QVBoxLayout * left_layout
Definition citydlg.h:449
void prev_city()
Definition citydlg.cpp:3274
void city_rename()
Definition citydlg.cpp:2290
void refresh()
Definition citydlg.cpp:2899
void update_cma_tab()
Definition citydlg.cpp:2519
QPushButton * work_rem_but
Definition citydlg.h:484
float zoom
Definition citydlg.h:503
QSplitter * central_splitter
Definition citydlg.h:445
QWidget * prod_happ_widget
Definition citydlg.h:447
void cma_toggle_changed(int val)
Definition citydlg.cpp:2613
void show_targets()
Definition citydlg.cpp:3513
city_dialog(QWidget *parent=nullptr)
Definition citydlg.cpp:1481
QWidget * top_widget
Definition citydlg.h:448
void update_happiness_button()
Definition citydlg.cpp:2080
QPushButton * prev_city_but
Definition citydlg.h:480
void cma_enable()
Definition citydlg.cpp:2382
QLabel * cma_result_pix
Definition citydlg.h:461
struct city * dlgcity
Definition citydlg.h:501
void update_sliders()
Definition citydlg.cpp:2467
void update_improvements()
Definition citydlg.cpp:3378
GtkWidget * worklist
Definition citydlg.c:176
QHBoxLayout * happiness_layout
Definition citydlg.h:442
QCheckBox * future_targets
Definition citydlg.h:471
void change_production(bool next)
Definition citydlg.cpp:2035
void cma_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:2437
QCheckBox * cma_max_growth
Definition citydlg.h:470
void item_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:3220
void show_targets_worklist()
Definition citydlg.cpp:3529
QCheckBox * show_wonders
Definition citydlg.h:474
void cma_context_menu(const QPoint &p)
Definition citydlg.cpp:2669
void cma_changed()
Definition citydlg.cpp:2397
QPushButton * buy_button
Definition citydlg.h:477
QRadioButton * r4
Definition citydlg.h:475
void update_units()
Definition citydlg.cpp:3162
QRadioButton * r2
Definition citydlg.h:475
QTableWidget * p_table_p
Definition citydlg.h:466
void save_cma()
Definition citydlg.cpp:2346
QPixmap * citizen_pixmap
Definition citydlg.h:488
void production_changed(int index)
Definition citydlg.cpp:3495
void update_prod_buttons()
Definition citydlg.cpp:2158
QWidget * happiness_widget
Definition citydlg.h:456
QGroupBox * happiness_group
Definition citydlg.h:455
QCheckBox * show_buildings
Definition citydlg.h:473
Definition city.h:320
struct worker_task_list * task_reqs
Definition city.h:412
int surplus[O_LAST]
Definition city.h:355
int food_stock
Definition city.h:367
int pollution
Definition city.h:369
int id
Definition city.h:326
int waste[O_LAST]
Definition city.h:356
struct unit_list * info_units_present
Definition city.h:474
struct unit_list * info_units_supported
Definition city.h:473
struct universal production
Definition city.h:396
int steal
Definition city.h:414
citizens size
Definition city.h:332
int culture
Definition city.h:465
int buy_cost
Definition city.h:466
struct tile * tile
Definition city.h:322
int shield_stock
Definition city.h:368
int prod[O_LAST]
Definition city.h:358
struct unit_list * units_supported
Definition city.h:406
struct city::@17::@20 client
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
bool allow_disorder
Definition cm.h:44
int factor[O_LAST]
Definition cm.h:47
bool max_growth
Definition cm.h:42
bool allow_specialists
Definition cm.h:45
bool require_happy
Definition cm.h:43
int minimal_surplus[O_LAST]
Definition cm.h:41
int happy_factor
Definition cm.h:48
Definition colors.h:21
Definition mapimg.c:367
struct requirement_vector obsolete_by
Definition improvement.h:59
Definition climisc.h:80
struct universal item
Definition climisc.h:81
enum unit_activity activity
struct city_list * cities
Definition player.h:281
struct player_economic economic
Definition player.h:284
QPixmap * pm
Definition sprite.h:25
Definition tile.h:50
int index
Definition tile.h:51
struct unit_list * units
Definition tile.h:58
int defense_strength
Definition unittype.h:523
int firepower
Definition unittype.h:532
const struct unit_type * obsoleted_by
Definition unittype.h:536
int vision_radius_sq
Definition unittype.h:529
int move_rate
Definition unittype.h:524
int attack_strength
Definition unittype.h:522
Definition unit.h:140
int upkeep[O_LAST]
Definition unit.h:150
int id
Definition unit.h:147
struct tile * tile
Definition unit.h:142
int homecity
Definition unit.h:148
enum universals_n kind
Definition fc_types.h:880
universals_u value
Definition fc_types.h:879
struct universal entries[MAX_LEN_WORKLIST]
Definition worklist.h:30
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define TRUE
Definition support.h:46
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
const char * advance_name_translation(const struct advance *padvance)
Definition tech.c:300
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
#define A_NONE
Definition tech.h:43
const char * text_happiness_nationality(const struct city *pcity)
Definition text.c:1841
const char * text_happiness_wonders(const struct city *pcity)
Definition text.c:1883
const char * text_happiness_units(const struct city *pcity)
Definition text.c:2047
const char * text_happiness_luxuries(const struct city *pcity)
Definition text.c:2085
const char * text_happiness_buildings(const struct city *pcity)
Definition text.c:1813
const char * unit_description(struct unit *punit)
Definition text.c:488
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_terrain(_tile)
Definition tile.h:111
int tileset_hex_width(const struct tileset *t)
Definition tilespec.c:722
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:6822
int tileset_unit_width(const struct tileset *t)
Definition tilespec.c:798
int tileset_unit_height(const struct tileset *t)
Definition tilespec.c:806
int tileset_small_sprite_width(const struct tileset *t)
Definition tilespec.c:902
struct tileset * get_tileset(void)
Definition tilespec.c:693
struct tileset * unscaled_tileset
Definition tilespec.c:569
int tileset_unit_layout_offset_y(const struct tileset *t)
Definition tilespec.c:883
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:713
int tileset_small_sprite_height(const struct tileset *t)
Definition tilespec.c:938
struct sprite * get_icon_sprite(const struct tileset *t, enum icon_type icon)
Definition tilespec.c:7018
int tileset_unit_with_upkeep_height(const struct tileset *t)
Definition tilespec.c:860
int tileset_hex_height(const struct tileset *t)
Definition tilespec.c:731
struct sprite * get_citizen_sprite(const struct tileset *t, enum citizen_category type, int citizen_index, const struct city *pcity)
Definition tilespec.c:6761
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:6844
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6795
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6813
@ ICON_CITYDLG
Definition tilespec.h:316
const struct unit_type * utype
Definition fc_types.h:698
const struct impr_type * building
Definition fc_types.h:691
bool can_unit_change_homecity(const struct unit *punit)
Definition unit.c:509
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:386
#define unit_tile(_pu)
Definition unit.h:397
#define unit_owner(_pu)
Definition unit.h:396
bool units_are_occupied(const struct unit_list *punits)
Definition unitlist.c:273
bool units_can_unload(const struct civ_map *nmap, const struct unit_list *punits)
Definition unitlist.c:301
bool units_can_upgrade(const struct civ_map *nmap, const struct unit_list *punits)
Definition unitlist.c:335
bool units_can_load(const struct unit_list *punits)
Definition unitlist.c:287
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1468
bool utype_is_consumed_by_action_result(enum action_result result, const struct unit_type *utype)
Definition unittype.c:1229
struct advance * utype_primary_tech_req(const struct unit_type *ptype)
Definition unittype.c:2696
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:387
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1438
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
const char * utype_values_translation(const struct unit_type *punittype)
Definition unittype.c:1617
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:773
#define utype_class(_t_)
Definition unittype.h:756
#define utype_fuel(ptype)
Definition unittype.h:843
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
void worklist_init(struct worklist *pwl)
Definition worklist.c:38
bool worklist_peek_ith(const struct worklist *pwl, struct universal *prod, int idx)
Definition worklist.c:86
bool worklist_insert(struct worklist *pwl, const struct universal *prod, int idx)
Definition worklist.c:167
void worklist_remove(struct worklist *pwl, int idx)
Definition worklist.c:122
int worklist_length(const struct worklist *pwl)
Definition worklist.c:57