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 "game.h"
45
46//agents
47#include "cma_core.h"
48#include "cma_fec.h"
49
50// client
51#include "citydlg_common.h"
52#include "client_main.h"
53#include "climisc.h"
54#include "control.h"
55#include "global_worklist.h"
56#include "helpdata.h"
57#include "mapview_common.h"
58#include "movement.h"
59#include "sprite.h"
60#include "text.h"
61#include "tilespec.h"
62
63// gui-qt
64#include "citydlg.h"
65#include "colors.h"
66#include "fc_client.h"
67#include "gui_main.h"
68#include "hudwidget.h"
69
70static bool city_dlg_created = false;
75extern QString split_text(QString text, bool cut);
76extern QString cut_helptext(QString text);
77
78/************************************************************************/
82{
83 m_timer.start();
84 startTimer(50);
86 sfont = new QFont;
88 pix = nullptr;
89}
90
91/************************************************************************/
95{
96 if (pix != nullptr) {
97 delete pix;
98 }
99 delete sfont;
100}
101
102/************************************************************************/
109
110/************************************************************************/
114{
115 struct sprite *sprite;
117 QImage img;
119 QRect crop;
120
121 if (VUT_UTYPE == target->kind) {
124 } else {
126 }
127 if (pix != nullptr) {
128 delete pix;
129 }
130 if (sprite == nullptr) {
131 pix = nullptr;
132 return;
133 }
134 img = sprite->pm->toImage();
136 cropped_img = img.copy(crop);
137 tpix = QPixmap::fromImage(cropped_img);
138 pix = new QPixmap(tpix.width(), tpix.height());
139 pix->fill(Qt::transparent);
140 pixmap_copy(pix, &tpix, 0 , 0, 0, 0, tpix.width(), tpix.height());
141}
142
143/************************************************************************/
147{
148 struct sprite *sprite;
149
152 } else {
153 sprite = nullptr;
154 }
155 if (pix != nullptr) {
156 delete pix;
157 }
158 if (sprite == nullptr) {
159 pix = nullptr;
160 return;
161 }
162 pix = new QPixmap(sprite->pm->width(),
163 sprite->pm->height());
164 pix->fill(Qt::transparent);
165 pixmap_copy(pix, sprite->pm, 0 , 0, 0, 0,
166 sprite->pm->width(), sprite->pm->height());
167 if (isVisible()) {
168 update();
169 }
170}
171
172/************************************************************************/
176{
177 if ((value() != minimum() && value() < maximum())
178 || (0 == minimum() && 0 == maximum())) {
179 m_animate_step = m_timer.elapsed() / 50;
180 update();
181 }
182}
183
184/************************************************************************/
188{
189 QPainter p;
191 QColor c;
192 QRect r, rx, r2;
193 int max;
194 int f_pixel_size;
195 int pix_width = 0;
196 int pixel_size = sfont->pixelSize();
197 int pbw, pbh;
198
199 if (pix != nullptr) {
200 pix_width = height() - 4;
201 }
202
203 if (pixel_size > 0) {
205 } else {
207
208 f_pixel_size = fm.height();
209 }
210
211 pbw = width();
212 pbh = height();
213
214 rx.setX(0);
215 rx.setY(0);
216 rx.setWidth(pbw);
217 rx.setHeight(pbh);
218 p.begin(this);
219 p.drawLine(rx.topLeft(), rx.topRight());
220 p.drawLine(rx.bottomLeft(), rx.bottomRight());
221
222 max = maximum();
223
224 if (max == 0) {
225 max = 1;
226 }
227
228 r = QRect(0, 0, pbw * value() / max, pbh);
229
230 gx = QLinearGradient(0 , 0, 0, pbh);
231 c = QColor(palette().color(QPalette::Highlight));
232 gx.setColorAt(0, c);
233 gx.setColorAt(0.5, QColor(40, 40, 40));
234 gx.setColorAt(1, c);
235 p.fillRect(r, QBrush(gx));
236 p.setClipRegion(reg.translated(m_animate_step % 32, 0));
237
238 g = QLinearGradient(0 , 0, pbw, pbh);
239 c.setAlphaF(0.1);
240 g.setColorAt(0, c);
241 c.setAlphaF(0.9);
242 g.setColorAt(1, c);
243 p.fillRect(r, QBrush(g));
244
245 p.setClipping(false);
246 r2 = QRect(pbw * value() / max, 0, pbw, pbh);
247 c = palette().color(QPalette::Window);
248 p.fillRect(r2, c);
249
250 // Draw icon
251 if (pix != nullptr) {
252 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
253 p.drawPixmap(2 , 2, pix_width
254 * static_cast<float>(pix->width()) / pix->height(),
255 pix_width, *pix, 0, 0, pix->width(), pix->height());
256 }
257
258 // Draw text
259 c = palette().color(QPalette::Text);
260 p.setPen(c);
261 sfont->setCapitalization(QFont::AllUppercase);
262 sfont->setBold(true);
263
264 if (text().contains('\n')) {
265 QString s1, s2;
266 int i, j;
267 QFont tmp_font = *sfont; // Don't make changes to font to be kept
268
269 i = text().indexOf('\n');
270 s1 = text().left(i);
271 s2 = text().right(text().length() - i);
272
273 if (2 * f_pixel_size >= 3 * pbh / 2) {
274 tmp_font.setPixelSize(pbh / 3);
275 }
276
277 p.setFont(tmp_font);
278
279 j = pbh - 2 * f_pixel_size;
280 p.setCompositionMode(QPainter::CompositionMode_ColorDodge);
282
283 if (fm.horizontalAdvance(s1) > rx.width()) {
284 s1 = fm.elidedText(s1, Qt::ElideRight, rx.width());
285 }
286
287 i = rx.width() - fm.horizontalAdvance(s1) + pix_width;
288 i = qMax(0, i);
289 p.drawText(i / 2, j / 3 + f_pixel_size, s1);
290
291 if (fm.horizontalAdvance(s2) > rx.width()) {
292 s2 = fm.elidedText(s2, Qt::ElideRight, rx.width());
293 }
294
295 i = rx.width() - fm.horizontalAdvance(s2) + pix_width;
296 i = qMax(0, i);
297
298 p.drawText(i / 2, pbh - j / 3, s2);
299 } else {
300 QString s;
301 int i, j;
302
303 p.setFont(*sfont);
304
305 s = text();
306 j = pbh - f_pixel_size;
307 p.setCompositionMode(QPainter::CompositionMode_ColorDodge);
309
310 if (fm.horizontalAdvance(s) > rx.width()) {
311 s = fm.elidedText(s, Qt::ElideRight, rx.width());
312 }
313
314 i = rx.width() - fm.horizontalAdvance(s) + pix_width;
315 i = qMax(0, i);
316 p.drawText(i / 2, j / 2 + f_pixel_size, s);
317 }
318
319 p.end();
320}
321
322/************************************************************************/
326{
327 int offset;
328 QRect r(-50, 0, width() + 50, height());
329 int chunk_width = 16;
330 int size = width() + 50;
331 reg = QRegion();
332
333 for (offset = 0; offset < (size * 2); offset += (chunk_width * 2)) {
334 QPolygon a;
335
336 a.setPoints(4, r.x(), r.y() + offset,
337 r.x() + r.width(), (r.y() + offset) - size,
338 r.x() + r.width(),
339 (r.y() + offset + chunk_width) - size,
340 r.x(), r.y() + offset + chunk_width);
341 reg += QRegion(a);
342 }
343
344}
345
346/************************************************************************/
349static void pixmap_put_x(QPixmap *pix)
350{
351 QPen pen(QColor(0, 0, 0));
352 QPainter p;
353
354 pen.setWidth(2);
355 p.begin(pix);
356 p.setRenderHint(QPainter::Antialiasing);
357 p.setPen(pen);
358 p.drawLine(0, 0, pix->width(), pix->height());
359 p.drawLine(pix->width(), 0, 0, pix->height());
360 p.end();
361}
362
363/************************************************************************/
366impr_item::impr_item(QWidget *parent, const impr_type *building,
367 struct city *pcity): QLabel(parent)
368{
370 dlgcity = pcity;
371 impr = building;
372 impr_pixmap = nullptr;
373 struct sprite *sprite;
374 sprite = get_building_sprite(tileset , building);
375
376 if (sprite != nullptr) {
378 sprite->pm->height());
379 impr_pixmap->map_pixmap.fill(Qt::transparent);
380 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
381 sprite->pm->width(), sprite->pm->height());
382 } else {
384 impr_pixmap->map_pixmap.fill(Qt::red);
385 }
386
389 setToolTip(get_tooltip_improvement(building, pcity, true).trimmed());
390}
391
392/************************************************************************/
396{
397 if (impr_pixmap) {
399 }
400}
401
402/************************************************************************/
406{
408 update();
409}
410
411/************************************************************************/
414#ifndef FC_QT5_MODE
416#else // FC_QT5_MODE
417void impr_item::enterEvent(QEvent *event)
418#endif // FC_QT5_MODE
419{
420 struct sprite *sprite;
421 QPainter p;
422
423 if (impr_pixmap) {
424 canvas_free(impr_pixmap);
425 }
426
428 if (impr && sprite) {
429 impr_pixmap = qtg_canvas_create(sprite->pm->width(),
430 sprite->pm->height());
431 impr_pixmap->map_pixmap.fill(QColor(palette().color(QPalette::Highlight)));
432 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
433 sprite->pm->width(), sprite->pm->height());
434 } else {
435 impr_pixmap = qtg_canvas_create(10, 10);
436 impr_pixmap->map_pixmap.fill(QColor(palette().color(QPalette::Highlight)));
437 }
438
439 init_pix();
440}
441
442/************************************************************************/
446{
447 struct sprite *sprite;
448
449 if (impr_pixmap) {
451 }
452
454 if (impr && sprite) {
456 sprite->pm->height());
457 impr_pixmap->map_pixmap.fill(Qt::transparent);
458 pixmap_copy(&impr_pixmap->map_pixmap, sprite->pm, 0 , 0, 0, 0,
459 sprite->pm->width(), sprite->pm->height());
460 } else {
462 impr_pixmap->map_pixmap.fill(Qt::red);
463 }
464
465 init_pix();
466}
467
468/************************************************************************/
472{
474 layout = new QHBoxLayout(this);
475 init_layout();
476}
477
478/************************************************************************/
482{
483 QSizePolicy size_fixed_policy(QSizePolicy::Fixed,
484 QSizePolicy::MinimumExpanding,
485 QSizePolicy::Slider);
486
489}
490
491/************************************************************************/
495{
496
497}
498
499/************************************************************************/
503{
504 impr_list.append(item);
505}
506
507/************************************************************************/
511{
512 int i = impr_list.count();
513 impr_item *ui;
514 int j;
515 setUpdatesEnabled(false);
516 setMouseTracking(false);
517
518 for (j = 0; j < i; j++) {
519 ui = impr_list[j];
520 layout->removeWidget(ui);
521 delete ui;
522 }
523
524 while (!impr_list.empty()) {
525 impr_list.removeFirst();
526 }
527
528 setMouseTracking(true);
529 setUpdatesEnabled(true);
530}
531
532/************************************************************************/
536{
537 QPoint p;
538
539 p = parentWidget()->parentWidget()->pos();
540 p = mapToGlobal(p);
541#ifndef FC_QT5_MODE
542 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
543 event->angleDelta(),
544 event->buttons(),
545 event->modifiers(),
546 event->phase(), false, event->source());
547#else // FC_QT5_MODE
548 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
549 event->angleDelta(),
550 event->angleDelta().y(),
551 Qt::Horizontal, event->buttons(),
552 event->modifiers(), event->phase(), event->source());
553#endif // FC_QT5_MODE
554 QApplication::sendEvent(parentWidget(), &new_event);
555}
556
557/************************************************************************/
561{
562 int i = impr_list.count();
563 int j;
564 int h = 0;
565 impr_item *ui;
566
567 setUpdatesEnabled(false);
568 hide();
569
570 for (j = 0; j < i; j++) {
571 ui = impr_list[j];
572 h = ui->height();
573 layout->addWidget(ui, 0, Qt::AlignVCenter);
574 }
575
576 if (impr_list.count() > 0) {
577 parentWidget()->parentWidget()->setFixedHeight(city_dlg->scroll_height
578 + h + 6);
579 } else {
580 parentWidget()->parentWidget()->setFixedHeight(0);
581 }
582
583 show();
584 setUpdatesEnabled(true);
585 layout->update();
587}
588
589/************************************************************************/
593{
594 QPoint p;
595
596 p = parentWidget()->parentWidget()->pos();
597 p = mapToGlobal(p);
598#ifndef FC_QT5_MODE
599 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
600 event->angleDelta(),
601 event->buttons(),
602 event->modifiers(),
603 event->phase(), false, event->source());
604#else // FC_QT5_MODE
605 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
606 event->angleDelta(),
607 event->angleDelta().y(),
608 Qt::Horizontal, event->buttons(),
609 event->modifiers(), event->phase(), event->source());
610#endif // FC_QT5_MODE
611 QApplication::sendEvent(parentWidget()->parentWidget(),
612 &new_event);
613}
614
615/************************************************************************/
619{
621 return;
622 }
623
624 if (event->button() == Qt::LeftButton) {
625 char buf[256];
626 int price;
627 const int impr_id = improvement_number(impr);
628 const int city_id = dlgcity->id;
630
632 impr) != TR_SUCCESS) {
633 return;
634 }
635
637
640 PL_("Sell %s for %d gold?",
641 "Sell %s for %d gold?", price),
643
644 ask->set_text_title(buf, (_("Sell improvement?")));
645 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
646 ask->setAttribute(Qt::WA_DeleteOnClose);
647 connect(ask, &hud_message_box::accepted, [=]() {
648 struct city *pcity = game_city_by_number(city_id);
649
650 if (pcity == nullptr) {
651 return;
652 }
654 });
655 ask->show();
656 }
657}
658
659/************************************************************************/
663 bool supp, int hppy_cost) : QLabel()
664{
667 QImage img;
668 QRect crop;
669 qunit = punit;
670 struct canvas *unit_pixmap;
671 struct tileset *tmp;
672 float isosize;
673
675 supported = supp;
676
677 tmp = nullptr;
678 if (unscaled_tileset) {
679 tmp = tileset;
681 }
682 isosize = 0.6;
684 isosize = 0.45;
685 }
686
687 if (punit) {
688 if (supported) {
691 } else {
694 }
695
696 unit_pixmap->map_pixmap.fill(Qt::transparent);
697 put_unit(punit, unit_pixmap, 1.0, 0, 0);
698
699 if (supported) {
703 }
704 } else {
706 unit_pixmap->map_pixmap.fill(Qt::transparent);
707 }
708
709 img = unit_pixmap->map_pixmap.toImage();
711 cropped_img = img.copy(crop);
714 * isosize, Qt::SmoothTransformation);
715 } else {
717 Qt::SmoothTransformation);
718 }
720 if (tmp != nullptr) {
721 tileset = tmp;
722 }
723
725 setFixedWidth(unit_img.width() + 4);
726 setFixedHeight(unit_img.height());
728}
729
730/************************************************************************/
734{
735 setPixmap(QPixmap::fromImage(unit_img));
736 update();
737}
738
739/************************************************************************/
745
746/************************************************************************/
750{
751 QMenu *menu;
752
754 return;
755 }
756
757 if (unit_owner(qunit) != client_player()) {
758 return;
759 }
760
761 menu = new QMenu(gui()->central_wdg);
762 menu->addAction(activate);
763 menu->addAction(activate_and_close);
764
765 if (sentry) {
766 menu->addAction(sentry);
767 }
768
769 if (fortify) {
770 menu->addAction(fortify);
771 }
772
773 if (change_home) {
774 menu->addAction(change_home);
775 }
776
777 if (load) {
778 menu->addAction(load);
779 }
780
781 if (unload) {
782 menu->addAction(unload);
783 }
784
785 if (unload_trans) {
786 menu->addAction(unload_trans);
787 }
788
789 if (disband_action) {
790 menu->addAction(disband_action);
791 }
792
793 if (upgrade) {
794 menu->addAction(upgrade);
795 }
796
797 menu->popup(event->globalPos());
798}
799
800/************************************************************************/
804{
805 struct unit_list *qunits;
806
808 return;
809 }
810
813 activate = new QAction(_("Activate unit"), this);
814 connect(activate, &QAction::triggered, this, &unit_item::activate_unit);
815 activate_and_close = new QAction(_("Activate and close dialog"), this);
816 connect(activate_and_close, &QAction::triggered, this,
818
820 sentry = new QAction(_("Sentry unit"), this);
821 connect(sentry, &QAction::triggered, this, &unit_item::sentry_unit);
822 } else {
823 sentry = NULL;
824 }
825
827 fortify = new QAction(_("Fortify unit"), this);
828 connect(fortify, &QAction::triggered, this, &unit_item::fortify_unit);
829 } else {
830 fortify = NULL;
831 }
833 disband_action = new QAction(_("Disband unit"), this);
834 connect(disband_action, &QAction::triggered, this, &unit_item::disband);
835 } else {
837 }
838
841 this);
842 connect(change_home, &QAction::triggered, this, &unit_item::change_homecity);
843 } else {
845 }
846
847 if (units_can_load(qunits)) {
848 load = new QAction(_("Load"), this);
849 connect(load, &QAction::triggered, this, &unit_item::load_unit);
850 } else {
851 load = NULL;
852 }
853
855 unload = new QAction(_("Unload"), this);
856 connect(unload, &QAction::triggered, this, &unit_item::unload_unit);
857 } else {
858 unload = NULL;
859 }
860
862 unload_trans = new QAction(_("Unload All From Transporter"), this);
863 connect(unload_trans, &QAction::triggered, this, &unit_item::unload_all);
864 } else {
866 }
867
868 if (units_can_upgrade(&(wld.map), qunits)) {
869 upgrade = new QAction(_("Upgrade Unit"), this);
870 connect(upgrade, &QAction::triggered, this, &unit_item::upgrade_unit);
871 } else {
872 upgrade = NULL;
873 }
874
876}
877
878/************************************************************************/
882{
883 struct unit_list *punits;
885
886 if (punit == nullptr) {
887 return;
888 }
889
894}
895
896/************************************************************************/
903
904/************************************************************************/
911
912/************************************************************************/
919
920/************************************************************************/
931
932/************************************************************************/
941
942/************************************************************************/
952
953/************************************************************************/
957{
958 if (qunit) {
960 }
961}
962
963/************************************************************************/
967{
968 if (qunit) {
970 }
971}
972
973/************************************************************************/
976#ifndef FC_QT5_MODE
978#else // FC_QT5_MODE
979void unit_item::enterEvent(QEvent *event)
980#endif // FC_QT5_MODE
981{
982 QImage temp_img(unit_img.size(), QImage::Format_ARGB32_Premultiplied);
983 QPainter p;
984
985 p.begin(&temp_img);
986 p.fillRect(0, 0, unit_img.width(), unit_img.height(),
987 QColor(palette().color(QPalette::Highlight)));
988 p.drawImage(0, 0, unit_img);
989 p.end();
990
991 setPixmap(QPixmap::fromImage(temp_img));
992 update();
993}
994
995/************************************************************************/
999{
1000 init_pix();
1001}
1002
1003/************************************************************************/
1007{
1008 QPoint p;
1009
1010 p = parentWidget()->parentWidget()->pos();
1011 p = mapToGlobal(p);
1012#ifndef FC_QT5_MODE
1013 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1014 event->angleDelta(),
1015 event->buttons(),
1016 event->modifiers(),
1017 event->phase(), false, event->source());
1018#else // FC_QT5_MODE
1019 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1020 event->angleDelta(),
1021 event->angleDelta().y(),
1022 Qt::Horizontal, event->buttons(),
1023 event->modifiers(), event->phase(), event->source());
1024#endif // FC_QT5_MODE
1025 QApplication::sendEvent(parentWidget()->parentWidget(),
1026 &new_event);
1027}
1028
1029/************************************************************************/
1033{
1034 if (event->button() == Qt::LeftButton) {
1035 if (qunit) {
1038 }
1039 }
1040}
1041
1042/************************************************************************/
1046{
1047 if (qunit) {
1049 }
1050}
1051
1052/************************************************************************/
1056{
1057 layout = new QHBoxLayout(this);
1058 init_layout();
1059 supports = supp;
1060}
1061
1062/************************************************************************/
1066{
1068 unit_list.clear();
1069}
1070
1071/************************************************************************/
1075{
1076 unit_list.append(item);
1077}
1078
1079/************************************************************************/
1083{
1084 QSizePolicy size_fixed_policy(QSizePolicy::Fixed,
1085 QSizePolicy::MinimumExpanding,
1086 QSizePolicy::Slider);
1089}
1090
1091/************************************************************************/
1095{
1096 QPoint p;
1097
1098 p = parentWidget()->parentWidget()->pos();
1099 p = mapToGlobal(p);
1100#ifndef FC_QT5_MODE
1101 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1102 event->angleDelta(),
1103 event->buttons(),
1104 event->modifiers(),
1105 event->phase(), false, event->source());
1106#else // FC_QT5_MODE
1107 QWheelEvent new_event(QPoint(5, 5), p + QPoint(5,5), event->pixelDelta(),
1108 event->angleDelta(),
1109 event->angleDelta().y(),
1110 Qt::Horizontal, event->buttons(),
1111 event->modifiers(), event->phase(), event->source());
1112#endif // FC_QT5_MODE
1113 QApplication::sendEvent(parentWidget(), &new_event);
1114}
1115
1116/************************************************************************/
1120{
1121 int i = unit_list.count();
1122 int j;
1123 int h;
1124 float hexfix;
1125 unit_item *ui;
1126
1127 setUpdatesEnabled(false);
1128 hide();
1129
1130 for (j = 0; j < i; j++) {
1131 ui = unit_list[j];
1132 layout->addWidget(ui, 0, Qt::AlignVCenter);
1133 }
1134
1135 hexfix = 1.0;
1137 hexfix = 0.75;
1138 }
1139
1141 h = tileset_unit_width(get_tileset()) * 0.7 * hexfix + 6;
1142 } else {
1144 }
1145 if (unit_list.count() > 0) {
1146 parentWidget()->parentWidget()->setFixedHeight(city_dlg->scroll_height
1147 + h);
1148 } else {
1149 parentWidget()->parentWidget()->setFixedHeight(0);
1150 }
1151 show();
1152 setUpdatesEnabled(true);
1153 layout->update();
1155}
1156
1157/************************************************************************/
1161{
1162 int i = unit_list.count();
1163 unit_item *ui;
1164 int j;
1165 setUpdatesEnabled(false);
1166 setMouseTracking(false);
1167
1168 for (j = 0; j < i; j++) {
1169 ui = unit_list[j];
1170 layout->removeWidget(ui);
1171 delete ui;
1172 }
1173
1174 while (!unit_list.empty()) {
1175 unit_list.removeFirst();
1176 }
1177
1178 setMouseTracking(true);
1179 setUpdatesEnabled(true);
1180}
1181
1182/************************************************************************/
1186city_label::city_label(int t, QWidget *parent) : QLabel(parent)
1187{
1188 type = t;
1189}
1190
1191/************************************************************************/
1195{
1196 int citnum, i;
1197 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
1198 int num_citizens = pcity->size;
1199
1201 return;
1202 }
1203
1204 i = 1 + (num_citizens * 5 / 200);
1205 w = w / i;
1206 citnum = event->pos().x() / w;
1207
1208 if (!can_client_issue_orders()) {
1209 return;
1210 }
1211
1213}
1214
1215/************************************************************************/
1219{
1220 pcity = pciti;
1221}
1222
1223/************************************************************************/
1227{
1229 radius = 0;
1235 view->map_pixmap.fill(Qt::black);
1237 miniview->map_pixmap.fill(Qt::black);
1238 delta_x = 0;
1239 delta_y = 0;
1240 setContextMenuPolicy(Qt::CustomContextMenu);
1241 connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
1242 this, SLOT(context_menu(const QPoint &)));
1243}
1244
1245/************************************************************************/
1253
1254/************************************************************************/
1258{
1260 QString str;
1261
1262 painter.begin(this);
1263 painter.drawPixmap(0, 0, zoomed_pixmap);
1264
1266 painter.fillRect(0, 0, zoomed_pixmap.width(), zoomed_pixmap.height(),
1267 QBrush(QColor(60, 60 , 60 , 110)));
1268 painter.setPen(QColor(255, 255, 255));
1269 // TRANS: %1 is custom string choosen by player.
1270 str = QString(_("Governor %1"))
1272 painter.drawText(5, zoomed_pixmap.height() - 10, str);
1273 }
1274
1275 painter.end();
1276}
1277
1278/************************************************************************/
1281void city_map::set_pixmap(struct city *pcity, float z)
1282{
1283 int r, max_r;
1284 QSize size;
1285
1286 zoom = z;
1287 r = sqrt(city_map_radius_sq_get(pcity));
1288
1289 if (radius != r) {
1291 radius = r;
1293 cutted_width = wdth * (r + 1) / max_r;
1294 cutted_height = hight * (r + 1) / max_r;
1297 delta_x = (wdth - cutted_width) / 2;
1298 delta_y = (hight - cutted_height) / 2;
1300 miniview->map_pixmap.fill(Qt::black);
1301 }
1302
1306 size = miniview->map_pixmap.size();
1308 Qt::KeepAspectRatio,
1309 Qt::SmoothTransformation);
1311 mcity = pcity;
1312}
1313
1314/************************************************************************/
1318{
1319 return zoomed_pixmap.size();
1320}
1321
1322/************************************************************************/
1326{
1327 return zoomed_pixmap.size();
1328}
1329
1330/************************************************************************/
1334{
1336 QPoint pos;
1337
1338 if (!can_client_issue_orders() || event->button() != Qt::LeftButton) {
1339 return;
1340 }
1341
1342 pos = event->pos();
1343 canvas_x = pos.x() / zoom + delta_x;
1344 canvas_y = pos.y() / zoom + delta_y;
1345
1347 canvas_x, canvas_y)) {
1349 }
1350}
1351
1352/************************************************************************/
1356{
1358 QAction *con_cultivate = nullptr;
1359 QAction *con_irrig = nullptr;
1360 QAction *con_plant = nullptr;
1361 QAction *con_mine = nullptr;
1362 QAction *con_road = nullptr;
1363 QAction *con_trfrm = nullptr;
1364 QAction *con_clean = nullptr;
1365 QAction *con_clear = nullptr;
1366 QMenu *con_menu;
1368 struct terrain *pterr;
1369 struct tile *ptile;
1370 struct universal for_terr;
1371 struct worker_task *ptask;
1372 int city_id = mcity->id;
1373
1374 if (!can_client_issue_orders()) {
1375 return;
1376 }
1377
1378 canvas_x = point.x() / zoom + delta_x;
1379 canvas_y = point.y() / zoom + delta_y;
1380
1382 canvas_x, canvas_y)) {
1383 return;
1384 }
1385
1387 city_x, city_y);
1388 pterr = tile_terrain(ptile);
1389 for_terr.kind = VUT_TERRAIN;
1390 for_terr.value.terrain = pterr;
1392
1393 wid_act = new QWidgetAction(this);
1394 wid_act->setDefaultWidget(new QLabel(_("Autosettler activity:")));
1395
1396 con_menu = new QMenu(this);
1397 con_menu->addAction(wid_act);
1398
1399 if (pterr->plant_result != NULL
1401 con_plant = con_menu->addAction(_("Plant"));
1402 }
1404 con_mine = con_menu->addAction(Q_("?act:Mine"));
1405 }
1406
1407 if (pterr->cultivate_result != NULL
1409 con_cultivate = con_menu->addAction(_("Cultivate"));
1410 }
1412 con_irrig = con_menu->addAction(_("Irrigate"));
1413 }
1414
1415 if (pterr->transform_result != pterr && pterr->transform_result != NULL
1417 NULL, &for_terr)) {
1418 con_trfrm = con_menu->addAction(_("Transform"));
1419 }
1420
1422 con_road = con_menu->addAction(_("Road"));
1423 }
1424
1425 if (prev_extra_in_tile(ptile, ERM_CLEAN,
1426 city_owner(mcity), NULL) != NULL) {
1427 con_clean = con_menu->addAction(_("Clean"));
1428 }
1429
1430 if (ptask != NULL) {
1431 con_clear = con_menu->addAction(_("Clear"));
1432 }
1433
1434 con_menu->setAttribute(Qt::WA_DeleteOnClose);
1435 connect(con_menu, &QMenu::triggered,
1437 bool target = false;
1438 struct packet_worker_task task;
1439
1440 if (!act) {
1441 return;
1442 }
1443
1444 task.city_id = city_id;
1445
1446 if (act == con_road) {
1448 target = TRUE;
1449 } else if (act == con_mine) {
1450 task.activity = ACTIVITY_MINE;
1451 target = TRUE;
1452 } else if (act == con_plant) {
1453 task.activity = ACTIVITY_PLANT;
1454 } else if (act == con_irrig) {
1456 target = TRUE;
1457 } else if (act == con_cultivate) {
1459 } else if (act == con_trfrm) {
1461 } else if (act == con_clean) {
1462 task.activity = ACTIVITY_CLEAN;
1463 target = TRUE;
1464 } else if (act == con_clear) {
1465 task.activity = ACTIVITY_LAST;
1466 } else {
1467 // Closed dialog without selecting any activity entry.
1468 return;
1469 }
1470
1471 task.want = 100;
1472
1473 if (target) {
1474 enum extra_cause cause = activity_to_extra_cause(task.activity);
1476 struct extra_type *tgt;
1477
1478 if (cause != EC_NONE) {
1479 tgt = next_extra_for_tile(ptile, cause, city_owner(mcity), NULL);
1480 } else if (rmcause != ERM_NONE) {
1482 } else {
1483 tgt = NULL;
1484 }
1485
1486 if (tgt != NULL) {
1487 task.tgt = extra_index(tgt);
1488 } else {
1489 task.tgt = -1;
1490 }
1491 } else {
1492 task.tgt = -1;
1493 }
1494
1495 task.tile_id = ptile->index;
1497 });
1498
1499 con_menu->popup(mapToGlobal(point));
1500}
1501
1502/************************************************************************/
1506{
1507 QFont f = QApplication::font();
1508 QFont *small_font;
1509 QFontMetrics fm(f);
1515 QHeaderView *header;
1516 QLabel *lab2, *label, *ql, *some_label;
1517 QPushButton *qpush2;
1519 QSizePolicy size_expanding_policy(QSizePolicy::Expanding,
1520 QSizePolicy::Expanding);
1521 QSlider *slider;
1522 QStringList info_list, str_list;
1527 int list_size;
1528 int h = 2 * fm.height() + 2;
1529
1531 zoom = 1.0;
1532
1533 happiness_shown = false;
1535 central_splitter->setOpaqueResize(false);
1537 central_left_splitter->setOpaqueResize(false);
1539 prod_unit_splitter->setOpaqueResize(false);
1540
1541 setMouseTracking(true);
1542 selected_row_p = -1;
1543 dlgcity = NULL;
1544 lcity_name = new QPushButton(this);
1545 lcity_name->setToolTip(_("Click to change city name"));
1546
1548 single_page_layout->setContentsMargins(0, 0 ,0 ,0);
1549 size_expanding_policy.setHorizontalStretch(0);
1550 size_expanding_policy.setVerticalStretch(0);
1552 current_building = 0;
1553
1554 // Map view
1555 map_box = new QGroupBox(this);
1556
1557 // City information widget texts about surpluses and so on
1558 info_wdg = new QWidget(this);
1559
1560 // Fill info_wdg with labels
1562
1563 info_wdg->setFont(*small_font);
1564 info_grid_layout->setSpacing(0);
1565 info_grid_layout->setContentsMargins(0, 0, 0, 0);
1566
1567
1568 for (enum city_info info_field = city_info_begin();
1571
1572 ql = new QLabel(_(city_info_name(info_field)), info_wdg);
1573 ql->setFont(*small_font);
1574 ql->setProperty(fonts::notify_label, "true");
1575 info_grid_layout->addWidget(ql, info_field, 0);
1576 qlt[info_field] = new QLabel(info_wdg);
1577 qlt[info_field]->setFont(*small_font);
1578 qlt[info_field]->setProperty(fonts::notify_label, "true");
1579 info_grid_layout->addWidget(qlt[info_field], info_field, 1);
1580 info_grid_layout->setRowStretch(info_field, 0);
1581 }
1582
1583 info_wdg->setLayout(info_grid_layout);
1584
1585 // Buy button
1586 buy_button = new QPushButton();
1587 buy_button->setIcon(fc_icons::instance()->get_icon("help-donate"));
1588 connect(buy_button, &QAbstractButton::clicked, this, &city_dialog::buy);
1589
1590 connect(lcity_name, &QAbstractButton::clicked, this, &city_dialog::city_rename);
1593 view = new city_map(this);
1594
1595 zoom_vbox = new QVBoxLayout();
1596 zoom_in_button = new QPushButton();
1597 zoom_in_button->setIcon(fc_icons::instance()->get_icon("plus"));
1598 zoom_in_button->setIconSize(QSize(16, 16));
1599 zoom_in_button->setFixedSize(QSize(20, 20));
1600 zoom_in_button->setToolTip(_("Zoom in"));
1601 connect(zoom_in_button, &QAbstractButton::clicked, this, &city_dialog::zoom_in);
1602 zoom_out_button = new QPushButton();
1603 zoom_out_button->setIcon(fc_icons::instance()->get_icon("minus"));
1604 zoom_out_button->setIconSize(QSize(16, 16));
1605 zoom_out_button->setFixedSize(QSize(20, 20));
1606 zoom_out_button->setToolTip(_("Zoom out"));
1607 connect(zoom_out_button, &QAbstractButton::clicked, this, &city_dialog::zoom_out);
1608 zoom_vbox->addWidget(zoom_in_button);
1609 zoom_vbox->addWidget(zoom_out_button);
1610
1611 // City map group box
1614 hbox_layout->addStretch(100);
1615 hbox_layout->addWidget(view);
1616 hbox_layout->addStretch(100);
1617 hbox_layout->addLayout(zoom_vbox);
1618 vbox_layout->addLayout(hbox_layout);
1619 vbox_layout->addWidget(lcity_name);
1620 map_box->setLayout(vbox_layout);
1621 map_box->setTitle(_("City map"));
1622
1623 // Current/supported units/improvements widgets
1624 supp_units = new QLabel();
1625 curr_units = new QLabel();
1626 curr_impr = new QLabel();
1627 curr_units->setAlignment(Qt::AlignLeft);
1628 curr_impr->setAlignment(Qt::AlignLeft);
1629 supp_units->setAlignment(Qt::AlignLeft);
1630 supported_units = new unit_info(true);
1631 scroll = new QScrollArea;
1632 scroll->setWidgetResizable(true);
1633 scroll->setMaximumHeight(tileset_unit_with_upkeep_height(get_tileset()) + 6
1634 + scroll->horizontalScrollBar()->height());
1635 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1636 scroll->setWidget(supported_units);
1637 current_units = new unit_info(false);
1638 scroll2 = new QScrollArea;
1639 scroll2->setWidgetResizable(true);
1640 scroll2->setMaximumHeight(tileset_unit_height(get_tileset()) + 6
1641 + scroll2->horizontalScrollBar()->height());
1642 scroll2->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1643 scroll2->setWidget(current_units);
1644 scroll_height = scroll2->horizontalScrollBar()->height();
1645 city_buildings = new impr_info(this);
1646 scroll3 = new QScrollArea;
1647 scroll3->setWidgetResizable(true);
1648 scroll3->setMaximumHeight(tileset_unit_height(tileset) + 6
1649 + scroll3->horizontalScrollBar()->height());
1650 scroll3->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1651 scroll3->setWidget(city_buildings);
1652 scroll->setProperty("city_scroll", true);
1653 scroll2->setProperty("city_scroll", true);
1654 scroll3->setProperty("city_scroll", true);
1655
1658 right_layout = new QVBoxLayout();
1660 units_layout = new QVBoxLayout();
1661 left_layout = new QVBoxLayout();
1662
1663 /* Checkboxes to show units/wonders/imrovements
1664 * on production list */
1667 show_buildings->setToolTip(_("Show buildings"));
1668 show_buildings->setChecked(true);
1669 label = new QLabel();
1670 label->setPixmap(*fc_icons::instance()->get_pixmap("building"));
1671 label->setToolTip(_("Show buildings"));
1672 prod_option_layout->addWidget(show_buildings, Qt::AlignLeft);
1673 prod_option_layout->addWidget(label, Qt::AlignLeft);
1674 prod_option_layout->addStretch(100);
1675 label = new QLabel();
1676 label->setPixmap(*fc_icons::instance()->get_pixmap("cunits"));
1677 label->setToolTip(_("Show units"));
1678 show_units = new QCheckBox;
1679 show_units->setToolTip(_("Show units"));
1680 show_units->setChecked(true);
1681 prod_option_layout->addWidget(show_units, Qt::AlignHCenter);
1682 prod_option_layout->addWidget(label, Qt::AlignHCenter);
1683 prod_option_layout->addStretch(100);
1684 label = new QLabel();
1685 label->setPixmap(*fc_icons::instance()->get_pixmap("wonder"));
1686 label->setToolTip(_("Show wonders"));
1687 show_wonders = new QCheckBox;
1688 show_wonders->setToolTip(_("Show wonders"));
1689 show_wonders->setChecked(true);
1690 prod_option_layout->addWidget(show_wonders);
1691 prod_option_layout->addWidget(label);
1692 prod_option_layout->addStretch(100);
1693 label = new QLabel();
1694 label->setPixmap(*fc_icons::instance()->get_pixmap("future"));
1695 label->setToolTip(_("Show future targets"));
1697 future_targets->setToolTip(_("Show future targets"));
1698 future_targets->setChecked(false);
1700 prod_option_layout->addWidget(label, Qt::AlignRight);
1701 prod_options = new QGroupBox(this);
1702 prod_options->setLayout(prod_option_layout);
1703 prod_options->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
1704
1705 // Prev/next and close buttons
1706 button = new QPushButton;
1707 button->setIcon(fc_icons::instance()->get_icon("city-close"));
1708 button->setIconSize(QSize(56, 56));
1709 button->setToolTip(_("Close city dialog"));
1710 connect(button, &QAbstractButton::clicked, this, &QWidget::hide);
1711
1712 next_city_but = new QPushButton();
1713 next_city_but->setIcon(fc_icons::instance()->get_icon("city-right"));
1714 next_city_but->setIconSize(QSize(56, 56));
1715 next_city_but->setToolTip(_("Show next city"));
1716 connect(next_city_but, &QAbstractButton::clicked, this, &city_dialog::next_city);
1717
1718 prev_city_but = new QPushButton();
1719 connect(prev_city_but, &QAbstractButton::clicked, this, &city_dialog::prev_city);
1720 prev_city_but->setIcon(fc_icons::instance()->get_icon("city-left"));
1721 prev_city_but->setIconSize(QSize(56, 56));
1722 prev_city_but->setToolTip(_("Show previous city"));
1723
1724 happiness_button = new QPushButton();
1725 happiness_button->setIcon(fc_icons::instance()->get_icon("city-switch"));
1726 happiness_button->setIconSize(QSize(56, 28));
1727 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);
1740
1741 hbox_layout->addLayout(vbox_layout, Qt::AlignLeft);
1742 hbox_layout->addWidget(info_wdg, Qt::AlignLeft);
1743 hbox_layout->addWidget(map_box, Qt::AlignCenter);
1744
1745 // Layout with city view and buttons
1746 lefttop_layout->addWidget(citizens_label, Qt::AlignHCenter);
1747 lefttop_layout->addStretch(0);
1748 lefttop_layout->addLayout(hbox_layout);
1749 lefttop_layout->addStretch(50);
1750
1751 // Layout for units/buildings
1752 curr_unit_wdg = new QWidget();
1753 supp_unit_wdg = new QWidget();
1754 curr_impr_wdg = new QWidget();
1755 v_layout = new QVBoxLayout;
1756 v_layout->addWidget(curr_impr);
1757 v_layout->addWidget(scroll3);
1758 v_layout->setContentsMargins(0 , 0 , 0, 0);
1759 v_layout->setSpacing(0);
1760 curr_impr_wdg->setLayout(v_layout);
1761 v_layout = new QVBoxLayout;
1762 v_layout->addWidget(curr_units);
1763 v_layout->addWidget(scroll2);
1764 v_layout->setContentsMargins(0 , 0 , 0, 0);
1765 v_layout->setSpacing(0);
1766 curr_unit_wdg->setLayout(v_layout);
1767 v_layout = new QVBoxLayout;
1768 v_layout->addWidget(supp_units);
1769 v_layout->addWidget(scroll);
1770 v_layout->setContentsMargins(0 , 0 , 0, 0);
1771 v_layout->setSpacing(0);
1772 supp_unit_wdg->setLayout(v_layout);
1773
1774 units_layout->addWidget(curr_unit_wdg);
1775 units_layout->addWidget(supp_unit_wdg);
1776 units_layout->addWidget(curr_impr_wdg);
1777 units_layout->setSpacing(0);
1778 units_layout->setContentsMargins(0 , 0 , 0, 0);
1779
1780 vbox = new QVBoxLayout;
1782 qgbprod = new QGroupBox;
1783 group_box = new QGroupBox(_("Worklist Option"));
1785 work_next_but = new QPushButton(fc_icons::instance()->get_icon(
1786 "go-down"), "");
1787 work_prev_but = new QPushButton(fc_icons::instance()->get_icon(
1788 "go-up"), "");
1789 work_add_but = new QPushButton(fc_icons::instance()->get_icon(
1790 "list-add"), "");
1791 work_rem_but = new QPushButton(style()->standardIcon(
1792 QStyle::SP_DialogDiscardButton), "");
1793 work_but_layout->addWidget(work_add_but);
1794 work_but_layout->addWidget(work_next_but);
1795 work_but_layout->addWidget(work_prev_but);
1796 work_but_layout->addWidget(work_rem_but);
1798 production_combo_p->setToolTip(_("Click to change current production"));
1799 p_table_p = new QTableWidget;
1800
1801 r1 = new QRadioButton(_("Change"));
1802 r2 = new QRadioButton(_("Insert Before"));
1803 r3 = new QRadioButton(_("Insert After"));
1804 r4 = new QRadioButton(_("Add Last"));
1805 r4->setChecked(true);
1806 group_box->setLayout(vbox);
1807
1808
1809 p_table_p->setColumnCount(3);
1810 p_table_p->setProperty("showGrid", "false");
1811 p_table_p->setProperty("selectionBehavior", "SelectRows");
1812 p_table_p->setEditTriggers(QAbstractItemView::NoEditTriggers);
1813 p_table_p->verticalHeader()->setVisible(false);
1814 p_table_p->horizontalHeader()->setVisible(false);
1815 p_table_p->setSelectionMode(QAbstractItemView::SingleSelection);
1816 production_combo_p->setFixedHeight(h);
1817 p_table_p->setMinimumWidth(200);
1818 p_table_p->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
1819 p_table_p->setContextMenuPolicy(Qt::CustomContextMenu);
1820 p_table_p->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
1821 header = p_table_p->horizontalHeader();
1822 header->setStretchLastSection(true);
1823
1824 qgbprod->setTitle(_("Worklist"));
1825 vbox_layout->setSpacing(0);
1826 vbox_layout->addWidget(prod_options);
1827 vbox_layout->addWidget(buy_button);
1828 vbox_layout->addWidget(production_combo_p);
1829 vbox_layout->addLayout(work_but_layout);
1830 vbox_layout->addWidget(p_table_p);
1831 qgbprod->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1832 qgbprod->setLayout(vbox_layout);
1833
1834 worklist_layout->setSpacing(0);
1835 worklist_layout->addWidget(qgbprod);
1836 connect(p_table_p,
1837 &QWidget::customContextMenuRequested, this,
1840 connect(work_add_but, &QAbstractButton::clicked, this, &city_dialog::show_targets_worklist);
1841 connect(work_prev_but, &QAbstractButton::clicked, this, &city_dialog::worklist_up);
1842 connect(work_next_but, &QAbstractButton::clicked, this, &city_dialog::worklist_down);
1843 connect(work_rem_but, &QAbstractButton::clicked, this, &city_dialog::worklist_del);
1844 connect(p_table_p,
1845 &QTableWidget::itemDoubleClicked,
1847 connect(p_table_p->selectionModel(),
1849 const QItemSelection &)),
1851 const QItemSelection &)));
1852 happiness_group = new QGroupBox(_("Happiness"));
1853 gridl = new QGridLayout;
1854
1855 nationality_table = new QTableWidget;
1856 nationality_table->setColumnCount(3);
1857 nationality_table->setProperty("showGrid", "false");
1858 nationality_table->setProperty("selectionBehavior", "SelectRows");
1859 nationality_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1860 nationality_table->verticalHeader()->setVisible(false);
1861 nationality_table->horizontalHeader()->setStretchLastSection(true);
1862
1863 info_list.clear();
1864 info_list << _("Cities:") << _("Luxuries:") << _("Buildings:")
1865 << _("Nationality:") << _("Units:") << _("Wonders:");
1866
1867 for (int i = 0; i < info_list.count(); i++) {
1868 lab_table[i] = new city_label(1 + i, this);
1869 gridl->addWidget(lab_table[i], i, 1, 1, 1);
1870 lab2 = new QLabel(this);
1871 lab2->setFont(*small_font);
1872 lab2->setProperty(fonts::notify_label, "true");
1873 lab2->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1874 lab2->setText(info_list.at(i));
1875 gridl->addWidget(lab2, i, 0, 1, 1);
1876 }
1877
1878 gridl->setSpacing(0);
1879 happiness_group->setLayout(gridl);
1880
1881
1885 happiness_layout->setStretch(0, 10);
1886 happiness_widget = new QWidget();
1888 qgbox = new QGroupBox(_("Presets:"));
1889 qsliderbox = new QGroupBox(_("Governor settings"));
1890 result_box = new QGroupBox(_("Results:"));
1891 hbox = new QHBoxLayout;
1892 gridl = new QGridLayout;
1894
1895 qpush2
1896 = new QPushButton(style()->standardIcon(QStyle::SP_DialogSaveButton),
1897 _("Save"));
1898 connect(qpush2, &QAbstractButton::pressed, this, &city_dialog::save_cma);
1899
1900 cma_info_text = new QLabel;
1901 cma_info_text->setFont(*small_font);
1902 cma_info_text->setAlignment(Qt::AlignCenter);
1903 cma_table = new QTableWidget;
1904 cma_table->setColumnCount(1);
1905 cma_table->setProperty("showGrid", "false");
1906 cma_table->setProperty("selectionBehavior", "SelectRows");
1907 cma_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1908 cma_table->setSelectionMode(QAbstractItemView::SingleSelection);
1909 cma_table->setContextMenuPolicy(Qt::CustomContextMenu);
1910 cma_table->verticalHeader()->setVisible(false);
1911 cma_table->horizontalHeader()->setVisible(false);
1912 cma_table->horizontalHeader()->setSectionResizeMode(
1913 QHeaderView::Stretch);
1914
1915 connect(cma_table->selectionModel(),
1917 const QItemSelection &)),
1919 const QItemSelection &)));
1920 connect(cma_table,
1921 &QWidget::customContextMenuRequested, this,
1923 connect(cma_table, &QTableWidget::cellDoubleClicked, this,
1925 gridl->addWidget(cma_table, 0, 0, 1, 2);
1926 qgbox->setLayout(gridl);
1927 hbox->addWidget(cma_info_text);
1928 result_box->setLayout(hbox);
1929 str_list << _("Food") << _("Shield") << _("Trade") << _("Gold")
1930 << _("Luxury") << _("Science") << _("Celebrate")
1931 << _("Maximize growth");
1932 some_label = new QLabel(_("Minimal Surplus"));
1934 some_label->setAlignment(Qt::AlignRight);
1935 slider_grid->addWidget(some_label, 0, 0, 1, 3);
1936 some_label = new QLabel(_("Priority"));
1938 some_label->setAlignment(Qt::AlignCenter);
1939 slider_grid->addWidget(some_label, 0, 3, 1, 2);
1940
1941 list_size = str_list.count();
1942 for (int i = 0; i < list_size; i++) {
1943 some_label = new QLabel(str_list.at(i));
1944 slider_grid->addWidget(some_label, i + 1, 0, 1, 1);
1945 some_label = new QLabel("0");
1946 some_label->setMinimumWidth(25);
1947
1948 if (i < list_size - 2) {
1949 slider = new QSlider(Qt::Horizontal);
1950 slider->setPageStep(1);
1951 slider->setFocusPolicy(Qt::TabFocus);
1952 slider_tab[2 * i] = slider;
1953 slider->setRange(-20, 20);
1954 slider->setSingleStep(1);
1955 slider_grid->addWidget(some_label, i + 1, 1, 1, 1);
1956 slider_grid->addWidget(slider, i + 1, 2, 1, 1);
1957 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1958
1959 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1960 } else if (i == list_size - 2) {
1962 slider_grid->addWidget(cma_celeb_checkbox, i + 1, 2 , 1 , 1);
1963 connect(cma_celeb_checkbox,
1964 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1965 } else {
1966 fc_assert(i == list_size - 1);
1967
1969 slider_grid->addWidget(cma_max_growth, i + 1, 2 , 1 , 1);
1970 connect(cma_max_growth,
1971 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1972 }
1973
1974 if (i <= list_size - 2) {
1975 some_label = new QLabel("0");
1976 some_label->setMinimumWidth(25);
1977 slider = new QSlider(Qt::Horizontal);
1978 slider->setFocusPolicy(Qt::TabFocus);
1979 slider->setRange(0, 25);
1980 slider_tab[2 * i + 1] = slider;
1981 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1982 slider_grid->addWidget(some_label, i + 1, 3, 1, 1);
1983 slider_grid->addWidget(slider, i + 1, 4, 1, 1);
1984 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1985 }
1986 }
1987
1988 cma_enable_but = new QPushButton();
1989 cma_enable_but->setFocusPolicy(Qt::TabFocus);
1990 connect(cma_enable_but, &QAbstractButton::pressed, this, &city_dialog::cma_enable);
1991 slider_grid->addWidget(cma_enable_but, O_LAST + 4, 0, 1, 3);
1992 slider_grid->addWidget(qpush2, O_LAST + 4, 3, 1, 2);
1993
1994 qsliderbox->setLayout(slider_grid);
1995 cma_result = new QLabel;
1996 cma_result_pix = new QLabel;
1997
1998 hbox = new QHBoxLayout;
1999 hbox->addWidget(cma_result_pix);
2000 hbox->addWidget(cma_result);
2001 hbox->addStretch(10);
2002 right_layout->addWidget(qgbox);
2003 right_layout->addLayout(hbox);
2004 right_layout->addWidget(qsliderbox);
2005
2006 split_widget1 = new QWidget;
2007 split_widget1->setLayout(worklist_layout);
2008 split_widget2 = new QWidget;
2009 split_widget2->setLayout(units_layout);
2012 prod_unit_splitter->setStretchFactor(0, 3);
2013 prod_unit_splitter->setStretchFactor(1, 97);
2014 prod_unit_splitter->setOrientation(Qt::Horizontal);
2016 top_widget = new QWidget;
2017 top_widget->setLayout(lefttop_layout);
2018 top_widget->setSizePolicy(QSizePolicy::Minimum,
2019 QSizePolicy::Minimum);
2020 scroll_info = new QScrollArea();
2021 scroll_info->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
2022 scroll_unit = new QScrollArea();
2023 scroll_info->setWidget(top_widget);
2024 scroll_info->setWidgetResizable(true);
2025 prod_happ_widget = new QWidget;
2026 prod_happ_widget->setLayout(leftbot_layout);
2027 prod_happ_widget->setSizePolicy(QSizePolicy::MinimumExpanding,
2028 QSizePolicy::MinimumExpanding);
2029 scroll_unit->setWidget(prod_happ_widget);
2030 scroll_unit->setWidgetResizable(true);
2033 central_left_splitter->setStretchFactor(0, 40);
2034 central_left_splitter->setStretchFactor(1, 60);
2035 central_left_splitter->setOrientation(Qt::Vertical);
2037
2038 split_widget1 = new QWidget(this);
2039 split_widget2 = new QWidget(this);
2040 split_widget1->setLayout(left_layout);
2041 split_widget2->setLayout(right_layout);
2042 central_splitter->addWidget(split_widget1);
2043 central_splitter->addWidget(split_widget2);
2044 central_splitter->setStretchFactor(0, 99);
2045 central_splitter->setStretchFactor(1, 1);
2046 central_splitter->setOrientation(Qt::Horizontal);
2048 setSizeGripEnabled(true);
2050
2051 installEventFilter(this);
2052
2053 ::city_dlg_created = true;
2054}
2055
2056/************************************************************************/
2060{
2061
2062 cid cprod;
2063 int i, pos;
2064 int item, targets_used;
2066 QString str;
2067 struct item items[MAX_NUM_PRODUCTION_TARGETS];
2068 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
2069 struct universal univ;
2070
2071 pos = 0;
2074 name_and_sort_items(targets, targets_used, items, false, dlgcity);
2075
2076 for (item = 0; item < targets_used; item++) {
2077 if (can_city_build_now(dlgcity, &items[item].item)) {
2078 prod_list << cid_encode(items[item].item);
2079 }
2080 }
2081
2082 for (i = 0; i < prod_list.size(); i++) {
2083 if (prod_list.at(i) == cprod) {
2084 if (next) {
2085 pos = i + 1;
2086 } else {
2087 pos = i - 1;
2088 }
2089 }
2090 }
2091 if (pos == prod_list.size()) {
2092 pos = 0;
2093 }
2094 if (pos == - 1) {
2095 pos = prod_list.size() - 1;
2096 }
2097 univ = cid_decode(static_cast<cid>(prod_list.at(pos)));
2099}
2100
2101/************************************************************************/
2105{
2106 if (happiness_shown) {
2107 happiness_button->setToolTip(_("Show city production"));
2108 } else {
2109 happiness_button->setToolTip(_("Show happiness information"));
2110 }
2111}
2112
2113/************************************************************************/
2117{
2118 setUpdatesEnabled(false);
2119
2120 if (!happiness_shown) {
2121 leftbot_layout->replaceWidget(prod_unit_splitter,
2123 Qt::FindDirectChildrenOnly);
2124 prod_unit_splitter->hide();
2125 happiness_widget->show();
2126 happiness_widget->updateGeometry();
2127 } else {
2128 leftbot_layout->replaceWidget(happiness_widget,
2130 Qt::FindDirectChildrenOnly);
2131 prod_unit_splitter->show();
2132 prod_unit_splitter->updateGeometry();
2133 happiness_widget->hide();
2134 }
2135
2136 setUpdatesEnabled(true);
2137 update();
2140}
2141
2142/************************************************************************/
2146{
2147 if (NULL == client.conn.playing
2149 prev_city_but->setDisabled(true);
2150 next_city_but->setDisabled(true);
2151 buy_button->setDisabled(true);
2152 cma_enable_but->setDisabled(true);
2153 production_combo_p->setDisabled(true);
2154 current_units->setDisabled(true);
2155 supported_units->setDisabled(true);
2156 view->setDisabled(true);
2157
2158 if (!client_is_observer()) {
2159 }
2160 } else {
2161 prev_city_but->setEnabled(true);
2162 next_city_but->setEnabled(true);
2163 buy_button->setEnabled(true);
2164 cma_enable_but->setEnabled(true);
2165 production_combo_p->setEnabled(true);
2166 current_units->setEnabled(true);
2167 supported_units->setEnabled(true);
2168 view->setEnabled(true);
2169 }
2170
2172 cma_enable_but->setEnabled(true);
2173 } else {
2174 cma_enable_but->setDisabled(true);
2175 }
2176
2178}
2179
2180/************************************************************************/
2184{
2185 work_next_but->setDisabled(true);
2186 work_prev_but->setDisabled(true);
2187 work_add_but->setDisabled(true);
2188 work_rem_but->setDisabled(true);
2189
2191 work_add_but->setEnabled(true);
2192
2193 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount()) {
2194 work_rem_but->setEnabled(true);
2195 }
2196
2197 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount() - 1) {
2198 work_next_but->setEnabled(true);
2199 }
2200
2201 if (selected_row_p > 0 && selected_row_p < p_table_p->rowCount()) {
2202 work_prev_but->setEnabled(true);
2203 }
2204 }
2205}
2206
2207/************************************************************************/
2211{
2212 if (citizen_pixmap) {
2213 citizen_pixmap->detach();
2214 delete citizen_pixmap;
2215 }
2216
2217 cma_table->clear();
2218 p_table_p->clear();
2219 nationality_table->clear();
2221 supported_units->clear_layout();
2222 removeEventFilter(this);
2223 ::city_dlg_created = false;
2224
2225 // Delete the one widget that currently does NOT have a parent
2226 if (happiness_shown) {
2227 delete prod_unit_splitter;
2228 } else {
2229 delete happiness_widget;
2230 }
2231}
2232
2233/************************************************************************/
2237{
2238 gui()->qt_settings.city_geometry = saveGeometry();
2239 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2240 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2241 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2242}
2243
2244/************************************************************************/
2248{
2249 if (!gui()->qt_settings.city_geometry.isNull()) {
2250 restoreGeometry(gui()->qt_settings.city_geometry);
2251 prod_unit_splitter->restoreState(gui()->qt_settings.city_splitter1);
2252 central_left_splitter->restoreState(gui()->qt_settings.city_splitter2);
2253 central_splitter->restoreState(gui()->qt_settings.city_splitter3);
2254 } else {
2255 QRect rect = QApplication::primaryScreen()->availableGeometry();
2256
2257 resize((rect.width() * 4) / 5, (rect.height() * 5) / 6);
2258 }
2259}
2260
2261/************************************************************************/
2265{
2266 gui()->qt_settings.city_geometry = saveGeometry();
2267 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2268 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2269 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2270}
2271
2272/************************************************************************/
2275bool city_dialog::eventFilter(QObject *obj, QEvent *event)
2276{
2277
2278 if (obj == this) {
2279 if (event->type() == QEvent::KeyPress) {
2280 }
2281
2282 if (event->type() == QEvent::ShortcutOverride) {
2283 QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
2284 if (key_event->key() == Qt::Key_Right) {
2285 next_city();
2286 event->setAccepted(true);
2287 return true;
2288 }
2289 if (key_event->key() == Qt::Key_Left) {
2290 prev_city();
2291 event->setAccepted(true);
2292 return true;
2293 }
2294 if (key_event->key() == Qt::Key_Up) {
2295 change_production(true);
2296 event->setAccepted(true);
2297 return true;
2298 }
2299 if (key_event->key() == Qt::Key_Down) {
2300 change_production(false);
2301 event->setAccepted(true);
2302 return true;
2303 }
2304 }
2305 }
2306 return QObject::eventFilter(obj, event);
2307}
2308
2309/************************************************************************/
2313{
2315 const int city_id = dlgcity->id;
2316
2317 if (!can_client_issue_orders()) {
2318 return;
2319 }
2320
2321 ask = new hud_input_box(gui()->central_wdg);
2322 ask->set_text_title_definput(_("What should we rename the city to?"),
2323 _("Rename City"), city_name_get(dlgcity));
2324 ask->setAttribute(Qt::WA_DeleteOnClose);
2325 connect(ask, &hud_message_box::accepted, this, [=]() {
2326 struct city *pcity = game_city_by_number(city_id);
2328
2329 if (!pcity) {
2330 return;
2331 }
2332
2333 ask_bytes = ask->input_edit.text().toUtf8();
2334 ::city_rename(pcity, ask_bytes.data());
2335 });
2336 ask->show();
2337}
2338
2339/************************************************************************/
2343{
2344 zoom = zoom * 1.2;
2345 if (dlgcity) {
2346 view->set_pixmap(dlgcity, zoom);
2347 }
2349 left_layout->update();
2350}
2351
2352/************************************************************************/
2356{
2357 zoom = zoom / 1.2;
2358 if (dlgcity) {
2359 view->set_pixmap(dlgcity, zoom);
2360 }
2362 left_layout->update();
2363}
2364
2365/************************************************************************/
2369{
2370 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
2371
2372 ask->set_text_title_definput(_("What should we name the preset?"),
2373 _("Name new preset"),
2374 _("new preset"));
2375 ask->setAttribute(Qt::WA_DeleteOnClose);
2376 connect(ask, &hud_message_box::accepted, this,
2378 struct cm_parameter param;
2379 QByteArray ask_bytes = ask->input_edit.text().toUtf8();
2380 QString text = ask_bytes.data();
2381 if (!text.isEmpty()) {
2382 param.allow_disorder = false;
2383 param.allow_specialists = true;
2384 param.require_happy = cma_celeb_checkbox->isChecked();
2385 param.max_growth = cma_max_growth->isChecked();
2386 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2387
2388 for (int i = O_FOOD; i < O_LAST; i++) {
2389 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2390 param.factor[i] = slider_tab[2 * i + 1]->value();
2391 }
2392
2393 ask_bytes = text.toUtf8();
2394 cmafec_preset_add(ask_bytes.data(), &param);
2396 }
2397 });
2398 ask->show();
2399}
2400
2401/************************************************************************/
2405{
2408
2409 return;
2410 }
2411
2412 cma_changed();
2414}
2415
2416/************************************************************************/
2420{
2421 struct cm_parameter param;
2422
2423 param.allow_disorder = false;
2424 param.allow_specialists = true;
2425 param.require_happy = cma_celeb_checkbox->isChecked();
2426 param.max_growth = cma_max_growth->isChecked();
2427 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2428
2429 for (int i = O_FOOD; i < O_LAST; i++) {
2430 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2431 param.factor[i] = slider_tab[2 * i + 1]->value();
2432 }
2433
2435}
2436
2437/************************************************************************/
2441{
2442 const struct cm_parameter *param;
2443
2444 if (!can_client_issue_orders()) {
2445 return;
2446 }
2450 }
2451
2454}
2455
2456/************************************************************************/
2460 const QItemSelection &ds)
2461{
2462 const struct cm_parameter *param;
2463 QModelIndex index;
2464 QModelIndexList indexes = sl.indexes();
2465
2466 if (indexes.isEmpty() || cma_table->signalsBlocked()) {
2467 return;
2468 }
2469
2470 index = indexes.at(0);
2471 int ind = index.row();
2472
2473 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2474 return;
2475 }
2476
2479
2483 }
2484}
2485
2486/************************************************************************/
2490{
2491 struct cm_parameter param;
2492 const struct cm_parameter *cparam;
2493 int output;
2494 QVariant qvar;
2495 QLabel *label;
2496
2497 if (!cma_is_city_under_agent(dlgcity, &param)) {
2498 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2499 return;
2500 }
2502 cm_copy_parameter(&param, cparam);
2503 }
2504
2505 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2506 slider_tab[output]->blockSignals(true);
2507 }
2508
2509 for (output = O_FOOD; output < O_LAST; output++) {
2510 qvar = slider_tab[2 * output + 1]->property("FC");
2511 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2512 label->setText(QString::number(param.factor[output]));
2513 slider_tab[2 * output + 1]->setValue(param.factor[output]);
2514 qvar = slider_tab[2 * output]->property("FC");
2515 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2516 label->setText(QString::number(param.minimal_surplus[output]));
2517 slider_tab[2 * output]->setValue(param.minimal_surplus[output]);
2518 }
2519
2520 slider_tab[2 * O_LAST + 1]->blockSignals(true);
2521 qvar = slider_tab[2 * O_LAST + 1]->property("FC");
2522 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2523 label->setText(QString::number(param.happy_factor));
2524 slider_tab[2 * O_LAST + 1]->setValue(param.happy_factor);
2525 slider_tab[2 * O_LAST + 1]->blockSignals(false);
2526 cma_celeb_checkbox->blockSignals(true);
2527 cma_celeb_checkbox->setChecked(param.require_happy);
2528 cma_celeb_checkbox->blockSignals(false);
2529 cma_max_growth->blockSignals(true);
2530 cma_max_growth->setChecked(param.max_growth);
2531 cma_max_growth->blockSignals(false);
2532
2533 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2534 slider_tab[output]->blockSignals(false);
2535 }
2536}
2537
2538/************************************************************************/
2542{
2543 QString s;
2545 struct cm_parameter param;
2546 QPixmap pix;
2547 int i;
2548
2549 cma_table->clear();
2550 cma_table->setRowCount(0);
2551
2552 for (i = 0; i < cmafec_preset_num(); i++) {
2553 item = new QTableWidgetItem;
2554 item->setText(cmafec_preset_get_descr(i));
2555 cma_table->insertRow(i);
2556 cma_table->setItem(i, 0, item);
2557 }
2558
2559 if (cmafec_preset_num() == 0) {
2560 cma_table->insertRow(0);
2561 item = new QTableWidgetItem;
2562 item->setText(_("No governor defined"));
2563 cma_table->setItem(0, 0, item);
2564 }
2565
2567 view->update();
2569 pix = style()->standardPixmap(QStyle::SP_DialogApplyButton);
2570 pix = pix.scaled(2 * pix.width(), 2 * pix.height(),
2571 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2572 cma_result_pix->setPixmap(pix);
2573 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2574 // TRANS: %1 is custom string chosen by player
2575 cma_result->setText(QString(_("<h3>Governor Enabled<br>(%1)</h3>"))
2576 .arg(s.toHtmlEscaped()));
2577 cma_result->setAlignment(Qt::AlignCenter);
2578 } else {
2579 pix = style()->standardPixmap(QStyle::SP_DialogCancelButton);
2580 pix = pix.scaled(1.6 * pix.width(), 1.6 * pix.height(),
2581 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2582 cma_result_pix->setPixmap(pix);
2583 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2584 cma_result->setText(QString(_("<h3>Governor Disabled</h3>")));
2585 cma_result->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
2586 }
2587
2591 cm_parameter *const >(&param));
2592 if (i >= 0 && i < cma_table->rowCount()) {
2593 cma_table->blockSignals(true);
2594 cma_table->setCurrentCell(i, 0);
2595 cma_table->blockSignals(false);
2596 }
2597
2598 cma_enable_but->setText(_("Disable"));
2599 } else {
2600 cma_enable_but->setText(_("Enable"));
2601 }
2603}
2604
2605/************************************************************************/
2609{
2610 int i;
2612
2613 i = cma_table->currentRow();
2614
2615 if (i == -1 || cmafec_preset_num() == 0) {
2616 return;
2617 }
2618
2620 ask->set_text_title(_("Remove this preset?"), cmafec_preset_get_descr(i));
2621 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
2622 ask->setDefaultButton(QMessageBox::Cancel);
2623 ask->setAttribute(Qt::WA_DeleteOnClose);
2624 connect(ask, &hud_message_box::accepted, this,
2628 });
2629 ask->show();
2630}
2631
2632/************************************************************************/
2636{
2638 cma_changed();
2640 }
2641}
2642
2643/************************************************************************/
2647{
2648 QVariant qvar;
2649 QSlider *slider;
2650 QLabel *label;
2651
2653 qvar = slider->property("FC");
2654
2655 if (qvar.isNull() || !qvar.isValid()) {
2656 return;
2657 }
2658
2659 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2660 label->setText(QString::number(value));
2661
2663 cma_changed();
2665 }
2666}
2667
2668/************************************************************************/
2687
2688/************************************************************************/
2692{
2693 QMenu *cma_menu = new QMenu(this);
2695
2696 cma_menu->setAttribute(Qt::WA_DeleteOnClose);
2697 cma_del_item = cma_menu->addAction(_("Remove Governor"));
2698 connect(cma_menu, &QMenu::triggered, this,
2700 if (act == cma_del_item) {
2701 cma_remove();
2702 }
2703 });
2704
2705 cma_menu->popup(QCursor::pos());
2706}
2707
2708/************************************************************************/
2712{
2713 QAction *action;
2714 QAction *disband;
2719 QMap<QString, cid>::const_iterator map_iter;
2720 QMenu *change_menu;
2721 QMenu *insert_menu;
2722 QMenu *list_menu;
2723 QMenu *options_menu;
2724 int city_id = dlgcity->id;
2725
2726 if (!can_client_issue_orders()) {
2727 return;
2728 }
2729 list_menu = new QMenu(this);
2730 change_menu = list_menu->addMenu(_("Change worklist"));
2731 insert_menu = list_menu->addMenu(_("Insert worklist"));
2732 wl_clear = list_menu->addAction(_("Clear"));
2733 connect(wl_clear, &QAction::triggered, this, &city_dialog::clear_worklist);
2734 list.clear();
2735
2739
2740 if (list.count() == 0) {
2741 wl_empty = change_menu->addAction(_("(no worklists defined)"));
2742 insert_menu->addAction(wl_empty);
2743 }
2744
2745 map_iter = list.constBegin();
2746
2747 while (map_iter != list.constEnd()) {
2748 action = change_menu->addAction(map_iter.key());
2749 action->setData(map_iter.value());
2750
2751 action = insert_menu->addAction(map_iter.key());
2752 action->setData(map_iter.value());
2753
2754 map_iter++;
2755 }
2756
2757 wl_save = list_menu->addAction(_("Save worklist"));
2758 connect(wl_save, &QAction::triggered, this, &city_dialog::save_worklist);
2759 options_menu = list_menu->addMenu(_("Options"));
2760 disband = options_menu->addAction(_("Allow disbanding city"));
2761 disband->setCheckable(true);
2762 disband->setChecked(is_city_option_set(dlgcity, CITYO_DISBAND));
2763 connect(disband, &QAction::triggered, this,
2765
2766 connect(change_menu, &QMenu::triggered, this, [=](QAction *act) {
2767 QVariant id = act->data();
2768 struct city *pcity = game_city_by_number(city_id);
2769 const struct worklist *worklist;
2770
2771 if (!pcity) {
2772 return;
2773 }
2774
2775#ifndef FC_QT5_MODE
2776 fc_assert_ret(id.typeId() == QMetaType::Int);
2777#else // FC_QT5_MODE
2778 fc_assert_ret(id.type() == QVariant::Int);
2779#endif // FC_QT5_MODE
2780
2783 });
2784
2785 connect(insert_menu, &QMenu::triggered, this,
2787 QVariant id = act->data();
2788 struct city *pcity = game_city_by_number(city_id);
2789 const struct worklist *worklist;
2790
2791 if (!pcity) {
2792 return;
2793 }
2794
2795#ifndef FC_QT5_MODE
2796 fc_assert_ret(id.typeId() == QMetaType::Int);
2797#else // FC_QT5_MODE
2798 fc_assert_ret(id.type() == QVariant::Int);
2799#endif // FC_QT5_MODE
2800
2803 });
2804
2805 list_menu->popup(QCursor::pos());
2806}
2807
2808/************************************************************************/
2812{
2813 QString str;
2814 int value;
2815
2816 buy_button->setDisabled(true);
2817
2818 if (!client_is_observer() && client.conn.playing != NULL) {
2819 value = dlgcity->client.buy_cost;
2820 str = QString(PL_("Buy (%1 gold)", "Buy (%1 gold)",
2821 value)).arg(QString::number(value));
2822
2823 if (client.conn.playing->economic.gold >= value && value != 0) {
2824 buy_button->setEnabled(true);
2825 }
2826 } else {
2827 str = QString(_("Buy"));
2828 }
2829
2830 buy_button->setText(str);
2831}
2832
2833/************************************************************************/
2837{
2838 enum citizen_category categories[MAX_CITY_SIZE];
2839 int i, j, width, height;
2840 QPainter p;
2841 QPixmap *pix;
2843 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
2844 int h = tileset_small_sprite_height(tileset) / gui()->map_scale;
2845
2846 i = 1 + (num_citizens * 5 / 200);
2847 w = w / i;
2848 QRect source_rect(0, 0, w, h);
2849 QRect dest_rect(0, 0, w, h);
2850 width = w * num_citizens;
2851 height = h;
2852
2853 if (citizen_pixmap) {
2854 citizen_pixmap->detach();
2855 delete citizen_pixmap;
2856 }
2857
2859
2860 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2861 dest_rect.moveTo(i * w, 0);
2862 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2863 p.begin(citizen_pixmap);
2864 p.drawPixmap(dest_rect, *pix, source_rect);
2865 p.end();
2866 }
2867
2869 citizens_label->setPixmap(*citizen_pixmap);
2870
2873
2874 for (int k = 0; k < FEELING_LAST - 1; k++) {
2877 static_cast<citizen_feeling>(k),
2878 categories);
2879
2880 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2881 dest_rect.moveTo(i * w, 0);
2882 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2883 p.begin(citizen_pixmap);
2884 p.drawPixmap(dest_rect, *pix, source_rect);
2885 p.end();
2886 }
2887
2888 lab_table[k]->setPixmap(*citizen_pixmap);
2889
2890 switch (k) {
2891 case FEELING_BASE:
2892 lab_table[k]->setToolTip(text_happiness_cities(dlgcity));
2893 break;
2894
2895 case FEELING_LUXURY:
2896 lab_table[k]->setToolTip(text_happiness_luxuries(dlgcity));
2897 break;
2898
2899 case FEELING_EFFECT :
2901 break;
2902
2905 break;
2906
2907 case FEELING_MARTIAL:
2908 lab_table[k]->setToolTip(text_happiness_units(dlgcity));
2909 break;
2910
2911 default:
2912 break;
2913 }
2914 }
2915}
2916
2917/************************************************************************/
2921{
2922 setUpdatesEnabled(false);
2923 production_combo_p->blockSignals(true);
2924
2925 if (dlgcity) {
2926 view->set_pixmap(dlgcity, zoom);
2927 view->update();
2928 update_title();
2934 update_units();
2938 } else {
2940 }
2941
2942 production_combo_p->blockSignals(false);
2943 setUpdatesEnabled(true);
2945 update();
2946}
2947
2948
2949/************************************************************************/
2953{
2954 QFont f = QApplication::font();
2955 QFontMetrics fm(f);
2956 QPixmap *pix = NULL;
2958 QString str;
2961 char buf[8];
2963 int h;
2964 int i = 0;
2965 struct sprite *sprite;
2966
2967 h = fm.height() + 6;
2968 nationality_table->clear();
2969 nationality_table->setRowCount(0);
2970 info_list.clear();
2971 info_list << _("#") << _("Flag") << _("Nation");
2972 nationality_table->setHorizontalHeaderLabels(info_list);
2973
2974 citizens_iterate(dlgcity, pslot, nationality) {
2975 nationality_table->insertRow(i);
2976
2977 for (int j = 0; j < nationality_table->columnCount(); j++) {
2978 item = new QTableWidgetItem;
2979
2980 switch (j) {
2981 case 0:
2983
2984 if (nationality_i == 0) {
2985 str = "-";
2986 } else {
2987 fc_snprintf(buf, sizeof(buf), "%d", nationality_i);
2988 str = QString(buf);
2989 }
2990
2991 item->setText(str);
2992 break;
2993
2994 case 1:
2997 (player_slot_get_player(pslot)));
2998
2999 if (sprite != NULL) {
3000 pix = sprite->pm;
3001 pix_scaled = pix->scaledToHeight(h);
3002 item->setData(Qt::DecorationRole, pix_scaled);
3003 } else {
3004 item->setText("FLAG MISSING");
3005 }
3006 break;
3007
3008 case 2:
3010 (player_slot_get_player(pslot)));
3011 break;
3012
3013 default:
3014 break;
3015 }
3016 nationality_table->setItem(i, j, item);
3017 }
3018 i++;
3020 nationality_table->horizontalHeader()->setStretchLastSection(false);
3021 nationality_table->resizeColumnsToContents();
3022 nationality_table->resizeRowsToContents();
3023 nationality_table->horizontalHeader()->setStretchLastSection(true);
3024}
3025
3026/************************************************************************/
3030{
3031 int illness = 0;
3032 char buffer[512];
3033 char buf_info[NUM_INFO_FIELDS][512];
3034 char buf_tooltip[NUM_INFO_FIELDS][512];
3035 int granaryturns;
3036 int spec;
3037
3038 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3039 buf_info[i][0] = '\0';
3040 buf_tooltip[i][0] = '\0';
3041 }
3042
3043 // Fill the buffers with the necessary info
3044 spec = city_specialists(dlgcity);
3046 "%3d (%4d)", dlgcity->size, spec);
3048 _("Population: %d, Specialists: %d"),
3049 dlgcity->size, spec);
3050 fc_snprintf(buf_info[INFO_FOOD], sizeof(buf_info[INFO_FOOD]), "%3d (%+4d)",
3053 "%3d (%+4d)", dlgcity->prod[O_SHIELD] + dlgcity->waste[O_SHIELD],
3055 fc_snprintf(buf_info[INFO_TRADE], sizeof(buf_info[INFO_TRADE]), "%3d (%+4d)",
3058 fc_snprintf(buf_info[INFO_GOLD], sizeof(buf_info[INFO_GOLD]), "%3d (%+4d)",
3065 "%4d/%-4d", dlgcity->food_stock,
3067
3069 sizeof(buf_tooltip[INFO_FOOD]));
3071 sizeof(buf_tooltip[INFO_SHIELD]));
3073 sizeof(buf_tooltip[INFO_TRADE]));
3075 sizeof(buf_tooltip[INFO_GOLD]));
3077 sizeof(buf_tooltip[INFO_SCIENCE]));
3079 sizeof(buf_tooltip[INFO_LUXURY]));
3081 sizeof(buf_tooltip[INFO_CULTURE]));
3083 sizeof(buf_tooltip[INFO_POLLUTION]));
3085 sizeof(buf_tooltip[INFO_ILLNESS]));
3086
3088
3089 if (granaryturns == 0) {
3090 // TRANS: city growth is blocked. Keep short.
3091 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("blocked"));
3092 } else if (granaryturns == FC_INFINITY) {
3093 // TRANS: city is not growing. Keep short.
3094 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("never"));
3095 } else {
3096 /* A negative value means we'll have famine in that many turns.
3097 But that's handled down below. */
3098 // TRANS: city growth turns. Keep short.
3100 PL_("%d turn", "%d turns", abs(granaryturns)),
3101 abs(granaryturns));
3102 }
3103
3105 "%4d", dlgcity->waste[O_TRADE]);
3112
3113 if (!game.info.illness_on) {
3115 " -.-");
3116 } else {
3117 illness = city_illness_calc(dlgcity, NULL, NULL, NULL, NULL);
3118 // Illness is in tenth of percent
3120 "%5.1f%%", (float) illness / 10.0);
3121 }
3122 if (dlgcity->steal) {
3124 PL_("%d time", "%d times", dlgcity->steal), dlgcity->steal);
3125 } else {
3127 _("Not stolen"));
3128 }
3129
3131 sizeof(buf_info[INFO_AIRLIFT]));
3133 sizeof(buf_tooltip[INFO_AIRLIFT]));
3134
3135 get_city_dialog_output_text(dlgcity, O_FOOD, buffer, sizeof(buffer));
3136
3137 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3138 qlt[i]->setText(QString(buf_info[i]));
3139
3140 if (buf_tooltip[i][0]) {
3141 qlt[i]->setToolTip("<pre>" + QString(buf_tooltip[i]).toHtmlEscaped()
3142 + "</pre>");
3143 }
3144 }
3145}
3146
3147/************************************************************************/
3151{
3154
3155 setContentsMargins(0, 0 ,0 ,0);
3157 dlgcity = qcity;
3158 production_combo_p->blockSignals(true);
3159 refresh();
3160 production_combo_p->blockSignals(false);
3161}
3162
3163/************************************************************************/
3167{
3168 struct worklist queue;
3169
3170 city_get_queue(dlgcity, &queue);
3171
3173 return;
3174 }
3175
3177 city_set_queue(dlgcity, &queue);
3178}
3179
3180/************************************************************************/
3184{
3185 unit_item *ui;
3186 struct unit_list *units;
3187 char buf[256];
3188 int n;
3189 int happy_cost;
3191 supported_units->setUpdatesEnabled(false);
3192 supported_units->clear_layout();
3193
3194 if (NULL != client.conn.playing
3197 } else {
3198 units = dlgcity->units_supported;
3199 }
3200
3201 unit_list_iterate(units, punit) {
3203 ui = new unit_item(this, punit, true, happy_cost);
3204 ui->init_pix();
3205 supported_units->add_item(ui);
3207 n = unit_list_size(units);
3208 fc_snprintf(buf, sizeof(buf), _("Supported units %d"), n);
3209 supp_units->setText(QString(buf));
3210 supported_units->update_units();
3211 supported_units->setUpdatesEnabled(true);
3212 current_units->setUpdatesEnabled(true);
3214
3215 if (NULL != client.conn.playing
3218 } else {
3219 units = dlgcity->tile->units;
3220 }
3221
3222 unit_list_iterate(units, punit) {
3223 ui = new unit_item(this , punit, false);
3224 ui->init_pix();
3227
3228 n = unit_list_size(units);
3229 fc_snprintf(buf, sizeof(buf), _("Present units %d"), n);
3230 curr_units->setText(QString(buf));
3231
3233 current_units->setUpdatesEnabled(true);
3234}
3235
3236/************************************************************************/
3240 const QItemSelection &ds)
3241{
3242 QModelIndex index;
3243 QModelIndexList indexes = sl.indexes();
3244
3245 if (indexes.isEmpty()) {
3246 return;
3247 }
3248
3249 index = indexes.at(0);
3250 selected_row_p = index.row();
3252}
3253
3254/************************************************************************/
3258{
3259 int size, i;
3260 struct city *other_pcity = NULL;
3261
3262 if (NULL == client.conn.playing) {
3263 return;
3264 }
3265
3267
3268 if (size <= 1) {
3269 return;
3270 }
3271
3272 for (i = 0; i < size; i++) {
3274 break;
3275 }
3276 }
3277
3278 if (i >= size - 1) {
3279 // Current city last in the list (size - 1) or disappeared (size)
3281 } else {
3283 }
3284
3287}
3288
3289/************************************************************************/
3293{
3294 int size, i;
3295 struct city *other_pcity = NULL;
3296
3297 if (NULL == client.conn.playing) {
3298 return;
3299 }
3300
3302
3303 if (size <= 1) {
3304 return;
3305 }
3306
3307 for (i = 0; i < size; i++) {
3309 break;
3310 }
3311 }
3312
3313 if (i == 0 || i == size) {
3314 // Current city in the beginning of the list or disappeared
3316 } else {
3318 }
3319
3322}
3323
3324/************************************************************************/
3328{
3329 char buf[32];
3330 QString str;
3332
3334 production_combo_p->setRange(0, cost);
3336 if (dlgcity->shield_stock >= cost) {
3337 production_combo_p->setValue(cost);
3338 } else {
3340 }
3341 production_combo_p->setAlignment(Qt::AlignCenter);
3342 str = QString(buf);
3343 str = str.simplified();
3344
3345 production_combo_p->setFormat(QString("(%p%) %2\n%1")
3347 str));
3348
3349 production_combo_p->updateGeometry();
3350
3351}
3352
3353/************************************************************************/
3357{
3358 char buf[1024], buf2[1024];
3360 int value = dlgcity->client.buy_cost;
3362 int city_id = dlgcity->id;
3363
3364 if (!can_client_issue_orders()) {
3365 return;
3366 }
3367
3369 fc_snprintf(buf2, ARRAY_SIZE(buf2), PL_("Treasury contains %d gold.",
3370 "Treasury contains %d gold.",
3371 client_player()->economic.gold),
3372 client_player()->economic.gold);
3373 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Buy %s for %d gold?",
3374 "Buy %s for %d gold?", value),
3375 name, value);
3376 ask->set_text_title(buf, buf2);
3377 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
3378 ask->setDefaultButton(QMessageBox::Cancel);
3379 ask->setAttribute(Qt::WA_DeleteOnClose);
3380 connect(ask, &hud_message_box::accepted, this, [=]() {
3381 struct city *pcity = game_city_by_number(city_id);
3382
3383 if (!pcity) {
3384 return;
3385 }
3386
3388 });
3389 ask->show();
3390}
3391
3392/************************************************************************/
3396{
3397 QFont f = QApplication::font();
3398 QFontMetrics fm(f);
3399 QPixmap *pix = NULL;
3403 struct sprite *sprite;
3404 int h, cost, item, targets_used, col, upkeep;
3405 struct item items[MAX_NUM_PRODUCTION_TARGETS];
3406 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
3407 struct worklist queue;
3408 impr_item *ui;
3409
3410 upkeep = 0;
3411 city_buildings->setUpdatesEnabled(false);
3413
3414 h = fm.height() + 6;
3416 name_and_sort_items(targets, targets_used, items, false, dlgcity);
3417
3418 for (item = 0; item < targets_used; item++) {
3419 struct universal target = items[item].item;
3420
3421 ui = new impr_item(this, target.value.building, dlgcity);
3422 ui->init_pix();
3424
3425 fc_assert_action(VUT_IMPROVEMENT == target.kind, continue);
3427 upkeep = upkeep + city_improvement_upkeep(dlgcity, target.value.building);
3428 if (sprite != nullptr) {
3429 pix = sprite->pm;
3430 pix_scaled = pix->scaledToHeight(h);
3431 }
3432 }
3433
3434 city_get_queue(dlgcity, &queue);
3435 p_table_p->setRowCount(worklist_length(&queue));
3436
3437 for (int i = 0; i < worklist_length(&queue); i++) {
3438 struct universal target = queue.entries[i];
3439
3440 tooltip = "";
3441
3442 if (VUT_UTYPE == target.kind) {
3445 tooltip = get_tooltip_unit(target.value.utype, true).trimmed();
3449 } else {
3453 dlgcity, true).trimmed();
3454
3456 cost = -1;
3457 } else {
3459 }
3460 }
3461
3462 for (col = 0; col < 3; col++) {
3463 qitem = new QTableWidgetItem();
3464 qitem->setToolTip(tooltip);
3465
3466 switch (col) {
3467 case 0:
3468 if (sprite) {
3469 pix = sprite->pm;
3470 pix_scaled = pix->scaledToHeight(h);
3471 qitem->setData(Qt::DecorationRole, pix_scaled);
3472 }
3473 break;
3474
3475 case 1:
3476 if (str.contains('[') && str.contains(']')) {
3477 int ii, ij;
3478
3479 ii = str.lastIndexOf('[');
3480 ij = str.lastIndexOf(']');
3481 if (ij > ii) {
3482 str = str.remove(ii, ij - ii + 1);
3483 }
3484 }
3485 qitem->setText(str);
3486 break;
3487
3488 case 2:
3489 qitem->setTextAlignment(Qt::AlignRight);
3490 qitem->setText(QString::number(cost));
3491 break;
3492 }
3493 p_table_p->setItem(i, col, qitem);
3494 }
3495 }
3496
3497 p_table_p->horizontalHeader()->setStretchLastSection(false);
3498 p_table_p->resizeColumnsToContents();
3499 p_table_p->resizeRowsToContents();
3500 p_table_p->horizontalHeader()->setStretchLastSection(true);
3501
3503 city_buildings->setUpdatesEnabled(true);
3504 city_buildings->setUpdatesEnabled(true);
3505
3506 curr_impr->setText(QString(_("Improvements - upkeep %1")).arg(upkeep));
3507}
3508
3509/************************************************************************/
3513{
3514 cid id;
3515 QVariant qvar;
3516
3518 struct universal univ;
3519
3520 id = qvar.toInt();
3521 univ = cid_production(id);
3523 }
3524}
3525
3526/************************************************************************/
3531{
3533 int when = 1;
3534
3535 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3536 when, selected_row_p, show_units->isChecked(),
3537 false, show_wonders->isChecked(),
3538 show_buildings->isChecked());
3539 pw->show();
3540}
3541
3542/************************************************************************/
3547{
3549 int when = 4;
3550
3551 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3552 when, selected_row_p, show_units->isChecked(),
3553 false, show_wonders->isChecked(),
3554 show_buildings->isChecked());
3555 pw->show();
3556}
3557
3558/************************************************************************/
3562{
3563 struct worklist empty;
3564
3565 if (!can_client_issue_orders()) {
3566 return;
3567 }
3568
3571}
3572
3573/************************************************************************/
3577{
3578 QModelIndex index;
3579 struct worklist queue;
3580 struct universal *target;
3581
3583 return;
3584 }
3585
3586 target = new universal;
3587 city_get_queue(dlgcity, &queue);
3588 worklist_peek_ith(&queue, target, selected_row_p);
3590 worklist_insert(&queue, target, selected_row_p - 1);
3591 city_set_queue(dlgcity, &queue);
3592 index = p_table_p->model()->index(selected_row_p - 1, 0);
3593 p_table_p->setCurrentIndex(index);
3594 delete target;
3595
3596}
3597
3598/************************************************************************/
3602{
3604
3605 if (selected_row_p < 0
3606 || selected_row_p >= p_table_p->rowCount()) {
3607 return;
3608 }
3609
3613}
3614
3615/************************************************************************/
3619{
3620 QModelIndex index;
3621 struct worklist queue;
3622 struct universal *target;
3623
3625 return;
3626 }
3627
3628 target = new universal;
3629 city_get_queue(dlgcity, &queue);
3630 worklist_peek_ith(&queue, target, selected_row_p);
3632 worklist_insert(&queue, target, selected_row_p + 1);
3633 city_set_queue(dlgcity, &queue);
3634 index = p_table_p->model()->index(selected_row_p + 1, 0);
3635 p_table_p->setCurrentIndex(index);
3636 delete target;
3637}
3638
3639/************************************************************************/
3643{
3644 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
3645 int city_id = dlgcity->id;
3646
3647 ask->set_text_title_definput(_("What should we name new worklist?"),
3648 _("Save current worklist"),
3649 _("New worklist"));
3650 ask->setAttribute(Qt::WA_DeleteOnClose);
3651 connect(ask, &hud_message_box::accepted, [=]() {
3652 struct global_worklist *gw;
3653 struct worklist queue;
3655 QString text;
3656 struct city *pcity = game_city_by_number(city_id);
3657
3658 ask_bytes = ask->input_edit.text().toUtf8();
3659 text = ask_bytes.data();
3660 if (!text.isEmpty()) {
3661 ask_bytes = text.toUtf8();
3663 city_get_queue(pcity, &queue);
3664 global_worklist_set(gw, &queue);
3665 }
3666 });
3667 ask->show();
3668}
3669
3670/************************************************************************/
3674{
3675 QString buf;
3676
3677 // Defeat keyboard shortcut mnemonics
3679 .replace("&", "&&"));
3680
3681 if (city_unhappy(dlgcity)) {
3682 // TRANS: city dialog title
3683 buf = QString(_("%1 - %2 citizens - DISORDER")).arg(city_name_get(dlgcity),
3685 } else if (city_celebrating(dlgcity)) {
3686 // TRANS: city dialog title
3687 buf = QString(_("%1 - %2 citizens - celebrating")).arg(city_name_get(dlgcity),
3689 } else if (city_happy(dlgcity)) {
3690 // TRANS: city dialog title
3691 buf = QString(_("%1 - %2 citizens - happy")).arg(city_name_get(dlgcity),
3693 } else {
3694 // TRANS: city dialog title
3695 buf = QString(_("%1 - %2 citizens")).arg(city_name_get(dlgcity),
3697 }
3698
3700}
3701
3702/************************************************************************/
3707{
3708 if (!::city_dlg_created) {
3709 ::city_dlg = new city_dialog(gui()->mapview_wdg);
3710 }
3711
3712 city_dlg->setup_ui(pcity);
3713 city_dlg->show();
3714 city_dlg->activateWindow();
3715 city_dlg->raise();
3716}
3717
3718/************************************************************************/
3722{
3723 if (!::city_dlg_created) {
3724 return;
3725 }
3726
3727 city_dlg->close();
3728 ::city_dlg_created = false;
3729}
3730
3731/************************************************************************/
3735{
3736 if (!::city_dlg_created) {
3737 return;
3738 }
3739
3741}
3742
3743/************************************************************************/
3750
3751/************************************************************************/
3755{
3756 if (!::city_dlg_created) {
3757 return;
3758 }
3759
3760 if (qtg_city_dialog_is_open(pcity)) {
3761 city_dlg->refresh();
3762 }
3763}
3764
3765/************************************************************************/
3769{
3771 QFont *f;
3772
3773 if (!::city_dlg_created) {
3774 return;
3775 }
3776
3777 l = city_dlg->findChildren<QLabel *>();
3778
3780
3781 for (int i = 0; i < l.size(); ++i) {
3782 if (l.at(i)->property(fonts::notify_label).isValid()) {
3783 l.at(i)->setFont(*f);
3784 }
3785 }
3786}
3787
3788/************************************************************************/
3805
3806/************************************************************************/
3810{
3811 if (!::city_dlg_created) {
3812 return false;
3813 }
3814
3815 if (city_dlg->dlgcity == pcity && city_dlg->isVisible()) {
3816 return true;
3817 }
3818
3819 return false;
3820}
3821
3822/************************************************************************/
3825bool fc_tooltip::eventFilter(QObject *obj, QEvent *ev)
3826{
3829 QRect rect;
3830
3831 if (ev->type() == QEvent::ToolTip) {
3833
3834 if (!view) {
3835 return false;
3836 }
3837
3838 help_event = static_cast<QHelpEvent *>(ev);
3839 QPoint pos = help_event->pos();
3840 QModelIndex index = view->indexAt(pos);
3841 QPoint hpos;
3842
3843 if (!index.isValid()) {
3844 return false;
3845 }
3846
3847 item_tooltip = view->model()->data(index, Qt::ToolTipRole).toString();
3848 rect = view->visualRect(index);
3849
3850 hpos = help_event->globalPos();
3851
3852 rect.setX(rect.x() + hpos.x());
3853 rect.setY(rect.y() + hpos.y());
3854
3855 if (!item_tooltip.isEmpty()) {
3856 QToolTip::showText(help_event->globalPos(), item_tooltip, view, rect);
3857 } else {
3858 QToolTip::hideText();
3859 }
3860
3861 return true;
3862 }
3863
3864 return false;
3865}
3866
3867/************************************************************************/
3871{
3872 return QString("<b>" + text + "</b>");
3873}
3874
3875/************************************************************************/
3879QString get_tooltip_improvement(const impr_type *building, struct city *pcity,
3880 bool ext)
3881{
3883 QString upkeep;
3884 QString s1, s2, str;
3885 const char *req = skip_intl_qualifier_prefix(_("?tech:None"));
3886
3887 if (pcity != nullptr) {
3888 upkeep = QString::number(city_improvement_upkeep(pcity, building));
3889 } else {
3890 upkeep = QString::number(building->upkeep);
3891 }
3893 if (pobs->source.kind == VUT_ADVANCE) {
3894 req = advance_name_translation(pobs->source.value.advance);
3895 break;
3896 }
3898 s2 = QString(req);
3899 str = _("Obsolete by:");
3900 str = str + " " + s2;
3901 def_str = "<p style='white-space:pre'><b>"
3902 + QString(improvement_name_translation(building)).toHtmlEscaped()
3903 + "</b>\n";
3904 if (pcity != nullptr) {
3905 def_str += QString(_("Cost: %1, Upkeep: %2\n"))
3906 .arg(impr_build_shield_cost(pcity, building))
3907 .arg(upkeep).toHtmlEscaped();
3908 } else {
3910
3911 def_str += QString(_("Cost Estimate: %1, Upkeep: %2\n"))
3912 .arg(cost_est)
3913 .arg(upkeep).toHtmlEscaped();
3914 }
3915 if (s1.compare(s2) != 0) {
3916 def_str = def_str + str.toHtmlEscaped() + "\n";
3917 }
3918 def_str = def_str + "\n";
3919 if (ext) {
3920 char buffer[8192];
3921
3922 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
3923 NULL, building);
3924 str = cut_helptext(str);
3925 str = split_text(str, true);
3926 str = str.trimmed();
3927 def_str = def_str + str.toHtmlEscaped();
3928 }
3929 return def_str;
3930}
3931
3932/************************************************************************/
3936QString get_tooltip_unit(const struct unit_type *utype, bool ext)
3937{
3940 QString str;
3941 const struct unit_type *obsolete;
3942 struct advance *tech;
3943
3944 def_str = "<b>"
3945 + QString(utype_name_translation(utype)).toHtmlEscaped()
3946 + "</b>\n";
3947 obsolete = utype->obsoleted_by;
3948 if (obsolete) {
3949 // FIXME: Don't give the impression that primary tech is (always) the only one.
3951 obsolete_str = QString("</td></tr><tr><td colspan=\"3\">");
3952 if (tech && tech != advance_by_number(A_NONE)) {
3953 /* TRANS: this and nearby literal strings are interpreted
3954 * as (Qt) HTML */
3955 obsolete_str = obsolete_str + QString(_("Obsoleted by %1 (%2)."))
3957 .arg(advance_name_translation(tech)).toHtmlEscaped();
3958 } else {
3959 obsolete_str = obsolete_str + QString(_("Obsoleted by %1."))
3960 .arg(utype_name_translation(obsolete)).toHtmlEscaped();
3961 }
3962 }
3963 def_str += "<table width=\"100\%\"><tr><td>"
3964 + bold(QString(_("Attack:"))) + " "
3965 + QString::number(utype->attack_strength).toHtmlEscaped()
3966 + QString("</td><td>") + bold(QString(_("Defense:"))) + " "
3967 + QString::number(utype->defense_strength).toHtmlEscaped()
3968 + QString("</td><td>") + bold(QString(_("Move:"))) + " "
3969 + QString(move_points_text(utype->move_rate, TRUE)).toHtmlEscaped()
3970 + QString("</td></tr><tr><td>")
3971 + bold(QString(_("Cost:"))) + " "
3972 + QString::number(utype_build_shield_cost_base(utype))
3973 .toHtmlEscaped()
3974 + QString("</td><td colspan=\"2\">")
3975 + bold(QString(_("Basic Upkeep:")))
3976 + " " + QString(helptext_unit_upkeep_str(utype)).toHtmlEscaped()
3977 + QString("</td></tr><tr><td>")
3978 + bold(QString(_("Hitpoints:"))) + " "
3979 + QString::number(utype->hp).toHtmlEscaped()
3980 + QString("</td><td>") + bold(QString(_("Firepower:"))) + " "
3981 + QString::number(utype->firepower).toHtmlEscaped()
3982 + QString("</td><td>") + bold(QString(_("Vision:"))) + " "
3983 + QString::number((int) sqrt((double) utype->vision_radius_sq))
3984 .toHtmlEscaped()
3985 + obsolete_str
3986 + QString("</td></tr></table><p style='white-space:pre'>");
3987 if (ext) {
3988 char buffer[8192];
3989 char buf2[1];
3990
3991 buf2[0] = '\0';
3992 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
3993 buf2, utype);
3994 str = cut_helptext(str);
3995 str = split_text(str, true);
3996 str = str.trimmed().toHtmlEscaped();
3997 def_str = def_str + str;
3998 }
3999
4000 return def_str;
4001};
4002
4003/************************************************************************/
4007{
4010 char buffer[8192];
4011 char buf2[1];
4012 struct universal *target;
4013
4014 buf2[0] = '\0';
4015 target = reinterpret_cast<universal *>(qvar.value<void *>());
4016
4017 if (target == NULL) {
4018 } else if (VUT_UTYPE == target->kind) {
4020 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
4021 buf2, target->value.utype);
4022 } else {
4023 if (!is_convert_improvement(target->value.building)) {
4025 }
4026
4027 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
4028 NULL, target->value.building);
4029 }
4030
4031 // Remove all lines from help which has '*' in first 3 chars
4033 ret_str = split_text(ret_str, true);
4034 ret_str = ret_str.trimmed();
4035 ret_str = def_str + ret_str.toHtmlEscaped();
4036
4037 return ret_str;
4038}
4039
4040/************************************************************************/
4044 QObject *parent,
4045 struct city *city)
4046 : QItemDelegate(parent)
4047{
4048 pd = sh;
4049 item_height = sh.y();
4050 pcity = city;
4051}
4052
4053/************************************************************************/
4058 const QModelIndex &index) const
4059{
4060 struct universal *target;
4061 QString name;
4062 QVariant qvar;
4063 QPixmap *pix;
4065 QRect rect1;
4066 QRect rect2;
4067 struct sprite *sprite;
4068 bool useless = false;
4069 bool is_coinage = false;
4070 bool is_neutral = false;
4071 bool is_sea = false;
4072 bool is_flying = false;
4073 bool is_unit = true;
4074 QPixmap pix_dec(option.rect.width(), option.rect.height());
4076 color col;
4077 QIcon icon = current_app()->style()->standardIcon(QStyle::SP_DialogCancelButton);
4078 bool free_sprite = false;
4079 struct unit_class *pclass;
4080
4081 if (!option.rect.isValid()) {
4082 return;
4083 }
4084
4085 qvar = index.data();
4086
4087 if (!qvar.isValid()) {
4088 return;
4089 }
4090
4091 target = reinterpret_cast<universal *>(qvar.value<void *>());
4092
4093 if (target == NULL) {
4094 col.qcolor = Qt::white;
4095 sprite = qtg_create_sprite(100, 100, &col);
4096 free_sprite = true;
4097 *sprite->pm = icon.pixmap(100, 100);
4098 name = _("Cancel");
4099 is_unit = false;
4100 } else if (VUT_UTYPE == target->kind) {
4103 pclass = utype_class(target->value.utype);
4107 is_sea = true;
4108 }
4109
4110 if ((utype_fuel(target->value.utype)
4115 /* FIXME: Assumed to be flying since only missiles can do suicide
4116 * attacks in classic-like rulesets. This isn't true for all
4117 * rulesets. Not a high priority to fix since all is_flying and
4118 * is_sea is used for is to set a color. */
4120 target->value.utype)) {
4121 if (is_sea) {
4122 is_sea = false;
4123 }
4124 is_flying = true;
4125 }
4126
4130 } else {
4131 is_unit = false;
4136 }
4137
4138 if (sprite != NULL) {
4139 pix = sprite->pm;
4140 pix_scaled = pix->scaledToHeight(item_height - 2, Qt::SmoothTransformation);
4141
4142 if (useless) {
4144 }
4145 }
4146
4147 opt = QItemDelegate::setOptions(index, option);
4148 painter->save();
4149 opt.displayAlignment = Qt::AlignLeft;
4150 opt.textElideMode = Qt::ElideMiddle;
4151 QItemDelegate::drawBackground(painter, opt, index);
4152 rect1 = option.rect;
4153 rect1.setWidth(pix_scaled.width() + 4);
4154 rect2 = option.rect;
4155 rect2.setLeft(option.rect.left() + rect1.width());
4156 rect2.setTop(rect2.top() + (rect2.height()
4157 - painter->fontMetrics().height()) / 2);
4158 QItemDelegate::drawDisplay(painter, opt, rect2, name);
4159
4160 if (is_unit) {
4161 if (is_sea) {
4162 pix_dec.fill(QColor(0, 0, 255, 80));
4163 } else if (is_flying) {
4164 pix_dec.fill(QColor(220, 0, 0, 80));
4165 } else if (is_neutral) {
4166 pix_dec.fill(QColor(0, 120, 0, 40));
4167 } else {
4168 pix_dec.fill(QColor(0, 0, 150, 40));
4169 }
4170
4171 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4172 }
4173
4174 if (is_coinage) {
4175 pix_dec.fill(QColor(255, 255, 0, 70));
4176 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4177 }
4178
4179 if (!pix_scaled.isNull()) {
4180 QItemDelegate::drawDecoration(painter, opt, rect1, pix_scaled);
4181 }
4182
4183 drawFocus(painter, opt, option.rect);
4184
4185 painter->restore();
4186
4187 if (free_sprite) {
4189 }
4190}
4191
4192/************************************************************************/
4197 const QRect &rect) const
4198{
4199 QPixmap pix(option.rect.width(), option.rect.height());
4200
4201 if ((option.state & QStyle::State_MouseOver) == 0 || !rect.isValid()) {
4202 return;
4203 }
4204
4205 pix.fill(QColor(50, 50, 50, 50));
4206 QItemDelegate::drawDecoration(painter, option, option.rect, pix);
4207}
4208
4209/************************************************************************/
4213 const QModelIndex &index) const
4214{
4215 QSize s;
4216
4217 s.setWidth(pd.x());
4218 s.setHeight(pd.y());
4219 return s;
4220}
4221
4222/************************************************************************/
4226 QObject *parent): QObject()
4227{
4229 target = ptarget;
4230}
4231
4232/************************************************************************/
4236{
4237 // Allocated as renegade in model
4238 if (target != NULL) {
4239 delete target;
4240 }
4241}
4242
4243/************************************************************************/
4247{
4248 return QVariant::fromValue((void *)target);
4249}
4250
4251/************************************************************************/
4255{
4256 return false;
4257}
4258
4259/************************************************************************/
4263 bool su, bool sw, bool sb,
4264 QObject *parent)
4265 : QAbstractListModel(parent)
4266{
4267 show_units = su;
4268 show_wonders = sw;
4270 mcity = pcity;
4271 future_t = f;
4272 populate();
4273}
4274
4275/************************************************************************/
4283
4284/************************************************************************/
4288{
4289 if (!index.isValid()) {
4290 return QVariant();
4291 }
4292
4293 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4294 && index.column() < columnCount()
4295 && (index.column() + index.row() * 3 < city_target_list.count())) {
4296 int r, c, t, new_index;
4297
4298 r = index.row();
4299 c = index.column();
4300 t = r * 3 + c;
4301 new_index = t / 3 + rowCount() * c;
4302 // Exception, shift whole column
4303 if ((c == 2) && city_target_list.count() % 3 == 1) {
4304 new_index = t / 3 + rowCount() * c - 1;
4305 }
4306 if (role == Qt::ToolTipRole) {
4308 }
4309
4310 return city_target_list[new_index]->data();
4311 }
4312
4313 return QVariant();
4314}
4315
4316/************************************************************************/
4320{
4322 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
4323 struct item items[MAX_NUM_PRODUCTION_TARGETS];
4324 struct universal *renegade;
4325 int item, targets_used;
4326 QString str;
4328 QFontMetrics fm(f);
4329
4330 sh.setY(fm.height() * 2);
4331 sh.setX(0);
4332
4334 city_target_list.clear();
4335
4337 future_t);
4338 name_and_sort_items(targets, targets_used, items, false, mcity);
4339
4340 for (item = 0; item < targets_used; item++) {
4341 if (future_t || can_city_build_now(mcity, &items[item].item)) {
4342 renegade = new universal(items[item].item);
4343
4344 // Renagade deleted in production_item destructor
4345 if (VUT_UTYPE == renegade->kind) {
4346 str = utype_name_translation(renegade->value.utype);
4347 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4348
4349 if (show_units) {
4350 pi = new production_item(renegade, this);
4352 } else {
4353 delete renegade;
4354 }
4355 } else {
4356 str = improvement_name_translation(renegade->value.building);
4357 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4358
4359 if ((is_wonder(renegade->value.building) && show_wonders)
4360 || (is_improvement(renegade->value.building) && show_buildings)
4361 || (is_convert_improvement(renegade->value.building))
4362 || (is_special_improvement(renegade->value.building)
4363 && show_buildings)) {
4364 pi = new production_item(renegade, this);
4366 } else {
4367 delete renegade;
4368 }
4369 }
4370 }
4371 }
4372
4373 pi = new production_item(nullptr, this);
4375 sh.setX(2 * sh.y() + sh.x());
4376 sh.setX(qMin(sh.x(), 250));
4377}
4378
4379/************************************************************************/
4383 const QVariant &value, int role)
4384{
4385 if (!index.isValid() || role != Qt::DisplayRole || role != Qt::ToolTipRole)
4386 return false;
4387
4388 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4389 && index.column() < columnCount()) {
4390 bool change = city_target_list[index.row()]->setData();
4391 return change;
4392 }
4393
4394 return false;
4395}
4396
4397/************************************************************************/
4406 bool future, int when, int curr,
4407 bool show_units, bool buy,
4408 bool show_wonders,
4409 bool show_buildings): QTableView()
4410{
4411 QPoint pos, sh;
4412 QRect rect = QApplication::primaryScreen()->availableGeometry();
4413 int desk_width = rect.width();
4414 int desk_height = rect.height();
4415 fc_tt = new fc_tooltip(this);
4416 setAttribute(Qt::WA_DeleteOnClose);
4417 setWindowFlags(Qt::Popup);
4418 verticalHeader()->setVisible(false);
4419 horizontalHeader()->setVisible(false);
4420 setProperty("showGrid", false);
4422 sh_units = show_units;
4423 pw_city = pcity;
4424 buy_it = buy;
4425 when_change = when;
4426 list_model = new city_production_model(pw_city, future, show_units,
4427 show_wonders, show_buildings, this);
4428 sh = list_model->sh;
4429 c_p_d = new city_production_delegate(sh, this, pw_city);
4432 viewport()->installEventFilter(fc_tt);
4433 installEventFilter(this);
4435 const QItemSelection &)),
4437 const QItemSelection &)));
4440 setFixedWidth(3 * sh.x() + 6);
4441 setFixedHeight(list_model->rowCount()*sh.y() + 6);
4442
4443 if (width() > desk_width) {
4445 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4446 } else {
4447 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4448 }
4449
4450 if (height() > desk_height) {
4452 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4453 } else {
4454 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4455 }
4456
4457 pos = QCursor::pos();
4458
4459 if (pos.x() + width() > desk_width) {
4460 pos.setX(desk_width - width());
4461 } else if (pos.x() - width() < 0) {
4462 pos.setX(0);
4463 }
4464
4465 if (pos.y() + height() > desk_height) {
4466 pos.setY(desk_height - height());
4467 } else if (pos.y() - height() < 0) {
4468 pos.setY(0);
4469 }
4470
4471 move(pos);
4472 setMouseTracking(true);
4473 setFocus();
4474}
4475
4476/************************************************************************/
4480{
4481 if (event->button() == Qt::RightButton) {
4482 close();
4483 return;
4484 }
4485
4486 QAbstractItemView::mousePressEvent(event);
4487}
4488
4489/************************************************************************/
4493{
4494 QRect pw_rect;
4495 QPoint br;
4496
4497 if (obj != this)
4498 return false;
4499
4500 if (ev->type() == QEvent::MouseButtonPress) {
4501 pw_rect.setTopLeft(pos());
4502 br.setX(pos().x() + width());
4503 br.setY(pos().y() + height());
4504 pw_rect.setBottomRight(br);
4505
4506 if (!pw_rect.contains(QCursor::pos())) {
4507 close();
4508 }
4509 }
4510
4511 return false;
4512}
4513
4514/************************************************************************/
4518 const QItemSelection &ds)
4519{
4520 QModelIndexList indexes = selectionModel()->selectedIndexes();
4521 QModelIndex index;
4522 QVariant qvar;
4523 struct worklist queue;
4524 struct universal *target;
4525
4526 if (indexes.isEmpty() || client_is_observer()) {
4527 return;
4528 }
4529 index = indexes.at(0);
4530 qvar = index.data(Qt::UserRole);
4531 if (!qvar.isValid()) {
4532 return;
4533 }
4534 target = reinterpret_cast<universal *>(qvar.value<void *>());
4535 if (target != NULL) {
4536 city_get_queue(pw_city, &queue);
4537 switch (when_change) {
4538 case 0: // Change current target
4540 if (city_can_buy(pw_city) && buy_it) {
4542 }
4543 break;
4544
4545 case 1: // Change current (selected on list)
4548 } else {
4550 worklist_insert(&queue, target, curr_selection);
4551 city_set_queue(pw_city, &queue);
4552 }
4553 break;
4554
4555 case 2: // Insert before
4557 curr_selection = 0;
4558 }
4561 worklist_insert(&queue, target, curr_selection);
4562 city_set_queue(pw_city, &queue);
4563 break;
4564
4565 case 3: // Insert after
4567 city_queue_insert(pw_city, -1, target);
4568 break;
4569 }
4571 worklist_insert(&queue, target, curr_selection);
4572 city_set_queue(pw_city, &queue);
4573 break;
4574
4575 case 4: // Add last
4576 city_queue_insert(pw_city, -1, target);
4577 break;
4578
4579 default:
4580 break;
4581 }
4582 }
4583 close();
4584 destroy();
4585}
4586
4587/************************************************************************/
4591{
4592 delete c_p_d;
4593 delete list_model;
4594 viewport()->removeEventFilter(fc_tt);
4595 removeEventFilter(this);
4596}
const char * action_id_name_translation(action_id act_id)
Definition actions.c:2002
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:927
#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:662
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:736
int city_granary_size(int city_size)
Definition city.c:2123
bool can_city_build_now(const struct city *pcity, const struct universal *target)
Definition city.c:1006
int city_unit_unhappiness(struct unit *punit, int *free_unhappy)
Definition city.c:3040
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:304
const char * city_name_get(const struct city *pcity)
Definition city.c:1128
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Definition city.c:1246
bool is_city_option_set(const struct city *pcity, enum city_options option)
Definition city.c:3376
int city_population(const struct city *pcity)
Definition city.c:1182
bool city_unhappy(const struct city *pcity)
Definition city.c:1618
bool city_celebrating(const struct city *pcity)
Definition city.c:1637
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2861
bool city_happy(const struct city *pcity)
Definition city.c:1606
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:136
int rs_max_city_radius_sq(void)
Definition city.c:158
citizens city_specialists(const struct city *pcity)
Definition city.c:3305
int city_turns_to_grow(const struct city *pcity)
Definition city.c:1988
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:699
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:3734
void qtg_real_city_dialog_refresh(struct city *pcity)
Definition citydlg.cpp:3754
QString split_text(QString text, bool cut)
Definition optiondlg.cpp:62
void city_font_update()
Definition citydlg.cpp:3768
bool qtg_city_dialog_is_open(struct city *pcity)
Definition citydlg.cpp:3809
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4006
void qtg_popdown_all_city_dialogs()
Definition citydlg.cpp:3746
static city_dialog * city_dlg
Definition citydlg.cpp:74
void qtg_refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.cpp:3793
static QString bold(QString text)
Definition citydlg.cpp:3870
void qtg_real_city_dialog_popup(struct city *pcity)
Definition citydlg.cpp:3706
QString get_tooltip_improvement(const impr_type *building, struct city *pcity, bool ext)
Definition citydlg.cpp:3879
static bool city_dlg_created
Definition citydlg.cpp:70
static void pixmap_put_x(QPixmap *pix)
Definition citydlg.cpp:349
QString cut_helptext(QString text)
QString get_tooltip_unit(const struct unit_type *utype, bool ext)
Definition citydlg.cpp:3936
void destroy_city_dialog()
Definition citydlg.cpp:3721
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:1186
void set_city(struct city *pcity)
Definition citydlg.cpp:1218
struct city * pcity
Definition citydlg.h:426
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1194
int wdth
Definition citydlg.h:287
int cutted_height
Definition citydlg.h:290
QSize sizeHint() const
Definition citydlg.cpp:1317
void paintEvent(QPaintEvent *event)
Definition citydlg.cpp:1257
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1333
void set_pixmap(struct city *pcity, float z)
Definition citydlg.cpp:1281
void context_menu(QPoint point)
Definition citydlg.cpp:1355
canvas * miniview
Definition citydlg.h:274
int hight
Definition citydlg.h:288
struct city * mcity
Definition citydlg.h:284
QSize minimumSizeHint() const
Definition citydlg.cpp:1325
float zoom
Definition citydlg.h:286
QPixmap zoomed_pixmap
Definition citydlg.h:275
city_map(QWidget *parent)
Definition citydlg.cpp:1226
int cutted_width
Definition citydlg.h:289
int radius
Definition citydlg.h:285
int delta_y
Definition citydlg.h:292
int delta_x
Definition citydlg.h:291
city_production_delegate(QPoint sh, QObject *parent, struct city *city)
Definition citydlg.cpp:4043
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4056
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4212
struct city * pcity
Definition citydlg.h:318
void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
Definition citydlg.cpp:4195
int rowCount(const QModelIndex &index=QModelIndex()) const
Definition citydlg.h:356
city_production_model(struct city *pcity, bool f, bool su, bool sw, bool sb, QObject *parent=0)
Definition citydlg.cpp:4262
QList< production_item * > city_target_list
Definition citydlg.h:372
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole)
Definition citydlg.cpp:4382
int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition citydlg.h:360
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition citydlg.cpp:4287
struct city * mcity
Definition citydlg.h:373
static fc_font * instance()
Definition fonts.cpp:41
QFont * get_font(QString name)
Definition fonts.cpp:63
static fc_icons * instance()
bool eventFilter(QObject *obj, QEvent *event)
Definition citydlg.cpp:3825
void update_buildings()
Definition citydlg.cpp:560
QHBoxLayout * layout
Definition citydlg.h:260
void add_item(impr_item *item)
Definition citydlg.cpp:502
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:535
impr_info(QWidget *parent)
Definition citydlg.cpp:471
void clear_layout()
Definition citydlg.cpp:510
void init_layout()
Definition citydlg.cpp:481
QList< impr_item * > impr_list
Definition citydlg.h:261
void mouseDoubleClickEvent(QMouseEvent *event)
Definition citydlg.cpp:618
impr_item(QWidget *parent, const struct impr_type *building, struct city *pcity)
Definition citydlg.cpp:366
void init_pix()
Definition citydlg.cpp:405
void enterEvent(QEnterEvent *event)
Definition citydlg.cpp:415
struct canvas * impr_pixmap
Definition citydlg.h:232
struct city * dlgcity
Definition citydlg.h:233
const struct impr_type * impr
Definition citydlg.h:231
void leaveEvent(QEvent *event)
Definition citydlg.cpp:445
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:592
struct universal * target
Definition citydlg.h:342
QVariant data() const
Definition citydlg.cpp:4246
production_item(struct universal *ptarget, QObject *parent)
Definition citydlg.cpp:4225
bool eventFilter(QObject *obj, QEvent *ev)
Definition citydlg.cpp:4492
void prod_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:4517
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:4479
city_production_model * list_model
Definition citydlg.h:387
struct city * pw_city
Definition citydlg.h:404
fc_tooltip * fc_tt
Definition citydlg.h:409
city_production_delegate * c_p_d
Definition citydlg.h:388
production_widget(QWidget *parent, struct city *pcity, bool future, int when, int curr, bool show_units, bool buy=false, bool show_wonders=true, bool show_buildings=true)
Definition citydlg.cpp:4405
progress_bar(QWidget *parent)
Definition citydlg.cpp:81
void paintEvent(QPaintEvent *event)
Definition citydlg.cpp:187
int m_animate_step
Definition citydlg.h:132
void resizeEvent(QResizeEvent *event)
Definition citydlg.cpp:105
QRegion reg
Definition citydlg.h:134
void set_pixmap(struct universal *target)
Definition citydlg.cpp:113
void create_region()
Definition citydlg.cpp:325
QElapsedTimer m_timer
Definition citydlg.h:113
void timerEvent(QTimerEvent *event)
Definition citydlg.cpp:175
QPixmap * pix
Definition citydlg.h:133
QFont * sfont
Definition citydlg.h:135
void clicked()
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:1094
void init_layout()
Definition citydlg.cpp:1082
unit_info(bool supp)
Definition citydlg.cpp:1055
void add_item(unit_item *item)
Definition citydlg.cpp:1074
QHBoxLayout * layout
Definition citydlg.h:208
void update_units()
Definition citydlg.cpp:1119
void clear_layout()
Definition citydlg.cpp:1160
QList< unit_item * > unit_list
Definition citydlg.h:209
bool supports
Definition citydlg.h:212
QAction * activate
Definition citydlg.h:146
QAction * disband_action
Definition citydlg.h:144
void enterEvent(QEnterEvent *event)
Definition citydlg.cpp:977
void contextMenuEvent(QContextMenuEvent *ev)
Definition citydlg.cpp:749
QAction * sentry
Definition citydlg.h:148
struct unit * qunit
Definition citydlg.h:163
QAction * activate_and_close
Definition citydlg.h:147
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:1032
int happy_cost
Definition citydlg.h:167
void change_homecity()
Definition citydlg.cpp:935
QAction * unload
Definition citydlg.h:151
QAction * upgrade
Definition citydlg.h:152
bool supported
Definition citydlg.h:168
void fortify_unit()
Definition citydlg.cpp:966
void sentry_unit()
Definition citydlg.cpp:1045
QAction * unload_trans
Definition citydlg.h:153
void load_unit()
Definition citydlg.cpp:899
void wheelEvent(QWheelEvent *event)
Definition citydlg.cpp:1006
QAction * load
Definition citydlg.h:150
void activate_unit()
Definition citydlg.cpp:956
QAction * change_home
Definition citydlg.h:145
QAction * fortify
Definition citydlg.h:149
QImage unit_img
Definition citydlg.h:164
void create_actions()
Definition citydlg.cpp:803
void unload_all()
Definition citydlg.cpp:915
void disband()
Definition citydlg.cpp:881
void upgrade_unit()
Definition citydlg.cpp:923
void init_pix()
Definition citydlg.cpp:733
void leaveEvent(QEvent *event)
Definition citydlg.cpp:998
unit_item(QWidget *parent, struct unit *punit, bool supp=false, int happy_cost=0)
Definition citydlg.cpp:662
void unload_unit()
Definition citydlg.cpp:907
void activate_and_close_dialog()
Definition citydlg.cpp:945
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:808
void name_and_sort_items(struct universal *targets, int num_targets, struct item *items, bool show_cost, struct city *pcity)
Definition climisc.c:639
cid cid_encode(struct universal target)
Definition climisc.c:481
int collect_already_built_targets(struct universal *targets, struct city *pcity)
Definition climisc.c:901
struct universal cid_decode(cid id)
Definition climisc.c:524
#define MAX_NUM_PRODUCTION_TARGETS
Definition climisc.h:87
#define cid_production
Definition climisc.h:71
int cid
Definition climisc.h:31
static struct fc_sockaddr_list * list
Definition clinet.c:102
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Definition cm.c:2171
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:551
void cma_put_city_under_agent(struct city *pcity, const struct cm_parameter *const parameter)
Definition cma_core.c:523
void cma_release_city(struct city *pcity)
Definition cma_core.c:541
char * cmafec_preset_get_descr(int idx)
Definition cma_fec.c:169
const char * cmafec_get_short_descr_of_city(const struct city *pcity)
Definition cma_fec.c:221
const struct cm_parameter * cmafec_preset_get_parameter(int idx)
Definition cma_fec.c:182
void cmafec_preset_add(const char *descr_name, struct cm_parameter *pparam)
Definition cma_fec.c:136
int cmafec_preset_get_index_of_parameter(const struct cm_parameter *const parameter)
Definition cma_fec.c:196
void cmafec_preset_remove(int idx)
Definition cma_fec.c:153
int cmafec_preset_num(void)
Definition cma_fec.c:213
void cmafec_get_fe_parameter(struct city *pcity, struct cm_parameter *dest)
Definition cma_fec.c:115
char * incite_cost
Definition comments.c:74
void request_unit_fortify(struct unit *punit)
Definition control.c:2324
struct unit * request_unit_unload_all(struct unit *punit)
Definition control.c:1485
void unit_focus_set(struct unit *punit)
Definition control.c:501
void request_unit_change_homecity(struct unit *punit)
Definition control.c:2065
void request_unit_unload(struct unit *pcargo)
Definition control.c:2165
void request_unit_sentry(struct unit *punit)
Definition control.c:2313
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:41
bool qtg_request_transport(struct unit *pcargo, struct tile *ptile)
Definition dialogs.cpp:4865
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:391
#define EC_NONE
Definition fc_types.h:1114
@ TR_SUCCESS
Definition fc_types.h:1247
#define ERM_NONE
Definition fc_types.h:1137
@ 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:732
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:119
@ INFO_STEAL
Definition citydlg.c:121
@ INFO_CORRUPTION
Definition citydlg.c:120
@ NUM_INFO_FIELDS
Definition citydlg.c:122
@ INFO_ILLNESS
Definition citydlg.c:121
@ INFO_WASTE
Definition citydlg.c:120
@ INFO_GROWTH
Definition citydlg.c:119
@ INFO_SHIELD
Definition citydlg.c:118
@ INFO_CULTURE
Definition citydlg.c:120
@ INFO_GOLD
Definition citydlg.c:118
@ INFO_SCIENCE
Definition citydlg.c:119
@ INFO_POLLUTION
Definition citydlg.c:120
@ INFO_TRADE
Definition citydlg.c:118
@ INFO_AIRLIFT
Definition citydlg.c:121
@ INFO_GRANARY
Definition citydlg.c:119
@ INFO_FOOD
Definition citydlg.c:118
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:3879
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4006
#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_upkeep_str(const struct unit_type *utype)
Definition helpdata.c:4971
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1381
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype)
Definition helpdata.c:1865
int impr_sell_gold(const struct impr_type *pimprove)
enum test_result test_player_sell_building_now(struct player *pplayer, struct city *pcity, const struct impr_type *pimprove)
bool is_special_improvement(const struct impr_type *pimprove)
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
bool is_improvement(const struct impr_type *pimprove)
Impr_type_id improvement_number(const struct impr_type *pimprove)
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
bool is_convert_improvement(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
int impr_estimate_build_shield_cost(const struct player *pplayer, const struct tile *ptile, const struct impr_type *pimprove)
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_action(condition, action)
Definition log.h:187
void put_unit(const struct unit *punit, struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y)
void put_unit_city_overlays(struct unit *punit, struct canvas *pcanvas, int canvas_x, int canvas_y, int *upkeep_cost, int happy_cost)
void center_tile_mapcanvas(const struct tile *ptile)
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1015
static mpgui * gui
Definition mpgui_qt.cpp:52
const char *const default_font
Definition fonts.h:27
const char *const notify_label
Definition fonts.h:28
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
int send_packet_worker_task(struct connection *pc, const struct packet_worker_task *packet)
int dsend_packet_city_options_req(struct connection *pc, int city_id, bv_city_options options)
const char * text_happiness_cities(const struct city *pcity)
Definition text.c:1900
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
struct player * player_slot_get_player(const struct player_slot *pslot)
Definition player.c:437
void qtg_free_sprite(struct sprite *s)
Definition sprite.cpp:172
struct sprite * qtg_create_sprite(int width, int height, struct color *pcolor)
Definition sprite.cpp:181
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
#define ARRAY_SIZE(x)
Definition shared.h:85
#define FC_INFINITY
Definition shared.h:36
size_t size
Definition specvec.h:72
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
QPixmap map_pixmap
Definition canvas.h:25
void setup_ui(struct city *qcity)
Definition citydlg.cpp:3150
int current_building
Definition citydlg.h:506
void worklist_up()
Definition citydlg.cpp:3576
city_label * citizens_label
Definition citydlg.h:451
QPushButton * lcity_name
Definition citydlg.h:492
void show_happiness()
Definition citydlg.cpp:2116
void closeEvent(QCloseEvent *event)
Definition citydlg.cpp:2264
void update_nation_table()
Definition citydlg.cpp:2952
void hideEvent(QHideEvent *event)
Definition citydlg.cpp:2236
QPushButton * work_next_but
Definition citydlg.h:481
void next_city()
Definition citydlg.cpp:3257
progress_bar * production_combo_p
Definition citydlg.h:465
QTableWidget * nationality_table
Definition citydlg.h:467
QRadioButton * r3
Definition citydlg.h:475
QTableWidget * cma_table
Definition citydlg.h:468
void showEvent(QShowEvent *event)
Definition citydlg.cpp:2247
QPushButton * happiness_button
Definition citydlg.h:485
void cma_double_clicked(int row, int column)
Definition citydlg.cpp:2440
void display_worklist_menu(const QPoint &p)
Definition citydlg.cpp:2711
void update_disabled()
Definition citydlg.cpp:2145
QLabel * supp_units
Definition citydlg.h:462
QPushButton * next_city_but
Definition citydlg.h:479
QLabel * qlt[NUM_INFO_FIELDS]
Definition citydlg.h:458
QPushButton * work_prev_but
Definition citydlg.h:482
QHBoxLayout * single_page_layout
Definition citydlg.h:441
void update_buy_button()
Definition citydlg.cpp:2811
int selected_row_p
Definition citydlg.h:493
QHBoxLayout * leftbot_layout
Definition citydlg.h:446
void update_building()
Definition citydlg.cpp:3327
QPushButton * zoom_in_button
Definition citydlg.h:486
void save_worklist()
Definition citydlg.cpp:3642
void worklist_del()
Definition citydlg.cpp:3601
QGridLayout * info_grid_layout
Definition citydlg.h:453
void clear_worklist()
Definition citydlg.cpp:3561
bool happiness_shown
Definition citydlg.h:440
impr_info * city_buildings
Definition citydlg.h:491
QLabel * curr_impr
Definition citydlg.h:464
city_label * lab_table[6]
Definition citydlg.h:452
int scroll_height
Definition citydlg.h:502
QLabel * curr_units
Definition citydlg.h:463
unit_info * current_units
Definition citydlg.h:489
void zoom_out()
Definition citydlg.cpp:2355
void zoom_in()
Definition citydlg.cpp:2342
struct unit_node_vector supported_units
Definition citydlg.c:162
QPushButton * zoom_out_button
Definition citydlg.h:487
struct city * pcity
Definition citydlg.c:137
void update_info_label()
Definition citydlg.cpp:3029
QPushButton * work_add_but
Definition citydlg.h:483
city_dialog(QWidget *parent=0)
Definition citydlg.cpp:1505
QSplitter * central_left_splitter
Definition citydlg.h:444
void disband_state_changed(bool allow_disband)
Definition citydlg.cpp:2671
void update_citizens()
Definition citydlg.cpp:2836
QRadioButton * r1
Definition citydlg.h:475
void cma_slider(int val)
Definition citydlg.cpp:2646
QCheckBox * cma_celeb_checkbox
Definition citydlg.h:469
QCheckBox * show_units
Definition citydlg.h:472
void worklist_down()
Definition citydlg.cpp:3618
void update_title()
Definition citydlg.cpp:3673
QLabel * cma_info_text
Definition citydlg.h:459
void dbl_click_p(QTableWidgetItem *item)
Definition citydlg.cpp:3166
QPushButton * cma_enable_but
Definition citydlg.h:478
QLabel * cma_result
Definition citydlg.h:460
void cma_remove()
Definition citydlg.cpp:2608
QSlider * slider_tab[2 *O_LAST+2]
Definition citydlg.h:494
QPushButton * button
Definition citydlg.h:476
bool eventFilter(QObject *obj, QEvent *event)
Definition citydlg.cpp:2275
QSplitter * prod_unit_splitter
Definition citydlg.h:443
QVBoxLayout * left_layout
Definition citydlg.h:449
void prev_city()
Definition citydlg.cpp:3292
void city_rename()
Definition citydlg.cpp:2312
void refresh()
Definition citydlg.cpp:2920
void update_cma_tab()
Definition citydlg.cpp:2541
QPushButton * work_rem_but
Definition citydlg.h:484
float zoom
Definition citydlg.h:503
QSplitter * central_splitter
Definition citydlg.h:445
QWidget * prod_happ_widget
Definition citydlg.h:447
void cma_toggle_changed(int val)
Definition citydlg.cpp:2635
void show_targets()
Definition citydlg.cpp:3530
QWidget * top_widget
Definition citydlg.h:448
void update_happiness_button()
Definition citydlg.cpp:2104
QPushButton * prev_city_but
Definition citydlg.h:480
void cma_enable()
Definition citydlg.cpp:2404
QLabel * cma_result_pix
Definition citydlg.h:461
struct city * dlgcity
Definition citydlg.h:501
void update_sliders()
Definition citydlg.cpp:2489
void update_improvements()
Definition citydlg.cpp:3395
GtkWidget * worklist
Definition citydlg.c:175
QHBoxLayout * happiness_layout
Definition citydlg.h:442
QCheckBox * future_targets
Definition citydlg.h:471
void change_production(bool next)
Definition citydlg.cpp:2059
void cma_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:2459
QCheckBox * cma_max_growth
Definition citydlg.h:470
void item_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:3239
void show_targets_worklist()
Definition citydlg.cpp:3546
QCheckBox * show_wonders
Definition citydlg.h:474
void cma_context_menu(const QPoint &p)
Definition citydlg.cpp:2691
void cma_changed()
Definition citydlg.cpp:2419
QPushButton * buy_button
Definition citydlg.h:477
QRadioButton * r4
Definition citydlg.h:475
void update_units()
Definition citydlg.cpp:3183
QRadioButton * r2
Definition citydlg.h:475
QTableWidget * p_table_p
Definition citydlg.h:466
void save_cma()
Definition citydlg.cpp:2368
QPixmap * citizen_pixmap
Definition citydlg.h:488
void production_changed(int index)
Definition citydlg.cpp:3512
void update_prod_buttons()
Definition citydlg.cpp:2183
QWidget * happiness_widget
Definition citydlg.h:456
QGroupBox * happiness_group
Definition citydlg.h:455
QCheckBox * show_buildings
Definition citydlg.h:473
Definition city.h:320
struct worker_task_list * task_reqs
Definition city.h:412
int surplus[O_LAST]
Definition city.h:355
int food_stock
Definition city.h:367
int pollution
Definition city.h:369
int id
Definition city.h:326
int waste[O_LAST]
Definition city.h:356
struct unit_list * info_units_present
Definition city.h:474
struct unit_list * info_units_supported
Definition city.h:473
struct universal production
Definition city.h:396
int steal
Definition city.h:414
citizens size
Definition city.h:332
int culture
Definition city.h:465
int buy_cost
Definition city.h:466
struct tile * tile
Definition city.h:322
int shield_stock
Definition city.h:368
int prod[O_LAST]
Definition city.h:358
struct unit_list * units_supported
Definition city.h:406
struct city::@17::@20 client
struct packet_game_info info
Definition game.h:89
struct connection conn
Definition client_main.h:96
bool allow_disorder
Definition cm.h:44
int factor[O_LAST]
Definition cm.h:47
bool max_growth
Definition cm.h:42
bool allow_specialists
Definition cm.h:45
bool require_happy
Definition cm.h:43
int minimal_surplus[O_LAST]
Definition cm.h:41
int happy_factor
Definition cm.h:48
Definition colors.h:21
struct player * playing
Definition connection.h:151
Definition mapimg.c:367
struct requirement_vector obsolete_by
Definition improvement.h:59
Definition climisc.h:80
struct universal item
Definition climisc.h:81
enum unit_activity activity
struct city_list * cities
Definition player.h: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:903
universals_u value
Definition fc_types.h:902
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:1828
const char * text_happiness_wonders(const struct city *pcity)
Definition text.c:1870
const char * text_happiness_units(const struct city *pcity)
Definition text.c:2034
const char * text_happiness_luxuries(const struct city *pcity)
Definition text.c:2072
const char * text_happiness_buildings(const struct city *pcity)
Definition text.c:1800
const char * unit_description(struct unit *punit)
Definition text.c:475
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_terrain(_tile)
Definition tile.h:110
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:6787
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:6983
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:6726
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:6809
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6760
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6778
@ ICON_CITYDLG
Definition tilespec.h:314
const struct unit_type * utype
Definition fc_types.h:724
const struct impr_type * building
Definition fc_types.h:717
bool can_unit_change_homecity(const struct unit *punit)
Definition unit.c:481
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:361
#define unit_tile(_pu)
Definition unit.h:390
#define unit_owner(_pu)
Definition unit.h:389
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:2696
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:387
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1438
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
const char * utype_values_translation(const struct unit_type *punittype)
Definition unittype.c:1617
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:766
#define utype_class(_t_)
Definition unittype.h:749
#define utype_fuel(ptype)
Definition unittype.h:836
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