Freeciv-3.2
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 "counters.h"
45#include "game.h"
46
47//agents
48#include "cma_core.h"
49#include "cma_fec.h"
50
51// client
52#include "citydlg_common.h"
53#include "client_main.h"
54#include "climisc.h"
55#include "control.h"
56#include "global_worklist.h"
57#include "helpdata.h"
58#include "mapview_common.h"
59#include "movement.h"
60#include "sprite.h"
61#include "text.h"
62#include "tilespec.h"
63
64// gui-qt
65#include "citydlg.h"
66#include "colors.h"
67#include "fc_client.h"
68#include "gui_main.h"
69#include "hudwidget.h"
70
71static bool city_dlg_created = false;
76extern QString split_text(QString text, bool cut);
77extern QString cut_helptext(QString text);
78
79/************************************************************************/
83{
84 m_timer.start();
85 startTimer(50);
87 sfont = new QFont;
89 pix = nullptr;
90}
91
92/************************************************************************/
96{
97 if (pix != nullptr) {
98 delete pix;
99 }
100 delete sfont;
101}
102
103/************************************************************************/
110
111/************************************************************************/
115{
116 struct sprite *sprite;
118 QImage img;
120 QRect crop;
121
122 if (VUT_UTYPE == target->kind) {
125 } else {
127 }
128 if (pix != nullptr) {
129 delete pix;
130 }
131 if (sprite == nullptr) {
132 pix = nullptr;
133 return;
134 }
135 img = sprite->pm->toImage();
137 cropped_img = img.copy(crop);
138 tpix = QPixmap::fromImage(cropped_img);
139 pix = new QPixmap(tpix.width(), tpix.height());
140 pix->fill(Qt::transparent);
141 pixmap_copy(pix, &tpix, 0 , 0, 0, 0, tpix.width(), tpix.height());
142}
143
144/************************************************************************/
148{
149 struct sprite *sprite;
150
153 } else {
154 sprite = nullptr;
155 }
156 if (pix != nullptr) {
157 delete pix;
158 }
159 if (sprite == nullptr) {
160 pix = nullptr;
161 return;
162 }
163 pix = new QPixmap(sprite->pm->width(),
164 sprite->pm->height());
165 pix->fill(Qt::transparent);
166 pixmap_copy(pix, sprite->pm, 0 , 0, 0, 0,
167 sprite->pm->width(), sprite->pm->height());
168 if (isVisible()) {
169 update();
170 }
171}
172
173/************************************************************************/
177{
178 if ((value() != minimum() && value() < maximum())
179 || (0 == minimum() && 0 == maximum())) {
180 m_animate_step = m_timer.elapsed() / 50;
181 update();
182 }
183}
184
185/************************************************************************/
189{
190 QPainter p;
192 QColor c;
193 QRect r, rx, r2;
194 int max;
195 int f_pixel_size;
196 int pix_width = 0;
197 int pixel_size = sfont->pixelSize();
198 int pbw, pbh;
199
200 if (pix != nullptr) {
201 pix_width = height() - 4;
202 }
203
204 if (pixel_size > 0) {
206 } else {
208
209 f_pixel_size = fm.height();
210 }
211
212 pbw = width();
213 pbh = height();
214
215 rx.setX(0);
216 rx.setY(0);
217 rx.setWidth(pbw);
218 rx.setHeight(pbh);
219 p.begin(this);
220 p.drawLine(rx.topLeft(), rx.topRight());
221 p.drawLine(rx.bottomLeft(), rx.bottomRight());
222
223 max = maximum();
224
225 if (max == 0) {
226 max = 1;
227 }
228
229 r = QRect(0, 0, pbw * value() / max, pbh);
230
231 gx = QLinearGradient(0 , 0, 0, pbh);
232 c = QColor(palette().color(QPalette::Highlight));
233 gx.setColorAt(0, c);
234 gx.setColorAt(0.5, QColor(40, 40, 40));
235 gx.setColorAt(1, c);
236 p.fillRect(r, QBrush(gx));
237 p.setClipRegion(reg.translated(m_animate_step % 32, 0));
238
239 g = QLinearGradient(0 , 0, pbw, pbh);
240 c.setAlphaF(0.1);
241 g.setColorAt(0, c);
242 c.setAlphaF(0.9);
243 g.setColorAt(1, c);
244 p.fillRect(r, QBrush(g));
245
246 p.setClipping(false);
247 r2 = QRect(pbw * value() / max, 0, pbw, pbh);
248 c = palette().color(QPalette::Window);
249 p.fillRect(r2, c);
250
251 // Draw icon
252 if (pix != nullptr) {
253 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
254 p.drawPixmap(2 , 2, pix_width
255 * static_cast<float>(pix->width()) / pix->height(),
256 pix_width, *pix, 0, 0, pix->width(), pix->height());
257 }
258
259 // Draw text
260 c = palette().color(QPalette::Text);
261 p.setPen(c);
262 sfont->setCapitalization(QFont::AllUppercase);
263 sfont->setBold(true);
264
265 if (text().contains('\n')) {
266 QString s1, s2;
267 int i, j;
268 QFont tmp_font = *sfont; // Don't make changes to font to be kept
269
270 i = text().indexOf('\n');
271 s1 = text().left(i);
272 s2 = text().right(text().length() - i);
273
274 if (2 * f_pixel_size >= 3 * pbh / 2) {
275 tmp_font.setPixelSize(pbh / 3);
276 }
277
278 p.setFont(tmp_font);
279
280 j = pbh - 2 * f_pixel_size;
281 p.setCompositionMode(QPainter::CompositionMode_ColorDodge);
283
284 if (fm.horizontalAdvance(s1) > rx.width()) {
285 s1 = fm.elidedText(s1, Qt::ElideRight, rx.width());
286 }
287
288 i = rx.width() - fm.horizontalAdvance(s1) + pix_width;
289 i = qMax(0, i);
290 p.drawText(i / 2, j / 3 + f_pixel_size, s1);
291
292 if (fm.horizontalAdvance(s2) > rx.width()) {
293 s2 = fm.elidedText(s2, Qt::ElideRight, rx.width());
294 }
295
296 i = rx.width() - fm.horizontalAdvance(s2) + pix_width;
297 i = qMax(0, i);
298
299 p.drawText(i / 2, pbh - j / 3, s2);
300 } else {
301 QString s;
302 int i, j;
303
304 p.setFont(*sfont);
305
306 s = text();
307 j = pbh - f_pixel_size;
308 p.setCompositionMode(QPainter::CompositionMode_ColorDodge);
310
311 if (fm.horizontalAdvance(s) > rx.width()) {
312 s = fm.elidedText(s, Qt::ElideRight, rx.width());
313 }
314
315 i = rx.width() - fm.horizontalAdvance(s) + pix_width;
316 i = qMax(0, i);
317 p.drawText(i / 2, j / 2 + f_pixel_size, s);
318 }
319
320 p.end();
321}
322
323/************************************************************************/
327{
328 int offset;
329 QRect r(-50, 0, width() + 50, height());
330 int chunk_width = 16;
331 int size = width() + 50;
332 reg = QRegion();
333
334 for (offset = 0; offset < (size * 2); offset += (chunk_width * 2)) {
335 QPolygon a;
336
337 a.setPoints(4, r.x(), r.y() + offset,
338 r.x() + r.width(), (r.y() + offset) - size,
339 r.x() + r.width(),
340 (r.y() + offset + chunk_width) - size,
341 r.x(), r.y() + offset + chunk_width);
342 reg += QRegion(a);
343 }
344
345}
346
347/************************************************************************/
350static void pixmap_put_x(QPixmap *pix)
351{
352 QPen pen(QColor(0, 0, 0));
353 QPainter p;
354
355 pen.setWidth(2);
356 p.begin(pix);
357 p.setRenderHint(QPainter::Antialiasing);
358 p.setPen(pen);
359 p.drawLine(0, 0, pix->width(), pix->height());
360 p.drawLine(pix->width(), 0, 0, pix->height());
361 p.end();
362}
363
364/************************************************************************/
367impr_item::impr_item(QWidget *parent, const impr_type *building,
368 struct city *pcity): QLabel(parent)
369{
371 dlgcity = pcity;
372 impr = building;
373 impr_pixmap = nullptr;
374 struct sprite *sprite;
375 sprite = get_building_sprite(tileset , building);
376
377 if (sprite != nullptr) {
379 sprite->pm->height());
380 impr_pixmap->map_pixmap.fill(Qt::transparent);
381 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
382 sprite->pm->width(), sprite->pm->height());
383 } else {
385 impr_pixmap->map_pixmap.fill(Qt::red);
386 }
387
390 setToolTip(get_tooltip_improvement(building, pcity, true).trimmed());
391}
392
393/************************************************************************/
397{
398 if (impr_pixmap) {
400 }
401}
402
403/************************************************************************/
407{
409 update();
410}
411
412/************************************************************************/
415#ifndef FC_QT5_MODE
417#else // FC_QT5_MODE
418void impr_item::enterEvent(QEvent *event)
419#endif // FC_QT5_MODE
420{
421 struct sprite *sprite;
422 QPainter p;
423
424 if (impr_pixmap) {
425 canvas_free(impr_pixmap);
426 }
427
429 if (impr && sprite) {
430 impr_pixmap = qtg_canvas_create(sprite->pm->width(),
431 sprite->pm->height());
432 impr_pixmap->map_pixmap.fill(QColor(palette().color(QPalette::Highlight)));
433 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
434 sprite->pm->width(), sprite->pm->height());
435 } else {
436 impr_pixmap = qtg_canvas_create(10, 10);
437 impr_pixmap->map_pixmap.fill(QColor(palette().color(QPalette::Highlight)));
438 }
439
440 init_pix();
441}
442
443/************************************************************************/
447{
448 struct sprite *sprite;
449
450 if (impr_pixmap) {
452 }
453
455 if (impr && sprite) {
457 sprite->pm->height());
458 impr_pixmap->map_pixmap.fill(Qt::transparent);
459 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
460 sprite->pm->width(), sprite->pm->height());
461 } else {
463 impr_pixmap->map_pixmap.fill(Qt::red);
464 }
465
466 init_pix();
467}
468
469/************************************************************************/
473{
475 layout = new QHBoxLayout(this);
476 init_layout();
477}
478
479/************************************************************************/
483{
484 QSizePolicy size_fixed_policy(QSizePolicy::Fixed,
485 QSizePolicy::MinimumExpanding,
486 QSizePolicy::Slider);
487
490}
491
492/************************************************************************/
496{
497
498}
499
500/************************************************************************/
504{
505 impr_list.append(item);
506}
507
508/************************************************************************/
512{
513 int i = impr_list.count();
514 impr_item *ui;
515 int j;
516 setUpdatesEnabled(false);
517 setMouseTracking(false);
518
519 for (j = 0; j < i; j++) {
520 ui = impr_list[j];
521 layout->removeWidget(ui);
522 delete ui;
523 }
524
525 while (!impr_list.empty()) {
526 impr_list.removeFirst();
527 }
528
529 setMouseTracking(true);
530 setUpdatesEnabled(true);
531}
532
533/************************************************************************/
537{
538 QPoint p;
539
540 p = parentWidget()->parentWidget()->pos();
541 p = mapToGlobal(p);
542#ifndef FC_QT5_MODE
543 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
544 event->angleDelta(),
545 event->buttons(),
546 event->modifiers(),
547 event->phase(), false, event->source());
548#else // FC_QT5_MODE
549 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
550 event->angleDelta(),
551 event->angleDelta().y(),
552 Qt::Horizontal, event->buttons(),
553 event->modifiers(), event->phase(), event->source());
554#endif // FC_QT5_MODE
555 QApplication::sendEvent(parentWidget(), &new_event);
556}
557
558/************************************************************************/
562{
563 int i = impr_list.count();
564 int j;
565 int h = 0;
566 impr_item *ui;
567
568 setUpdatesEnabled(false);
569 hide();
570
571 for (j = 0; j < i; j++) {
572 ui = impr_list[j];
573 h = ui->height();
574 layout->addWidget(ui, 0, Qt::AlignVCenter);
575 }
576
577 if (impr_list.count() > 0) {
578 parentWidget()->parentWidget()->setFixedHeight(city_dlg->scroll_height
579 + h + 6);
580 } else {
581 parentWidget()->parentWidget()->setFixedHeight(0);
582 }
583
584 show();
585 setUpdatesEnabled(true);
586 layout->update();
588}
589
590/************************************************************************/
594{
595 QPoint p;
596
597 p = parentWidget()->parentWidget()->pos();
598 p = mapToGlobal(p);
599#ifndef FC_QT5_MODE
600 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
601 event->angleDelta(),
602 event->buttons(),
603 event->modifiers(),
604 event->phase(), false, event->source());
605#else // FC_QT5_MODE
606 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
607 event->angleDelta(),
608 event->angleDelta().y(),
609 Qt::Horizontal, event->buttons(),
610 event->modifiers(), event->phase(), event->source());
611#endif // FC_QT5_MODE
612 QApplication::sendEvent(parentWidget()->parentWidget(),
613 &new_event);
614}
615
616/************************************************************************/
620{
622 return;
623 }
624
625 if (event->button() == Qt::LeftButton) {
626 char buf[256];
627 int price;
628 const int impr_id = improvement_number(impr);
629 const int city_id = dlgcity->id;
631
633 impr) != TR_SUCCESS) {
634 return;
635 }
636
638
641 PL_("Sell %s for %d gold?",
642 "Sell %s for %d gold?", price),
644
645 ask->set_text_title(buf, (_("Sell improvement?")));
646 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
647 ask->setAttribute(Qt::WA_DeleteOnClose);
648 connect(ask, &hud_message_box::accepted, [=]() {
649 struct city *pcity = game_city_by_number(city_id);
650
651 if (pcity == nullptr) {
652 return;
653 }
655 });
656 ask->show();
657 }
658}
659
660/************************************************************************/
664 bool supp, int hppy_cost) : QLabel()
665{
668 QImage img;
669 QRect crop;
670 qunit = punit;
671 struct canvas *unit_pixmap;
672 struct tileset *tmp;
673 float isosize;
674
676 supported = supp;
677
678 tmp = nullptr;
679 if (unscaled_tileset) {
680 tmp = tileset;
682 }
683 isosize = 0.6;
685 isosize = 0.45;
686 }
687
688 if (punit) {
689 if (supported) {
692 } else {
695 }
696
697 unit_pixmap->map_pixmap.fill(Qt::transparent);
698 put_unit(punit, unit_pixmap, 1.0, 0, 0);
699
700 if (supported) {
704 }
705 } else {
707 unit_pixmap->map_pixmap.fill(Qt::transparent);
708 }
709
710 img = unit_pixmap->map_pixmap.toImage();
712 cropped_img = img.copy(crop);
715 * isosize, Qt::SmoothTransformation);
716 } else {
718 Qt::SmoothTransformation);
719 }
721 if (tmp != nullptr) {
722 tileset = tmp;
723 }
724
726 setFixedWidth(unit_img.width() + 4);
727 setFixedHeight(unit_img.height());
729}
730
731/************************************************************************/
735{
736 setPixmap(QPixmap::fromImage(unit_img));
737 update();
738}
739
740/************************************************************************/
746
747/************************************************************************/
751{
752 QMenu *menu;
753
755 return;
756 }
757
758 if (unit_owner(qunit) != client_player()) {
759 return;
760 }
761
762 menu = new QMenu(gui()->central_wdg);
763 menu->addAction(activate);
764 menu->addAction(activate_and_close);
765
766 if (sentry) {
767 menu->addAction(sentry);
768 }
769
770 if (fortify) {
771 menu->addAction(fortify);
772 }
773
774 if (change_home) {
775 menu->addAction(change_home);
776 }
777
778 if (load) {
779 menu->addAction(load);
780 }
781
782 if (unload) {
783 menu->addAction(unload);
784 }
785
786 if (unload_trans) {
787 menu->addAction(unload_trans);
788 }
789
790 if (disband_action) {
791 menu->addAction(disband_action);
792 }
793
794 if (upgrade) {
795 menu->addAction(upgrade);
796 }
797
798 menu->popup(event->globalPos());
799}
800
801/************************************************************************/
805{
806 struct unit_list *qunits;
807
809 return;
810 }
811
814 activate = new QAction(_("Activate unit"), this);
815 connect(activate, &QAction::triggered, this, &unit_item::activate_unit);
816 activate_and_close = new QAction(_("Activate and close dialog"), this);
817 connect(activate_and_close, &QAction::triggered, this,
819
821 sentry = new QAction(_("Sentry unit"), this);
822 connect(sentry, &QAction::triggered, this, &unit_item::sentry_unit);
823 } else {
824 sentry = NULL;
825 }
826
828 fortify = new QAction(_("Fortify unit"), this);
829 connect(fortify, &QAction::triggered, this, &unit_item::fortify_unit);
830 } else {
831 fortify = NULL;
832 }
834 disband_action = new QAction(_("Disband unit"), this);
835 connect(disband_action, &QAction::triggered, this, &unit_item::disband);
836 } else {
838 }
839
842 this);
843 connect(change_home, &QAction::triggered, this, &unit_item::change_homecity);
844 } else {
846 }
847
848 if (units_can_load(qunits)) {
849 load = new QAction(_("Load"), this);
850 connect(load, &QAction::triggered, this, &unit_item::load_unit);
851 } else {
852 load = NULL;
853 }
854
856 unload = new QAction(_("Unload"), this);
857 connect(unload, &QAction::triggered, this, &unit_item::unload_unit);
858 } else {
859 unload = NULL;
860 }
861
863 unload_trans = new QAction(_("Unload All From Transporter"), this);
864 connect(unload_trans, &QAction::triggered, this, &unit_item::unload_all);
865 } else {
867 }
868
869 if (units_can_upgrade(&(wld.map), qunits)) {
870 upgrade = new QAction(_("Upgrade Unit"), this);
871 connect(upgrade, &QAction::triggered, this, &unit_item::upgrade_unit);
872 } else {
873 upgrade = NULL;
874 }
875
877}
878
879/************************************************************************/
883{
884 struct unit_list *punits;
886
887 if (punit == nullptr) {
888 return;
889 }
890
895}
896
897/************************************************************************/
904
905/************************************************************************/
912
913/************************************************************************/
920
921/************************************************************************/
932
933/************************************************************************/
942
943/************************************************************************/
953
954/************************************************************************/
958{
959 if (qunit) {
961 }
962}
963
964/************************************************************************/
968{
969 if (qunit) {
971 }
972}
973
974/************************************************************************/
977#ifndef FC_QT5_MODE
979#else // FC_QT5_MODE
980void unit_item::enterEvent(QEvent *event)
981#endif // FC_QT5_MODE
982{
983 QImage temp_img(unit_img.size(), QImage::Format_ARGB32_Premultiplied);
984 QPainter p;
985
986 p.begin(&temp_img);
987 p.fillRect(0, 0, unit_img.width(), unit_img.height(),
988 QColor(palette().color(QPalette::Highlight)));
989 p.drawImage(0, 0, unit_img);
990 p.end();
991
992 setPixmap(QPixmap::fromImage(temp_img));
993 update();
994}
995
996/************************************************************************/
1000{
1001 init_pix();
1002}
1003
1004/************************************************************************/
1008{
1009 QPoint p;
1010
1011 p = parentWidget()->parentWidget()->pos();
1012 p = mapToGlobal(p);
1013#ifndef FC_QT5_MODE
1014 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1015 event->angleDelta(),
1016 event->buttons(),
1017 event->modifiers(),
1018 event->phase(), false, event->source());
1019#else // FC_QT5_MODE
1020 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1021 event->angleDelta(),
1022 event->angleDelta().y(),
1023 Qt::Horizontal, event->buttons(),
1024 event->modifiers(), event->phase(), event->source());
1025#endif // FC_QT5_MODE
1026 QApplication::sendEvent(parentWidget()->parentWidget(),
1027 &new_event);
1028}
1029
1030/************************************************************************/
1034{
1035 if (event->button() == Qt::LeftButton) {
1036 if (qunit) {
1039 }
1040 }
1041}
1042
1043/************************************************************************/
1047{
1048 if (qunit) {
1050 }
1051}
1052
1053/************************************************************************/
1057{
1058 layout = new QHBoxLayout(this);
1059 init_layout();
1060 supports = supp;
1061}
1062
1063/************************************************************************/
1067{
1069 unit_list.clear();
1070}
1071
1072/************************************************************************/
1076{
1077 unit_list.append(item);
1078}
1079
1080/************************************************************************/
1084{
1085 QSizePolicy size_fixed_policy(QSizePolicy::Fixed,
1086 QSizePolicy::MinimumExpanding,
1087 QSizePolicy::Slider);
1090}
1091
1092/************************************************************************/
1096{
1097 QPoint p;
1098
1099 p = parentWidget()->parentWidget()->pos();
1100 p = mapToGlobal(p);
1101#ifndef FC_QT5_MODE
1102 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1103 event->angleDelta(),
1104 event->buttons(),
1105 event->modifiers(),
1106 event->phase(), false, event->source());
1107#else // FC_QT5_MODE
1108 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1109 event->angleDelta(),
1110 event->angleDelta().y(),
1111 Qt::Horizontal, event->buttons(),
1112 event->modifiers(), event->phase(), event->source());
1113#endif // FC_QT5_MODE
1114 QApplication::sendEvent(parentWidget(), &new_event);
1115}
1116
1117/************************************************************************/
1121{
1122 int i = unit_list.count();
1123 int j;
1124 int h;
1125 float hexfix;
1126 unit_item *ui;
1127
1128 setUpdatesEnabled(false);
1129 hide();
1130
1131 for (j = 0; j < i; j++) {
1132 ui = unit_list[j];
1133 layout->addWidget(ui, 0, Qt::AlignVCenter);
1134 }
1135
1136 hexfix = 1.0;
1138 hexfix = 0.75;
1139 }
1140
1142 h = tileset_unit_width(get_tileset()) * 0.7 * hexfix + 6;
1143 } else {
1145 }
1146 if (unit_list.count() > 0) {
1147 parentWidget()->parentWidget()->setFixedHeight(city_dlg->scroll_height
1148 + h);
1149 } else {
1150 parentWidget()->parentWidget()->setFixedHeight(0);
1151 }
1152 show();
1153 setUpdatesEnabled(true);
1154 layout->update();
1156}
1157
1158/************************************************************************/
1162{
1163 int i = unit_list.count();
1164 unit_item *ui;
1165 int j;
1166 setUpdatesEnabled(false);
1167 setMouseTracking(false);
1168
1169 for (j = 0; j < i; j++) {
1170 ui = unit_list[j];
1171 layout->removeWidget(ui);
1172 delete ui;
1173 }
1174
1175 while (!unit_list.empty()) {
1176 unit_list.removeFirst();
1177 }
1178
1179 setMouseTracking(true);
1180 setUpdatesEnabled(true);
1181}
1182
1183/************************************************************************/
1187city_label::city_label(int t, QWidget *parent) : QLabel(parent)
1188{
1189 type = t;
1190}
1191
1192/************************************************************************/
1196{
1197 int citnum, i;
1198 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
1199 int num_citizens = pcity->size;
1200
1202 return;
1203 }
1204
1205 i = 1 + (num_citizens * 5 / 200);
1206 w = w / i;
1207 citnum = event->pos().x() / w;
1208
1209 if (!can_client_issue_orders()) {
1210 return;
1211 }
1212
1214}
1215
1216/************************************************************************/
1220{
1221 pcity = pciti;
1222}
1223
1224/************************************************************************/
1228{
1230 radius = 0;
1236 view->map_pixmap.fill(Qt::black);
1238 miniview->map_pixmap.fill(Qt::black);
1239 delta_x = 0;
1240 delta_y = 0;
1241 setContextMenuPolicy(Qt::CustomContextMenu);
1242 connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
1243 this, SLOT(context_menu(const QPoint &)));
1244}
1245
1246/************************************************************************/
1254
1255/************************************************************************/
1259{
1261 QString str;
1262
1263 painter.begin(this);
1264 painter.drawPixmap(0, 0, zoomed_pixmap);
1265
1267 painter.fillRect(0, 0, zoomed_pixmap.width(), zoomed_pixmap.height(),
1268 QBrush(QColor(60, 60 , 60 , 110)));
1269 painter.setPen(QColor(255, 255, 255));
1270 // TRANS: %1 is a custom string chosen by player.
1271 str = QString(_("Governor %1"))
1273 painter.drawText(5, zoomed_pixmap.height() - 10, str);
1274 }
1275
1276 painter.end();
1277}
1278
1279/************************************************************************/
1282void city_map::set_pixmap(struct city *pcity, float z)
1283{
1284 int r, max_r;
1285 QSize size;
1286
1287 zoom = z;
1288 r = sqrt(city_map_radius_sq_get(pcity));
1289
1290 if (radius != r) {
1292 radius = r;
1294 cutted_width = wdth * (r + 1) / max_r;
1295 cutted_height = height * (r + 1) / max_r;
1298 delta_x = (wdth - cutted_width) / 2;
1299 delta_y = (height - cutted_height) / 2;
1301 miniview->map_pixmap.fill(Qt::black);
1302 }
1303
1307 size = miniview->map_pixmap.size();
1309 Qt::KeepAspectRatio,
1310 Qt::SmoothTransformation);
1312 mcity = pcity;
1313}
1314
1315/************************************************************************/
1319{
1320 return zoomed_pixmap.size();
1321}
1322
1323/************************************************************************/
1327{
1328 return zoomed_pixmap.size();
1329}
1330
1331/************************************************************************/
1335{
1337 QPoint pos;
1338
1339 if (!can_client_issue_orders() || event->button() != Qt::LeftButton) {
1340 return;
1341 }
1342
1343 pos = event->pos();
1344 canvas_x = pos.x() / zoom + delta_x;
1345 canvas_y = pos.y() / zoom + delta_y;
1346
1348 canvas_x, canvas_y)) {
1350 }
1351}
1352
1353/************************************************************************/
1357{
1359 QAction *con_cultivate = nullptr;
1360 QAction *con_irrig = nullptr;
1361 QAction *con_plant = nullptr;
1362 QAction *con_mine = nullptr;
1363 QAction *con_road = nullptr;
1364 QAction *con_trfrm = nullptr;
1365 QAction *con_clean = nullptr;
1366 QAction *con_clear = nullptr;
1367 QMenu *con_menu;
1369 struct terrain *pterr;
1370 struct tile *ptile;
1371 struct universal for_terr;
1372 struct worker_task *ptask;
1373 int city_id = mcity->id;
1374
1375 if (!can_client_issue_orders()) {
1376 return;
1377 }
1378
1379 canvas_x = point.x() / zoom + delta_x;
1380 canvas_y = point.y() / zoom + delta_y;
1381
1383 canvas_x, canvas_y)) {
1384 return;
1385 }
1386
1388 city_x, city_y);
1389 pterr = tile_terrain(ptile);
1390 for_terr.kind = VUT_TERRAIN;
1391 for_terr.value.terrain = pterr;
1393
1394 wid_act = new QWidgetAction(this);
1395 wid_act->setDefaultWidget(new QLabel(_("Autosettler activity:")));
1396
1397 con_menu = new QMenu(this);
1398 con_menu->addAction(wid_act);
1399
1400 if (pterr->plant_result != NULL
1402 con_plant = con_menu->addAction(_("Plant"));
1403 }
1405 con_mine = con_menu->addAction(Q_("?act:Mine"));
1406 }
1407
1408 if (pterr->cultivate_result != NULL
1410 con_cultivate = con_menu->addAction(_("Cultivate"));
1411 }
1413 con_irrig = con_menu->addAction(_("Irrigate"));
1414 }
1415
1416 if (pterr->transform_result != pterr && pterr->transform_result != NULL
1418 NULL, &for_terr)) {
1419 con_trfrm = con_menu->addAction(_("Transform"));
1420 }
1421
1423 con_road = con_menu->addAction(_("Road"));
1424 }
1425
1426 if (prev_extra_in_tile(ptile, ERM_CLEAN,
1427 city_owner(mcity), NULL) != NULL) {
1428 con_clean = con_menu->addAction(_("Clean"));
1429 }
1430
1431 if (ptask != NULL) {
1432 con_clear = con_menu->addAction(_("Clear"));
1433 }
1434
1435 con_menu->setAttribute(Qt::WA_DeleteOnClose);
1436 connect(con_menu, &QMenu::triggered,
1438 bool target = false;
1439 struct packet_worker_task task;
1440
1441 if (!act) {
1442 return;
1443 }
1444
1445 task.city_id = city_id;
1446
1447 if (act == con_road) {
1449 target = TRUE;
1450 } else if (act == con_mine) {
1451 task.activity = ACTIVITY_MINE;
1452 target = TRUE;
1453 } else if (act == con_plant) {
1454 task.activity = ACTIVITY_PLANT;
1455 } else if (act == con_irrig) {
1457 target = TRUE;
1458 } else if (act == con_cultivate) {
1460 } else if (act == con_trfrm) {
1462 } else if (act == con_clean) {
1463 task.activity = ACTIVITY_CLEAN;
1464 target = TRUE;
1465 } else if (act == con_clear) {
1466 task.activity = ACTIVITY_LAST;
1467 } else {
1468 // Closed dialog without selecting any activity entry.
1469 return;
1470 }
1471
1472 task.want = 100;
1473
1474 if (target) {
1475 enum extra_cause cause = activity_to_extra_cause(task.activity);
1477 struct extra_type *tgt;
1478
1479 if (cause != EC_NONE) {
1480 tgt = next_extra_for_tile(ptile, cause, city_owner(mcity), NULL);
1481 } else if (rmcause != ERM_NONE) {
1483 } else {
1484 tgt = NULL;
1485 }
1486
1487 if (tgt != NULL) {
1488 task.tgt = extra_index(tgt);
1489 } else {
1490 task.tgt = -1;
1491 }
1492 } else {
1493 task.tgt = -1;
1494 }
1495
1496 task.tile_id = ptile->index;
1498 });
1499
1500 con_menu->popup(mapToGlobal(point));
1501}
1502
1503/************************************************************************/
1507{
1508 QFont f = QApplication::font();
1509 QFont *small_font;
1510 QFontMetrics fm(f);
1516 QHeaderView *header;
1517 QLabel *lab2, *label, *ql, *some_label;
1518 QPushButton *qpush2;
1520 QSizePolicy size_expanding_policy(QSizePolicy::Expanding,
1521 QSizePolicy::Expanding);
1522 QSlider *slider;
1523 QStringList info_list, str_list;
1528 int list_size;
1529 int h = 2 * fm.height() + 2;
1530
1533 zoom = 1.0;
1534
1536 central_splitter->setOpaqueResize(false);
1538 central_left_splitter->setOpaqueResize(false);
1540 prod_unit_splitter->setOpaqueResize(false);
1541
1542 setMouseTracking(true);
1543 selected_row_p = -1;
1544 dlgcity = NULL;
1545 lcity_name = new QPushButton(this);
1546 lcity_name->setToolTip(_("Click to change city name"));
1547
1549 single_page_layout->setContentsMargins(0, 0 ,0 ,0);
1550 size_expanding_policy.setHorizontalStretch(0);
1551 size_expanding_policy.setVerticalStretch(0);
1553 current_building = 0;
1554
1555 // Map view
1556 map_box = new QGroupBox(this);
1557
1558 // City information widget texts about surpluses and so on
1559 info_wdg = new QWidget(this);
1560
1561 // Fill info_wdg with labels
1563
1564 info_wdg->setFont(*small_font);
1565 info_grid_layout->setSpacing(0);
1566 info_grid_layout->setContentsMargins(0, 0, 0, 0);
1567
1568
1569 for (enum city_info info_field = city_info_begin();
1572
1573 ql = new QLabel(_(city_info_name(info_field)), info_wdg);
1574 ql->setFont(*small_font);
1575 ql->setProperty(fonts::notify_label, "true");
1576 info_grid_layout->addWidget(ql, info_field, 0);
1577 qlt[info_field] = new QLabel(info_wdg);
1578 qlt[info_field]->setFont(*small_font);
1579 qlt[info_field]->setProperty(fonts::notify_label, "true");
1580 info_grid_layout->addWidget(qlt[info_field], info_field, 1);
1581 info_grid_layout->setRowStretch(info_field, 0);
1582 }
1583
1584 info_wdg->setLayout(info_grid_layout);
1585
1586 // Buy button
1587 buy_button = new QPushButton();
1588 buy_button->setIcon(fc_icons::instance()->get_icon("help-donate"));
1589 connect(buy_button, &QAbstractButton::clicked, this, &city_dialog::buy);
1590
1591 connect(lcity_name, &QAbstractButton::clicked, this, &city_dialog::city_rename);
1594 view = new city_map(this);
1595
1596 zoom_vbox = new QVBoxLayout();
1597 zoom_in_button = new QPushButton();
1598 zoom_in_button->setIcon(fc_icons::instance()->get_icon("plus"));
1599 zoom_in_button->setIconSize(QSize(16, 16));
1600 zoom_in_button->setFixedSize(QSize(20, 20));
1601 zoom_in_button->setToolTip(_("Zoom in"));
1602 connect(zoom_in_button, &QAbstractButton::clicked, this, &city_dialog::zoom_in);
1603 zoom_out_button = new QPushButton();
1604 zoom_out_button->setIcon(fc_icons::instance()->get_icon("minus"));
1605 zoom_out_button->setIconSize(QSize(16, 16));
1606 zoom_out_button->setFixedSize(QSize(20, 20));
1607 zoom_out_button->setToolTip(_("Zoom out"));
1608 connect(zoom_out_button, &QAbstractButton::clicked, this, &city_dialog::zoom_out);
1609 zoom_vbox->addWidget(zoom_in_button);
1610 zoom_vbox->addWidget(zoom_out_button);
1611
1612 // City map group box
1615 hbox_layout->addStretch(100);
1616 hbox_layout->addWidget(view);
1617 hbox_layout->addStretch(100);
1618 hbox_layout->addLayout(zoom_vbox);
1619 vbox_layout->addLayout(hbox_layout);
1620 vbox_layout->addWidget(lcity_name);
1621 map_box->setLayout(vbox_layout);
1622 map_box->setTitle(_("City map"));
1623
1624 // Current/supported units/improvements widgets
1625 supp_units = new QLabel();
1626 curr_units = new QLabel();
1627 curr_impr = new QLabel();
1628 curr_units->setAlignment(Qt::AlignLeft);
1629 curr_impr->setAlignment(Qt::AlignLeft);
1630 supp_units->setAlignment(Qt::AlignLeft);
1631 supported_units = new unit_info(true);
1632 scroll = new QScrollArea;
1633 scroll->setWidgetResizable(true);
1634 scroll->setMaximumHeight(tileset_unit_with_upkeep_height(get_tileset()) + 6
1635 + scroll->horizontalScrollBar()->height());
1636 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1637 scroll->setWidget(supported_units);
1638 current_units = new unit_info(false);
1639 scroll2 = new QScrollArea;
1640 scroll2->setWidgetResizable(true);
1641 scroll2->setMaximumHeight(tileset_unit_height(get_tileset()) + 6
1642 + scroll2->horizontalScrollBar()->height());
1643 scroll2->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1644 scroll2->setWidget(current_units);
1645 scroll_height = scroll2->horizontalScrollBar()->height();
1646 city_buildings = new impr_info(this);
1647 scroll3 = new QScrollArea;
1648 scroll3->setWidgetResizable(true);
1649 scroll3->setMaximumHeight(tileset_unit_height(tileset) + 6
1650 + scroll3->horizontalScrollBar()->height());
1651 scroll3->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1652 scroll3->setWidget(city_buildings);
1653 scroll->setProperty("city_scroll", true);
1654 scroll2->setProperty("city_scroll", true);
1655 scroll3->setProperty("city_scroll", true);
1656
1659 right_layout = new QVBoxLayout();
1661 units_layout = new QVBoxLayout();
1662 left_layout = new QVBoxLayout();
1663
1664 /* Checkboxes to show units/wonders/imrovements
1665 * on production list */
1668 show_buildings->setToolTip(_("Show buildings"));
1669 show_buildings->setChecked(true);
1670 label = new QLabel();
1671 label->setPixmap(*fc_icons::instance()->get_pixmap("building"));
1672 label->setToolTip(_("Show buildings"));
1673 prod_option_layout->addWidget(show_buildings, Qt::AlignLeft);
1674 prod_option_layout->addWidget(label, Qt::AlignLeft);
1675 prod_option_layout->addStretch(100);
1676 label = new QLabel();
1677 label->setPixmap(*fc_icons::instance()->get_pixmap("cunits"));
1678 label->setToolTip(_("Show units"));
1679 show_units = new QCheckBox;
1680 show_units->setToolTip(_("Show units"));
1681 show_units->setChecked(true);
1682 prod_option_layout->addWidget(show_units, Qt::AlignHCenter);
1683 prod_option_layout->addWidget(label, Qt::AlignHCenter);
1684 prod_option_layout->addStretch(100);
1685 label = new QLabel();
1686 label->setPixmap(*fc_icons::instance()->get_pixmap("wonder"));
1687 label->setToolTip(_("Show wonders"));
1688 show_wonders = new QCheckBox;
1689 show_wonders->setToolTip(_("Show wonders"));
1690 show_wonders->setChecked(true);
1691 prod_option_layout->addWidget(show_wonders);
1692 prod_option_layout->addWidget(label);
1693 prod_option_layout->addStretch(100);
1694 label = new QLabel();
1695 label->setPixmap(*fc_icons::instance()->get_pixmap("future"));
1696 label->setToolTip(_("Show future targets"));
1698 future_targets->setToolTip(_("Show future targets"));
1699 future_targets->setChecked(false);
1701 prod_option_layout->addWidget(label, Qt::AlignRight);
1702 prod_options = new QGroupBox(this);
1703 prod_options->setLayout(prod_option_layout);
1704 prod_options->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
1705
1706 // Prev/next and close buttons
1707 button = new QPushButton;
1708 button->setIcon(fc_icons::instance()->get_icon("city-close"));
1709 button->setIconSize(QSize(56, 56));
1710 button->setToolTip(_("Close city dialog"));
1711 connect(button, &QAbstractButton::clicked, this, &QWidget::hide);
1712
1713 next_city_but = new QPushButton();
1714 next_city_but->setIcon(fc_icons::instance()->get_icon("city-right"));
1715 next_city_but->setIconSize(QSize(56, 56));
1716 next_city_but->setToolTip(_("Show next city"));
1717 connect(next_city_but, &QAbstractButton::clicked, this, &city_dialog::next_city);
1718
1719 prev_city_but = new QPushButton();
1720 connect(prev_city_but, &QAbstractButton::clicked, this, &city_dialog::prev_city);
1721 prev_city_but->setIcon(fc_icons::instance()->get_icon("city-left"));
1722 prev_city_but->setIconSize(QSize(56, 56));
1723 prev_city_but->setToolTip(_("Show previous city"));
1724
1725 happiness_button = new QPushButton();
1726 happiness_button->setIcon(fc_icons::instance()->get_icon("city-switch"));
1727 happiness_button->setIconSize(QSize(56, 28));
1728 connect(happiness_button, &QAbstractButton::clicked, this, &city_dialog::show_happiness);
1729
1730 button->setFixedSize(64, 64);
1731 prev_city_but->setFixedSize(64, 64);
1732 next_city_but->setFixedSize(64, 64);
1733 happiness_button->setFixedSize(64, 32);
1735 vbox_layout->addWidget(prev_city_but);
1736 vbox_layout->addWidget(next_city_but);
1737 vbox_layout->addWidget(button);
1738 vbox_layout->addWidget(happiness_button, Qt::AlignHCenter);
1739
1740 counterss_button = new QPushButton();
1741 connect(counterss_button, &QAbstractButton::clicked, this, &city_dialog::show_counters);
1742 vbox_layout->addWidget(counterss_button, Qt::AlignHCenter);
1743
1744 update_tabs();
1746
1747 hbox_layout->addLayout(vbox_layout, Qt::AlignLeft);
1748 hbox_layout->addWidget(info_wdg, Qt::AlignLeft);
1749 hbox_layout->addWidget(map_box, Qt::AlignCenter);
1750
1751 // Layout with city view and buttons
1752 lefttop_layout->addWidget(citizens_label, Qt::AlignHCenter);
1753 lefttop_layout->addStretch(0);
1754 lefttop_layout->addLayout(hbox_layout);
1755 lefttop_layout->addStretch(50);
1756
1757 // Layout for units/buildings
1758 curr_unit_wdg = new QWidget();
1759 supp_unit_wdg = new QWidget();
1760 curr_impr_wdg = new QWidget();
1761 v_layout = new QVBoxLayout;
1762 v_layout->addWidget(curr_impr);
1763 v_layout->addWidget(scroll3);
1764 v_layout->setContentsMargins(0 , 0 , 0, 0);
1765 v_layout->setSpacing(0);
1766 curr_impr_wdg->setLayout(v_layout);
1767 v_layout = new QVBoxLayout;
1768 v_layout->addWidget(curr_units);
1769 v_layout->addWidget(scroll2);
1770 v_layout->setContentsMargins(0 , 0 , 0, 0);
1771 v_layout->setSpacing(0);
1772 curr_unit_wdg->setLayout(v_layout);
1773 v_layout = new QVBoxLayout;
1774 v_layout->addWidget(supp_units);
1775 v_layout->addWidget(scroll);
1776 v_layout->setContentsMargins(0 , 0 , 0, 0);
1777 v_layout->setSpacing(0);
1778 supp_unit_wdg->setLayout(v_layout);
1779
1780 units_layout->addWidget(curr_unit_wdg);
1781 units_layout->addWidget(supp_unit_wdg);
1782 units_layout->addWidget(curr_impr_wdg);
1783 units_layout->setSpacing(0);
1784 units_layout->setContentsMargins(0 , 0 , 0, 0);
1785
1786 vbox = new QVBoxLayout;
1788 qgbprod = new QGroupBox;
1789 group_box = new QGroupBox(_("Worklist Option"));
1791 work_next_but = new QPushButton(fc_icons::instance()->get_icon(
1792 "go-down"), "");
1793 work_prev_but = new QPushButton(fc_icons::instance()->get_icon(
1794 "go-up"), "");
1795 work_add_but = new QPushButton(fc_icons::instance()->get_icon(
1796 "list-add"), "");
1797 work_rem_but = new QPushButton(style()->standardIcon(
1798 QStyle::SP_DialogDiscardButton), "");
1799 work_but_layout->addWidget(work_add_but);
1800 work_but_layout->addWidget(work_next_but);
1801 work_but_layout->addWidget(work_prev_but);
1802 work_but_layout->addWidget(work_rem_but);
1804 production_combo_p->setToolTip(_("Click to change current production"));
1805 p_table_p = new QTableWidget;
1806
1807 r1 = new QRadioButton(_("Change"));
1808 r2 = new QRadioButton(_("Insert Before"));
1809 r3 = new QRadioButton(_("Insert After"));
1810 r4 = new QRadioButton(_("Add Last"));
1811 r4->setChecked(true);
1812 group_box->setLayout(vbox);
1813
1814
1815 p_table_p->setColumnCount(3);
1816 p_table_p->setProperty("showGrid", "false");
1817 p_table_p->setProperty("selectionBehavior", "SelectRows");
1818 p_table_p->setEditTriggers(QAbstractItemView::NoEditTriggers);
1819 p_table_p->verticalHeader()->setVisible(false);
1820 p_table_p->horizontalHeader()->setVisible(false);
1821 p_table_p->setSelectionMode(QAbstractItemView::SingleSelection);
1822 production_combo_p->setFixedHeight(h);
1823 p_table_p->setMinimumWidth(200);
1824 p_table_p->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
1825 p_table_p->setContextMenuPolicy(Qt::CustomContextMenu);
1826 p_table_p->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
1827 header = p_table_p->horizontalHeader();
1828 header->setStretchLastSection(true);
1829
1830 qgbprod->setTitle(_("Worklist"));
1831 vbox_layout->setSpacing(0);
1832 vbox_layout->addWidget(prod_options);
1833 vbox_layout->addWidget(buy_button);
1834 vbox_layout->addWidget(production_combo_p);
1835 vbox_layout->addLayout(work_but_layout);
1836 vbox_layout->addWidget(p_table_p);
1837 qgbprod->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1838 qgbprod->setLayout(vbox_layout);
1839
1840 worklist_layout->setSpacing(0);
1841 worklist_layout->addWidget(qgbprod);
1842 connect(p_table_p,
1843 &QWidget::customContextMenuRequested, this,
1846 connect(work_add_but, &QAbstractButton::clicked, this, &city_dialog::show_targets_worklist);
1847 connect(work_prev_but, &QAbstractButton::clicked, this, &city_dialog::worklist_up);
1848 connect(work_next_but, &QAbstractButton::clicked, this, &city_dialog::worklist_down);
1849 connect(work_rem_but, &QAbstractButton::clicked, this, &city_dialog::worklist_del);
1850 connect(p_table_p,
1851 &QTableWidget::itemDoubleClicked,
1853 connect(p_table_p->selectionModel(),
1855 const QItemSelection &)),
1857 const QItemSelection &)));
1858 happiness_group = new QGroupBox(_("Happiness"));
1859 gridl = new QGridLayout;
1860
1861 nationality_table = new QTableWidget;
1862 nationality_table->setColumnCount(3);
1863 nationality_table->setProperty("showGrid", "false");
1864 nationality_table->setProperty("selectionBehavior", "SelectRows");
1865 nationality_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1866 nationality_table->verticalHeader()->setVisible(false);
1867 nationality_table->horizontalHeader()->setStretchLastSection(true);
1868
1869 info_list.clear();
1870 info_list << _("Cities:") << _("Luxuries:") << _("Buildings:")
1871 << _("Nationality:") << _("Units:") << _("Wonders:");
1872
1873 for (int i = 0; i < info_list.count(); i++) {
1874 lab_table[i] = new city_label(1 + i, this);
1875 gridl->addWidget(lab_table[i], i, 1, 1, 1);
1876 lab2 = new QLabel(this);
1877 lab2->setFont(*small_font);
1878 lab2->setProperty(fonts::notify_label, "true");
1879 lab2->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1880 lab2->setText(info_list.at(i));
1881 gridl->addWidget(lab2, i, 0, 1, 1);
1882 }
1883
1884 gridl->setSpacing(0);
1885 happiness_group->setLayout(gridl);
1886
1887
1891 happiness_layout->setStretch(0, 10);
1892 happiness_widget = new QWidget();
1894 qgbox = new QGroupBox(_("Presets:"));
1895 qsliderbox = new QGroupBox(_("Governor settings"));
1896 result_box = new QGroupBox(_("Results:"));
1897 hbox = new QHBoxLayout;
1898 gridl = new QGridLayout;
1900
1902 counterss_frame = new QFrame();
1904
1905 qpush2
1906 = new QPushButton(style()->standardIcon(QStyle::SP_DialogSaveButton),
1907 _("Save"));
1908 connect(qpush2, &QAbstractButton::pressed, this, &city_dialog::save_cma);
1909
1910 cma_info_text = new QLabel;
1911 cma_info_text->setFont(*small_font);
1912 cma_info_text->setAlignment(Qt::AlignCenter);
1913 cma_table = new QTableWidget;
1914 cma_table->setColumnCount(1);
1915 cma_table->setProperty("showGrid", "false");
1916 cma_table->setProperty("selectionBehavior", "SelectRows");
1917 cma_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1918 cma_table->setSelectionMode(QAbstractItemView::SingleSelection);
1919 cma_table->setContextMenuPolicy(Qt::CustomContextMenu);
1920 cma_table->verticalHeader()->setVisible(false);
1921 cma_table->horizontalHeader()->setVisible(false);
1922 cma_table->horizontalHeader()->setSectionResizeMode(
1923 QHeaderView::Stretch);
1924
1925 connect(cma_table->selectionModel(),
1927 const QItemSelection &)),
1929 const QItemSelection &)));
1930 connect(cma_table,
1931 &QWidget::customContextMenuRequested, this,
1933 connect(cma_table, &QTableWidget::cellDoubleClicked, this,
1935 gridl->addWidget(cma_table, 0, 0, 1, 2);
1936 qgbox->setLayout(gridl);
1937 hbox->addWidget(cma_info_text);
1938 result_box->setLayout(hbox);
1939 str_list << _("Food") << _("Shield") << _("Trade") << _("Gold")
1940 << _("Luxury") << _("Science") << _("Celebrate")
1941 << _("Maximize growth");
1942 some_label = new QLabel(_("Minimal Surplus"));
1944 some_label->setAlignment(Qt::AlignRight);
1945 slider_grid->addWidget(some_label, 0, 0, 1, 3);
1946 some_label = new QLabel(_("Priority"));
1948 some_label->setAlignment(Qt::AlignCenter);
1949 slider_grid->addWidget(some_label, 0, 3, 1, 2);
1950
1951 list_size = str_list.count();
1952 for (int i = 0; i < list_size; i++) {
1953 some_label = new QLabel(str_list.at(i));
1954 slider_grid->addWidget(some_label, i + 1, 0, 1, 1);
1955 some_label = new QLabel("0");
1956 some_label->setMinimumWidth(25);
1957
1958 if (i < list_size - 2) {
1959 slider = new QSlider(Qt::Horizontal);
1960 slider->setPageStep(1);
1961 slider->setFocusPolicy(Qt::TabFocus);
1962 slider_tab[2 * i] = slider;
1963 slider->setRange(-20, 20);
1964 slider->setSingleStep(1);
1965 slider_grid->addWidget(some_label, i + 1, 1, 1, 1);
1966 slider_grid->addWidget(slider, i + 1, 2, 1, 1);
1967 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1968
1969 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1970 } else if (i == list_size - 2) {
1972 slider_grid->addWidget(cma_celeb_checkbox, i + 1, 2 , 1 , 1);
1973 connect(cma_celeb_checkbox,
1974 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1975 } else {
1976 fc_assert(i == list_size - 1);
1977
1979 slider_grid->addWidget(cma_max_growth, i + 1, 2 , 1 , 1);
1980 connect(cma_max_growth,
1981 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1982 }
1983
1984 if (i <= list_size - 2) {
1985 some_label = new QLabel("0");
1986 some_label->setMinimumWidth(25);
1987 slider = new QSlider(Qt::Horizontal);
1988 slider->setFocusPolicy(Qt::TabFocus);
1989 slider->setRange(0, 25);
1990 slider_tab[2 * i + 1] = slider;
1991 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1992 slider_grid->addWidget(some_label, i + 1, 3, 1, 1);
1993 slider_grid->addWidget(slider, i + 1, 4, 1, 1);
1994 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1995 }
1996 }
1997
1998 cma_enable_but = new QPushButton();
1999 cma_enable_but->setFocusPolicy(Qt::TabFocus);
2000 connect(cma_enable_but, &QAbstractButton::pressed, this, &city_dialog::cma_enable);
2001 slider_grid->addWidget(cma_enable_but, O_LAST + 4, 0, 1, 3);
2002 slider_grid->addWidget(qpush2, O_LAST + 4, 3, 1, 2);
2003
2004 qsliderbox->setLayout(slider_grid);
2005 cma_result = new QLabel;
2006 cma_result_pix = new QLabel;
2007
2008 hbox = new QHBoxLayout;
2009 QScrollArea *govA = new QScrollArea();
2010 hbox->addWidget(cma_result_pix);
2011 hbox->addWidget(cma_result);
2012 hbox->addStretch(10);
2013 govA->setWidget(qsliderbox);
2014 govA->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
2015 right_layout->addWidget(qgbox);
2016 right_layout->addLayout(hbox);
2017 right_layout->addWidget(govA);
2018
2019 split_widget1 = new QWidget;
2020 split_widget1->setLayout(worklist_layout);
2021 split_widget2 = new QWidget;
2022 split_widget2->setLayout(units_layout);
2025 prod_unit_splitter->setStretchFactor(0, 3);
2026 prod_unit_splitter->setStretchFactor(1, 97);
2027 prod_unit_splitter->setOrientation(Qt::Horizontal);
2029 top_widget = new QWidget;
2030 top_widget->setLayout(lefttop_layout);
2031 top_widget->setSizePolicy(QSizePolicy::Minimum,
2032 QSizePolicy::Minimum);
2033 scroll_info = new QScrollArea();
2034 scroll_info->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
2035 scroll_unit = new QScrollArea();
2036 scroll_info->setWidget(top_widget);
2037 scroll_info->setWidgetResizable(true);
2038 prod_happ_widget = new QWidget;
2039 prod_happ_widget->setLayout(leftbot_layout);
2040 prod_happ_widget->setSizePolicy(QSizePolicy::MinimumExpanding,
2041 QSizePolicy::MinimumExpanding);
2042 scroll_unit->setWidget(prod_happ_widget);
2043 scroll_unit->setWidgetResizable(true);
2046 central_left_splitter->setStretchFactor(0, 40);
2047 central_left_splitter->setStretchFactor(1, 60);
2048 central_left_splitter->setOrientation(Qt::Vertical);
2050
2051 split_widget1 = new QWidget(this);
2052 split_widget2 = new QWidget(this);
2053 split_widget1->setLayout(left_layout);
2054 split_widget2->setLayout(right_layout);
2055 central_splitter->addWidget(split_widget1);
2056 central_splitter->addWidget(split_widget2);
2057 central_splitter->setStretchFactor(0, 99);
2058 central_splitter->setStretchFactor(1, 1);
2059 central_splitter->setOrientation(Qt::Horizontal);
2061 setSizeGripEnabled(true);
2063
2064 installEventFilter(this);
2065
2066 ::city_dlg_created = true;
2067
2069}
2070
2071/************************************************************************/
2075{
2076
2077 cid cprod;
2078 int i, pos;
2079 int item, targets_used;
2081 QString str;
2082 struct item items[MAX_NUM_PRODUCTION_TARGETS];
2083 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
2084 struct universal univ;
2085
2086 pos = 0;
2089 name_and_sort_items(targets, targets_used, items, false, dlgcity);
2090
2091 for (item = 0; item < targets_used; item++) {
2092 if (can_city_build_now(&(wld.map), dlgcity, &items[item].item)) {
2093 prod_list << cid_encode(items[item].item);
2094 }
2095 }
2096
2097 for (i = 0; i < prod_list.size(); i++) {
2098 if (prod_list.at(i) == cprod) {
2099 if (next) {
2100 pos = i + 1;
2101 } else {
2102 pos = i - 1;
2103 }
2104 }
2105 }
2106 if (pos == prod_list.size()) {
2107 pos = 0;
2108 }
2109 if (pos == - 1) {
2110 pos = prod_list.size() - 1;
2111 }
2112 univ = cid_decode(static_cast<cid>(prod_list.at(pos)));
2114}
2115
2116/************************************************************************/
2120{
2121 if (current_tab == happiness) {
2122 happiness_button->setToolTip(_("Show city production"));
2123 counterss_button->setToolTip(_("Show counters information"));
2124
2125 } else {
2126 happiness_button->setToolTip(_("Show happiness information"));
2127
2128 if (current_tab == counters) {
2129 counterss_button->setToolTip(_("Show city production"));
2130 }
2131 else {
2132 counterss_button->setToolTip(_("Show counters information"));
2133 }
2134 }
2135}
2136
2137/************************************************************************/
2141{
2143 setUpdatesEnabled(false);
2144
2145
2146 if (current_tab != happiness) {
2147 leftbot_layout->replaceWidget(active_tab,
2149 Qt::FindDirectChildrenOnly);
2150 active_tab->hide();
2151 happiness_widget->show();
2152 happiness_widget->updateGeometry();
2154 } else {
2155 /* We do not change prod_unit_splitter to current_tab,
2156 * because happiness is active tab and clicked -
2157 * switching to default */
2158 leftbot_layout->replaceWidget(happiness_widget,
2160 Qt::FindDirectChildrenOnly);
2161 prod_unit_splitter->show();
2162 prod_unit_splitter->updateGeometry();
2163 happiness_widget->hide();
2165 }
2166
2167 setUpdatesEnabled(true);
2168 update();
2169 update_tabs();
2170}
2171
2172/************************************************************************/
2176{
2178 setUpdatesEnabled(false);
2179
2180
2181 if (current_tab != counters) {
2182 leftbot_layout->replaceWidget(active_tab,
2184 Qt::FindDirectChildrenOnly);
2185 active_tab->hide();
2186 counterss_frame->show();
2187 counterss_frame->updateGeometry();
2189 } else {
2190 /* We do not change prod_unit_splitter to current_tab,
2191 * because counters is active tab and clicked -
2192 * switching to default */
2193 leftbot_layout->replaceWidget(counterss_frame,
2195 Qt::FindDirectChildrenOnly);
2196 prod_unit_splitter->show();
2197 prod_unit_splitter->updateGeometry();
2198 counterss_frame->hide();
2200 }
2201
2202 setUpdatesEnabled(true);
2203 update();
2204 update_tabs();
2205}
2206
2207/************************************************************************/
2211{
2212 if (NULL == client.conn.playing
2214 prev_city_but->setDisabled(true);
2215 next_city_but->setDisabled(true);
2216 buy_button->setDisabled(true);
2217 cma_enable_but->setDisabled(true);
2218 production_combo_p->setDisabled(true);
2219 current_units->setDisabled(true);
2220 supported_units->setDisabled(true);
2221 view->setDisabled(true);
2222
2223 if (!client_is_observer()) {
2224 }
2225 } else {
2226 prev_city_but->setEnabled(true);
2227 next_city_but->setEnabled(true);
2228 buy_button->setEnabled(true);
2229 cma_enable_but->setEnabled(true);
2230 production_combo_p->setEnabled(true);
2231 current_units->setEnabled(true);
2232 supported_units->setEnabled(true);
2233 view->setEnabled(true);
2234 }
2235
2237 cma_enable_but->setEnabled(true);
2238 } else {
2239 cma_enable_but->setDisabled(true);
2240 }
2241
2243}
2244
2245/************************************************************************/
2249{
2250 work_next_but->setDisabled(true);
2251 work_prev_but->setDisabled(true);
2252 work_add_but->setDisabled(true);
2253 work_rem_but->setDisabled(true);
2254
2256 work_add_but->setEnabled(true);
2257
2258 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount()) {
2259 work_rem_but->setEnabled(true);
2260 }
2261
2262 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount() - 1) {
2263 work_next_but->setEnabled(true);
2264 }
2265
2266 if (selected_row_p > 0 && selected_row_p < p_table_p->rowCount()) {
2267 work_prev_but->setEnabled(true);
2268 }
2269 }
2270}
2271
2272/************************************************************************/
2276{
2277 if (citizen_pixmap) {
2278 citizen_pixmap->detach();
2279 delete citizen_pixmap;
2280 }
2281
2282 cma_table->clear();
2283 p_table_p->clear();
2284 nationality_table->clear();
2286 supported_units->clear_layout();
2287 removeEventFilter(this);
2288 ::city_dlg_created = false;
2289
2290 // Delete the one widget that currently does NOT have a parent
2291 if (current_tab == common) {
2292 delete happiness_widget;
2293 delete counterss_frame;
2294 }
2295 else if (current_tab == counters) {
2296 delete happiness_widget;
2297 delete prod_unit_splitter;
2298 }else {
2299 delete counterss_frame;
2300 delete prod_unit_splitter;
2301 }
2302}
2303
2304/************************************************************************/
2308{
2309 gui()->qt_settings.city_geometry = saveGeometry();
2310 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2311 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2312 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2313}
2314
2315/************************************************************************/
2319{
2320 if (!gui()->qt_settings.city_geometry.isNull()) {
2321 restoreGeometry(gui()->qt_settings.city_geometry);
2322 prod_unit_splitter->restoreState(gui()->qt_settings.city_splitter1);
2323 central_left_splitter->restoreState(gui()->qt_settings.city_splitter2);
2324 central_splitter->restoreState(gui()->qt_settings.city_splitter3);
2325 } else {
2326 QRect rect = QApplication::primaryScreen()->availableGeometry();
2327
2328 resize((rect.width() * 4) / 5, (rect.height() * 5) / 6);
2329 }
2330}
2331
2332/************************************************************************/
2336{
2337 gui()->qt_settings.city_geometry = saveGeometry();
2338 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2339 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2340 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2341}
2342
2343/************************************************************************/
2346bool city_dialog::eventFilter(QObject *obj, QEvent *event)
2347{
2348
2349 if (obj == this) {
2350 if (event->type() == QEvent::KeyPress) {
2351 }
2352
2353 if (event->type() == QEvent::ShortcutOverride) {
2354 QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
2355 if (key_event->key() == Qt::Key_Right) {
2356 next_city();
2357 event->setAccepted(true);
2358 return true;
2359 }
2360 if (key_event->key() == Qt::Key_Left) {
2361 prev_city();
2362 event->setAccepted(true);
2363 return true;
2364 }
2365 if (key_event->key() == Qt::Key_Up) {
2366 change_production(true);
2367 event->setAccepted(true);
2368 return true;
2369 }
2370 if (key_event->key() == Qt::Key_Down) {
2371 change_production(false);
2372 event->setAccepted(true);
2373 return true;
2374 }
2375 }
2376 }
2377 return QObject::eventFilter(obj, event);
2378}
2379
2380/************************************************************************/
2384{
2386 const int city_id = dlgcity->id;
2387
2388 if (!can_client_issue_orders()) {
2389 return;
2390 }
2391
2392 ask = new hud_input_box(gui()->central_wdg);
2393 ask->set_text_title_definput(_("What should we rename the city to?"),
2394 _("Rename City"), city_name_get(dlgcity));
2395 ask->setAttribute(Qt::WA_DeleteOnClose);
2396 connect(ask, &hud_message_box::accepted, this, [=]() {
2397 struct city *pcity = game_city_by_number(city_id);
2399
2400 if (!pcity) {
2401 return;
2402 }
2403
2404 ask_bytes = ask->input_edit.text().toUtf8();
2405 ::city_rename(pcity, ask_bytes.data());
2406 });
2407 ask->show();
2408}
2409
2410/************************************************************************/
2414{
2415 zoom = zoom * 1.2;
2416 if (dlgcity) {
2417 view->set_pixmap(dlgcity, zoom);
2418 }
2420 left_layout->update();
2421}
2422
2423/************************************************************************/
2427{
2428 zoom = zoom / 1.2;
2429 if (dlgcity) {
2430 view->set_pixmap(dlgcity, zoom);
2431 }
2433 left_layout->update();
2434}
2435
2436/************************************************************************/
2440{
2441 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
2442
2443 ask->set_text_title_definput(_("What should we name the preset?"),
2444 _("Name new preset"),
2445 _("new preset"));
2446 ask->setAttribute(Qt::WA_DeleteOnClose);
2447 connect(ask, &hud_message_box::accepted, this,
2449 struct cm_parameter param;
2450 QByteArray ask_bytes = ask->input_edit.text().toUtf8();
2451 QString text = ask_bytes.data();
2452 if (!text.isEmpty()) {
2453 param.allow_disorder = false;
2454 param.allow_specialists = true;
2455 param.require_happy = cma_celeb_checkbox->isChecked();
2456 param.max_growth = cma_max_growth->isChecked();
2457 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2458
2459 for (int i = O_FOOD; i < O_LAST; i++) {
2460 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2461 param.factor[i] = slider_tab[2 * i + 1]->value();
2462 }
2463
2464 ask_bytes = text.toUtf8();
2465 cmafec_preset_add(ask_bytes.data(), &param);
2467 }
2468 });
2469 ask->show();
2470}
2471
2472/************************************************************************/
2476{
2479
2480 return;
2481 }
2482
2483 cma_changed();
2485}
2486
2487/************************************************************************/
2491{
2492 struct cm_parameter param;
2493
2494 param.allow_disorder = false;
2495 param.allow_specialists = true;
2496 param.require_happy = cma_celeb_checkbox->isChecked();
2497 param.max_growth = cma_max_growth->isChecked();
2498 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2499
2500 for (int i = O_FOOD; i < O_LAST; i++) {
2501 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2502 param.factor[i] = slider_tab[2 * i + 1]->value();
2503 }
2504
2506}
2507
2508/************************************************************************/
2512{
2513 const struct cm_parameter *param;
2514
2515 if (!can_client_issue_orders()) {
2516 return;
2517 }
2521 }
2522
2525}
2526
2527/************************************************************************/
2531 const QItemSelection &ds)
2532{
2533 const struct cm_parameter *param;
2534 QModelIndex index;
2535 QModelIndexList indexes = sl.indexes();
2536
2537 if (indexes.isEmpty() || cma_table->signalsBlocked()) {
2538 return;
2539 }
2540
2541 index = indexes.at(0);
2542 int ind = index.row();
2543
2544 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2545 return;
2546 }
2547
2550
2554 }
2555}
2556
2557/************************************************************************/
2561{
2562 struct cm_parameter param;
2563 const struct cm_parameter *cparam;
2564 int output;
2565 QVariant qvar;
2566 QLabel *label;
2567
2568 if (!cma_is_city_under_agent(dlgcity, &param)) {
2569 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2570 return;
2571 }
2573 cm_copy_parameter(&param, cparam);
2574 }
2575
2576 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2577 slider_tab[output]->blockSignals(true);
2578 }
2579
2580 for (output = O_FOOD; output < O_LAST; output++) {
2581 qvar = slider_tab[2 * output + 1]->property("FC");
2582 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2583 label->setText(QString::number(param.factor[output]));
2584 slider_tab[2 * output + 1]->setValue(param.factor[output]);
2585 qvar = slider_tab[2 * output]->property("FC");
2586 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2587 label->setText(QString::number(param.minimal_surplus[output]));
2588 slider_tab[2 * output]->setValue(param.minimal_surplus[output]);
2589 }
2590
2591 slider_tab[2 * O_LAST + 1]->blockSignals(true);
2592 qvar = slider_tab[2 * O_LAST + 1]->property("FC");
2593 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2594 label->setText(QString::number(param.happy_factor));
2595 slider_tab[2 * O_LAST + 1]->setValue(param.happy_factor);
2596 slider_tab[2 * O_LAST + 1]->blockSignals(false);
2597 cma_celeb_checkbox->blockSignals(true);
2598 cma_celeb_checkbox->setChecked(param.require_happy);
2599 cma_celeb_checkbox->blockSignals(false);
2600 cma_max_growth->blockSignals(true);
2601 cma_max_growth->setChecked(param.max_growth);
2602 cma_max_growth->blockSignals(false);
2603
2604 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2605 slider_tab[output]->blockSignals(false);
2606 }
2607}
2608
2609/************************************************************************/
2613{
2614 QString s;
2616 struct cm_parameter param;
2617 QPixmap pix;
2618 int i;
2619
2620 cma_table->clear();
2621 cma_table->setRowCount(0);
2622
2623 for (i = 0; i < cmafec_preset_num(); i++) {
2624 item = new QTableWidgetItem;
2625 item->setText(cmafec_preset_get_descr(i));
2626 cma_table->insertRow(i);
2627 cma_table->setItem(i, 0, item);
2628 }
2629
2630 if (cmafec_preset_num() == 0) {
2631 cma_table->insertRow(0);
2632 item = new QTableWidgetItem;
2633 item->setText(_("No governor defined"));
2634 cma_table->setItem(0, 0, item);
2635 }
2636
2638 view->update();
2640 pix = style()->standardPixmap(QStyle::SP_DialogApplyButton);
2641 pix = pix.scaled(2 * pix.width(), 2 * pix.height(),
2642 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2643 cma_result_pix->setPixmap(pix);
2644 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2645 // TRANS: %1 is custom string chosen by player
2646 cma_result->setText(QString(_("<h3>Governor Enabled<br>(%1)</h3>"))
2647 .arg(s.toHtmlEscaped()));
2648 cma_result->setAlignment(Qt::AlignCenter);
2649 } else {
2650 pix = style()->standardPixmap(QStyle::SP_DialogCancelButton);
2651 pix = pix.scaled(1.6 * pix.width(), 1.6 * pix.height(),
2652 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2653 cma_result_pix->setPixmap(pix);
2654 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2655 cma_result->setText(QString(_("<h3>Governor Disabled</h3>")));
2656 cma_result->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
2657 }
2658
2662 cm_parameter *const >(&param));
2663 if (i >= 0 && i < cma_table->rowCount()) {
2664 cma_table->blockSignals(true);
2665 cma_table->setCurrentCell(i, 0);
2666 cma_table->blockSignals(false);
2667 }
2668
2669 cma_enable_but->setText(_("Disable"));
2670 } else {
2671 cma_enable_but->setText(_("Enable"));
2672 }
2674}
2675
2676/************************************************************************/
2680{
2681 int i;
2683
2684 i = cma_table->currentRow();
2685
2686 if (i == -1 || cmafec_preset_num() == 0) {
2687 return;
2688 }
2689
2691 ask->set_text_title(_("Remove this preset?"), cmafec_preset_get_descr(i));
2692 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
2693 ask->setDefaultButton(QMessageBox::Cancel);
2694 ask->setAttribute(Qt::WA_DeleteOnClose);
2695 connect(ask, &hud_message_box::accepted, this,
2699 });
2700 ask->show();
2701}
2702
2703/************************************************************************/
2707{
2709 cma_changed();
2711 }
2712}
2713
2714/************************************************************************/
2718{
2719 QVariant qvar;
2720 QSlider *slider;
2721 QLabel *label;
2722
2724 qvar = slider->property("FC");
2725
2726 if (qvar.isNull() || !qvar.isValid()) {
2727 return;
2728 }
2729
2730 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2731 label->setText(QString::number(value));
2732
2734 cma_changed();
2736 }
2737}
2738
2739/************************************************************************/
2759
2760/************************************************************************/
2764{
2765 QMenu *cma_menu = new QMenu(this);
2767
2768 cma_menu->setAttribute(Qt::WA_DeleteOnClose);
2769 cma_del_item = cma_menu->addAction(_("Remove Governor"));
2770 connect(cma_menu, &QMenu::triggered, this,
2772 if (act == cma_del_item) {
2773 cma_remove();
2774 }
2775 });
2776
2777 cma_menu->popup(QCursor::pos());
2778}
2779
2780/************************************************************************/
2784{
2785 QAction *action;
2786 QAction *disband;
2791 QMap<QString, cid>::const_iterator map_iter;
2792 QMenu *change_menu;
2793 QMenu *insert_menu;
2794 QMenu *list_menu;
2795 QMenu *options_menu;
2796 int city_id = dlgcity->id;
2797
2798 if (!can_client_issue_orders()) {
2799 return;
2800 }
2801 list_menu = new QMenu(this);
2802 change_menu = list_menu->addMenu(_("Change worklist"));
2803 insert_menu = list_menu->addMenu(_("Insert worklist"));
2804 wl_clear = list_menu->addAction(_("Clear"));
2805 connect(wl_clear, &QAction::triggered, this, &city_dialog::clear_worklist);
2806 list.clear();
2807
2811
2812 if (list.count() == 0) {
2813 wl_empty = change_menu->addAction(_("(no worklists defined)"));
2814 insert_menu->addAction(wl_empty);
2815 }
2816
2817 map_iter = list.constBegin();
2818
2819 while (map_iter != list.constEnd()) {
2820 action = change_menu->addAction(map_iter.key());
2821 action->setData(map_iter.value());
2822
2823 action = insert_menu->addAction(map_iter.key());
2824 action->setData(map_iter.value());
2825
2826 map_iter++;
2827 }
2828
2829 wl_save = list_menu->addAction(_("Save worklist"));
2830 connect(wl_save, &QAction::triggered, this, &city_dialog::save_worklist);
2831 options_menu = list_menu->addMenu(_("Options"));
2832 disband = options_menu->addAction(_("Allow disbanding city"));
2833 disband->setCheckable(true);
2834 disband->setChecked(is_city_option_set(dlgcity, CITYO_DISBAND));
2835 connect(disband, &QAction::triggered, this,
2837
2838 connect(change_menu, &QMenu::triggered, this, [=](QAction *act) {
2839 QVariant id = act->data();
2840 struct city *pcity = game_city_by_number(city_id);
2841 const struct worklist *worklist;
2842
2843 if (!pcity) {
2844 return;
2845 }
2846
2847#ifndef FC_QT5_MODE
2848 fc_assert_ret(id.typeId() == QMetaType::Int);
2849#else // FC_QT5_MODE
2850 fc_assert_ret(id.type() == QVariant::Int);
2851#endif // FC_QT5_MODE
2852
2855 });
2856
2857 connect(insert_menu, &QMenu::triggered, this,
2859 QVariant id = act->data();
2860 struct city *pcity = game_city_by_number(city_id);
2861 const struct worklist *worklist;
2862
2863 if (!pcity) {
2864 return;
2865 }
2866
2867#ifndef FC_QT5_MODE
2868 fc_assert_ret(id.typeId() == QMetaType::Int);
2869#else // FC_QT5_MODE
2870 fc_assert_ret(id.type() == QVariant::Int);
2871#endif // FC_QT5_MODE
2872
2875 });
2876
2877 list_menu->popup(QCursor::pos());
2878}
2879
2880/************************************************************************/
2884{
2885 QString str;
2886 int value;
2887
2888 buy_button->setDisabled(true);
2889
2890 if (!client_is_observer() && client.conn.playing != NULL) {
2891 value = dlgcity->client.buy_cost;
2892 str = QString(PL_("Buy (%1 gold)", "Buy (%1 gold)",
2893 value)).arg(QString::number(value));
2894
2895 if (client.conn.playing->economic.gold >= value && value != 0) {
2896 buy_button->setEnabled(true);
2897 }
2898 } else {
2899 str = QString(_("Buy"));
2900 }
2901
2902 buy_button->setText(str);
2903}
2904
2905/************************************************************************/
2909{
2910 enum citizen_category categories[MAX_CITY_SIZE];
2911 int i, j, width, height;
2912 QPainter p;
2913 QPixmap *pix;
2915 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
2916 int h = tileset_small_sprite_height(tileset) / gui()->map_scale;
2917
2918 i = 1 + (num_citizens * 5 / 200);
2919 w = w / i;
2920 QRect source_rect(0, 0, w, h);
2921 QRect dest_rect(0, 0, w, h);
2922 width = w * num_citizens;
2923 height = h;
2924
2925 if (citizen_pixmap) {
2926 citizen_pixmap->detach();
2927 delete citizen_pixmap;
2928 }
2929
2931
2932 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2933 dest_rect.moveTo(i * w, 0);
2934 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2935 p.begin(citizen_pixmap);
2936 p.drawPixmap(dest_rect, *pix, source_rect);
2937 p.end();
2938 }
2939
2941 citizens_label->setPixmap(*citizen_pixmap);
2942
2945
2946 for (int k = 0; k < FEELING_LAST - 1; k++) {
2949 static_cast<citizen_feeling>(k),
2950 categories);
2951
2952 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2953 dest_rect.moveTo(i * w, 0);
2954 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2955 p.begin(citizen_pixmap);
2956 p.drawPixmap(dest_rect, *pix, source_rect);
2957 p.end();
2958 }
2959
2960 lab_table[k]->setPixmap(*citizen_pixmap);
2961
2962 switch (k) {
2963 case FEELING_BASE:
2964 lab_table[k]->setToolTip(text_happiness_cities(dlgcity));
2965 break;
2966
2967 case FEELING_LUXURY:
2968 lab_table[k]->setToolTip(text_happiness_luxuries(dlgcity));
2969 break;
2970
2971 case FEELING_EFFECT :
2973 break;
2974
2977 break;
2978
2979 case FEELING_MARTIAL:
2980 lab_table[k]->setToolTip(text_happiness_units(dlgcity));
2981 break;
2982
2983 default:
2984 break;
2985 }
2986 }
2987}
2988
2989/************************************************************************/
2993{
2994 setUpdatesEnabled(false);
2995 production_combo_p->blockSignals(true);
2996
2997 if (dlgcity) {
2998 view->set_pixmap(dlgcity, zoom);
2999 view->update();
3000 update_title();
3007 update_units();
3011 } else {
3013 }
3014
3015 production_combo_p->blockSignals(false);
3016 setUpdatesEnabled(true);
3018 update();
3019}
3020
3021/************************************************************************/
3025{
3026 QFont *small_font;
3027
3029
3030 qDeleteAll(counterss_frame->findChildren<QWidget*>("", Qt::FindDirectChildrenOnly));
3032 QString helptext;
3033 char buf[1024];
3034 QLabel *name, *value, *activated, *help;
3035
3036 name = new QLabel(name_translation_get(&pcount->name));
3037 fc_snprintf(buf, sizeof(buf), _("Current value is: %d"),
3039 value = new QLabel(buf);
3040 fc_snprintf(buf, sizeof(buf), _("Activated once value equal "
3041 "or higher than: %d"),
3042 pcount->checkpoint);
3043 activated = new QLabel(buf);
3044 if (pcount->helptext != nullptr) {
3045 strvec_iterate(pcount->helptext, text_) {
3046 helptext += text_;
3048 }
3049 help = new QLabel(helptext);
3050
3051 name->setFont(*small_font);
3052 value->setFont(*small_font);
3053 activated->setFont(*small_font);
3054 help->setFont(*small_font);
3055
3056 counterss_layout->addWidget(name);
3057 counterss_layout->addWidget(value);
3058 counterss_layout->addWidget(activated);
3059 counterss_layout->addWidget(help);
3061}
3062
3063/************************************************************************/
3067{
3068 QFont f = QApplication::font();
3069 QFontMetrics fm(f);
3070 QPixmap *pix = NULL;
3072 QString str;
3075 char buf[8];
3077 int h;
3078 int i = 0;
3079 struct sprite *sprite;
3080
3081 h = fm.height() + 6;
3082 nationality_table->clear();
3083 nationality_table->setRowCount(0);
3084 info_list.clear();
3085 info_list << _("#") << _("Flag") << _("Nation");
3086 nationality_table->setHorizontalHeaderLabels(info_list);
3087
3088 citizens_iterate(dlgcity, pslot, nationality) {
3089 nationality_table->insertRow(i);
3090
3091 for (int j = 0; j < nationality_table->columnCount(); j++) {
3092 item = new QTableWidgetItem;
3093
3094 switch (j) {
3095 case 0:
3097
3098 if (nationality_i == 0) {
3099 str = "-";
3100 } else {
3101 fc_snprintf(buf, sizeof(buf), "%d", nationality_i);
3102 str = QString(buf);
3103 }
3104
3105 item->setText(str);
3106 break;
3107
3108 case 1:
3111 (player_slot_get_player(pslot)));
3112
3113 if (sprite != NULL) {
3114 pix = sprite->pm;
3115 pix_scaled = pix->scaledToHeight(h);
3116 item->setData(Qt::DecorationRole, pix_scaled);
3117 } else {
3118 item->setText("FLAG MISSING");
3119 }
3120 break;
3121
3122 case 2:
3124 (player_slot_get_player(pslot)));
3125 break;
3126
3127 default:
3128 break;
3129 }
3130 nationality_table->setItem(i, j, item);
3131 }
3132 i++;
3134 nationality_table->horizontalHeader()->setStretchLastSection(false);
3135 nationality_table->resizeColumnsToContents();
3136 nationality_table->resizeRowsToContents();
3137 nationality_table->horizontalHeader()->setStretchLastSection(true);
3138}
3139
3140/************************************************************************/
3144{
3145 int illness = 0;
3146 char buffer[512];
3147 char buf_info[NUM_INFO_FIELDS][512];
3148 char buf_tooltip[NUM_INFO_FIELDS][512];
3149 int granaryturns;
3150 int spec;
3151
3152 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3153 buf_info[i][0] = '\0';
3154 buf_tooltip[i][0] = '\0';
3155 }
3156
3157 // Fill the buffers with the necessary info
3158 spec = city_specialists(dlgcity);
3160 "%3d (%4d)", dlgcity->size, spec);
3162 _("Population: %d, Specialists: %d"),
3163 dlgcity->size, spec);
3164 fc_snprintf(buf_info[INFO_FOOD], sizeof(buf_info[INFO_FOOD]), "%3d (%+4d)",
3167 "%3d (%+4d)", dlgcity->prod[O_SHIELD] + dlgcity->waste[O_SHIELD],
3169 fc_snprintf(buf_info[INFO_TRADE], sizeof(buf_info[INFO_TRADE]), "%3d (%+4d)",
3172 fc_snprintf(buf_info[INFO_GOLD], sizeof(buf_info[INFO_GOLD]), "%3d (%+4d)",
3179 "%4d/%-4d", dlgcity->food_stock,
3181
3183 sizeof(buf_tooltip[INFO_FOOD]));
3185 sizeof(buf_tooltip[INFO_SHIELD]));
3187 sizeof(buf_tooltip[INFO_TRADE]));
3189 sizeof(buf_tooltip[INFO_GOLD]));
3191 sizeof(buf_tooltip[INFO_SCIENCE]));
3193 sizeof(buf_tooltip[INFO_LUXURY]));
3195 sizeof(buf_tooltip[INFO_CULTURE]));
3197 sizeof(buf_tooltip[INFO_POLLUTION]));
3199 sizeof(buf_tooltip[INFO_ILLNESS]));
3200
3202
3203 if (granaryturns == 0) {
3204 // TRANS: city growth is blocked. Keep short.
3205 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("blocked"));
3206 } else if (granaryturns == FC_INFINITY) {
3207 // TRANS: city is not growing. Keep short.
3208 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("never"));
3209 } else {
3210 /* A negative value means we'll have famine in that many turns.
3211 But that's handled down below. */
3212 // TRANS: city growth turns. Keep short.
3214 PL_("%d turn", "%d turns", abs(granaryturns)),
3215 abs(granaryturns));
3216 }
3217
3219 "%4d", dlgcity->waste[O_TRADE]);
3226
3227 if (!game.info.illness_on) {
3229 " -.-");
3230 } else {
3231 illness = city_illness_calc(dlgcity, NULL, NULL, NULL, NULL);
3232 // Illness is in tenth of percent
3234 "%5.1f%%", (float) illness / 10.0);
3235 }
3236 if (dlgcity->steal) {
3238 PL_("%d time", "%d times", dlgcity->steal), dlgcity->steal);
3239 } else {
3241 _("Not stolen"));
3242 }
3243
3245 sizeof(buf_info[INFO_AIRLIFT]));
3247 sizeof(buf_tooltip[INFO_AIRLIFT]));
3248
3249 get_city_dialog_output_text(dlgcity, O_FOOD, buffer, sizeof(buffer));
3250
3251 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3252 qlt[i]->setText(QString(buf_info[i]));
3253
3254 if (buf_tooltip[i][0]) {
3255 qlt[i]->setToolTip("<pre>" + QString(buf_tooltip[i]).toHtmlEscaped()
3256 + "</pre>");
3257 }
3258 }
3259}
3260
3261/************************************************************************/
3265{
3268
3269 setContentsMargins(0, 0 ,0 ,0);
3271 dlgcity = qcity;
3272 production_combo_p->blockSignals(true);
3273 refresh();
3274 production_combo_p->blockSignals(false);
3275}
3276
3277/************************************************************************/
3281{
3282 struct worklist queue;
3283
3284 city_get_queue(dlgcity, &queue);
3285
3287 return;
3288 }
3289
3291 city_set_queue(dlgcity, &queue);
3292}
3293
3294/************************************************************************/
3298{
3299 unit_item *ui;
3300 struct unit_list *units;
3301 char buf[256];
3302 int n;
3303 int happy_cost;
3305 const struct civ_map *nmap = &(wld.map);
3306
3307 supported_units->setUpdatesEnabled(false);
3308 supported_units->clear_layout();
3309
3310 if (NULL != client.conn.playing
3313 } else {
3314 units = dlgcity->units_supported;
3315 }
3316
3317 unit_list_iterate(units, punit) {
3319 ui = new unit_item(this, punit, true, happy_cost);
3320 ui->init_pix();
3321 supported_units->add_item(ui);
3323 n = unit_list_size(units);
3324 fc_snprintf(buf, sizeof(buf), _("Supported units %d"), n);
3325 supp_units->setText(QString(buf));
3326 supported_units->update_units();
3327 supported_units->setUpdatesEnabled(true);
3328 current_units->setUpdatesEnabled(true);
3330
3331 if (NULL != client.conn.playing
3334 } else {
3335 units = dlgcity->tile->units;
3336 }
3337
3338 unit_list_iterate(units, punit) {
3339 ui = new unit_item(this , punit, false);
3340 ui->init_pix();
3343
3344 n = unit_list_size(units);
3345 fc_snprintf(buf, sizeof(buf), _("Present units %d"), n);
3346 curr_units->setText(QString(buf));
3347
3349 current_units->setUpdatesEnabled(true);
3350}
3351
3352/************************************************************************/
3356 const QItemSelection &ds)
3357{
3358 QModelIndex index;
3359 QModelIndexList indexes = sl.indexes();
3360
3361 if (indexes.isEmpty()) {
3362 return;
3363 }
3364
3365 index = indexes.at(0);
3366 selected_row_p = index.row();
3368}
3369
3370/************************************************************************/
3374{
3375 int size, i;
3376 struct city *other_pcity = NULL;
3377
3378 if (NULL == client.conn.playing) {
3379 return;
3380 }
3381
3383
3384 if (size <= 1) {
3385 return;
3386 }
3387
3388 for (i = 0; i < size; i++) {
3390 break;
3391 }
3392 }
3393
3394 if (i >= size - 1) {
3395 // Current city last in the list (size - 1) or disappeared (size)
3397 } else {
3399 }
3400
3403}
3404
3405/************************************************************************/
3409{
3410 int size, i;
3411 struct city *other_pcity = NULL;
3412
3413 if (NULL == client.conn.playing) {
3414 return;
3415 }
3416
3418
3419 if (size <= 1) {
3420 return;
3421 }
3422
3423 for (i = 0; i < size; i++) {
3425 break;
3426 }
3427 }
3428
3429 if (i == 0 || i == size) {
3430 // Current city in the beginning of the list or disappeared
3432 } else {
3434 }
3435
3438}
3439
3440/************************************************************************/
3444{
3445 char buf[32];
3446 QString str;
3448
3450 production_combo_p->setRange(0, cost);
3452 if (dlgcity->shield_stock >= cost) {
3453 production_combo_p->setValue(cost);
3454 } else {
3456 }
3457 production_combo_p->setAlignment(Qt::AlignCenter);
3458 str = QString(buf);
3459 str = str.simplified();
3460
3461 production_combo_p->setFormat(QString("(%p%) %2\n%1")
3463 str));
3464
3465 production_combo_p->updateGeometry();
3466
3467}
3468
3469/************************************************************************/
3473{
3474 char buf[1024], buf2[1024];
3476 int value = dlgcity->client.buy_cost;
3478 int city_id = dlgcity->id;
3479
3480 if (!can_client_issue_orders()) {
3481 return;
3482 }
3483
3485 fc_snprintf(buf2, ARRAY_SIZE(buf2), PL_("Treasury contains %d gold.",
3486 "Treasury contains %d gold.",
3487 client_player()->economic.gold),
3488 client_player()->economic.gold);
3489 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Buy %s for %d gold?",
3490 "Buy %s for %d gold?", value),
3491 name, value);
3492 ask->set_text_title(buf, buf2);
3493 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
3494 ask->setDefaultButton(QMessageBox::Cancel);
3495 ask->setAttribute(Qt::WA_DeleteOnClose);
3496 connect(ask, &hud_message_box::accepted, this, [=]() {
3497 struct city *pcity = game_city_by_number(city_id);
3498
3499 if (!pcity) {
3500 return;
3501 }
3502
3504 });
3505 ask->show();
3506}
3507
3508/************************************************************************/
3512{
3513 QFont f = QApplication::font();
3514 QFontMetrics fm(f);
3515 QPixmap *pix = NULL;
3519 struct sprite *sprite;
3520 int h, cost, item, targets_used, col, upkeep;
3521 struct item items[MAX_NUM_PRODUCTION_TARGETS];
3522 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
3523 struct worklist queue;
3524 impr_item *ui;
3525
3526 upkeep = 0;
3527 city_buildings->setUpdatesEnabled(false);
3529
3530 h = fm.height() + 6;
3532 name_and_sort_items(targets, targets_used, items, false, dlgcity);
3533
3534 for (item = 0; item < targets_used; item++) {
3535 struct universal target = items[item].item;
3536
3537 ui = new impr_item(this, target.value.building, dlgcity);
3538 ui->init_pix();
3540
3541 fc_assert_action(VUT_IMPROVEMENT == target.kind, continue);
3543 upkeep = upkeep + city_improvement_upkeep(dlgcity, target.value.building);
3544 if (sprite != nullptr) {
3545 pix = sprite->pm;
3546 pix_scaled = pix->scaledToHeight(h);
3547 }
3548 }
3549
3550 city_get_queue(dlgcity, &queue);
3551 p_table_p->setRowCount(worklist_length(&queue));
3552
3553 for (int i = 0; i < worklist_length(&queue); i++) {
3554 struct universal target = queue.entries[i];
3555
3556 tooltip = "";
3557
3558 if (VUT_UTYPE == target.kind) {
3561 tooltip = get_tooltip_unit(target.value.utype, true).trimmed();
3565 } else {
3569 dlgcity, true).trimmed();
3570
3572 cost = -1;
3573 } else {
3575 }
3576 }
3577
3578 for (col = 0; col < 3; col++) {
3579 qitem = new QTableWidgetItem();
3580 qitem->setToolTip(tooltip);
3581
3582 switch (col) {
3583 case 0:
3584 if (sprite) {
3585 pix = sprite->pm;
3586 pix_scaled = pix->scaledToHeight(h);
3587 qitem->setData(Qt::DecorationRole, pix_scaled);
3588 }
3589 break;
3590
3591 case 1:
3592 if (str.contains('[') && str.contains(']')) {
3593 int ii, ij;
3594
3595 ii = str.lastIndexOf('[');
3596 ij = str.lastIndexOf(']');
3597 if (ij > ii) {
3598 str = str.remove(ii, ij - ii + 1);
3599 }
3600 }
3601 qitem->setText(str);
3602 break;
3603
3604 case 2:
3605 qitem->setTextAlignment(Qt::AlignRight);
3606 qitem->setText(QString::number(cost));
3607 break;
3608 }
3609 p_table_p->setItem(i, col, qitem);
3610 }
3611 }
3612
3613 p_table_p->horizontalHeader()->setStretchLastSection(false);
3614 p_table_p->resizeColumnsToContents();
3615 p_table_p->resizeRowsToContents();
3616 p_table_p->horizontalHeader()->setStretchLastSection(true);
3617
3619 city_buildings->setUpdatesEnabled(true);
3620 city_buildings->setUpdatesEnabled(true);
3621
3622 curr_impr->setText(QString(_("Improvements - upkeep %1")).arg(upkeep));
3623}
3624
3625/************************************************************************/
3629{
3630 cid id;
3631 QVariant qvar;
3632
3634 struct universal univ;
3635
3636 id = qvar.toInt();
3637 univ = cid_production(id);
3639 }
3640}
3641
3642/************************************************************************/
3647{
3649 int when = 1;
3650
3651 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3652 when, selected_row_p, show_units->isChecked(),
3653 false, show_wonders->isChecked(),
3654 show_buildings->isChecked());
3655 pw->show();
3656}
3657
3658/************************************************************************/
3663{
3665 int when = 4;
3666
3667 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3668 when, selected_row_p, show_units->isChecked(),
3669 false, show_wonders->isChecked(),
3670 show_buildings->isChecked());
3671 pw->show();
3672}
3673
3674/************************************************************************/
3678{
3679 struct worklist empty;
3680
3681 if (!can_client_issue_orders()) {
3682 return;
3683 }
3684
3687}
3688
3689/************************************************************************/
3693{
3694 QModelIndex index;
3695 struct worklist queue;
3696 struct universal *target;
3697
3699 return;
3700 }
3701
3702 target = new universal;
3703 city_get_queue(dlgcity, &queue);
3704 worklist_peek_ith(&queue, target, selected_row_p);
3706 worklist_insert(&queue, target, selected_row_p - 1);
3707 city_set_queue(dlgcity, &queue);
3708 index = p_table_p->model()->index(selected_row_p - 1, 0);
3709 p_table_p->setCurrentIndex(index);
3710 delete target;
3711
3712}
3713
3714/************************************************************************/
3718{
3720
3721 if (selected_row_p < 0
3722 || selected_row_p >= p_table_p->rowCount()) {
3723 return;
3724 }
3725
3729}
3730
3731/************************************************************************/
3735{
3736 QModelIndex index;
3737 struct worklist queue;
3738 struct universal *target;
3739
3741 return;
3742 }
3743
3744 target = new universal;
3745 city_get_queue(dlgcity, &queue);
3746 worklist_peek_ith(&queue, target, selected_row_p);
3748 worklist_insert(&queue, target, selected_row_p + 1);
3749 city_set_queue(dlgcity, &queue);
3750 index = p_table_p->model()->index(selected_row_p + 1, 0);
3751 p_table_p->setCurrentIndex(index);
3752 delete target;
3753}
3754
3755/************************************************************************/
3759{
3760 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
3761 int city_id = dlgcity->id;
3762
3763 ask->set_text_title_definput(_("What should we name new worklist?"),
3764 _("Save current worklist"),
3765 _("New worklist"));
3766 ask->setAttribute(Qt::WA_DeleteOnClose);
3767 connect(ask, &hud_message_box::accepted, [=]() {
3768 struct global_worklist *gw;
3769 struct worklist queue;
3771 QString text;
3772 struct city *pcity = game_city_by_number(city_id);
3773
3774 ask_bytes = ask->input_edit.text().toUtf8();
3775 text = ask_bytes.data();
3776 if (!text.isEmpty()) {
3777 ask_bytes = text.toUtf8();
3779 city_get_queue(pcity, &queue);
3780 global_worklist_set(gw, &queue);
3781 }
3782 });
3783 ask->show();
3784}
3785
3786/************************************************************************/
3790{
3791 QString buf;
3792
3793 // Defeat keyboard shortcut mnemonics
3795 .replace("&", "&&"));
3796
3797 if (city_unhappy(dlgcity)) {
3798 // TRANS: city dialog title
3799 buf = QString(_("%1 - %2 citizens - DISORDER")).arg(city_name_get(dlgcity),
3801 } else if (city_celebrating(dlgcity)) {
3802 // TRANS: city dialog title
3803 buf = QString(_("%1 - %2 citizens - celebrating")).arg(city_name_get(dlgcity),
3805 } else if (city_happy(dlgcity)) {
3806 // TRANS: city dialog title
3807 buf = QString(_("%1 - %2 citizens - happy")).arg(city_name_get(dlgcity),
3809 } else {
3810 // TRANS: city dialog title
3811 buf = QString(_("%1 - %2 citizens")).arg(city_name_get(dlgcity),
3813 }
3814
3816}
3817
3818/************************************************************************/
3823{
3824 if (!::city_dlg_created) {
3825 ::city_dlg = new city_dialog(gui()->mapview_wdg);
3826 }
3827
3828 city_dlg->setup_ui(pcity);
3829 city_dlg->show();
3830 city_dlg->activateWindow();
3831 city_dlg->raise();
3832}
3833
3834/************************************************************************/
3838{
3839 if (!::city_dlg_created) {
3840 return;
3841 }
3842
3843 city_dlg->close();
3844 ::city_dlg_created = false;
3845}
3846
3847/************************************************************************/
3851{
3852 if (!::city_dlg_created) {
3853 return;
3854 }
3855
3857}
3858
3859/************************************************************************/
3866
3867/************************************************************************/
3871{
3872 if (!::city_dlg_created) {
3873 return;
3874 }
3875
3876 if (qtg_city_dialog_is_open(pcity)) {
3877 city_dlg->refresh();
3878 }
3879}
3880
3881/************************************************************************/
3885{
3887 QFont *f;
3888
3889 if (!::city_dlg_created) {
3890 return;
3891 }
3892
3893 l = city_dlg->findChildren<QLabel *>();
3894
3896
3897 for (int i = 0; i < l.size(); ++i) {
3898 if (l.at(i)->property(fonts::notify_label).isValid()) {
3899 l.at(i)->setFont(*f);
3900 }
3901 }
3902}
3903
3904/************************************************************************/
3921
3922/************************************************************************/
3926{
3927 if (!::city_dlg_created) {
3928 return false;
3929 }
3930
3931 if (city_dlg->dlgcity == pcity && city_dlg->isVisible()) {
3932 return true;
3933 }
3934
3935 return false;
3936}
3937
3938/************************************************************************/
3941bool fc_tooltip::eventFilter(QObject *obj, QEvent *ev)
3942{
3945 QRect rect;
3946
3947 if (ev->type() == QEvent::ToolTip) {
3949
3950 if (!view) {
3951 return false;
3952 }
3953
3954 help_event = static_cast<QHelpEvent *>(ev);
3955 QPoint pos = help_event->pos();
3956 QModelIndex index = view->indexAt(pos);
3957 QPoint hpos;
3958
3959 if (!index.isValid()) {
3960 return false;
3961 }
3962
3963 item_tooltip = view->model()->data(index, Qt::ToolTipRole).toString();
3964 rect = view->visualRect(index);
3965
3966 hpos = help_event->globalPos();
3967
3968 rect.setX(rect.x() + hpos.x());
3969 rect.setY(rect.y() + hpos.y());
3970
3971 if (!item_tooltip.isEmpty()) {
3972 QToolTip::showText(help_event->globalPos(), item_tooltip, view, rect);
3973 } else {
3974 QToolTip::hideText();
3975 }
3976
3977 return true;
3978 }
3979
3980 return false;
3981}
3982
3983/************************************************************************/
3987{
3988 return QString("<b>" + text + "</b>");
3989}
3990
3991/************************************************************************/
3995QString get_tooltip_improvement(const impr_type *building, struct city *pcity,
3996 bool ext)
3997{
3999 QString upkeep;
4000 QString s1, s2, str;
4001 const char *req = skip_intl_qualifier_prefix(_("?tech:None"));
4002
4003 if (pcity != nullptr) {
4004 upkeep = QString::number(city_improvement_upkeep(pcity, building));
4005 } else {
4006 upkeep = QString::number(building->upkeep);
4007 }
4009 if (pobs->source.kind == VUT_ADVANCE) {
4010 req = advance_name_translation(pobs->source.value.advance);
4011 break;
4012 }
4014 s2 = QString(req);
4015 str = _("Obsolete by:");
4016 str = str + " " + s2;
4017 def_str = "<p style='white-space:pre'><b>"
4018 + QString(improvement_name_translation(building)).toHtmlEscaped()
4019 + "</b>\n";
4020 if (pcity != nullptr) {
4021 def_str += QString(_("Cost: %1, Upkeep: %2\n"))
4022 .arg(impr_build_shield_cost(pcity, building))
4023 .arg(upkeep).toHtmlEscaped();
4024 } else {
4026
4027 def_str += QString(_("Cost Estimate: %1, Upkeep: %2\n"))
4028 .arg(cost_est)
4029 .arg(upkeep).toHtmlEscaped();
4030 }
4031 if (s1.compare(s2) != 0) {
4032 def_str = def_str + str.toHtmlEscaped() + "\n";
4033 }
4034 def_str = def_str + "\n";
4035 if (ext) {
4036 char buffer[8192];
4037
4038 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
4039 NULL, building);
4040 str = cut_helptext(str);
4041 str = split_text(str, true);
4042 str = str.trimmed();
4043 def_str = def_str + str.toHtmlEscaped();
4044 }
4045 return def_str;
4046}
4047
4048/************************************************************************/
4052QString get_tooltip_unit(const struct unit_type *utype, bool ext)
4053{
4056 QString str;
4057 const struct unit_type *obsolete;
4058 struct advance *tech;
4059
4060 def_str = "<b>"
4061 + QString(utype_name_translation(utype)).toHtmlEscaped()
4062 + "</b>\n";
4063 obsolete = utype->obsoleted_by;
4064 if (obsolete) {
4065 // FIXME: Don't give the impression that primary tech is (always) the only one.
4067 obsolete_str = QString("</td></tr><tr><td colspan=\"3\">");
4068 if (tech && tech != advance_by_number(A_NONE)) {
4069 /* TRANS: this and nearby literal strings are interpreted
4070 * as (Qt) HTML */
4071 obsolete_str = obsolete_str + QString(_("Obsoleted by %1 (%2)."))
4073 .arg(advance_name_translation(tech)).toHtmlEscaped();
4074 } else {
4075 obsolete_str = obsolete_str + QString(_("Obsoleted by %1."))
4076 .arg(utype_name_translation(obsolete)).toHtmlEscaped();
4077 }
4078 }
4079 def_str += "<table width=\"100\%\"><tr><td>"
4080 + bold(QString(_("Attack:"))) + " "
4081 + QString::number(utype->attack_strength).toHtmlEscaped()
4082 + QString("</td><td>") + bold(QString(_("Defense:"))) + " "
4083 + QString::number(utype->defense_strength).toHtmlEscaped()
4084 + QString("</td><td>") + bold(QString(_("Move:"))) + " "
4085 + QString(move_points_text(utype->move_rate, TRUE)).toHtmlEscaped()
4086 + QString("</td></tr><tr><td>")
4087 + bold(QString(_("Cost:"))) + " "
4088 + QString::number(utype_build_shield_cost_base(utype))
4089 .toHtmlEscaped()
4090 + QString("</td><td colspan=\"2\">")
4091 + bold(QString(_("Basic Upkeep:")))
4092 + " " + QString(helptext_unit_upkeep_str(utype)).toHtmlEscaped()
4093 + QString("</td></tr><tr><td>")
4094 + bold(QString(_("Hitpoints:"))) + " "
4095 + QString::number(utype->hp).toHtmlEscaped()
4096 + QString("</td><td>") + bold(QString(_("Firepower:"))) + " "
4097 + QString::number(utype->firepower).toHtmlEscaped()
4098 + QString("</td><td>") + bold(QString(_("Vision:"))) + " "
4099 + QString::number((int) sqrt((double) utype->vision_radius_sq))
4100 .toHtmlEscaped()
4101 + obsolete_str
4102 + QString("</td></tr></table><p style='white-space:pre'>");
4103 if (ext) {
4104 char buffer[8192];
4105 char buf2[1];
4106
4107 buf2[0] = '\0';
4108 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
4109 buf2, utype, TRUE);
4110 str = cut_helptext(str);
4111 str = split_text(str, true);
4112 str = str.trimmed().toHtmlEscaped();
4113 def_str = def_str + str;
4114 }
4115
4116 return def_str;
4117};
4118
4119/************************************************************************/
4123{
4126 char buffer[8192];
4127 char buf2[1];
4128 struct universal *target;
4129
4130 buf2[0] = '\0';
4131 target = reinterpret_cast<universal *>(qvar.value<void *>());
4132
4133 if (target == NULL) {
4134 } else if (VUT_UTYPE == target->kind) {
4136 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
4137 buf2, target->value.utype, TRUE);
4138 } else {
4139 if (!is_convert_improvement(target->value.building)) {
4141 }
4142
4143 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
4144 NULL, target->value.building);
4145 }
4146
4147 // Remove all lines from help which has '*' in first 3 chars
4149 ret_str = split_text(ret_str, true);
4150 ret_str = ret_str.trimmed();
4151 ret_str = def_str + ret_str.toHtmlEscaped();
4152
4153 return ret_str;
4154}
4155
4156/************************************************************************/
4160 QObject *parent,
4161 struct city *city)
4162 : QItemDelegate(parent)
4163{
4164 pd = sh;
4165 item_height = sh.y();
4166 pcity = city;
4167}
4168
4169/************************************************************************/
4174 const QModelIndex &index) const
4175{
4176 struct universal *target;
4177 QString name;
4178 QVariant qvar;
4179 QPixmap *pix;
4181 QRect rect1;
4182 QRect rect2;
4183 struct sprite *sprite;
4184 bool useless = false;
4185 bool is_coinage = false;
4186 bool is_neutral = false;
4187 bool is_sea = false;
4188 bool is_flying = false;
4189 bool is_unit = true;
4190 QPixmap pix_dec(option.rect.width(), option.rect.height());
4192 color col;
4193 QIcon icon = current_app()->style()->standardIcon(QStyle::SP_DialogCancelButton);
4194 bool free_sprite = false;
4195 struct unit_class *pclass;
4196
4197 if (!option.rect.isValid()) {
4198 return;
4199 }
4200
4201 qvar = index.data();
4202
4203 if (!qvar.isValid()) {
4204 return;
4205 }
4206
4207 target = reinterpret_cast<universal *>(qvar.value<void *>());
4208
4209 if (target == NULL) {
4210 col.qcolor = Qt::white;
4211 sprite = qtg_create_sprite(100, 100, &col);
4212 free_sprite = true;
4213 *sprite->pm = icon.pixmap(100, 100);
4214 name = _("Cancel");
4215 is_unit = false;
4216 } else if (VUT_UTYPE == target->kind) {
4219 pclass = utype_class(target->value.utype);
4223 is_sea = true;
4224 }
4225
4226 if ((utype_fuel(target->value.utype)
4231 /* FIXME: Assumed to be flying since only missiles can do suicide
4232 * attacks in classic-like rulesets. This isn't true for all
4233 * rulesets. Not a high priority to fix since all is_flying and
4234 * is_sea is used for is to set a color. */
4236 target->value.utype)) {
4237 if (is_sea) {
4238 is_sea = false;
4239 }
4240 is_flying = true;
4241 }
4242
4246 } else {
4247 is_unit = false;
4252 }
4253
4254 if (sprite != NULL) {
4255 pix = sprite->pm;
4256 pix_scaled = pix->scaledToHeight(item_height - 2, Qt::SmoothTransformation);
4257
4258 if (useless) {
4260 }
4261 }
4262
4263 opt = QItemDelegate::setOptions(index, option);
4264 painter->save();
4265 opt.displayAlignment = Qt::AlignLeft;
4266 opt.textElideMode = Qt::ElideMiddle;
4267 QItemDelegate::drawBackground(painter, opt, index);
4268 rect1 = option.rect;
4269 rect1.setWidth(pix_scaled.width() + 4);
4270 rect2 = option.rect;
4271 rect2.setLeft(option.rect.left() + rect1.width());
4272 rect2.setTop(rect2.top() + (rect2.height()
4273 - painter->fontMetrics().height()) / 2);
4274 QItemDelegate::drawDisplay(painter, opt, rect2, name);
4275
4276 if (is_unit) {
4277 if (is_sea) {
4278 pix_dec.fill(QColor(0, 0, 255, 80));
4279 } else if (is_flying) {
4280 pix_dec.fill(QColor(220, 0, 0, 80));
4281 } else if (is_neutral) {
4282 pix_dec.fill(QColor(0, 120, 0, 40));
4283 } else {
4284 pix_dec.fill(QColor(0, 0, 150, 40));
4285 }
4286
4287 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4288 }
4289
4290 if (is_coinage) {
4291 pix_dec.fill(QColor(255, 255, 0, 70));
4292 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4293 }
4294
4295 if (!pix_scaled.isNull()) {
4296 QItemDelegate::drawDecoration(painter, opt, rect1, pix_scaled);
4297 }
4298
4299 drawFocus(painter, opt, option.rect);
4300
4301 painter->restore();
4302
4303 if (free_sprite) {
4305 }
4306}
4307
4308/************************************************************************/
4313 const QRect &rect) const
4314{
4315 QPixmap pix(option.rect.width(), option.rect.height());
4316
4317 if ((option.state & QStyle::State_MouseOver) == 0 || !rect.isValid()) {
4318 return;
4319 }
4320
4321 pix.fill(QColor(50, 50, 50, 50));
4322 QItemDelegate::drawDecoration(painter, option, option.rect, pix);
4323}
4324
4325/************************************************************************/
4329 const QModelIndex &index) const
4330{
4331 QSize s;
4332
4333 s.setWidth(pd.x());
4334 s.setHeight(pd.y());
4335 return s;
4336}
4337
4338/************************************************************************/
4342 QObject *parent): QObject()
4343{
4345 target = ptarget;
4346}
4347
4348/************************************************************************/
4352{
4353 // Allocated as renegade in model
4354 if (target != NULL) {
4355 delete target;
4356 }
4357}
4358
4359/************************************************************************/
4363{
4364 return QVariant::fromValue((void *)target);
4365}
4366
4367/************************************************************************/
4371{
4372 return false;
4373}
4374
4375/************************************************************************/
4379 bool su, bool sw, bool sb,
4380 QObject *parent)
4381 : QAbstractListModel(parent)
4382{
4383 show_units = su;
4384 show_wonders = sw;
4386 mcity = pcity;
4387 future_t = f;
4388 populate();
4389}
4390
4391/************************************************************************/
4399
4400/************************************************************************/
4404{
4405 if (!index.isValid()) {
4406 return QVariant();
4407 }
4408
4409 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4410 && index.column() < columnCount()
4411 && (index.column() + index.row() * 3 < city_target_list.count())) {
4412 int r, c, t, new_index;
4413
4414 r = index.row();
4415 c = index.column();
4416 t = r * 3 + c;
4417 new_index = t / 3 + rowCount() * c;
4418 // Exception, shift whole column
4419 if ((c == 2) && city_target_list.count() % 3 == 1) {
4420 new_index = t / 3 + rowCount() * c - 1;
4421 }
4422 if (role == Qt::ToolTipRole) {
4424 }
4425
4426 return city_target_list[new_index]->data();
4427 }
4428
4429 return QVariant();
4430}
4431
4432/************************************************************************/
4436{
4438 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
4439 struct item items[MAX_NUM_PRODUCTION_TARGETS];
4440 struct universal *renegade;
4441 int item, targets_used;
4442 QString str;
4444 QFontMetrics fm(f);
4445
4446 sh.setY(fm.height() * 2);
4447 sh.setX(0);
4448
4450 city_target_list.clear();
4451
4453 future_t);
4454 name_and_sort_items(targets, targets_used, items, false, mcity);
4455
4456 for (item = 0; item < targets_used; item++) {
4457 if (future_t || can_city_build_now(&(wld.map), mcity, &items[item].item)) {
4458 renegade = new universal(items[item].item);
4459
4460 // Renegade deleted in production_item destructor
4461 if (VUT_UTYPE == renegade->kind) {
4462 str = utype_name_translation(renegade->value.utype);
4463 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4464
4465 if (show_units) {
4466 pi = new production_item(renegade, this);
4468 } else {
4469 delete renegade;
4470 }
4471 } else {
4472 str = improvement_name_translation(renegade->value.building);
4473 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4474
4475 if ((is_wonder(renegade->value.building) && show_wonders)
4476 || (is_improvement(renegade->value.building) && show_buildings)
4477 || (is_convert_improvement(renegade->value.building))
4478 || (is_special_improvement(renegade->value.building)
4479 && show_buildings)) {
4480 pi = new production_item(renegade, this);
4482 } else {
4483 delete renegade;
4484 }
4485 }
4486 }
4487 }
4488
4489 pi = new production_item(nullptr, this);
4491 sh.setX(2 * sh.y() + sh.x());
4492 sh.setX(qMin(sh.x(), 250));
4493}
4494
4495/************************************************************************/
4499 const QVariant &value, int role)
4500{
4501 if (!index.isValid() || role != Qt::DisplayRole || role != Qt::ToolTipRole)
4502 return false;
4503
4504 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4505 && index.column() < columnCount()) {
4506 bool change = city_target_list[index.row()]->setData();
4507 return change;
4508 }
4509
4510 return false;
4511}
4512
4513/************************************************************************/
4522 bool future, int when, int curr,
4523 bool show_units, bool buy,
4524 bool show_wonders,
4525 bool show_buildings): QTableView()
4526{
4527 QPoint pos, sh;
4528 QRect rect = QApplication::primaryScreen()->availableGeometry();
4529 int desk_width = rect.width();
4530 int desk_height = rect.height();
4531 fc_tt = new fc_tooltip(this);
4532 setAttribute(Qt::WA_DeleteOnClose);
4533 setWindowFlags(Qt::Popup);
4534 verticalHeader()->setVisible(false);
4535 horizontalHeader()->setVisible(false);
4536 setProperty("showGrid", false);
4538 sh_units = show_units;
4539 pw_city = pcity;
4540 buy_it = buy;
4541 when_change = when;
4542 list_model = new city_production_model(pw_city, future, show_units,
4543 show_wonders, show_buildings, this);
4544 sh = list_model->sh;
4545 c_p_d = new city_production_delegate(sh, this, pw_city);
4548 viewport()->installEventFilter(fc_tt);
4549 installEventFilter(this);
4551 const QItemSelection &)),
4553 const QItemSelection &)));
4556 setFixedWidth(3 * sh.x() + 6);
4557 setFixedHeight(list_model->rowCount()*sh.y() + 6);
4558
4559 if (width() > desk_width) {
4561 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4562 } else {
4563 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4564 }
4565
4566 if (height() > desk_height) {
4568 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4569 } else {
4570 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4571 }
4572
4573 pos = QCursor::pos();
4574
4575 if (pos.x() + width() > desk_width) {
4576 pos.setX(desk_width - width());
4577 } else if (pos.x() - width() < 0) {
4578 pos.setX(0);
4579 }
4580
4581 if (pos.y() + height() > desk_height) {
4582 pos.setY(desk_height - height());
4583 } else if (pos.y() - height() < 0) {
4584 pos.setY(0);
4585 }
4586
4587 move(pos);
4588 setMouseTracking(true);
4589 setFocus();
4590}
4591
4592/************************************************************************/
4596{
4597 if (event->button() == Qt::RightButton) {
4598 close();
4599 return;
4600 }
4601
4602 QAbstractItemView::mousePressEvent(event);
4603}
4604
4605/************************************************************************/
4609{
4610 QRect pw_rect;
4611 QPoint br;
4612
4613 if (obj != this)
4614 return false;
4615
4616 if (ev->type() == QEvent::MouseButtonPress) {
4617 pw_rect.setTopLeft(pos());
4618 br.setX(pos().x() + width());
4619 br.setY(pos().y() + height());
4620 pw_rect.setBottomRight(br);
4621
4622 if (!pw_rect.contains(QCursor::pos())) {
4623 close();
4624 }
4625 }
4626
4627 return false;
4628}
4629
4630/************************************************************************/
4634 const QItemSelection &ds)
4635{
4636 QModelIndexList indexes = selectionModel()->selectedIndexes();
4637 QModelIndex index;
4638 QVariant qvar;
4639 struct worklist queue;
4640 struct universal *target;
4641
4642 if (indexes.isEmpty() || client_is_observer()) {
4643 return;
4644 }
4645 index = indexes.at(0);
4646 qvar = index.data(Qt::UserRole);
4647 if (!qvar.isValid()) {
4648 return;
4649 }
4650 target = reinterpret_cast<universal *>(qvar.value<void *>());
4651 if (target != NULL) {
4652 city_get_queue(pw_city, &queue);
4653 switch (when_change) {
4654 case 0: // Change current target
4656 if (city_can_buy(pw_city) && buy_it) {
4658 }
4659 break;
4660
4661 case 1: // Change current (selected on list)
4664 } else {
4666 worklist_insert(&queue, target, curr_selection);
4667 city_set_queue(pw_city, &queue);
4668 }
4669 break;
4670
4671 case 2: // Insert before
4673 curr_selection = 0;
4674 }
4677 worklist_insert(&queue, target, curr_selection);
4678 city_set_queue(pw_city, &queue);
4679 break;
4680
4681 case 3: // Insert after
4683 city_queue_insert(pw_city, -1, target);
4684 break;
4685 }
4687 worklist_insert(&queue, target, curr_selection);
4688 city_set_queue(pw_city, &queue);
4689 break;
4690
4691 case 4: // Add last
4692 city_queue_insert(pw_city, -1, target);
4693 break;
4694
4695 default:
4696 break;
4697 }
4698 }
4699 close();
4700 destroy();
4701}
4702
4703/************************************************************************/
4707{
4708 delete c_p_d;
4709 delete list_model;
4710 viewport()->removeEventFilter(fc_tt);
4711 removeEventFilter(this);
4712}
const char * action_id_name_translation(action_id act_id)
Definition actions.c:2011
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:945
#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:2132
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:1137
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Definition city.c:1255
bool is_city_option_set(const struct city *pcity, enum city_options option)
Definition city.c:3388
int city_population(const struct city *pcity)
Definition city.c:1191
int city_unit_unhappiness(const struct civ_map *nmap, struct unit *punit, int *free_unhappy)
Definition city.c:3049
bool city_unhappy(const struct city *pcity)
Definition city.c:1626
bool city_celebrating(const struct city *pcity)
Definition city.c:1645
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2870
bool city_happy(const struct city *pcity)
Definition city.c:1614
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:3317
bool can_city_build_now(const struct civ_map *nmap, const struct city *pcity, const struct universal *target)
Definition city.c:1013
int city_turns_to_grow(const struct city *pcity)
Definition city.c:1996
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:3850
void qtg_real_city_dialog_refresh(struct city *pcity)
Definition citydlg.cpp:3870
QString split_text(QString text, bool cut)
Definition optiondlg.cpp:62
void city_font_update()
Definition citydlg.cpp:3884
bool qtg_city_dialog_is_open(struct city *pcity)
Definition citydlg.cpp:3925
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4122
void qtg_popdown_all_city_dialogs()
Definition citydlg.cpp:3862
static city_dialog * city_dlg
Definition citydlg.cpp:75
void qtg_refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.cpp:3909
static QString bold(QString text)
Definition citydlg.cpp:3986
void qtg_real_city_dialog_popup(struct city *pcity)
Definition citydlg.cpp:3822
QString get_tooltip_improvement(const impr_type *building, struct city *pcity, bool ext)
Definition citydlg.cpp:3995
static bool city_dlg_created
Definition citydlg.cpp:71
static void pixmap_put_x(QPixmap *pix)
Definition citydlg.cpp:350
QString cut_helptext(QString text)
QString get_tooltip_unit(const struct unit_type *utype, bool ext)
Definition citydlg.cpp:4052
void destroy_city_dialog()
Definition citydlg.cpp:3837
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)
city_label(int type, QWidget *parent=0)
Definition citydlg.cpp:1187
void set_city(struct city *pcity)
Definition citydlg.cpp:1219
struct city * pcity
Definition citydlg.h:427
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1195
int wdth
Definition citydlg.h:288
int cutted_height
Definition citydlg.h:291
QSize sizeHint() const
Definition citydlg.cpp:1318
void paintEvent(QPaintEvent *event)
Definition citydlg.cpp:1258
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1334
int height
Definition citydlg.h:289
void set_pixmap(struct city *pcity, float z)
Definition citydlg.cpp:1282
void context_menu(QPoint point)
Definition citydlg.cpp:1356
canvas * miniview
Definition citydlg.h:275
struct city * mcity
Definition citydlg.h:285
QSize minimumSizeHint() const
Definition citydlg.cpp:1326
float zoom
Definition citydlg.h:287
QPixmap zoomed_pixmap
Definition citydlg.h:276
city_map(QWidget *parent)
Definition citydlg.cpp:1227
int cutted_width
Definition citydlg.h:290
int radius
Definition citydlg.h:286
int delta_y
Definition citydlg.h:293
int delta_x
Definition citydlg.h:292
city_production_delegate(QPoint sh, QObject *parent, struct city *city)
Definition citydlg.cpp:4159
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4172
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4328
struct city * pcity
Definition citydlg.h:319
void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
Definition citydlg.cpp:4311
int rowCount(const QModelIndex &index=QModelIndex()) const
Definition citydlg.h:357
city_production_model(struct city *pcity, bool f, bool su, bool sw, bool sb, QObject *parent=0)
Definition citydlg.cpp:4378
QList< production_item * > city_target_list
Definition citydlg.h:373
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole)
Definition citydlg.cpp:4498
int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition citydlg.h:361
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition citydlg.cpp:4403
struct city * mcity
Definition citydlg.h:374
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:3941
void update_buildings()
Definition citydlg.cpp:561
QHBoxLayout * layout
Definition citydlg.h:261
void add_item(impr_item *item)
Definition citydlg.cpp:503
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:536
impr_info(QWidget *parent)
Definition citydlg.cpp:472
void clear_layout()
Definition citydlg.cpp:511
void init_layout()
Definition citydlg.cpp:482
QList< impr_item * > impr_list
Definition citydlg.h:262
void mouseDoubleClickEvent(QMouseEvent *event)
Definition citydlg.cpp:619
impr_item(QWidget *parent, const struct impr_type *building, struct city *pcity)
Definition citydlg.cpp:367
void init_pix()
Definition citydlg.cpp:406
void enterEvent(QEnterEvent *event)
Definition citydlg.cpp:416
struct canvas * impr_pixmap
Definition citydlg.h:233
struct city * dlgcity
Definition citydlg.h:234
const struct impr_type * impr
Definition citydlg.h:232
void leaveEvent(QEvent *event)
Definition citydlg.cpp:446
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:593
struct universal * target
Definition citydlg.h:343
QVariant data() const
Definition citydlg.cpp:4362
production_item(struct universal *ptarget, QObject *parent)
Definition citydlg.cpp:4341
bool eventFilter(QObject *obj, QEvent *ev)
Definition citydlg.cpp:4608
void prod_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:4633
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:4595
city_production_model * list_model
Definition citydlg.h:388
struct city * pw_city
Definition citydlg.h:405
fc_tooltip * fc_tt
Definition citydlg.h:410
city_production_delegate * c_p_d
Definition citydlg.h:389
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:4521
progress_bar(QWidget *parent)
Definition citydlg.cpp:82
void paintEvent(QPaintEvent *event)
Definition citydlg.cpp:188
int m_animate_step
Definition citydlg.h:133
void resizeEvent(QResizeEvent *event)
Definition citydlg.cpp:106
QRegion reg
Definition citydlg.h:135
void set_pixmap(struct universal *target)
Definition citydlg.cpp:114
void create_region()
Definition citydlg.cpp:326
QElapsedTimer m_timer
Definition citydlg.h:114
void timerEvent(QTimerEvent *event)
Definition citydlg.cpp:176
QPixmap * pix
Definition citydlg.h:134
QFont * sfont
Definition citydlg.h:136
void clicked()
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:1095
void init_layout()
Definition citydlg.cpp:1083
unit_info(bool supp)
Definition citydlg.cpp:1056
void add_item(unit_item *item)
Definition citydlg.cpp:1075
QHBoxLayout * layout
Definition citydlg.h:209
void update_units()
Definition citydlg.cpp:1120
void clear_layout()
Definition citydlg.cpp:1161
QList< unit_item * > unit_list
Definition citydlg.h:210
bool supports
Definition citydlg.h:213
QAction * activate
Definition citydlg.h:147
QAction * disband_action
Definition citydlg.h:145
void enterEvent(QEnterEvent *event)
Definition citydlg.cpp:978
void contextMenuEvent(QContextMenuEvent *ev)
Definition citydlg.cpp:750
QAction * sentry
Definition citydlg.h:149
struct unit * qunit
Definition citydlg.h:164
QAction * activate_and_close
Definition citydlg.h:148
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1033
int happy_cost
Definition citydlg.h:168
void change_homecity()
Definition citydlg.cpp:936
QAction * unload
Definition citydlg.h:152
QAction * upgrade
Definition citydlg.h:153
bool supported
Definition citydlg.h:169
void fortify_unit()
Definition citydlg.cpp:967
void sentry_unit()
Definition citydlg.cpp:1046
QAction * unload_trans
Definition citydlg.h:154
void load_unit()
Definition citydlg.cpp:900
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:1007
QAction * load
Definition citydlg.h:151
void activate_unit()
Definition citydlg.cpp:957
QAction * change_home
Definition citydlg.h:146
QAction * fortify
Definition citydlg.h:150
QImage unit_img
Definition citydlg.h:165
void create_actions()
Definition citydlg.cpp:804
void unload_all()
Definition citydlg.cpp:916
void disband()
Definition citydlg.cpp:882
void upgrade_unit()
Definition citydlg.cpp:924
void init_pix()
Definition citydlg.cpp:734
void leaveEvent(QEvent *event)
Definition citydlg.cpp:999
unit_item(QWidget *parent, struct unit *punit, bool supp=false, int happy_cost=0)
Definition citydlg.cpp:663
void unload_unit()
Definition citydlg.cpp:908
void activate_and_close_dialog()
Definition citydlg.cpp:946
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:818
void name_and_sort_items(struct universal *targets, int num_targets, struct item *items, bool show_cost, struct city *pcity)
Definition climisc.c:649
cid cid_encode(struct universal target)
Definition climisc.c:482
int collect_already_built_targets(struct universal *targets, struct city *pcity)
Definition climisc.c:912
struct universal cid_decode(cid id)
Definition climisc.c:525
#define MAX_NUM_PRODUCTION_TARGETS
Definition climisc.h:89
#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:2174
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:552
void cma_put_city_under_agent(struct city *pcity, const struct cm_parameter *const parameter)
Definition cma_core.c:524
void cma_release_city(struct city *pcity)
Definition cma_core.c:542
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:75
void request_unit_fortify(struct unit *punit)
Definition control.c:2353
struct unit * request_unit_unload_all(struct unit *punit)
Definition control.c:1511
void unit_focus_set(struct unit *punit)
Definition control.c:506
void request_unit_change_homecity(struct unit *punit)
Definition control.c:2094
void request_unit_unload(struct unit *pcargo)
Definition control.c:2194
void request_unit_sentry(struct unit *punit)
Definition control.c:2342
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:41
int counter_index(const struct counter *pcount)
Definition counters.c:174
#define city_counters_iterate_end
Definition counters.h:64
#define city_counters_iterate(pcount)
Definition counters.h:57
bool qtg_request_transport(struct unit *pcargo, struct tile *ptile)
Definition dialogs.cpp:4874
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:846
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:765
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:790
enum extra_cause activity_to_extra_cause(enum unit_activity act)
Definition extras.c:1076
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
Definition extras.c:1097
#define extra_index(_e_)
Definition extras.h:183
unsigned char citizens
Definition fc_types.h:388
#define EC_NONE
Definition fc_types.h:1113
@ TR_SUCCESS
Definition fc_types.h:1246
#define ERM_NONE
Definition fc_types.h:1136
@ 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:734
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct city * game_city_by_number(int id)
Definition game.c:107
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:3995
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4122
void set_theme_style()
Definition themes.cpp:107
#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:229
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype, bool class_help)
Definition helpdata.c:1992
char * helptext_unit_upkeep_str(const struct unit_type *utype)
Definition helpdata.c:5062
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1439
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:1047
static mpgui * gui
Definition mpgui_qt.cpp:52
static const char * name_translation_get(const struct name_translation *ptrans)
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, enum city_wl_cancel_behavior wl_cb)
const char * text_happiness_cities(const struct city *pcity)
Definition text.c:1906
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
#define strvec_iterate(psv, str)
#define strvec_iterate_end
QPixmap map_pixmap
Definition canvas.h:25
void setup_ui(struct city *qcity)
Definition citydlg.cpp:3264
int current_building
Definition citydlg.h:513
void worklist_up()
Definition citydlg.cpp:3692
struct city_dialog::@144 happiness
city_label * citizens_label
Definition citydlg.h:456
QPushButton * lcity_name
Definition citydlg.h:499
void show_happiness()
Definition citydlg.cpp:2140
void closeEvent(QCloseEvent *event)
Definition citydlg.cpp:2335
void show_counters()
Definition citydlg.cpp:2175
void update_nation_table()
Definition citydlg.cpp:3066
void hideEvent(QHideEvent *event)
Definition citydlg.cpp:2307
QPushButton * work_next_but
Definition citydlg.h:487
void next_city()
Definition citydlg.cpp:3373
progress_bar * production_combo_p
Definition citydlg.h:471
QTableWidget * nationality_table
Definition citydlg.h:473
QRadioButton * r3
Definition citydlg.h:481
QTableWidget * cma_table
Definition citydlg.h:474
void showEvent(QShowEvent *event)
Definition citydlg.cpp:2318
QPushButton * happiness_button
Definition citydlg.h:491
void cma_double_clicked(int row, int column)
Definition citydlg.cpp:2511
void display_worklist_menu(const QPoint &p)
Definition citydlg.cpp:2783
void update_disabled()
Definition citydlg.cpp:2210
QLabel * supp_units
Definition citydlg.h:468
QPushButton * next_city_but
Definition citydlg.h:485
QLabel * qlt[NUM_INFO_FIELDS]
Definition citydlg.h:464
QPushButton * work_prev_but
Definition citydlg.h:488
QHBoxLayout * single_page_layout
Definition citydlg.h:445
void update_buy_button()
Definition citydlg.cpp:2883
int selected_row_p
Definition citydlg.h:500
QHBoxLayout * leftbot_layout
Definition citydlg.h:451
void update_building()
Definition citydlg.cpp:3443
QPushButton * zoom_in_button
Definition citydlg.h:493
void save_worklist()
Definition citydlg.cpp:3758
void worklist_del()
Definition citydlg.cpp:3717
QGridLayout * info_grid_layout
Definition citydlg.h:458
void clear_worklist()
Definition citydlg.cpp:3677
QPushButton * counterss_button
Definition citydlg.h:492
impr_info * city_buildings
Definition citydlg.h:498
QLabel * curr_impr
Definition citydlg.h:470
city_label * lab_table[6]
Definition citydlg.h:457
int scroll_height
Definition citydlg.h:509
QLabel * curr_units
Definition citydlg.h:469
unit_info * current_units
Definition citydlg.h:496
void zoom_out()
Definition citydlg.cpp:2426
void zoom_in()
Definition citydlg.cpp:2413
struct unit_node_vector supported_units
Definition citydlg.c:163
QPushButton * zoom_out_button
Definition citydlg.h:494
struct city * pcity
Definition citydlg.c:138
void update_info_label()
Definition citydlg.cpp:3143
QPushButton * work_add_but
Definition citydlg.h:489
city_dialog(QWidget *parent=0)
Definition citydlg.cpp:1506
QSplitter * central_left_splitter
Definition citydlg.h:449
void disband_state_changed(bool allow_disband)
Definition citydlg.cpp:2742
void update_citizens()
Definition citydlg.cpp:2908
QRadioButton * r1
Definition citydlg.h:481
void cma_slider(int val)
Definition citydlg.cpp:2717
QCheckBox * cma_celeb_checkbox
Definition citydlg.h:475
QCheckBox * show_units
Definition citydlg.h:478
enum city_dialog::city_dialog_tab current_tab
void worklist_down()
Definition citydlg.cpp:3734
void update_title()
Definition citydlg.cpp:3789
QLabel * cma_info_text
Definition citydlg.h:465
void dbl_click_p(QTableWidgetItem *item)
Definition citydlg.cpp:3280
QPushButton * cma_enable_but
Definition citydlg.h:484
QLabel * cma_result
Definition citydlg.h:466
void cma_remove()
Definition citydlg.cpp:2679
QSlider * slider_tab[2 *O_LAST+2]
Definition citydlg.h:501
QPushButton * button
Definition citydlg.h:482
bool eventFilter(QObject *obj, QEvent *event)
Definition citydlg.cpp:2346
QSplitter * prod_unit_splitter
Definition citydlg.h:448
QVBoxLayout * left_layout
Definition citydlg.h:454
void prev_city()
Definition citydlg.cpp:3408
void city_rename()
Definition citydlg.cpp:2383
void refresh()
Definition citydlg.cpp:2992
void update_cma_tab()
Definition citydlg.cpp:2612
QPushButton * work_rem_but
Definition citydlg.h:490
float zoom
Definition citydlg.h:510
QSplitter * central_splitter
Definition citydlg.h:450
QWidget * prod_happ_widget
Definition citydlg.h:452
void cma_toggle_changed(int val)
Definition citydlg.cpp:2706
void show_targets()
Definition citydlg.cpp:3646
struct city_dialog::@145 counters
QVBoxLayout * counterss_layout
Definition citydlg.h:447
QFrame * counterss_frame
Definition citydlg.h:462
QWidget * top_widget
Definition citydlg.h:453
void update_tabs()
Definition citydlg.cpp:2119
QPushButton * prev_city_but
Definition citydlg.h:486
void cma_enable()
Definition citydlg.cpp:2475
QLabel * cma_result_pix
Definition citydlg.h:467
struct city * dlgcity
Definition citydlg.h:508
void update_counters_table()
Definition citydlg.cpp:3024
void update_sliders()
Definition citydlg.cpp:2560
void update_improvements()
Definition citydlg.cpp:3511
GtkWidget * worklist
Definition citydlg.c:176
QHBoxLayout * happiness_layout
Definition citydlg.h:446
QCheckBox * future_targets
Definition citydlg.h:477
void change_production(bool next)
Definition citydlg.cpp:2074
void cma_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:2530
QCheckBox * cma_max_growth
Definition citydlg.h:476
void item_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:3355
void show_targets_worklist()
Definition citydlg.cpp:3662
QCheckBox * show_wonders
Definition citydlg.h:480
void cma_context_menu(const QPoint &p)
Definition citydlg.cpp:2763
void cma_changed()
Definition citydlg.cpp:2490
QPushButton * buy_button
Definition citydlg.h:483
QRadioButton * r4
Definition citydlg.h:481
void update_units()
Definition citydlg.cpp:3297
QRadioButton * r2
Definition citydlg.h:481
QTableWidget * p_table_p
Definition citydlg.h:472
void save_cma()
Definition citydlg.cpp:2439
QPixmap * citizen_pixmap
Definition citydlg.h:495
void production_changed(int index)
Definition citydlg.cpp:3628
void update_prod_buttons()
Definition citydlg.cpp:2248
QWidget * happiness_widget
Definition citydlg.h:461
QGroupBox * happiness_group
Definition citydlg.h:460
QCheckBox * show_buildings
Definition citydlg.h:479
Definition city.h:320
struct worker_task_list * task_reqs
Definition city.h:412
int surplus[O_LAST]
Definition city.h:355
enum city_wl_cancel_behavior wlcb
Definition city.h:404
int food_stock
Definition city.h:367
int * counter_values
Definition city.h:408
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
struct player * playing
Definition connection.h:151
Definition mapimg.c:367
struct requirement_vector obsolete_by
Definition improvement.h:59
Definition climisc.h:82
struct universal item
Definition climisc.h:83
enum unit_activity activity
struct city_list * cities
Definition player.h:279
struct player_economic economic
Definition player.h:282
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:516
int firepower
Definition unittype.h:525
const struct unit_type * obsoleted_by
Definition unittype.h:529
int vision_radius_sq
Definition unittype.h:522
int move_rate
Definition unittype.h:517
int attack_strength
Definition unittype.h:515
Definition unit.h:138
int upkeep[O_LAST]
Definition unit.h:148
int id
Definition unit.h:145
struct tile * tile
Definition unit.h:140
int homecity
Definition unit.h:146
enum universals_n kind
Definition fc_types.h:902
universals_u value
Definition fc_types.h:901
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:974
#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:290
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:1834
const char * text_happiness_wonders(const struct city *pcity)
Definition text.c:1876
const char * text_happiness_units(const struct city *pcity)
Definition text.c:2040
const char * text_happiness_luxuries(const struct city *pcity)
Definition text.c:2078
const char * text_happiness_buildings(const struct city *pcity)
Definition text.c:1806
const char * unit_description(struct unit *punit)
Definition text.c:481
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_terrain(_tile)
Definition tile.h:114
int tileset_hex_width(const struct tileset *t)
Definition tilespec.c:721
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:6784
int tileset_unit_width(const struct tileset *t)
Definition tilespec.c:797
int tileset_unit_height(const struct tileset *t)
Definition tilespec.c:805
int tileset_small_sprite_width(const struct tileset *t)
Definition tilespec.c:901
struct tileset * get_tileset(void)
Definition tilespec.c:692
struct tileset * unscaled_tileset
Definition tilespec.c:568
int tileset_unit_layout_offset_y(const struct tileset *t)
Definition tilespec.c:882
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:712
int tileset_small_sprite_height(const struct tileset *t)
Definition tilespec.c:937
struct sprite * get_icon_sprite(const struct tileset *t, enum icon_type icon)
Definition tilespec.c:6980
int tileset_unit_with_upkeep_height(const struct tileset *t)
Definition tilespec.c:859
int tileset_hex_height(const struct tileset *t)
Definition tilespec.c:730
struct sprite * get_citizen_sprite(const struct tileset *t, enum citizen_category type, int citizen_index, const struct city *pcity)
Definition tilespec.c:6723
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:6806
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6757
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6775
@ ICON_CITYDLG
Definition tilespec.h:314
const struct unit_type * utype
Definition fc_types.h:721
const struct impr_type * building
Definition fc_types.h:714
bool can_unit_change_homecity(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:489
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:367
#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_upgrade(const struct civ_map *nmap, const struct unit_list *punits)
Definition unitlist.c:334
bool units_can_unload(const struct unit_list *punits)
Definition unitlist.c:301
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:2710
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:766
#define utype_class(_t_)
Definition unittype.h:749
#define utype_fuel(ptype)
Definition unittype.h:839
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
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