Freeciv-3.1
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/************************************************************************/
81progress_bar::progress_bar(QWidget *parent): QProgressBar(parent)
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/************************************************************************/
106{
108}
109
110/************************************************************************/
114{
115 struct sprite *sprite;
116 QImage cropped_img;
117 QImage img;
118 QPixmap tpix;
119 QRect crop;
120
121 if (VUT_UTYPE == target->kind) {
123 direction8_invalid());
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();
135 crop = zealous_crop_rect(img);
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;
190 QLinearGradient g, gx;
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) {
204 f_pixel_size = pixel_size;
205 } else {
206 QFontMetrics fm(*sfont);
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);
281 QFontMetrics fm(tmp_font);
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);
308 QFontMetrics fm(*sfont);
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{
369 setParent(parent);
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
387 setFixedWidth(impr_pixmap->map_pixmap.width() + 4);
388 setFixedHeight(impr_pixmap->map_pixmap.height());
389 setToolTip(get_tooltip_improvement(building, pcity, true).trimmed());
390}
391
392/************************************************************************/
396{
397 if (impr_pixmap) {
399 }
400}
401
402/************************************************************************/
406{
407 setPixmap(impr_pixmap->map_pixmap);
408 update();
409}
410
411/************************************************************************/
414#ifndef FC_QT5_MODE
415void impr_item::enterEvent(QEnterEvent *event)
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/************************************************************************/
471impr_info::impr_info(QWidget *parent): QFrame(parent)
472{
473 setParent(parent);
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
487 setSizePolicy(size_fixed_policy);
488 setLayout(layout);
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/************************************************************************/
535void impr_info::wheelEvent(QWheelEvent *event)
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();
586 updateGeometry();
587}
588
589/************************************************************************/
592void impr_item::wheelEvent(QWheelEvent *event)
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;
629 hud_message_box *ask;
630
632 impr) != TR_SUCCESS) {
633 return;
634 }
635
636 ask = new hud_message_box(city_dlg);
637
638 price = impr_sell_gold(impr);
639 fc_snprintf(buf, ARRAY_SIZE(buf),
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 }
653 city_sell_improvement(pcity, impr_id);
654 });
655 ask->show();
656 }
657}
658
659/************************************************************************/
662unit_item::unit_item(QWidget *parent, struct unit *punit,
663 bool supp, int hppy_cost) : QLabel()
664{
665 happy_cost = hppy_cost;
666 QImage cropped_img;
667 QImage img;
668 QRect crop;
669 qunit = punit;
670 struct canvas *unit_pixmap;
671 struct tileset *tmp;
672 float isosize;
673
674 setParent(parent);
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) {
700 put_unit_city_overlays(punit, unit_pixmap, 0,
703 }
704 } else {
705 unit_pixmap = qtg_canvas_create(10, 10);
706 unit_pixmap->map_pixmap.fill(Qt::transparent);
707 }
708
709 img = unit_pixmap->map_pixmap.toImage();
710 crop = zealous_crop_rect(img);
711 cropped_img = img.copy(crop);
713 unit_img = cropped_img.scaledToHeight(tileset_unit_width(get_tileset())
714 * isosize, Qt::SmoothTransformation);
715 } else {
716 unit_img = cropped_img.scaledToHeight(tileset_unit_width(get_tileset()),
717 Qt::SmoothTransformation);
718 }
719 canvas_free(unit_pixmap);
720 if (tmp != nullptr) {
721 tileset = tmp;
722 }
723
725 setFixedWidth(unit_img.width() + 4);
726 setFixedHeight(unit_img.height());
727 setToolTip(unit_description(qunit));
728}
729
730/************************************************************************/
734{
735 setPixmap(QPixmap::fromImage(unit_img));
736 update();
737}
738
739/************************************************************************/
745
746/************************************************************************/
749void unit_item::contextMenuEvent(QContextMenuEvent *event)
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
811 qunits = unit_list_new();
812 unit_list_append(qunits, qunit);
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
819 if (can_unit_do_activity_client(qunit, ACTIVITY_SENTRY)) {
820 sentry = new QAction(_("Sentry unit"), this);
821 connect(sentry, &QAction::triggered, this, &unit_item::sentry_unit);
822 } else {
823 sentry = NULL;
824 }
825
826 if (can_unit_do_activity_client(qunit, ACTIVITY_FORTIFYING)) {
827 fortify = new QAction(_("Fortify unit"), this);
828 connect(fortify, &QAction::triggered, this, &unit_item::fortify_unit);
829 } else {
830 fortify = NULL;
831 }
832 if (unit_can_do_action(qunit, ACTION_DISBAND_UNIT)) {
833 disband_action = new QAction(_("Disband unit"), this);
834 connect(disband_action, &QAction::triggered, this, &unit_item::disband);
835 } else {
836 disband_action = NULL;
837 }
838
840 change_home = new QAction(action_id_name_translation(ACTION_HOME_CITY),
841 this);
842 connect(change_home, &QAction::triggered, this, &unit_item::change_homecity);
843 } else {
844 change_home = NULL;
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
854 if (units_can_unload(qunits)) {
855 unload = new QAction(_("Unload"), this);
856 connect(unload, &QAction::triggered, this, &unit_item::unload_unit);
857 } else {
858 unload = NULL;
859 }
860
861 if (units_are_occupied(qunits)) {
862 unload_trans = new QAction(_("Unload All From Transporter"), this);
863 connect(unload_trans, &QAction::triggered, this, &unit_item::unload_all);
864 } else {
865 unload_trans = NULL;
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
875 unit_list_destroy(qunits);
876}
877
878/************************************************************************/
882{
883 struct unit_list *punits;
885
886 if (punit == nullptr) {
887 return;
888 }
889
890 punits = unit_list_new();
891 unit_list_append(punits, punit);
892 popup_disband_dialog(punits);
893 unit_list_destroy(punits);
894}
895
896/************************************************************************/
903
904/************************************************************************/
911
912/************************************************************************/
919
920/************************************************************************/
924{
925 struct unit_list *qunits;
926 qunits = unit_list_new();
927 unit_list_append(qunits, qunit);
928 popup_upgrade_dialog(qunits);
929 unit_list_destroy(qunits);
930}
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
977void unit_item::enterEvent(QEnterEvent *event)
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/************************************************************************/
1055unit_info::unit_info(bool supp) : QFrame()
1056{
1057 layout = new QHBoxLayout(this);
1058 init_layout();
1059 supports = supp;
1060}
1061
1062/************************************************************************/
1066{
1067 qDeleteAll(unit_list);
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);
1087 setSizePolicy(size_fixed_policy);
1088 setLayout(layout);
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();
1154 updateGeometry();
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
1200 if (cma_is_city_under_agent(pcity, NULL)) {
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/************************************************************************/
1226city_map::city_map(QWidget *parent): QWidget(parent)
1227{
1228 setParent(parent);
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/************************************************************************/
1257void city_map::paintEvent(QPaintEvent *event)
1258{
1259 QPainter painter;
1260 QString str;
1261
1262 painter.begin(this);
1263 painter.drawPixmap(0, 0, zoomed_pixmap);
1264
1265 if (cma_is_city_under_agent(mcity, NULL)) {
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 a custom string chosen 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) {
1290 max_r = sqrt(rs_max_city_radius_sq());
1291 radius = r;
1293 cutted_width = wdth * (r + 1) / max_r;
1294 cutted_height = height * (r + 1) / max_r;
1297 delta_x = (wdth - cutted_width) / 2;
1298 delta_y = (height - cutted_height) / 2;
1300 miniview->map_pixmap.fill(Qt::black);
1301 }
1302
1306 size = miniview->map_pixmap.size();
1308 Qt::KeepAspectRatio,
1309 Qt::SmoothTransformation);
1310 setFixedSize(zoomed_pixmap.size());
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{
1335 int canvas_x, canvas_y, city_x, city_y;
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
1346 if (canvas_to_city_pos(&city_x, &city_y, city_map_radius_sq_get(mcity),
1347 canvas_x, canvas_y)) {
1348 city_toggle_worker(mcity, city_x, city_y);
1349 }
1350}
1351
1352/************************************************************************/
1355void city_map::context_menu(QPoint point)
1356{
1357 int canvas_x, canvas_y, city_x, city_y;
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_pollution = nullptr;
1365 QAction *con_fallout = nullptr;
1366 QAction *con_clear = nullptr;
1367 QMenu *con_menu;
1368 QWidgetAction *wid_act;
1369 struct terrain *pterr;
1370 struct tile *ptile;
1371 struct universal for_terr;
1372 struct worker_task *ptask;
1373 int city_id = mcity->id;
1374
1375 if (!can_client_issue_orders()) {
1376 return;
1377 }
1378
1379 canvas_x = point.x() / zoom + delta_x;
1380 canvas_y = point.y() / zoom + delta_y;
1381
1382 if (!canvas_to_city_pos(&city_x, &city_y, city_map_radius_sq_get(mcity),
1383 canvas_x, canvas_y)) {
1384 return;
1385 }
1386
1388 city_x, city_y);
1389 pterr = tile_terrain(ptile);
1390 for_terr.kind = VUT_TERRAIN;
1391 for_terr.value.terrain = pterr;
1392 ptask = worker_task_list_get(mcity->task_reqs, 0);
1393
1394 wid_act = new QWidgetAction(this);
1395 wid_act->setDefaultWidget(new QLabel(_("Autosettler activity:")));
1396
1397 con_menu = new QMenu(this);
1398 con_menu->addAction(wid_act);
1399
1400 if (pterr->plant_result != NULL
1401 && action_id_univs_not_blocking(ACTION_PLANT, NULL, &for_terr)) {
1402 con_plant = con_menu->addAction(_("Plant"));
1403 }
1404 if (action_id_univs_not_blocking(ACTION_MINE, NULL, &for_terr)) {
1405 con_mine = con_menu->addAction(Q_("?act:Mine"));
1406 }
1407
1408 if (pterr->cultivate_result != NULL
1409 && action_id_univs_not_blocking(ACTION_CULTIVATE, NULL, &for_terr)) {
1410 con_cultivate = con_menu->addAction(_("Cultivate"));
1411 }
1412 if (action_id_univs_not_blocking(ACTION_IRRIGATE, NULL, &for_terr)) {
1413 con_irrig = con_menu->addAction(_("Irrigate"));
1414 }
1415
1416 if (pterr->transform_result != pterr && pterr->transform_result != NULL
1417 && action_id_univs_not_blocking(ACTION_TRANSFORM_TERRAIN,
1418 NULL, &for_terr)) {
1419 con_trfrm = con_menu->addAction(_("Transform"));
1420 }
1421
1422 if (next_extra_for_tile(ptile, EC_ROAD, city_owner(mcity), NULL) != NULL) {
1423 con_road = con_menu->addAction(_("Road"));
1424 }
1425
1426 if (prev_extra_in_tile(ptile, ERM_CLEANPOLLUTION,
1427 city_owner(mcity), NULL) != NULL) {
1428 con_pollution = con_menu->addAction(_("Clean Pollution"));
1429 }
1430
1431 if (prev_extra_in_tile(ptile, ERM_CLEANFALLOUT,
1432 city_owner(mcity), NULL) != NULL) {
1433 con_fallout = con_menu->addAction(_("Clean Fallout"));
1434 }
1435
1436 if (ptask != NULL) {
1437 con_clear = con_menu->addAction(_("Clear"));
1438 }
1439
1440 con_menu->setAttribute(Qt::WA_DeleteOnClose);
1441 connect(con_menu, &QMenu::triggered,
1442 CAPTURE_DEFAULT_THIS (QAction *act) {
1443 bool target = false;
1444 struct packet_worker_task task;
1445
1446 if (!act) {
1447 return;
1448 }
1449
1450 task.city_id32 = city_id;
1451 task.city_id16 = task.city_id32;
1452
1453 if (act == con_road) {
1454 task.activity = ACTIVITY_GEN_ROAD;
1455 target = TRUE;
1456 } else if (act == con_mine) {
1457 task.activity = ACTIVITY_MINE;
1458 target = TRUE;
1459 } else if (act == con_plant) {
1460 task.activity = ACTIVITY_PLANT;
1461 } else if (act == con_irrig) {
1462 task.activity = ACTIVITY_IRRIGATE;
1463 target = TRUE;
1464 } else if (act == con_cultivate) {
1465 task.activity = ACTIVITY_CULTIVATE;
1466 } else if (act == con_trfrm) {
1467 task.activity = ACTIVITY_TRANSFORM;
1468 } else if (act == con_pollution) {
1469 task.activity = ACTIVITY_POLLUTION;
1470 target = TRUE;
1471 } else if (act == con_fallout) {
1472 task.activity = ACTIVITY_FALLOUT;
1473 target = TRUE;
1474 } else if (act == con_clear) {
1475 task.activity = ACTIVITY_LAST;
1476 } else {
1477 /* Closed dialog without selecting any activity entry. */
1478 return;
1479 }
1480
1481 task.want = 100;
1482
1483 if (target) {
1484 enum extra_cause cause = activity_to_extra_cause(task.activity);
1485 enum extra_rmcause rmcause = activity_to_extra_rmcause(task.activity);
1486 struct extra_type *tgt;
1487
1488 if (cause != EC_NONE) {
1489 tgt = next_extra_for_tile(ptile, cause, city_owner(mcity), NULL);
1490 } else if (rmcause != ERM_NONE) {
1491 tgt = prev_extra_in_tile(ptile, rmcause, city_owner(mcity), NULL);
1492 } else {
1493 tgt = NULL;
1494 }
1495
1496 if (tgt != NULL) {
1497 task.tgt = extra_index(tgt);
1498 } else {
1499 task.tgt = -1;
1500 }
1501 } else {
1502 task.tgt = -1;
1503 }
1504
1505 task.tile_id = ptile->index;
1507 });
1508
1509 con_menu->popup(mapToGlobal(point));
1510}
1511
1512/************************************************************************/
1515city_dialog::city_dialog(QWidget *parent): qfc_dialog(parent)
1516{
1517 QFont f = QApplication::font();
1518 QFont *small_font;
1519 QFontMetrics fm(f);
1520 QGridLayout *gridl, *slider_grid;
1521 QGroupBox *group_box, *map_box, *prod_options,
1522 *qgbox, *qgbprod, *qsliderbox, *result_box;
1523 QHBoxLayout *hbox, *hbox_layout, *prod_option_layout,
1524 *work_but_layout;
1525 QHeaderView *header;
1526 QLabel *lab2, *label, *ql, *some_label;
1527 QPushButton *qpush2;
1528 QScrollArea *scroll, *scroll2, *scroll3, *scroll_info, *scroll_unit;
1529 QSizePolicy size_expanding_policy(QSizePolicy::Expanding,
1530 QSizePolicy::Expanding);
1531 QSlider *slider;
1532 QStringList info_list, str_list;
1533 QVBoxLayout *lefttop_layout, *units_layout, *worklist_layout,
1534 *right_layout, *vbox, *vbox_layout, *zoom_vbox, *v_layout;
1535 QWidget *split_widget1, *split_widget2, *info_wdg, *curr_unit_wdg,
1536 *supp_unit_wdg, *curr_impr_wdg;
1537 int list_size;
1538 int h = 2 * fm.height() + 2;
1539
1541 zoom = 1.0;
1542
1543 happiness_shown = false;
1544 central_splitter = new QSplitter;
1545 central_splitter->setOpaqueResize(false);
1546 central_left_splitter = new QSplitter;
1547 central_left_splitter->setOpaqueResize(false);
1548 prod_unit_splitter = new QSplitter;
1549 prod_unit_splitter->setOpaqueResize(false);
1550
1551 setMouseTracking(true);
1552 selected_row_p = -1;
1553 dlgcity = NULL;
1554 lcity_name = new QPushButton(this);
1555 lcity_name->setToolTip(_("Click to change city name"));
1556
1557 single_page_layout = new QHBoxLayout();
1558 single_page_layout->setContentsMargins(0, 0 ,0 ,0);
1559 size_expanding_policy.setHorizontalStretch(0);
1560 size_expanding_policy.setVerticalStretch(0);
1561 setSizePolicy(size_expanding_policy);
1562 current_building = 0;
1563
1564 /* map view */
1565 map_box = new QGroupBox(this);
1566
1567 /* City information widget texts about surpluses and so on */
1568 info_wdg = new QWidget(this);
1569
1570 /* Fill info_wdg with labels */
1571 info_grid_layout = new QGridLayout(parent);
1572
1573 info_wdg->setFont(*small_font);
1574 info_grid_layout->setSpacing(0);
1575 info_grid_layout->setContentsMargins(0, 0, 0, 0);
1576
1577
1578 for (enum city_info info_field = city_info_begin();
1579 info_field != city_info_end();
1580 info_field = city_info_next(info_field)) {
1581
1582 ql = new QLabel(_(city_info_name(info_field)), info_wdg);
1583 ql->setFont(*small_font);
1584 ql->setProperty(fonts::notify_label, "true");
1585 info_grid_layout->addWidget(ql, info_field, 0);
1586 qlt[info_field] = new QLabel(info_wdg);
1587 qlt[info_field]->setFont(*small_font);
1588 qlt[info_field]->setProperty(fonts::notify_label, "true");
1589 info_grid_layout->addWidget(qlt[info_field], info_field, 1);
1590 info_grid_layout->setRowStretch(info_field, 0);
1591 }
1592
1593 info_wdg->setLayout(info_grid_layout);
1594
1595 /* Buy button */
1596 buy_button = new QPushButton();
1597 buy_button->setIcon(fc_icons::instance()->get_icon("help-donate"));
1598 connect(buy_button, &QAbstractButton::clicked, this, &city_dialog::buy);
1599
1600 connect(lcity_name, &QAbstractButton::clicked, this, &city_dialog::city_rename);
1602 citizen_pixmap = NULL;
1603 view = new city_map(this);
1604
1605 zoom_vbox = new QVBoxLayout();
1606 zoom_in_button = new QPushButton();
1607 zoom_in_button->setIcon(fc_icons::instance()->get_icon("plus"));
1608 zoom_in_button->setIconSize(QSize(16, 16));
1609 zoom_in_button->setFixedSize(QSize(20, 20));
1610 zoom_in_button->setToolTip(_("Zoom in"));
1611 connect(zoom_in_button, &QAbstractButton::clicked, this, &city_dialog::zoom_in);
1612 zoom_out_button = new QPushButton();
1613 zoom_out_button->setIcon(fc_icons::instance()->get_icon("minus"));
1614 zoom_out_button->setIconSize(QSize(16, 16));
1615 zoom_out_button->setFixedSize(QSize(20, 20));
1616 zoom_out_button->setToolTip(_("Zoom out"));
1617 connect(zoom_out_button, &QAbstractButton::clicked, this, &city_dialog::zoom_out);
1618 zoom_vbox->addWidget(zoom_in_button);
1619 zoom_vbox->addWidget(zoom_out_button);
1620
1621 /* City map group box */
1622 vbox_layout = new QVBoxLayout;
1623 hbox_layout = new QHBoxLayout;
1624 hbox_layout->addStretch(100);
1625 hbox_layout->addWidget(view);
1626 hbox_layout->addStretch(100);
1627 hbox_layout->addLayout(zoom_vbox);
1628 vbox_layout->addLayout(hbox_layout);
1629 vbox_layout->addWidget(lcity_name);
1630 map_box->setLayout(vbox_layout);
1631 map_box->setTitle(_("City map"));
1632
1633 /* current/supported units/improvements widgets */
1634 supp_units = new QLabel();
1635 curr_units = new QLabel();
1636 curr_impr = new QLabel();
1637 curr_units->setAlignment(Qt::AlignLeft);
1638 curr_impr->setAlignment(Qt::AlignLeft);
1639 supp_units->setAlignment(Qt::AlignLeft);
1640 supported_units = new unit_info(true);
1641 scroll = new QScrollArea;
1642 scroll->setWidgetResizable(true);
1643 scroll->setMaximumHeight(tileset_unit_with_upkeep_height(get_tileset()) + 6
1644 + scroll->horizontalScrollBar()->height());
1645 scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1646 scroll->setWidget(supported_units);
1647 current_units = new unit_info(false);
1648 scroll2 = new QScrollArea;
1649 scroll2->setWidgetResizable(true);
1650 scroll2->setMaximumHeight(tileset_unit_height(get_tileset()) + 6
1651 + scroll2->horizontalScrollBar()->height());
1652 scroll2->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1653 scroll2->setWidget(current_units);
1654 scroll_height = scroll2->horizontalScrollBar()->height();
1655 city_buildings = new impr_info(this);
1656 scroll3 = new QScrollArea;
1657 scroll3->setWidgetResizable(true);
1658 scroll3->setMaximumHeight(tileset_unit_height(tileset) + 6
1659 + scroll3->horizontalScrollBar()->height());
1660 scroll3->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1661 scroll3->setWidget(city_buildings);
1662 scroll->setProperty("city_scroll", true);
1663 scroll2->setProperty("city_scroll", true);
1664 scroll3->setProperty("city_scroll", true);
1665
1666 lefttop_layout = new QVBoxLayout();
1667 worklist_layout = new QVBoxLayout();
1668 right_layout = new QVBoxLayout();
1669 leftbot_layout = new QHBoxLayout();
1670 units_layout = new QVBoxLayout();
1671 left_layout = new QVBoxLayout();
1672
1673 /* Checkboxes to show units/wonders/imrovements
1674 * on production list */
1675 prod_option_layout = new QHBoxLayout;
1676 show_buildings = new QCheckBox;
1677 show_buildings->setToolTip(_("Show buildings"));
1678 show_buildings->setChecked(true);
1679 label = new QLabel();
1680 label->setPixmap(*fc_icons::instance()->get_pixmap("building"));
1681 label->setToolTip(_("Show buildings"));
1682 prod_option_layout->addWidget(show_buildings, Qt::AlignLeft);
1683 prod_option_layout->addWidget(label, Qt::AlignLeft);
1684 prod_option_layout->addStretch(100);
1685 label = new QLabel();
1686 label->setPixmap(*fc_icons::instance()->get_pixmap("cunits"));
1687 label->setToolTip(_("Show units"));
1688 show_units = new QCheckBox;
1689 show_units->setToolTip(_("Show units"));
1690 show_units->setChecked(true);
1691 prod_option_layout->addWidget(show_units, Qt::AlignHCenter);
1692 prod_option_layout->addWidget(label, Qt::AlignHCenter);
1693 prod_option_layout->addStretch(100);
1694 label = new QLabel();
1695 label->setPixmap(*fc_icons::instance()->get_pixmap("wonder"));
1696 label->setToolTip(_("Show wonders"));
1697 show_wonders = new QCheckBox;
1698 show_wonders->setToolTip(_("Show wonders"));
1699 show_wonders->setChecked(true);
1700 prod_option_layout->addWidget(show_wonders);
1701 prod_option_layout->addWidget(label);
1702 prod_option_layout->addStretch(100);
1703 label = new QLabel();
1704 label->setPixmap(*fc_icons::instance()->get_pixmap("future"));
1705 label->setToolTip(_("Show future targets"));
1706 future_targets = new QCheckBox;
1707 future_targets->setToolTip(_("Show future targets"));
1708 future_targets->setChecked(false);
1709 prod_option_layout->addWidget(future_targets);
1710 prod_option_layout->addWidget(label, Qt::AlignRight);
1711 prod_options = new QGroupBox(this);
1712 prod_options->setLayout(prod_option_layout);
1713 prod_options->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
1714
1715 /* prev/next and close buttons */
1716 button = new QPushButton;
1717 button->setIcon(fc_icons::instance()->get_icon("city-close"));
1718 button->setIconSize(QSize(56, 56));
1719 button->setToolTip(_("Close city dialog"));
1720 connect(button, &QAbstractButton::clicked, this, &QWidget::hide);
1721
1722 next_city_but = new QPushButton();
1723 next_city_but->setIcon(fc_icons::instance()->get_icon("city-right"));
1724 next_city_but->setIconSize(QSize(56, 56));
1725 next_city_but->setToolTip(_("Show next city"));
1726 connect(next_city_but, &QAbstractButton::clicked, this, &city_dialog::next_city);
1727
1728 prev_city_but = new QPushButton();
1729 connect(prev_city_but, &QAbstractButton::clicked, this, &city_dialog::prev_city);
1730 prev_city_but->setIcon(fc_icons::instance()->get_icon("city-left"));
1731 prev_city_but->setIconSize(QSize(56, 56));
1732 prev_city_but->setToolTip(_("Show previous city"));
1733
1734 happiness_button = new QPushButton();
1735 happiness_button->setIcon(fc_icons::instance()->get_icon("city-switch"));
1736 happiness_button->setIconSize(QSize(56, 28));
1737 connect(happiness_button, &QAbstractButton::clicked, this, &city_dialog::show_happiness);
1739
1740 button->setFixedSize(64, 64);
1741 prev_city_but->setFixedSize(64, 64);
1742 next_city_but->setFixedSize(64, 64);
1743 happiness_button->setFixedSize(64, 32);
1744 vbox_layout = new QVBoxLayout;
1745 vbox_layout->addWidget(prev_city_but);
1746 vbox_layout->addWidget(next_city_but);
1747 vbox_layout->addWidget(button);
1748 vbox_layout->addWidget(happiness_button, Qt::AlignHCenter);
1749 hbox_layout = new QHBoxLayout;
1750
1751 hbox_layout->addLayout(vbox_layout, Qt::AlignLeft);
1752 hbox_layout->addWidget(info_wdg, Qt::AlignLeft);
1753 hbox_layout->addWidget(map_box, Qt::AlignCenter);
1754
1755 /* Layout with city view and buttons */
1756 lefttop_layout->addWidget(citizens_label, Qt::AlignHCenter);
1757 lefttop_layout->addStretch(0);
1758 lefttop_layout->addLayout(hbox_layout);
1759 lefttop_layout->addStretch(50);
1760
1761 /* Layout for units/buildings */
1762 curr_unit_wdg = new QWidget();
1763 supp_unit_wdg = new QWidget();
1764 curr_impr_wdg = new QWidget();
1765 v_layout = new QVBoxLayout;
1766 v_layout->addWidget(curr_impr);
1767 v_layout->addWidget(scroll3);
1768 v_layout->setContentsMargins(0 , 0 , 0, 0);
1769 v_layout->setSpacing(0);
1770 curr_impr_wdg->setLayout(v_layout);
1771 v_layout = new QVBoxLayout;
1772 v_layout->addWidget(curr_units);
1773 v_layout->addWidget(scroll2);
1774 v_layout->setContentsMargins(0 , 0 , 0, 0);
1775 v_layout->setSpacing(0);
1776 curr_unit_wdg->setLayout(v_layout);
1777 v_layout = new QVBoxLayout;
1778 v_layout->addWidget(supp_units);
1779 v_layout->addWidget(scroll);
1780 v_layout->setContentsMargins(0 , 0 , 0, 0);
1781 v_layout->setSpacing(0);
1782 supp_unit_wdg->setLayout(v_layout);
1783
1784 units_layout->addWidget(curr_unit_wdg);
1785 units_layout->addWidget(supp_unit_wdg);
1786 units_layout->addWidget(curr_impr_wdg);
1787 units_layout->setSpacing(0);
1788 units_layout->setContentsMargins(0 , 0 , 0, 0);
1789
1790 vbox = new QVBoxLayout;
1791 vbox_layout = new QVBoxLayout;
1792 qgbprod = new QGroupBox;
1793 group_box = new QGroupBox(_("Worklist Option"));
1794 work_but_layout = new QHBoxLayout;
1795 work_next_but = new QPushButton(fc_icons::instance()->get_icon(
1796 "go-down"), "");
1797 work_prev_but = new QPushButton(fc_icons::instance()->get_icon(
1798 "go-up"), "");
1799 work_add_but = new QPushButton(fc_icons::instance()->get_icon(
1800 "list-add"), "");
1801 work_rem_but = new QPushButton(style()->standardIcon(
1802 QStyle::SP_DialogDiscardButton), "");
1803 work_but_layout->addWidget(work_add_but);
1804 work_but_layout->addWidget(work_next_but);
1805 work_but_layout->addWidget(work_prev_but);
1806 work_but_layout->addWidget(work_rem_but);
1807 production_combo_p = new progress_bar(parent);
1808 production_combo_p->setToolTip(_("Click to change current production"));
1809 p_table_p = new QTableWidget;
1810
1811 r1 = new QRadioButton(_("Change"));
1812 r2 = new QRadioButton(_("Insert Before"));
1813 r3 = new QRadioButton(_("Insert After"));
1814 r4 = new QRadioButton(_("Add Last"));
1815 r4->setChecked(true);
1816 group_box->setLayout(vbox);
1817
1818
1819 p_table_p->setColumnCount(3);
1820 p_table_p->setProperty("showGrid", "false");
1821 p_table_p->setProperty("selectionBehavior", "SelectRows");
1822 p_table_p->setEditTriggers(QAbstractItemView::NoEditTriggers);
1823 p_table_p->verticalHeader()->setVisible(false);
1824 p_table_p->horizontalHeader()->setVisible(false);
1825 p_table_p->setSelectionMode(QAbstractItemView::SingleSelection);
1826 production_combo_p->setFixedHeight(h);
1827 p_table_p->setMinimumWidth(200);
1828 p_table_p->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
1829 p_table_p->setContextMenuPolicy(Qt::CustomContextMenu);
1830 p_table_p->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
1831 header = p_table_p->horizontalHeader();
1832 header->setStretchLastSection(true);
1833
1834 qgbprod->setTitle(_("Worklist"));
1835 vbox_layout->setSpacing(0);
1836 vbox_layout->addWidget(prod_options);
1837 vbox_layout->addWidget(buy_button);
1838 vbox_layout->addWidget(production_combo_p);
1839 vbox_layout->addLayout(work_but_layout);
1840 vbox_layout->addWidget(p_table_p);
1841 qgbprod->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1842 qgbprod->setLayout(vbox_layout);
1843
1844 worklist_layout->setSpacing(0);
1845 worklist_layout->addWidget(qgbprod);
1846 connect(p_table_p,
1847 &QWidget::customContextMenuRequested, this,
1850 connect(work_add_but, &QAbstractButton::clicked, this, &city_dialog::show_targets_worklist);
1851 connect(work_prev_but, &QAbstractButton::clicked, this, &city_dialog::worklist_up);
1852 connect(work_next_but, &QAbstractButton::clicked, this, &city_dialog::worklist_down);
1853 connect(work_rem_but, &QAbstractButton::clicked, this, &city_dialog::worklist_del);
1854 connect(p_table_p,
1855 &QTableWidget::itemDoubleClicked,
1857 connect(p_table_p->selectionModel(),
1858 SIGNAL(selectionChanged(const QItemSelection &,
1859 const QItemSelection &)),
1860 SLOT(item_selected(const QItemSelection &,
1861 const QItemSelection &)));
1862 happiness_group = new QGroupBox(_("Happiness"));
1863 gridl = new QGridLayout;
1864
1865 nationality_table = new QTableWidget;
1866 nationality_table->setColumnCount(3);
1867 nationality_table->setProperty("showGrid", "false");
1868 nationality_table->setProperty("selectionBehavior", "SelectRows");
1869 nationality_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1870 nationality_table->verticalHeader()->setVisible(false);
1871 nationality_table->horizontalHeader()->setStretchLastSection(true);
1872
1873 info_list.clear();
1874 info_list << _("Cities:") << _("Luxuries:") << _("Buildings:")
1875 << _("Nationality:") << _("Units:") << _("Wonders:");
1876
1877 for (int i = 0; i < info_list.count(); i++) {
1878 lab_table[i] = new city_label(1 + i, this);
1879 gridl->addWidget(lab_table[i], i, 1, 1, 1);
1880 lab2 = new QLabel(this);
1881 lab2->setFont(*small_font);
1882 lab2->setProperty(fonts::notify_label, "true");
1883 lab2->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1884 lab2->setText(info_list.at(i));
1885 gridl->addWidget(lab2, i, 0, 1, 1);
1886 }
1887
1888 gridl->setSpacing(0);
1889 happiness_group->setLayout(gridl);
1890
1891
1892 happiness_layout = new QHBoxLayout;
1895 happiness_layout->setStretch(0, 10);
1896 happiness_widget = new QWidget();
1898 qgbox = new QGroupBox(_("Presets:"));
1899 qsliderbox = new QGroupBox(_("Governor settings"));
1900 result_box = new QGroupBox(_("Results:"));
1901 hbox = new QHBoxLayout;
1902 gridl = new QGridLayout;
1903 slider_grid = new QGridLayout;
1904
1905 qpush2
1906 = new QPushButton(style()->standardIcon(QStyle::SP_DialogSaveButton),
1907 _("Save"));
1908 connect(qpush2, &QAbstractButton::pressed, this, &city_dialog::save_cma);
1909
1910 cma_info_text = new QLabel;
1911 cma_info_text->setFont(*small_font);
1912 cma_info_text->setAlignment(Qt::AlignCenter);
1913 cma_table = new QTableWidget;
1914 cma_table->setColumnCount(1);
1915 cma_table->setProperty("showGrid", "false");
1916 cma_table->setProperty("selectionBehavior", "SelectRows");
1917 cma_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
1918 cma_table->setSelectionMode(QAbstractItemView::SingleSelection);
1919 cma_table->setContextMenuPolicy(Qt::CustomContextMenu);
1920 cma_table->verticalHeader()->setVisible(false);
1921 cma_table->horizontalHeader()->setVisible(false);
1922 cma_table->horizontalHeader()->setSectionResizeMode(
1923 QHeaderView::Stretch);
1924
1925 connect(cma_table->selectionModel(),
1926 SIGNAL(selectionChanged(const QItemSelection &,
1927 const QItemSelection &)),
1928 SLOT(cma_selected(const QItemSelection &,
1929 const QItemSelection &)));
1930 connect(cma_table,
1931 &QWidget::customContextMenuRequested, this,
1933 connect(cma_table, &QTableWidget::cellDoubleClicked, this,
1935 gridl->addWidget(cma_table, 0, 0, 1, 2);
1936 qgbox->setLayout(gridl);
1937 hbox->addWidget(cma_info_text);
1938 result_box->setLayout(hbox);
1939 str_list << _("Food") << _("Shield") << _("Trade") << _("Gold")
1940 << _("Luxury") << _("Science") << _("Celebrate")
1941 << _("Maximize growth");
1942 some_label = new QLabel(_("Minimal Surplus"));
1943 some_label->setFont(*fc_font::instance()->get_font(fonts::notify_label));
1944 some_label->setAlignment(Qt::AlignRight);
1945 slider_grid->addWidget(some_label, 0, 0, 1, 3);
1946 some_label = new QLabel(_("Priority"));
1947 some_label->setFont(*fc_font::instance()->get_font(fonts::notify_label));
1948 some_label->setAlignment(Qt::AlignCenter);
1949 slider_grid->addWidget(some_label, 0, 3, 1, 2);
1950
1951 list_size = str_list.count();
1952 for (int i = 0; i < list_size; i++) {
1953 some_label = new QLabel(str_list.at(i));
1954 slider_grid->addWidget(some_label, i + 1, 0, 1, 1);
1955 some_label = new QLabel("0");
1956 some_label->setMinimumWidth(25);
1957
1958 if (i < list_size - 2) {
1959 slider = new QSlider(Qt::Horizontal);
1960 slider->setPageStep(1);
1961 slider->setFocusPolicy(Qt::TabFocus);
1962 slider_tab[2 * i] = slider;
1963 slider->setRange(-20, 20);
1964 slider->setSingleStep(1);
1965 slider_grid->addWidget(some_label, i + 1, 1, 1, 1);
1966 slider_grid->addWidget(slider, i + 1, 2, 1, 1);
1967 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1968
1969 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1970 } else if (i == list_size - 2) {
1971 cma_celeb_checkbox = new QCheckBox;
1972 slider_grid->addWidget(cma_celeb_checkbox, i + 1, 2 , 1 , 1);
1973 connect(cma_celeb_checkbox,
1974 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1975 } else {
1976 fc_assert(i == list_size - 1);
1977
1978 cma_max_growth = new QCheckBox;
1979 slider_grid->addWidget(cma_max_growth, i + 1, 2 , 1 , 1);
1980 connect(cma_max_growth,
1981 &QCheckBox::stateChanged, this, &city_dialog::cma_toggle_changed);
1982 }
1983
1984 if (i <= list_size - 2) {
1985 some_label = new QLabel("0");
1986 some_label->setMinimumWidth(25);
1987 slider = new QSlider(Qt::Horizontal);
1988 slider->setFocusPolicy(Qt::TabFocus);
1989 slider->setRange(0, 25);
1990 slider_tab[2 * i + 1] = slider;
1991 slider->setProperty("FC", QVariant::fromValue((void *)some_label));
1992 slider_grid->addWidget(some_label, i + 1, 3, 1, 1);
1993 slider_grid->addWidget(slider, i + 1, 4, 1, 1);
1994 connect(slider, &QAbstractSlider::valueChanged, this, &city_dialog::cma_slider);
1995 }
1996 }
1997
1998 cma_enable_but = new QPushButton();
1999 cma_enable_but->setFocusPolicy(Qt::TabFocus);
2000 connect(cma_enable_but, &QAbstractButton::pressed, this, &city_dialog::cma_enable);
2001 slider_grid->addWidget(cma_enable_but, O_LAST + 4, 0, 1, 3);
2002 slider_grid->addWidget(qpush2, O_LAST + 4, 3, 1, 2);
2003
2004 qsliderbox->setLayout(slider_grid);
2005 cma_result = new QLabel;
2006 cma_result_pix = new QLabel;
2007
2008 hbox = new QHBoxLayout;
2009 QScrollArea *govA = new QScrollArea();
2010 hbox->addWidget(cma_result_pix);
2011 hbox->addWidget(cma_result);
2012 hbox->addStretch(10);
2013 govA->setWidget(qsliderbox);
2014 govA->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
2015 right_layout->addWidget(qgbox);
2016 right_layout->addLayout(hbox);
2017 right_layout->addWidget(govA);
2018
2019 split_widget1 = new QWidget;
2020 split_widget1->setLayout(worklist_layout);
2021 split_widget2 = new QWidget;
2022 split_widget2->setLayout(units_layout);
2023 prod_unit_splitter->addWidget(split_widget1);
2024 prod_unit_splitter->addWidget(split_widget2);
2025 prod_unit_splitter->setStretchFactor(0, 3);
2026 prod_unit_splitter->setStretchFactor(1, 97);
2027 prod_unit_splitter->setOrientation(Qt::Horizontal);
2029 top_widget = new QWidget;
2030 top_widget->setLayout(lefttop_layout);
2031 top_widget->setSizePolicy(QSizePolicy::Minimum,
2032 QSizePolicy::Minimum);
2033 scroll_info = new QScrollArea();
2034 scroll_info->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
2035 scroll_unit = new QScrollArea();
2036 scroll_info->setWidget(top_widget);
2037 scroll_info->setWidgetResizable(true);
2038 prod_happ_widget = new QWidget;
2039 prod_happ_widget->setLayout(leftbot_layout);
2040 prod_happ_widget->setSizePolicy(QSizePolicy::MinimumExpanding,
2041 QSizePolicy::MinimumExpanding);
2042 scroll_unit->setWidget(prod_happ_widget);
2043 scroll_unit->setWidgetResizable(true);
2044 central_left_splitter->addWidget(scroll_info);
2045 central_left_splitter->addWidget(scroll_unit);
2046 central_left_splitter->setStretchFactor(0, 40);
2047 central_left_splitter->setStretchFactor(1, 60);
2048 central_left_splitter->setOrientation(Qt::Vertical);
2050
2051 split_widget1 = new QWidget(this);
2052 split_widget2 = new QWidget(this);
2053 split_widget1->setLayout(left_layout);
2054 split_widget2->setLayout(right_layout);
2055 central_splitter->addWidget(split_widget1);
2056 central_splitter->addWidget(split_widget2);
2057 central_splitter->setStretchFactor(0, 99);
2058 central_splitter->setStretchFactor(1, 1);
2059 central_splitter->setOrientation(Qt::Horizontal);
2061 setSizeGripEnabled(true);
2062 setLayout(single_page_layout);
2063
2064 installEventFilter(this);
2065
2066 ::city_dlg_created = true;
2067}
2068
2069/************************************************************************/
2073{
2074
2075 cid cprod;
2076 int i, pos;
2077 int item, targets_used;
2078 QList<cid> prod_list;
2079 QString str;
2080 struct item items[MAX_NUM_PRODUCTION_TARGETS];
2081 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
2082 struct universal univ;
2083
2084 pos = 0;
2085 cprod = cid_encode(dlgcity->production);
2086 targets_used = collect_eventually_buildable_targets(targets, dlgcity, false);
2087 name_and_sort_items(targets, targets_used, items, false, dlgcity);
2088
2089 for (item = 0; item < targets_used; item++) {
2090 if (can_city_build_now(&(wld.map), dlgcity, &items[item].item)) {
2091 prod_list << cid_encode(items[item].item);
2092 }
2093 }
2094
2095 for (i = 0; i < prod_list.size(); i++) {
2096 if (prod_list.at(i) == cprod) {
2097 if (next) {
2098 pos = i + 1;
2099 } else {
2100 pos = i - 1;
2101 }
2102 }
2103 }
2104 if (pos == prod_list.size()) {
2105 pos = 0;
2106 }
2107 if (pos == - 1) {
2108 pos = prod_list.size() - 1;
2109 }
2110 univ = cid_decode(static_cast<cid>(prod_list.at(pos)));
2112}
2113
2114/************************************************************************/
2118{
2119 if (happiness_shown) {
2120 happiness_button->setToolTip(_("Show city production"));
2121 } else {
2122 happiness_button->setToolTip(_("Show happiness information"));
2123 }
2124}
2125
2126/************************************************************************/
2130{
2131 setUpdatesEnabled(false);
2132
2133 if (!happiness_shown) {
2134 leftbot_layout->replaceWidget(prod_unit_splitter,
2136 Qt::FindDirectChildrenOnly);
2137 prod_unit_splitter->hide();
2138 happiness_widget->show();
2139 happiness_widget->updateGeometry();
2140 } else {
2141 leftbot_layout->replaceWidget(happiness_widget,
2143 Qt::FindDirectChildrenOnly);
2144 prod_unit_splitter->show();
2145 prod_unit_splitter->updateGeometry();
2146 happiness_widget->hide();
2147 }
2148
2149 setUpdatesEnabled(true);
2150 update();
2153}
2154
2155/************************************************************************/
2159{
2160 if (NULL == client.conn.playing
2162 prev_city_but->setDisabled(true);
2163 next_city_but->setDisabled(true);
2164 buy_button->setDisabled(true);
2165 cma_enable_but->setDisabled(true);
2166 production_combo_p->setDisabled(true);
2167 current_units->setDisabled(true);
2168 supported_units->setDisabled(true);
2169 view->setDisabled(true);
2170
2171 if (!client_is_observer()) {
2172 }
2173 } else {
2174 prev_city_but->setEnabled(true);
2175 next_city_but->setEnabled(true);
2176 buy_button->setEnabled(true);
2177 cma_enable_but->setEnabled(true);
2178 production_combo_p->setEnabled(true);
2179 current_units->setEnabled(true);
2180 supported_units->setEnabled(true);
2181 view->setEnabled(true);
2182 }
2183
2185 cma_enable_but->setEnabled(true);
2186 } else {
2187 cma_enable_but->setDisabled(true);
2188 }
2189
2191}
2192
2193/************************************************************************/
2197{
2198 work_next_but->setDisabled(true);
2199 work_prev_but->setDisabled(true);
2200 work_add_but->setDisabled(true);
2201 work_rem_but->setDisabled(true);
2202
2204 work_add_but->setEnabled(true);
2205
2206 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount()) {
2207 work_rem_but->setEnabled(true);
2208 }
2209
2210 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount() - 1) {
2211 work_next_but->setEnabled(true);
2212 }
2213
2214 if (selected_row_p > 0 && selected_row_p < p_table_p->rowCount()) {
2215 work_prev_but->setEnabled(true);
2216 }
2217 }
2218}
2219
2220/************************************************************************/
2224{
2225 if (citizen_pixmap) {
2226 citizen_pixmap->detach();
2227 delete citizen_pixmap;
2228 }
2229
2230 cma_table->clear();
2231 p_table_p->clear();
2232 nationality_table->clear();
2234 supported_units->clear_layout();
2235 removeEventFilter(this);
2236 ::city_dlg_created = false;
2237
2238 // Delete the one widget that currently does NOT have a parent
2239 if (happiness_shown) {
2240 delete prod_unit_splitter;
2241 } else {
2242 delete happiness_widget;
2243 }
2244}
2245
2246/************************************************************************/
2250{
2251 gui()->qt_settings.city_geometry = saveGeometry();
2252 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2253 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2254 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2255}
2256
2257/************************************************************************/
2261{
2262 if (!gui()->qt_settings.city_geometry.isNull()) {
2263 restoreGeometry(gui()->qt_settings.city_geometry);
2264 prod_unit_splitter->restoreState(gui()->qt_settings.city_splitter1);
2265 central_left_splitter->restoreState(gui()->qt_settings.city_splitter2);
2266 central_splitter->restoreState(gui()->qt_settings.city_splitter3);
2267 } else {
2268 QRect rect = QApplication::primaryScreen()->availableGeometry();
2269
2270 resize((rect.width() * 4) / 5, (rect.height() * 5) / 6);
2271 }
2272}
2273
2274/************************************************************************/
2278{
2279 gui()->qt_settings.city_geometry = saveGeometry();
2280 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2281 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2282 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2283}
2284
2285/************************************************************************/
2288bool city_dialog::eventFilter(QObject *obj, QEvent *event)
2289{
2290
2291 if (obj == this) {
2292 if (event->type() == QEvent::KeyPress) {
2293 }
2294
2295 if (event->type() == QEvent::ShortcutOverride) {
2296 QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
2297 if (key_event->key() == Qt::Key_Right) {
2298 next_city();
2299 event->setAccepted(true);
2300 return true;
2301 }
2302 if (key_event->key() == Qt::Key_Left) {
2303 prev_city();
2304 event->setAccepted(true);
2305 return true;
2306 }
2307 if (key_event->key() == Qt::Key_Up) {
2308 change_production(true);
2309 event->setAccepted(true);
2310 return true;
2311 }
2312 if (key_event->key() == Qt::Key_Down) {
2313 change_production(false);
2314 event->setAccepted(true);
2315 return true;
2316 }
2317 }
2318 }
2319 return QObject::eventFilter(obj, event);
2320}
2321
2322/************************************************************************/
2326{
2327 hud_input_box *ask;
2328 const int city_id = dlgcity->id;
2329
2330 if (!can_client_issue_orders()) {
2331 return;
2332 }
2333
2334 ask = new hud_input_box(gui()->central_wdg);
2335 ask->set_text_title_definput(_("What should we rename the city to?"),
2336 _("Rename City"), city_name_get(dlgcity));
2337 ask->setAttribute(Qt::WA_DeleteOnClose);
2338 connect(ask, &hud_message_box::accepted, this, [=]() {
2339 struct city *pcity = game_city_by_number(city_id);
2340 QByteArray ask_bytes;
2341
2342 if (!pcity) {
2343 return;
2344 }
2345
2346 ask_bytes = ask->input_edit.text().toUtf8();
2347 ::city_rename(pcity, ask_bytes.data());
2348 });
2349 ask->show();
2350}
2351
2352/************************************************************************/
2356{
2357 zoom = zoom * 1.2;
2358 if (dlgcity) {
2359 view->set_pixmap(dlgcity, zoom);
2360 }
2361 updateGeometry();
2362 left_layout->update();
2363}
2364
2365/************************************************************************/
2369{
2370 zoom = zoom / 1.2;
2371 if (dlgcity) {
2372 view->set_pixmap(dlgcity, zoom);
2373 }
2374 updateGeometry();
2375 left_layout->update();
2376}
2377
2378/************************************************************************/
2382{
2383 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
2384
2385 ask->set_text_title_definput(_("What should we name the preset?"),
2386 _("Name new preset"),
2387 _("new preset"));
2388 ask->setAttribute(Qt::WA_DeleteOnClose);
2389 connect(ask, &hud_message_box::accepted, this,
2391 struct cm_parameter param;
2392 QByteArray ask_bytes = ask->input_edit.text().toUtf8();
2393 QString text = ask_bytes.data();
2394 if (!text.isEmpty()) {
2395 param.allow_disorder = false;
2396 param.allow_specialists = true;
2397 param.require_happy = cma_celeb_checkbox->isChecked();
2398 param.max_growth = cma_max_growth->isChecked();
2399 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2400
2401 for (int i = O_FOOD; i < O_LAST; i++) {
2402 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2403 param.factor[i] = slider_tab[2 * i + 1]->value();
2404 }
2405
2406 ask_bytes = text.toUtf8();
2407 cmafec_preset_add(ask_bytes.data(), &param);
2409 }
2410 });
2411 ask->show();
2412}
2413
2414/************************************************************************/
2418{
2419 if (cma_is_city_under_agent(dlgcity, NULL)) {
2421
2422 return;
2423 }
2424
2425 cma_changed();
2427}
2428
2429/************************************************************************/
2433{
2434 struct cm_parameter param;
2435
2436 param.allow_disorder = false;
2437 param.allow_specialists = true;
2438 param.require_happy = cma_celeb_checkbox->isChecked();
2439 param.max_growth = cma_max_growth->isChecked();
2440 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2441
2442 for (int i = O_FOOD; i < O_LAST; i++) {
2443 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2444 param.factor[i] = slider_tab[2 * i + 1]->value();
2445 }
2446
2448}
2449
2450/************************************************************************/
2453void city_dialog::cma_double_clicked(int row, int column)
2454{
2455 const struct cm_parameter *param;
2456
2457 if (!can_client_issue_orders()) {
2458 return;
2459 }
2460 param = cmafec_preset_get_parameter(row);
2461 if (cma_is_city_under_agent(dlgcity, NULL)) {
2463 }
2464
2467}
2468
2469/************************************************************************/
2472void city_dialog::cma_selected(const QItemSelection &sl,
2473 const QItemSelection &ds)
2474{
2475 const struct cm_parameter *param;
2476 QModelIndex index;
2477 QModelIndexList indexes = sl.indexes();
2478
2479 if (indexes.isEmpty() || cma_table->signalsBlocked()) {
2480 return;
2481 }
2482
2483 index = indexes.at(0);
2484 int ind = index.row();
2485
2486 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2487 return;
2488 }
2489
2490 param = cmafec_preset_get_parameter(ind);
2492
2493 if (cma_is_city_under_agent(dlgcity, NULL)) {
2496 }
2497}
2498
2499/************************************************************************/
2503{
2504 struct cm_parameter param;
2505 const struct cm_parameter *cparam;
2506 int output;
2507 QVariant qvar;
2508 QLabel *label;
2509
2510 if (!cma_is_city_under_agent(dlgcity, &param)) {
2511 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2512 return;
2513 }
2514 cparam = cmafec_preset_get_parameter(cma_table->currentRow());
2515 cm_copy_parameter(&param, cparam);
2516 }
2517
2518 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2519 slider_tab[output]->blockSignals(true);
2520 }
2521
2522 for (output = O_FOOD; output < O_LAST; output++) {
2523 qvar = slider_tab[2 * output + 1]->property("FC");
2524 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2525 label->setText(QString::number(param.factor[output]));
2526 slider_tab[2 * output + 1]->setValue(param.factor[output]);
2527 qvar = slider_tab[2 * output]->property("FC");
2528 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2529 label->setText(QString::number(param.minimal_surplus[output]));
2530 slider_tab[2 * output]->setValue(param.minimal_surplus[output]);
2531 }
2532
2533 slider_tab[2 * O_LAST + 1]->blockSignals(true);
2534 qvar = slider_tab[2 * O_LAST + 1]->property("FC");
2535 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2536 label->setText(QString::number(param.happy_factor));
2537 slider_tab[2 * O_LAST + 1]->setValue(param.happy_factor);
2538 slider_tab[2 * O_LAST + 1]->blockSignals(false);
2539 cma_celeb_checkbox->blockSignals(true);
2540 cma_celeb_checkbox->setChecked(param.require_happy);
2541 cma_celeb_checkbox->blockSignals(false);
2542 cma_max_growth->blockSignals(true);
2543 cma_max_growth->setChecked(param.max_growth);
2544 cma_max_growth->blockSignals(false);
2545
2546 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2547 slider_tab[output]->blockSignals(false);
2548 }
2549}
2550
2551/************************************************************************/
2555{
2556 QString s;
2557 QTableWidgetItem *item;
2558 struct cm_parameter param;
2559 QPixmap pix;
2560 int i;
2561
2562 cma_table->clear();
2563 cma_table->setRowCount(0);
2564
2565 for (i = 0; i < cmafec_preset_num(); i++) {
2566 item = new QTableWidgetItem;
2567 item->setText(cmafec_preset_get_descr(i));
2568 cma_table->insertRow(i);
2569 cma_table->setItem(i, 0, item);
2570 }
2571
2572 if (cmafec_preset_num() == 0) {
2573 cma_table->insertRow(0);
2574 item = new QTableWidgetItem;
2575 item->setText(_("No governor defined"));
2576 cma_table->setItem(0, 0, item);
2577 }
2578
2579 if (cma_is_city_under_agent(dlgcity, NULL)) {
2580 view->update();
2582 pix = style()->standardPixmap(QStyle::SP_DialogApplyButton);
2583 pix = pix.scaled(2 * pix.width(), 2 * pix.height(),
2584 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2585 cma_result_pix->setPixmap(pix);
2586 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2587 /* TRANS: %1 is custom string chosen by player */
2588 cma_result->setText(QString(_("<h3>Governor Enabled<br>(%1)</h3>"))
2589 .arg(s.toHtmlEscaped()));
2590 cma_result->setAlignment(Qt::AlignCenter);
2591 } else {
2592 pix = style()->standardPixmap(QStyle::SP_DialogCancelButton);
2593 pix = pix.scaled(1.6 * pix.width(), 1.6 * pix.height(),
2594 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2595 cma_result_pix->setPixmap(pix);
2596 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2597 cma_result->setText(QString(_("<h3>Governor Disabled</h3>")));
2598 cma_result->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
2599 }
2600
2601 if (cma_is_city_under_agent(dlgcity, NULL)) {
2603 i = cmafec_preset_get_index_of_parameter(const_cast <struct
2604 cm_parameter *const >(&param));
2605 if (i >= 0 && i < cma_table->rowCount()) {
2606 cma_table->blockSignals(true);
2607 cma_table->setCurrentCell(i, 0);
2608 cma_table->blockSignals(false);
2609 }
2610
2611 cma_enable_but->setText(_("Disable"));
2612 } else {
2613 cma_enable_but->setText(_("Enable"));
2614 }
2616}
2617
2618/************************************************************************/
2622{
2623 int i;
2624 hud_message_box *ask;
2625
2626 i = cma_table->currentRow();
2627
2628 if (i == -1 || cmafec_preset_num() == 0) {
2629 return;
2630 }
2631
2632 ask = new hud_message_box(city_dlg);
2633 ask->set_text_title(_("Remove this preset?"), cmafec_preset_get_descr(i));
2634 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
2635 ask->setDefaultButton(QMessageBox::Cancel);
2636 ask->setAttribute(Qt::WA_DeleteOnClose);
2637 connect(ask, &hud_message_box::accepted, this,
2641 });
2642 ask->show();
2643}
2644
2645/************************************************************************/
2649{
2650 if (cma_is_city_under_agent(dlgcity, NULL)) {
2651 cma_changed();
2653 }
2654}
2655
2656/************************************************************************/
2660{
2661 QVariant qvar;
2662 QSlider *slider;
2663 QLabel *label;
2664
2665 slider = qobject_cast<QSlider *>(sender());
2666 qvar = slider->property("FC");
2667
2668 if (qvar.isNull() || !qvar.isValid()) {
2669 return;
2670 }
2671
2672 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2673 label->setText(QString::number(value));
2674
2675 if (cma_is_city_under_agent(dlgcity, NULL)) {
2676 cma_changed();
2678 }
2679}
2680
2681/************************************************************************/
2685{
2686 bv_city_options new_options;
2687
2688 BV_CLR_ALL(new_options);
2689
2690 if (allow_disband) {
2691 BV_SET(new_options, CITYO_DISBAND);
2692 } else {
2693 BV_CLR(new_options, CITYO_DISBAND);
2694 }
2695
2696 if (!client_is_observer()) {
2698 new_options);
2699 }
2700}
2701
2702/************************************************************************/
2706{
2707 QMenu *cma_menu = new QMenu(this);
2708 QAction *cma_del_item;
2709
2710 cma_menu->setAttribute(Qt::WA_DeleteOnClose);
2711 cma_del_item = cma_menu->addAction(_("Remove Governor"));
2712 connect(cma_menu, &QMenu::triggered, this,
2713 CAPTURE_DEFAULT_THIS (QAction *act) {
2714 if (act == cma_del_item) {
2715 cma_remove();
2716 }
2717 });
2718
2719 cma_menu->popup(QCursor::pos());
2720}
2721
2722/************************************************************************/
2726{
2727 QAction *action;
2728 QAction *disband;
2729 QAction *wl_save;
2730 QAction *wl_clear;
2731 QAction *wl_empty;
2732 QMap<QString, cid> list;
2733 QMap<QString, cid>::const_iterator map_iter;
2734 QMenu *change_menu;
2735 QMenu *insert_menu;
2736 QMenu *list_menu;
2737 QMenu *options_menu;
2738 int city_id = dlgcity->id;
2739
2740 if (!can_client_issue_orders()) {
2741 return;
2742 }
2743 list_menu = new QMenu(this);
2744 change_menu = list_menu->addMenu(_("Change worklist"));
2745 insert_menu = list_menu->addMenu(_("Insert worklist"));
2746 wl_clear = list_menu->addAction(_("Clear"));
2747 connect(wl_clear, &QAction::triggered, this, &city_dialog::clear_worklist);
2748 list.clear();
2749
2751 list.insert(global_worklist_name(pgwl), global_worklist_id(pgwl));
2753
2754 if (list.count() == 0) {
2755 wl_empty = change_menu->addAction(_("(no worklists defined)"));
2756 insert_menu->addAction(wl_empty);
2757 }
2758
2759 map_iter = list.constBegin();
2760
2761 while (map_iter != list.constEnd()) {
2762 action = change_menu->addAction(map_iter.key());
2763 action->setData(map_iter.value());
2764
2765 action = insert_menu->addAction(map_iter.key());
2766 action->setData(map_iter.value());
2767
2768 map_iter++;
2769 }
2770
2771 wl_save = list_menu->addAction(_("Save worklist"));
2772 connect(wl_save, &QAction::triggered, this, &city_dialog::save_worklist);
2773 options_menu = list_menu->addMenu(_("Options"));
2774 disband = options_menu->addAction(_("Allow disbanding city"));
2775 disband->setCheckable(true);
2776 disband->setChecked(is_city_option_set(dlgcity, CITYO_DISBAND));
2777 connect(disband, &QAction::triggered, this,
2779
2780 connect(change_menu, &QMenu::triggered, this, [=](QAction *act) {
2781 QVariant id = act->data();
2782 struct city *pcity = game_city_by_number(city_id);
2783 const struct worklist *worklist;
2784
2785 if (!pcity) {
2786 return;
2787 }
2788
2789#ifndef FC_QT5_MODE
2790 fc_assert_ret(id.typeId() == QMetaType::Int);
2791#else // FC_QT5_MODE
2792 fc_assert_ret(id.type() == QVariant::Int);
2793#endif // FC_QT5_MODE
2794
2797 });
2798
2799 connect(insert_menu, &QMenu::triggered, this,
2800 CAPTURE_DEFAULT_THIS (QAction *act) {
2801 QVariant id = act->data();
2802 struct city *pcity = game_city_by_number(city_id);
2803 const struct worklist *worklist;
2804
2805 if (!pcity) {
2806 return;
2807 }
2808
2809#ifndef FC_QT5_MODE
2810 fc_assert_ret(id.typeId() == QMetaType::Int);
2811#else // FC_QT5_MODE
2812 fc_assert_ret(id.type() == QVariant::Int);
2813#endif // FC_QT5_MODE
2814
2817 });
2818
2819 list_menu->popup(QCursor::pos());
2820}
2821
2822/************************************************************************/
2826{
2827 QString str;
2828 int value;
2829
2830 buy_button->setDisabled(true);
2831
2832 if (!client_is_observer() && client.conn.playing != NULL) {
2833 value = dlgcity->client.buy_cost;
2834 str = QString(PL_("Buy (%1 gold)", "Buy (%1 gold)",
2835 value)).arg(QString::number(value));
2836
2837 if (client.conn.playing->economic.gold >= value && value != 0) {
2838 buy_button->setEnabled(true);
2839 }
2840 } else {
2841 str = QString(_("Buy"));
2842 }
2843
2844 buy_button->setText(str);
2845}
2846
2847/************************************************************************/
2851{
2852 enum citizen_category categories[MAX_CITY_SIZE];
2853 int i, j, width, height;
2854 QPainter p;
2855 QPixmap *pix;
2856 int num_citizens = get_city_citizen_types(dlgcity, FEELING_FINAL, categories);
2857 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
2858 int h = tileset_small_sprite_height(tileset) / gui()->map_scale;
2859
2860 i = 1 + (num_citizens * 5 / 200);
2861 w = w / i;
2862 QRect source_rect(0, 0, w, h);
2863 QRect dest_rect(0, 0, w, h);
2864 width = w * num_citizens;
2865 height = h;
2866
2867 if (citizen_pixmap) {
2868 citizen_pixmap->detach();
2869 delete citizen_pixmap;
2870 }
2871
2872 citizen_pixmap = new QPixmap(width, height);
2873
2874 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2875 dest_rect.moveTo(i * w, 0);
2876 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2877 p.begin(citizen_pixmap);
2878 p.drawPixmap(dest_rect, *pix, source_rect);
2879 p.end();
2880 }
2881
2883 citizens_label->setPixmap(*citizen_pixmap);
2884
2887
2888 for (int k = 0; k < FEELING_LAST - 1; k++) {
2890 num_citizens = get_city_citizen_types(dlgcity,
2891 static_cast<citizen_feeling>(k),
2892 categories);
2893
2894 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2895 dest_rect.moveTo(i * w, 0);
2896 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2897 p.begin(citizen_pixmap);
2898 p.drawPixmap(dest_rect, *pix, source_rect);
2899 p.end();
2900 }
2901
2902 lab_table[k]->setPixmap(*citizen_pixmap);
2903
2904 switch (k) {
2905 case FEELING_BASE:
2906 lab_table[k]->setToolTip(text_happiness_cities(dlgcity));
2907 break;
2908
2909 case FEELING_LUXURY:
2910 lab_table[k]->setToolTip(text_happiness_luxuries(dlgcity));
2911 break;
2912
2913 case FEELING_EFFECT :
2915 break;
2916
2919 break;
2920
2921 case FEELING_MARTIAL:
2922 lab_table[k]->setToolTip(text_happiness_units(dlgcity));
2923 break;
2924
2925 default:
2926 break;
2927 }
2928 }
2929}
2930
2931/************************************************************************/
2935{
2936 setUpdatesEnabled(false);
2937 production_combo_p->blockSignals(true);
2938
2939 if (dlgcity) {
2940 view->set_pixmap(dlgcity, zoom);
2941 view->update();
2942 update_title();
2948 update_units();
2952 } else {
2954 }
2955
2956 production_combo_p->blockSignals(false);
2957 setUpdatesEnabled(true);
2958 updateGeometry();
2959 update();
2960}
2961
2962
2963/************************************************************************/
2967{
2968 QFont f = QApplication::font();
2969 QFontMetrics fm(f);
2970 QPixmap *pix = NULL;
2971 QPixmap pix_scaled;
2972 QString str;
2973 QStringList info_list;
2974 QTableWidgetItem *item;
2975 char buf[8];
2976 citizens nationality_i;
2977 int h;
2978 int i = 0;
2979 struct sprite *sprite;
2980
2981 h = fm.height() + 6;
2982 nationality_table->clear();
2983 nationality_table->setRowCount(0);
2984 info_list.clear();
2985 info_list << _("#") << _("Flag") << _("Nation");
2986 nationality_table->setHorizontalHeaderLabels(info_list);
2987
2988 citizens_iterate(dlgcity, pslot, nationality) {
2989 nationality_table->insertRow(i);
2990
2991 for (int j = 0; j < nationality_table->columnCount(); j++) {
2992 item = new QTableWidgetItem;
2993
2994 switch (j) {
2995 case 0:
2996 nationality_i = citizens_nation_get(dlgcity, pslot);
2997
2998 if (nationality_i == 0) {
2999 str = "-";
3000 } else {
3001 fc_snprintf(buf, sizeof(buf), "%d", nationality_i);
3002 str = QString(buf);
3003 }
3004
3005 item->setText(str);
3006 break;
3007
3008 case 1:
3011 (player_slot_get_player(pslot)));
3012
3013 if (sprite != NULL) {
3014 pix = sprite->pm;
3015 pix_scaled = pix->scaledToHeight(h);
3016 item->setData(Qt::DecorationRole, pix_scaled);
3017 } else {
3018 item->setText("FLAG MISSING");
3019 }
3020 break;
3021
3022 case 2:
3024 (player_slot_get_player(pslot)));
3025 break;
3026
3027 default:
3028 break;
3029 }
3030 nationality_table->setItem(i, j, item);
3031 }
3032 i++;
3034 nationality_table->horizontalHeader()->setStretchLastSection(false);
3035 nationality_table->resizeColumnsToContents();
3036 nationality_table->resizeRowsToContents();
3037 nationality_table->horizontalHeader()->setStretchLastSection(true);
3038}
3039
3040/************************************************************************/
3044{
3045 int illness = 0;
3046 char buffer[512];
3047 char buf_info[NUM_INFO_FIELDS][512];
3048 char buf_tooltip[NUM_INFO_FIELDS][512];
3049 int granaryturns;
3050 int spec;
3051
3052 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3053 buf_info[i][0] = '\0';
3054 buf_tooltip[i][0] = '\0';
3055 }
3056
3057 /* fill the buffers with the necessary info */
3058 spec = city_specialists(dlgcity);
3059 fc_snprintf(buf_info[INFO_CITIZEN], sizeof(buf_info[INFO_CITIZEN]),
3060 "%3d (%4d)", dlgcity->size, spec);
3061 fc_snprintf(buf_tooltip[INFO_CITIZEN], sizeof(buf_tooltip[INFO_CITIZEN]),
3062 _("Population: %d, Specialists: %d"),
3063 dlgcity->size, spec);
3064 fc_snprintf(buf_info[INFO_FOOD], sizeof(buf_info[INFO_FOOD]), "%3d (%+4d)",
3066 fc_snprintf(buf_info[INFO_SHIELD], sizeof(buf_info[INFO_SHIELD]),
3067 "%3d (%+4d)", dlgcity->prod[O_SHIELD] + dlgcity->waste[O_SHIELD],
3069 fc_snprintf(buf_info[INFO_TRADE], sizeof(buf_info[INFO_TRADE]), "%3d (%+4d)",
3072 fc_snprintf(buf_info[INFO_GOLD], sizeof(buf_info[INFO_GOLD]), "%3d (%+4d)",
3074 fc_snprintf(buf_info[INFO_LUXURY], sizeof(buf_info[INFO_LUXURY]), "%3d",
3076 fc_snprintf(buf_info[INFO_SCIENCE], sizeof(buf_info[INFO_SCIENCE]), "%3d",
3078 fc_snprintf(buf_info[INFO_GRANARY], sizeof(buf_info[INFO_GRANARY]),
3079 "%4d/%-4d", dlgcity->food_stock,
3081
3083 sizeof(buf_tooltip[INFO_FOOD]));
3085 sizeof(buf_tooltip[INFO_SHIELD]));
3087 sizeof(buf_tooltip[INFO_TRADE]));
3089 sizeof(buf_tooltip[INFO_GOLD]));
3091 sizeof(buf_tooltip[INFO_SCIENCE]));
3093 sizeof(buf_tooltip[INFO_LUXURY]));
3095 sizeof(buf_tooltip[INFO_CULTURE]));
3097 sizeof(buf_tooltip[INFO_POLLUTION]));
3099 sizeof(buf_tooltip[INFO_ILLNESS]));
3100
3101 granaryturns = city_turns_to_grow(dlgcity);
3102
3103 if (granaryturns == 0) {
3104 /* TRANS: city growth is blocked. Keep short. */
3105 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("blocked"));
3106 } else if (granaryturns == FC_INFINITY) {
3107 /* TRANS: city is not growing. Keep short. */
3108 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("never"));
3109 } else {
3110 /* A negative value means we'll have famine in that many turns.
3111 But that's handled down below. */
3112 /* TRANS: city growth turns. Keep short. */
3113 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]),
3114 PL_("%d turn", "%d turns", abs(granaryturns)),
3115 abs(granaryturns));
3116 }
3117
3118 fc_snprintf(buf_info[INFO_CORRUPTION], sizeof(buf_info[INFO_CORRUPTION]),
3119 "%4d", dlgcity->waste[O_TRADE]);
3120 fc_snprintf(buf_info[INFO_WASTE], sizeof(buf_info[INFO_WASTE]), "%4d",
3122 fc_snprintf(buf_info[INFO_CULTURE], sizeof(buf_info[INFO_CULTURE]), "%4d",
3124 fc_snprintf(buf_info[INFO_POLLUTION], sizeof(buf_info[INFO_POLLUTION]), "%4d",
3126
3127 if (!game.info.illness_on) {
3128 fc_snprintf(buf_info[INFO_ILLNESS], sizeof(buf_info[INFO_ILLNESS]),
3129 " -.-");
3130 } else {
3131 illness = city_illness_calc(dlgcity, NULL, NULL, NULL, NULL);
3132 /* illness is in tenth of percent */
3133 fc_snprintf(buf_info[INFO_ILLNESS], sizeof(buf_info[INFO_ILLNESS]),
3134 "%5.1f%%", (float) illness / 10.0);
3135 }
3136 if (dlgcity->steal) {
3137 fc_snprintf(buf_info[INFO_STEAL], sizeof(buf_info[INFO_STEAL]),
3138 PL_("%d time", "%d times", dlgcity->steal), dlgcity->steal);
3139 } else {
3140 fc_snprintf(buf_info[INFO_STEAL], sizeof(buf_info[INFO_STEAL]),
3141 _("Not stolen"));
3142 }
3143
3145 sizeof(buf_info[INFO_AIRLIFT]));
3147 sizeof(buf_tooltip[INFO_AIRLIFT]));
3148
3149 get_city_dialog_output_text(dlgcity, O_FOOD, buffer, sizeof(buffer));
3150
3151 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3152 qlt[i]->setText(QString(buf_info[i]));
3153
3154 if (buf_tooltip[i][0]) {
3155 qlt[i]->setToolTip("<pre>" + QString(buf_tooltip[i]).toHtmlEscaped()
3156 + "</pre>");
3157 }
3158 }
3159}
3160
3161/************************************************************************/
3164void city_dialog::setup_ui(struct city *qcity)
3165{
3166 QPixmap q_pix = *get_icon_sprite(tileset, ICON_CITYDLG)->pm;
3167 QIcon q_icon =::QIcon(q_pix);
3168
3169 setContentsMargins(0, 0 ,0 ,0);
3170 setWindowIcon(q_icon);
3171 dlgcity = qcity;
3172 production_combo_p->blockSignals(true);
3173 refresh();
3174 production_combo_p->blockSignals(false);
3175}
3176
3177/************************************************************************/
3180void city_dialog::dbl_click_p(QTableWidgetItem *item)
3181{
3182 struct worklist queue;
3183
3184 city_get_queue(dlgcity, &queue);
3185
3186 if (selected_row_p < 0 || selected_row_p > worklist_length(&queue)) {
3187 return;
3188 }
3189
3191 city_set_queue(dlgcity, &queue);
3192}
3193
3194/************************************************************************/
3198{
3199 unit_item *ui;
3200 struct unit_list *units;
3201 char buf[256];
3202 int n;
3203 int happy_cost;
3204 int free_unhappy = get_city_bonus(dlgcity, EFT_MAKE_CONTENT_MIL);
3205 const struct civ_map *nmap = &(wld.map);
3206
3207 supported_units->setUpdatesEnabled(false);
3208 supported_units->clear_layout();
3209
3210 if (NULL != client.conn.playing
3213 } else {
3214 units = dlgcity->units_supported;
3215 }
3216
3217 unit_list_iterate(units, punit) {
3218 happy_cost = city_unit_unhappiness(nmap, punit, &free_unhappy);
3219 ui = new unit_item(this, punit, true, happy_cost);
3220 ui->init_pix();
3221 supported_units->add_item(ui);
3223 n = unit_list_size(units);
3224 fc_snprintf(buf, sizeof(buf), _("Supported units %d"), n);
3225 supp_units->setText(QString(buf));
3226 supported_units->update_units();
3227 supported_units->setUpdatesEnabled(true);
3228 current_units->setUpdatesEnabled(true);
3230
3231 if (NULL != client.conn.playing
3234 } else {
3235 units = dlgcity->tile->units;
3236 }
3237
3238 unit_list_iterate(units, punit) {
3239 ui = new unit_item(this , punit, false);
3240 ui->init_pix();
3243
3244 n = unit_list_size(units);
3245 fc_snprintf(buf, sizeof(buf), _("Present units %d"), n);
3246 curr_units->setText(QString(buf));
3247
3249 current_units->setUpdatesEnabled(true);
3250}
3251
3252/************************************************************************/
3255void city_dialog::item_selected(const QItemSelection &sl,
3256 const QItemSelection &ds)
3257{
3258 QModelIndex index;
3259 QModelIndexList indexes = sl.indexes();
3260
3261 if (indexes.isEmpty()) {
3262 return;
3263 }
3264
3265 index = indexes.at(0);
3266 selected_row_p = index.row();
3268}
3269
3270/************************************************************************/
3274{
3275 int size, i;
3276 struct city *other_pcity = NULL;
3277
3278 if (NULL == client.conn.playing) {
3279 return;
3280 }
3281
3282 size = city_list_size(client.conn.playing->cities);
3283
3284 if (size <= 1) {
3285 return;
3286 }
3287
3288 for (i = 0; i < size; i++) {
3289 if (dlgcity == city_list_get(client.conn.playing->cities, i)) {
3290 break;
3291 }
3292 }
3293
3294 if (i >= size - 1) {
3295 // Current city last in the list (size - 1) or disappeared (size)
3296 other_pcity = city_list_get(client.conn.playing->cities, 0);
3297 } else {
3298 other_pcity = city_list_get(client.conn.playing->cities, i + 1);
3299 }
3300
3301 center_tile_mapcanvas(other_pcity->tile);
3302 qtg_real_city_dialog_popup(other_pcity);
3303}
3304
3305/************************************************************************/
3309{
3310 int size, i;
3311 struct city *other_pcity = NULL;
3312
3313 if (NULL == client.conn.playing) {
3314 return;
3315 }
3316
3317 size = city_list_size(client.conn.playing->cities);
3318
3319 if (size <= 1) {
3320 return;
3321 }
3322
3323 for (i = 0; i < size; i++) {
3324 if (dlgcity == city_list_get(client.conn.playing->cities, i)) {
3325 break;
3326 }
3327 }
3328
3329 if (i == 0 || i == size) {
3330 // Current city in the beginning of the list or disappeared
3331 other_pcity = city_list_get(client.conn.playing->cities, size - 1);
3332 } else {
3333 other_pcity = city_list_get(client.conn.playing->cities, i - 1);
3334 }
3335
3336 center_tile_mapcanvas(other_pcity->tile);
3337 qtg_real_city_dialog_popup(other_pcity);
3338}
3339
3340/************************************************************************/
3344{
3345 char buf[32];
3346 QString str;
3348
3349 get_city_dialog_production(dlgcity, buf, sizeof(buf));
3350 production_combo_p->setRange(0, cost);
3352 if (dlgcity->shield_stock >= cost) {
3353 production_combo_p->setValue(cost);
3354 } else {
3356 }
3357 production_combo_p->setAlignment(Qt::AlignCenter);
3358 str = QString(buf);
3359 str = str.simplified();
3360
3361 production_combo_p->setFormat(QString("(%p%) %2\n%1")
3363 str));
3364
3365 production_combo_p->updateGeometry();
3366
3367}
3368
3369/************************************************************************/
3373{
3374 char buf[1024], buf2[1024];
3376 int value = dlgcity->client.buy_cost;
3377 hud_message_box *ask;
3378 int city_id = dlgcity->id;
3379
3380 if (!can_client_issue_orders()) {
3381 return;
3382 }
3383
3384 ask = new hud_message_box(city_dlg);
3385 fc_snprintf(buf2, ARRAY_SIZE(buf2), PL_("Treasury contains %d gold.",
3386 "Treasury contains %d gold.",
3387 client_player()->economic.gold),
3388 client_player()->economic.gold);
3389 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Buy %s for %d gold?",
3390 "Buy %s for %d gold?", value),
3391 name, value);
3392 ask->set_text_title(buf, buf2);
3393 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
3394 ask->setDefaultButton(QMessageBox::Cancel);
3395 ask->setAttribute(Qt::WA_DeleteOnClose);
3396 connect(ask, &hud_message_box::accepted, this, [=]() {
3397 struct city *pcity = game_city_by_number(city_id);
3398
3399 if (!pcity) {
3400 return;
3401 }
3402
3404 });
3405 ask->show();
3406}
3407
3408/************************************************************************/
3412{
3413 QFont f = QApplication::font();
3414 QFontMetrics fm(f);
3415 QPixmap *pix = NULL;
3416 QPixmap pix_scaled;
3417 QString str, tooltip;
3418 QTableWidgetItem *qitem;
3419 struct sprite *sprite;
3420 int h, cost, item, targets_used, col, upkeep;
3421 struct item items[MAX_NUM_PRODUCTION_TARGETS];
3422 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
3423 struct worklist queue;
3424 impr_item *ui;
3425
3426 upkeep = 0;
3427 city_buildings->setUpdatesEnabled(false);
3429
3430 h = fm.height() + 6;
3431 targets_used = collect_already_built_targets(targets, dlgcity);
3432 name_and_sort_items(targets, targets_used, items, false, dlgcity);
3433
3434 for (item = 0; item < targets_used; item++) {
3435 struct universal target = items[item].item;
3436
3437 ui = new impr_item(this, target.value.building, dlgcity);
3438 ui->init_pix();
3440
3441 fc_assert_action(VUT_IMPROVEMENT == target.kind, continue);
3443 upkeep = upkeep + city_improvement_upkeep(dlgcity, target.value.building);
3444 if (sprite != nullptr) {
3445 pix = sprite->pm;
3446 pix_scaled = pix->scaledToHeight(h);
3447 }
3448 }
3449
3450 city_get_queue(dlgcity, &queue);
3451 p_table_p->setRowCount(worklist_length(&queue));
3452
3453 for (int i = 0; i < worklist_length(&queue); i++) {
3454 struct universal target = queue.entries[i];
3455
3456 tooltip = "";
3457
3458 if (VUT_UTYPE == target.kind) {
3461 tooltip = get_tooltip_unit(target.value.utype, true).trimmed();
3463 direction8_invalid());
3464 } else {
3468 dlgcity, true).trimmed();
3469
3470 if (improvement_has_flag(target.value.building, IF_GOLD)) {
3471 cost = -1;
3472 } else {
3474 }
3475 }
3476
3477 for (col = 0; col < 3; col++) {
3478 qitem = new QTableWidgetItem();
3479 qitem->setToolTip(tooltip);
3480
3481 switch (col) {
3482 case 0:
3483 if (sprite) {
3484 pix = sprite->pm;
3485 pix_scaled = pix->scaledToHeight(h);
3486 qitem->setData(Qt::DecorationRole, pix_scaled);
3487 }
3488 break;
3489
3490 case 1:
3491 if (str.contains('[') && str.contains(']')) {
3492 int ii, ij;
3493
3494 ii = str.lastIndexOf('[');
3495 ij = str.lastIndexOf(']');
3496 if (ij > ii) {
3497 str = str.remove(ii, ij - ii + 1);
3498 }
3499 }
3500 qitem->setText(str);
3501 break;
3502
3503 case 2:
3504 qitem->setTextAlignment(Qt::AlignRight);
3505 qitem->setText(QString::number(cost));
3506 break;
3507 }
3508 p_table_p->setItem(i, col, qitem);
3509 }
3510 }
3511
3512 p_table_p->horizontalHeader()->setStretchLastSection(false);
3513 p_table_p->resizeColumnsToContents();
3514 p_table_p->resizeRowsToContents();
3515 p_table_p->horizontalHeader()->setStretchLastSection(true);
3516
3518 city_buildings->setUpdatesEnabled(true);
3519 city_buildings->setUpdatesEnabled(true);
3520
3521 curr_impr->setText(QString(_("Improvements - upkeep %1")).arg(upkeep));
3522}
3523
3524/************************************************************************/
3528{
3529 cid id;
3530 QVariant qvar;
3531
3533 struct universal univ;
3534
3535 id = qvar.toInt();
3536 univ = cid_production(id);
3538 }
3539}
3540
3541/************************************************************************/
3546{
3548 int when = 1;
3549
3550 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3551 when, selected_row_p, show_units->isChecked(),
3552 false, show_wonders->isChecked(),
3553 show_buildings->isChecked());
3554 pw->show();
3555}
3556
3557/************************************************************************/
3562{
3564 int when = 4;
3565
3566 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3567 when, selected_row_p, show_units->isChecked(),
3568 false, show_wonders->isChecked(),
3569 show_buildings->isChecked());
3570 pw->show();
3571}
3572
3573/************************************************************************/
3577{
3578 struct worklist empty;
3579
3580 if (!can_client_issue_orders()) {
3581 return;
3582 }
3583
3584 worklist_init(&empty);
3585 city_set_worklist(dlgcity, &empty);
3586}
3587
3588/************************************************************************/
3592{
3593 QModelIndex index;
3594 struct worklist queue;
3595 struct universal *target;
3596
3597 if (selected_row_p < 1 || selected_row_p >= p_table_p->rowCount()) {
3598 return;
3599 }
3600
3601 target = new universal;
3602 city_get_queue(dlgcity, &queue);
3603 worklist_peek_ith(&queue, target, selected_row_p);
3605 worklist_insert(&queue, target, selected_row_p - 1);
3606 city_set_queue(dlgcity, &queue);
3607 index = p_table_p->model()->index(selected_row_p - 1, 0);
3608 p_table_p->setCurrentIndex(index);
3609 delete target;
3610
3611}
3612
3613/************************************************************************/
3617{
3618 QTableWidgetItem *item;
3619
3620 if (selected_row_p < 0
3621 || selected_row_p >= p_table_p->rowCount()) {
3622 return;
3623 }
3624
3628}
3629
3630/************************************************************************/
3634{
3635 QModelIndex index;
3636 struct worklist queue;
3637 struct universal *target;
3638
3639 if (selected_row_p < 0 || selected_row_p >= p_table_p->rowCount() - 1) {
3640 return;
3641 }
3642
3643 target = new universal;
3644 city_get_queue(dlgcity, &queue);
3645 worklist_peek_ith(&queue, target, selected_row_p);
3647 worklist_insert(&queue, target, selected_row_p + 1);
3648 city_set_queue(dlgcity, &queue);
3649 index = p_table_p->model()->index(selected_row_p + 1, 0);
3650 p_table_p->setCurrentIndex(index);
3651 delete target;
3652}
3653
3654/************************************************************************/
3658{
3659 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
3660 int city_id = dlgcity->id;
3661
3662 ask->set_text_title_definput(_("What should we name new worklist?"),
3663 _("Save current worklist"),
3664 _("New worklist"));
3665 ask->setAttribute(Qt::WA_DeleteOnClose);
3666 connect(ask, &hud_message_box::accepted, [=]() {
3667 struct global_worklist *gw;
3668 struct worklist queue;
3669 QByteArray ask_bytes;
3670 QString text;
3671 struct city *pcity = game_city_by_number(city_id);
3672
3673 ask_bytes = ask->input_edit.text().toUtf8();
3674 text = ask_bytes.data();
3675 if (!text.isEmpty()) {
3676 ask_bytes = text.toUtf8();
3677 gw = global_worklist_new(ask_bytes.data());
3678 city_get_queue(pcity, &queue);
3679 global_worklist_set(gw, &queue);
3680 }
3681 });
3682 ask->show();
3683}
3684
3685/************************************************************************/
3689{
3690 QString buf;
3691
3692 // Defeat keyboard shortcut mnemonics
3693 lcity_name->setText(QString(city_name_get(dlgcity))
3694 .replace("&", "&&"));
3695
3696 if (city_unhappy(dlgcity)) {
3697 /* TRANS: city dialog title */
3698 buf = QString(_("%1 - %2 citizens - DISORDER")).arg(city_name_get(dlgcity),
3700 } else if (city_celebrating(dlgcity)) {
3701 /* TRANS: city dialog title */
3702 buf = QString(_("%1 - %2 citizens - celebrating")).arg(city_name_get(dlgcity),
3704 } else if (city_happy(dlgcity)) {
3705 /* TRANS: city dialog title */
3706 buf = QString(_("%1 - %2 citizens - happy")).arg(city_name_get(dlgcity),
3708 } else {
3709 /* TRANS: city dialog title */
3710 buf = QString(_("%1 - %2 citizens")).arg(city_name_get(dlgcity),
3712 }
3713
3714 setWindowTitle(buf);
3715}
3716
3717/************************************************************************/
3722{
3723 if (!::city_dlg_created) {
3724 ::city_dlg = new city_dialog(gui()->mapview_wdg);
3725 }
3726
3727 city_dlg->setup_ui(pcity);
3728 city_dlg->show();
3729 city_dlg->activateWindow();
3730 city_dlg->raise();
3731}
3732
3733/************************************************************************/
3737{
3738 if (!::city_dlg_created) {
3739 return;
3740 }
3741
3742 city_dlg->close();
3743 ::city_dlg_created = false;
3744}
3745
3746/************************************************************************/
3750{
3751 if (!::city_dlg_created) {
3752 return;
3753 }
3754
3756}
3757
3758/************************************************************************/
3765
3766/************************************************************************/
3770{
3771 if (!::city_dlg_created) {
3772 return;
3773 }
3774
3775 if (qtg_city_dialog_is_open(pcity)) {
3776 city_dlg->refresh();
3777 }
3778}
3779
3780/************************************************************************/
3784{
3785 QList<QLabel *> l;
3786 QFont *f;
3787
3788 if (!::city_dlg_created) {
3789 return;
3790 }
3791
3792 l = city_dlg->findChildren<QLabel *>();
3793
3795
3796 for (int i = 0; i < l.size(); ++i) {
3797 if (l.at(i)->property(fonts::notify_label).isValid()) {
3798 l.at(i)->setFont(*f);
3799 }
3800 }
3801}
3802
3803/************************************************************************/
3809{
3810
3811 struct city *pcity_sup, *pcity_pre;
3812
3813 pcity_sup = game_city_by_number(punit->homecity);
3814 pcity_pre = tile_city(punit->tile);
3815
3818
3819}
3820
3821/************************************************************************/
3825{
3826 if (!::city_dlg_created) {
3827 return false;
3828 }
3829
3830 if (city_dlg->dlgcity == pcity && city_dlg->isVisible()) {
3831 return true;
3832 }
3833
3834 return false;
3835}
3836
3837/************************************************************************/
3840bool fc_tooltip::eventFilter(QObject *obj, QEvent *ev)
3841{
3842 QHelpEvent *help_event;
3843 QString item_tooltip;
3844 QRect rect;
3845
3846 if (ev->type() == QEvent::ToolTip) {
3847 QAbstractItemView *view = qobject_cast<QAbstractItemView *>(obj->parent());
3848
3849 if (!view) {
3850 return false;
3851 }
3852
3853 help_event = static_cast<QHelpEvent *>(ev);
3854 QPoint pos = help_event->pos();
3855 QModelIndex index = view->indexAt(pos);
3856 QPoint hpos;
3857
3858 if (!index.isValid()) {
3859 return false;
3860 }
3861
3862 item_tooltip = view->model()->data(index, Qt::ToolTipRole).toString();
3863 rect = view->visualRect(index);
3864
3865 hpos = help_event->globalPos();
3866
3867 rect.setX(rect.x() + hpos.x());
3868 rect.setY(rect.y() + hpos.y());
3869
3870 if (!item_tooltip.isEmpty()) {
3871 QToolTip::showText(help_event->globalPos(), item_tooltip, view, rect);
3872 } else {
3873 QToolTip::hideText();
3874 }
3875
3876 return true;
3877 }
3878
3879 return false;
3880}
3881
3882/************************************************************************/
3885static QString bold(QString text)
3886{
3887 return QString("<b>" + text + "</b>");
3888}
3889
3890/************************************************************************/
3894QString get_tooltip_improvement(const impr_type *building, struct city *pcity,
3895 bool ext)
3896{
3897 QString def_str;
3898 QString upkeep;
3899 QString s1, s2, str;
3900 const char *req = skip_intl_qualifier_prefix(_("?tech:None"));
3901
3902 if (pcity != nullptr) {
3903 upkeep = QString::number(city_improvement_upkeep(pcity, building));
3904 } else {
3905 upkeep = QString::number(building->upkeep);
3906 }
3907 requirement_vector_iterate(&building->obsolete_by, pobs) {
3908 if (pobs->source.kind == VUT_ADVANCE) {
3909 req = advance_name_translation(pobs->source.value.advance);
3910 break;
3911 }
3913 s2 = QString(req);
3914 str = _("Obsolete by:");
3915 str = str + " " + s2;
3916 def_str = "<p style='white-space:pre'><b>"
3917 + QString(improvement_name_translation(building)).toHtmlEscaped()
3918 + "</b>\n";
3919 if (pcity != nullptr) {
3920 def_str += QString(_("Cost: %1, Upkeep: %2\n"))
3921 .arg(impr_build_shield_cost(pcity, building))
3922 .arg(upkeep).toHtmlEscaped();
3923 } else {
3924 int cost_est = impr_estimate_build_shield_cost(client.conn.playing, NULL, building);
3925
3926 def_str += QString(_("Cost Estimate: %1, Upkeep: %2\n"))
3927 .arg(cost_est)
3928 .arg(upkeep).toHtmlEscaped();
3929 }
3930 if (s1.compare(s2) != 0) {
3931 def_str = def_str + str.toHtmlEscaped() + "\n";
3932 }
3933 def_str = def_str + "\n";
3934 if (ext) {
3935 char buffer[8192];
3936
3937 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
3938 NULL, building);
3939 str = cut_helptext(str);
3940 str = split_text(str, true);
3941 str = str.trimmed();
3942 def_str = def_str + str.toHtmlEscaped();
3943 }
3944 return def_str;
3945}
3946
3947/************************************************************************/
3951QString get_tooltip_unit(const struct unit_type *utype, bool ext)
3952{
3953 QString def_str;
3954 QString obsolete_str;
3955 QString str;
3956 const struct unit_type *obsolete;
3957 struct advance *tech;
3958
3959 def_str = "<b>"
3960 + QString(utype_name_translation(utype)).toHtmlEscaped()
3961 + "</b>\n";
3962 obsolete = utype->obsoleted_by;
3963 if (obsolete) {
3964 tech = obsolete->require_advance;
3965 obsolete_str = QString("</td></tr><tr><td colspan=\"3\">");
3966 if (tech && tech != advance_by_number(A_NONE)) {
3967 /* TRANS: this and nearby literal strings are interpreted
3968 * as (Qt) HTML */
3969 obsolete_str = obsolete_str + QString(_("Obsoleted by %1 (%2)."))
3970 .arg(utype_name_translation(obsolete))
3971 .arg(advance_name_translation(tech)).toHtmlEscaped();
3972 } else {
3973 obsolete_str = obsolete_str + QString(_("Obsoleted by %1."))
3974 .arg(utype_name_translation(obsolete)).toHtmlEscaped();
3975 }
3976 }
3977 def_str += "<table width=\"100\%\"><tr><td>"
3978 + bold(QString(_("Attack:"))) + " "
3979 + QString::number(utype->attack_strength).toHtmlEscaped()
3980 + QString("</td><td>") + bold(QString(_("Defense:"))) + " "
3981 + QString::number(utype->defense_strength).toHtmlEscaped()
3982 + QString("</td><td>") + bold(QString(_("Move:"))) + " "
3983 + QString(move_points_text(utype->move_rate, TRUE)).toHtmlEscaped()
3984 + QString("</td></tr><tr><td>")
3985 + bold(QString(_("Cost:"))) + " "
3986 + QString::number(utype_build_shield_cost_base(utype))
3987 .toHtmlEscaped()
3988 + QString("</td><td colspan=\"2\">")
3989 + bold(QString(_("Basic Upkeep:")))
3990 + " " + QString(helptext_unit_upkeep_str(utype)).toHtmlEscaped()
3991 + QString("</td></tr><tr><td>")
3992 + bold(QString(_("Hitpoints:"))) + " "
3993 + QString::number(utype->hp).toHtmlEscaped()
3994 + QString("</td><td>") + bold(QString(_("Firepower:"))) + " "
3995 + QString::number(utype->firepower).toHtmlEscaped()
3996 + QString("</td><td>") + bold(QString(_("Vision:"))) + " "
3997 + QString::number((int) sqrt((double) utype->vision_radius_sq))
3998 .toHtmlEscaped()
3999 + obsolete_str
4000 + QString("</td></tr></table><p style='white-space:pre'>");
4001 if (ext) {
4002 char buffer[8192];
4003 char buf2[1];
4004
4005 buf2[0] = '\0';
4006 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
4007 buf2, utype);
4008 str = cut_helptext(str);
4009 str = split_text(str, true);
4010 str = str.trimmed().toHtmlEscaped();
4011 def_str = def_str + str;
4012 }
4013
4014 return def_str;
4015};
4016
4017/************************************************************************/
4020QString get_tooltip(QVariant qvar)
4021{
4022 QString str, def_str, ret_str;
4023 QStringList sl;
4024 char buffer[8192];
4025 char buf2[1];
4026 struct universal *target;
4027
4028 buf2[0] = '\0';
4029 target = reinterpret_cast<universal *>(qvar.value<void *>());
4030
4031 if (target == NULL) {
4032 } else if (VUT_UTYPE == target->kind) {
4033 def_str = get_tooltip_unit(target->value.utype);
4034 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
4035 buf2, target->value.utype);
4036 } else {
4037 if (!improvement_has_flag(target->value.building, IF_GOLD)) {
4038 def_str = get_tooltip_improvement(target->value.building);
4039 }
4040
4041 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
4042 NULL, target->value.building);
4043 }
4044
4045 /* Remove all lines from help which has '*' in first 3 chars */
4046 ret_str = cut_helptext(str);
4047 ret_str = split_text(ret_str, true);
4048 ret_str = ret_str.trimmed();
4049 ret_str = def_str + ret_str.toHtmlEscaped();
4050
4051 return ret_str;
4052}
4053
4054/************************************************************************/
4058 QObject *parent,
4059 struct city *city)
4060 : QItemDelegate(parent)
4061{
4062 pd = sh;
4063 item_height = sh.y();
4064 pcity = city;
4065}
4066
4067/************************************************************************/
4070void city_production_delegate::paint(QPainter *painter,
4071 const QStyleOptionViewItem &option,
4072 const QModelIndex &index) const
4073{
4074 struct universal *target;
4075 QString name;
4076 QVariant qvar;
4077 QPixmap *pix;
4078 QPixmap pix_scaled;
4079 QRect rect1;
4080 QRect rect2;
4081 struct sprite *sprite;
4082 bool useless = false;
4083 bool is_coinage = false;
4084 bool is_neutral = false;
4085 bool is_sea = false;
4086 bool is_flying = false;
4087 bool is_unit = true;
4088 QPixmap pix_dec(option.rect.width(), option.rect.height());
4089 QStyleOptionViewItem opt;
4090 color col;
4091 QIcon icon = current_app()->style()->standardIcon(QStyle::SP_DialogCancelButton);
4092 bool free_sprite = false;
4093 struct unit_class *pclass;
4094
4095 if (!option.rect.isValid()) {
4096 return;
4097 }
4098
4099 qvar = index.data();
4100
4101 if (!qvar.isValid()) {
4102 return;
4103 }
4104
4105 target = reinterpret_cast<universal *>(qvar.value<void *>());
4106
4107 if (target == NULL) {
4108 col.qcolor = Qt::white;
4109 sprite = qtg_create_sprite(100, 100, &col);
4110 free_sprite = true;
4111 *sprite->pm = icon.pixmap(100, 100);
4112 name = _("Cancel");
4113 is_unit = false;
4114 } else if (VUT_UTYPE == target->kind) {
4116 is_neutral = utype_has_flag(target->value.utype, UTYF_CIVILIAN);
4117 pclass = utype_class(target->value.utype);
4118 if (!uclass_has_flag(pclass, UCF_TERRAIN_DEFENSE)
4119 && !utype_can_do_action_result(target->value.utype, ACTRES_FORTIFY)
4120 && !uclass_has_flag(pclass, UCF_ZOC)) {
4121 is_sea = true;
4122 }
4123
4124 if ((utype_fuel(target->value.utype)
4125 && !uclass_has_flag(pclass, UCF_TERRAIN_DEFENSE)
4126 && !utype_can_do_action_result(target->value.utype, ACTRES_PILLAGE)
4127 && !utype_can_do_action_result(target->value.utype, ACTRES_FORTIFY)
4128 && !uclass_has_flag(pclass, UCF_ZOC))
4129 /* FIXME: Assumed to be flying since only missiles can do suicide
4130 * attacks in classic-like rulesets. This isn't true for all
4131 * rulesets. Not a high priority to fix since all is_flying and
4132 * is_sea is used for is to set a color. */
4133 || utype_is_consumed_by_action_result(ACTRES_ATTACK,
4134 target->value.utype)) {
4135 if (is_sea) {
4136 is_sea = false;
4137 }
4138 is_flying = true;
4139 }
4140
4142 direction8_invalid());
4143 } else {
4144 is_unit = false;
4147 useless = is_improvement_redundant(pcity, target->value.building);
4148 is_coinage = improvement_has_flag(target->value.building, IF_GOLD);
4149 }
4150
4151 if (sprite != NULL) {
4152 pix = sprite->pm;
4153 pix_scaled = pix->scaledToHeight(item_height - 2, Qt::SmoothTransformation);
4154
4155 if (useless) {
4156 pixmap_put_x(&pix_scaled);
4157 }
4158 }
4159
4160 opt = QItemDelegate::setOptions(index, option);
4161 painter->save();
4162 opt.displayAlignment = Qt::AlignLeft;
4163 opt.textElideMode = Qt::ElideMiddle;
4164 QItemDelegate::drawBackground(painter, opt, index);
4165 rect1 = option.rect;
4166 rect1.setWidth(pix_scaled.width() + 4);
4167 rect2 = option.rect;
4168 rect2.setLeft(option.rect.left() + rect1.width());
4169 rect2.setTop(rect2.top() + (rect2.height()
4170 - painter->fontMetrics().height()) / 2);
4171 QItemDelegate::drawDisplay(painter, opt, rect2, name);
4172
4173 if (is_unit) {
4174 if (is_sea) {
4175 pix_dec.fill(QColor(0, 0, 255, 80));
4176 } else if (is_flying) {
4177 pix_dec.fill(QColor(220, 0, 0, 80));
4178 } else if (is_neutral) {
4179 pix_dec.fill(QColor(0, 120, 0, 40));
4180 } else {
4181 pix_dec.fill(QColor(0, 0, 150, 40));
4182 }
4183
4184 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4185 }
4186
4187 if (is_coinage) {
4188 pix_dec.fill(QColor(255, 255, 0, 70));
4189 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4190 }
4191
4192 if (!pix_scaled.isNull()) {
4193 QItemDelegate::drawDecoration(painter, opt, rect1, pix_scaled);
4194 }
4195
4196 drawFocus(painter, opt, option.rect);
4197
4198 painter->restore();
4199
4200 if (free_sprite) {
4202 }
4203}
4204
4205/************************************************************************/
4209 const QStyleOptionViewItem &option,
4210 const QRect &rect) const
4211{
4212 QPixmap pix(option.rect.width(), option.rect.height());
4213
4214 if ((option.state & QStyle::State_MouseOver) == 0 || !rect.isValid()) {
4215 return;
4216 }
4217
4218 pix.fill(QColor(50, 50, 50, 50));
4219 QItemDelegate::drawDecoration(painter, option, option.rect, pix);
4220}
4221
4222/************************************************************************/
4225QSize city_production_delegate::sizeHint(const QStyleOptionViewItem &option,
4226 const QModelIndex &index) const
4227{
4228 QSize s;
4229
4230 s.setWidth(pd.x());
4231 s.setHeight(pd.y());
4232 return s;
4233}
4234
4235/************************************************************************/
4239 QObject *parent): QObject()
4240{
4241 setParent(parent);
4242 target = ptarget;
4243}
4244
4245/************************************************************************/
4249{
4250 /* allocated as renegade in model */
4251 if (target != NULL) {
4252 delete target;
4253 }
4254}
4255
4256/************************************************************************/
4260{
4261 return QVariant::fromValue((void *)target);
4262}
4263
4264/************************************************************************/
4268{
4269 return false;
4270}
4271
4272/************************************************************************/
4276 bool su, bool sw, bool sb,
4277 QObject *parent)
4278 : QAbstractListModel(parent)
4279{
4280 show_units = su;
4281 show_wonders = sw;
4282 show_buildings = sb;
4283 mcity = pcity;
4284 future_t = f;
4285 populate();
4286}
4287
4288/************************************************************************/
4296
4297/************************************************************************/
4300QVariant city_production_model::data(const QModelIndex &index, int role) const
4301{
4302 if (!index.isValid()) {
4303 return QVariant();
4304 }
4305
4306 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4307 && index.column() < columnCount()
4308 && (index.column() + index.row() * 3 < city_target_list.count())) {
4309 int r, c, t ,new_index;
4310 r = index.row();
4311 c = index.column();
4312 t = r * 3 + c;
4313 new_index = t / 3 + rowCount() * c;
4314 /* Exception, shift whole column */
4315 if ((c == 2) && city_target_list.count() % 3 == 1) {
4316 new_index = t / 3 + rowCount() * c - 1;
4317 }
4318 if (role == Qt::ToolTipRole) {
4319 return get_tooltip(city_target_list[new_index]->data());
4320 }
4321
4322 return city_target_list[new_index]->data();
4323 }
4324
4325 return QVariant();
4326}
4327
4328/************************************************************************/
4332{
4333 production_item *pi;
4334 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
4335 struct item items[MAX_NUM_PRODUCTION_TARGETS];
4336 struct universal *renegade;
4337 int item, targets_used;
4338 QString str;
4340 QFontMetrics fm(f);
4341
4342 sh.setY(fm.height() * 2);
4343 sh.setX(0);
4344
4345 qDeleteAll(city_target_list);
4346 city_target_list.clear();
4347
4348 targets_used = collect_eventually_buildable_targets(targets, mcity,
4349 future_t);
4350 name_and_sort_items(targets, targets_used, items, false, mcity);
4351
4352 for (item = 0; item < targets_used; item++) {
4353 if (future_t || can_city_build_now(&(wld.map), mcity, &items[item].item)) {
4354 renegade = new universal(items[item].item);
4355
4356 // Renegade deleted in production_item destructor
4357 if (VUT_UTYPE == renegade->kind) {
4359 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4360
4361 if (show_units) {
4362 pi = new production_item(renegade, this);
4363 city_target_list << pi;
4364 } else {
4365 delete renegade;
4366 }
4367 } else {
4369 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4370
4371 if ((is_wonder(renegade->value.building) && show_wonders)
4372 || (is_improvement(renegade->value.building) && show_buildings)
4373 || (improvement_has_flag(renegade->value.building, IF_GOLD))
4375 && show_buildings)) {
4376 pi = new production_item(renegade, this);
4377 city_target_list << pi;
4378 } else {
4379 delete renegade;
4380 }
4381 }
4382 }
4383 }
4384
4385 pi = new production_item(nullptr, this);
4386 city_target_list << pi;
4387 sh.setX(2 * sh.y() + sh.x());
4388 sh.setX(qMin(sh.x(), 250));
4389}
4390
4391/************************************************************************/
4394bool city_production_model::setData(const QModelIndex &index,
4395 const QVariant &value, int role)
4396{
4397 if (!index.isValid() || role != Qt::DisplayRole || role != Qt::ToolTipRole)
4398 return false;
4399
4400 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4401 && index.column() < columnCount()) {
4402 bool change = city_target_list[index.row()]->setData();
4403 return change;
4404 }
4405
4406 return false;
4407}
4408
4409/************************************************************************/
4417production_widget::production_widget(QWidget *parent, struct city *pcity,
4418 bool future, int when, int curr,
4419 bool show_units, bool buy,
4420 bool show_wonders,
4421 bool show_buildings): QTableView()
4422{
4423 QPoint pos, sh;
4424 QRect rect = QApplication::primaryScreen()->availableGeometry();
4425 int desk_width = rect.width();
4426 int desk_height = rect.height();
4427 fc_tt = new fc_tooltip(this);
4428 setAttribute(Qt::WA_DeleteOnClose);
4429 setWindowFlags(Qt::Popup);
4430 verticalHeader()->setVisible(false);
4431 horizontalHeader()->setVisible(false);
4432 setProperty("showGrid", false);
4433 curr_selection = curr;
4434 sh_units = show_units;
4435 pw_city = pcity;
4436 buy_it = buy;
4437 when_change = when;
4438 list_model = new city_production_model(pw_city, future, show_units,
4439 show_wonders, show_buildings, this);
4440 sh = list_model->sh;
4441 c_p_d = new city_production_delegate(sh, this, pw_city);
4442 setItemDelegate(c_p_d);
4443 setModel(list_model);
4444 viewport()->installEventFilter(fc_tt);
4445 installEventFilter(this);
4446 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection &,
4447 const QItemSelection &)),
4448 SLOT(prod_selected(const QItemSelection &,
4449 const QItemSelection &)));
4450 resizeRowsToContents();
4451 resizeColumnsToContents();
4452 setFixedWidth(3 * sh.x() + 6);
4453 setFixedHeight(list_model->rowCount()*sh.y() + 6);
4454
4455 if (width() > desk_width) {
4456 setFixedWidth(desk_width);
4457 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4458 } else {
4459 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4460 }
4461
4462 if (height() > desk_height) {
4463 setFixedHeight(desk_height);
4464 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4465 } else {
4466 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4467 }
4468
4469 pos = QCursor::pos();
4470
4471 if (pos.x() + width() > desk_width) {
4472 pos.setX(desk_width - width());
4473 } else if (pos.x() - width() < 0) {
4474 pos.setX(0);
4475 }
4476
4477 if (pos.y() + height() > desk_height) {
4478 pos.setY(desk_height - height());
4479 } else if (pos.y() - height() < 0) {
4480 pos.setY(0);
4481 }
4482
4483 move(pos);
4484 setMouseTracking(true);
4485 setFocus();
4486}
4487
4488/************************************************************************/
4492{
4493 if (event->button() == Qt::RightButton) {
4494 close();
4495 return;
4496 }
4497
4498 QAbstractItemView::mousePressEvent(event);
4499}
4500
4501/************************************************************************/
4504bool production_widget::eventFilter(QObject *obj, QEvent *ev)
4505{
4506 QRect pw_rect;
4507 QPoint br;
4508
4509 if (obj != this)
4510 return false;
4511
4512 if (ev->type() == QEvent::MouseButtonPress) {
4513 pw_rect.setTopLeft(pos());
4514 br.setX(pos().x() + width());
4515 br.setY(pos().y() + height());
4516 pw_rect.setBottomRight(br);
4517
4518 if (!pw_rect.contains(QCursor::pos())) {
4519 close();
4520 }
4521 }
4522
4523 return false;
4524}
4525
4526/************************************************************************/
4529void production_widget::prod_selected(const QItemSelection &sl,
4530 const QItemSelection &ds)
4531{
4532 QModelIndexList indexes = selectionModel()->selectedIndexes();
4533 QModelIndex index;
4534 QVariant qvar;
4535 struct worklist queue;
4536 struct universal *target;
4537
4538 if (indexes.isEmpty() || client_is_observer()) {
4539 return;
4540 }
4541 index = indexes.at(0);
4542 qvar = index.data(Qt::UserRole);
4543 if (!qvar.isValid()) {
4544 return;
4545 }
4546 target = reinterpret_cast<universal *>(qvar.value<void *>());
4547 if (target != NULL) {
4548 city_get_queue(pw_city, &queue);
4549 switch (when_change) {
4550 case 0: /* Change current target */
4552 if (city_can_buy(pw_city) && buy_it) {
4554 }
4555 break;
4556
4557 case 1: /* Change current (selected on list)*/
4558 if (curr_selection < 0 || curr_selection > worklist_length(&queue)) {
4560 } else {
4562 worklist_insert(&queue, target, curr_selection);
4563 city_set_queue(pw_city, &queue);
4564 }
4565 break;
4566
4567 case 2: /* Insert before */
4568 if (curr_selection < 0 || curr_selection > worklist_length(&queue)) {
4569 curr_selection = 0;
4570 }
4572 curr_selection = qMax(0, curr_selection);
4573 worklist_insert(&queue, target, curr_selection);
4574 city_set_queue(pw_city, &queue);
4575 break;
4576
4577 case 3: /* Insert after */
4578 if (curr_selection < 0 || curr_selection > worklist_length(&queue)) {
4579 city_queue_insert(pw_city, -1, target);
4580 break;
4581 }
4583 worklist_insert(&queue, target, curr_selection);
4584 city_set_queue(pw_city, &queue);
4585 break;
4586
4587 case 4: /* Add last */
4588 city_queue_insert(pw_city, -1, target);
4589 break;
4590
4591 default:
4592 break;
4593 }
4594 }
4595 close();
4596 destroy();
4597}
4598
4599/************************************************************************/
4603{
4604 delete c_p_d;
4605 delete list_model;
4606 viewport()->removeEventFilter(fc_tt);
4607 removeEventFilter(this);
4608}
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1910
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:962
#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:399
void qtg_canvas_free(struct canvas *store)
Definition canvas.cpp:47
struct canvas * qtg_canvas_create(int width, int height)
Definition canvas.cpp:35
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:78
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:100
static QFont * get_font(enum client_font font)
Definition canvas.cpp:359
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:658
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:722
int city_granary_size(int city_size)
Definition city.c:2104
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:300
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Definition city.c:1231
bool is_city_option_set(const struct city *pcity, enum city_options option)
Definition city.c:3301
int city_population(const struct city *pcity)
Definition city.c:1169
int city_unit_unhappiness(const struct civ_map *nmap, struct unit *punit, int *free_unhappy)
Definition city.c:2943
bool city_unhappy(const struct city *pcity)
Definition city.c:1599
bool city_celebrating(const struct city *pcity)
Definition city.c:1618
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2772
bool city_happy(const struct city *pcity)
Definition city.c:1587
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:132
int rs_max_city_radius_sq(void)
Definition city.c:154
citizens city_specialists(const struct city *pcity)
Definition city.c:3230
bool can_city_build_now(const struct civ_map *nmap, const struct city *pcity, const struct universal *target)
Definition city.c:991
int city_turns_to_grow(const struct city *pcity)
Definition city.c:1969
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:695
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
citizen_category
Definition city.h:259
#define city_owner(_pcity_)
Definition city.h:543
#define MAX_CITY_SIZE
Definition city.h:98
citizen_feeling
Definition city.h:270
@ FEELING_EFFECT
Definition city.h:273
@ FEELING_LUXURY
Definition city.h:272
@ FEELING_FINAL
Definition city.h:276
@ FEELING_LAST
Definition city.h:277
@ FEELING_BASE
Definition city.h:271
@ FEELING_NATIONALITY
Definition city.h:274
@ FEELING_MARTIAL
Definition city.h:275
void qtg_popdown_city_dialog(struct city *pcity)
Definition citydlg.cpp:3749
void qtg_real_city_dialog_refresh(struct city *pcity)
Definition citydlg.cpp:3769
QString split_text(QString text, bool cut)
Definition optiondlg.cpp:62
void city_font_update()
Definition citydlg.cpp:3783
bool qtg_city_dialog_is_open(struct city *pcity)
Definition citydlg.cpp:3824
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4020
void qtg_popdown_all_city_dialogs()
Definition citydlg.cpp:3761
static city_dialog * city_dlg
Definition citydlg.cpp:74
void qtg_refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.cpp:3808
static QString bold(QString text)
Definition citydlg.cpp:3885
void qtg_real_city_dialog_popup(struct city *pcity)
Definition citydlg.cpp:3721
QString get_tooltip_improvement(const impr_type *building, struct city *pcity, bool ext)
Definition citydlg.cpp:3894
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:3951
void destroy_city_dialog()
Definition citydlg.cpp:3736
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
int height
Definition citydlg.h:288
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
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:4057
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4070
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4225
struct city * pcity
Definition citydlg.h:318
void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
Definition citydlg.cpp:4208
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:4275
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:4394
int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition citydlg.h:360
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition citydlg.cpp:4300
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:3840
void set_text_title_definput(QString s1, QString s2, QString def_input)
QLineEdit input_edit
Definition hudwidget.h:119
int set_text_title(QString s1, QString s2, bool return_exec=false)
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:4259
production_item(struct universal *ptarget, QObject *parent)
Definition citydlg.cpp:4238
bool eventFilter(QObject *obj, QEvent *ev)
Definition citydlg.cpp:4504
void prod_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:4529
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:4491
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:4417
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:812
void name_and_sort_items(struct universal *targets, int num_targets, struct item *items, bool show_cost, struct city *pcity)
Definition climisc.c:643
cid cid_encode(struct universal target)
Definition climisc.c:476
int collect_already_built_targets(struct universal *targets, struct city *pcity)
Definition climisc.c:906
struct universal cid_decode(cid id)
Definition climisc.c:519
#define MAX_NUM_PRODUCTION_TARGETS
Definition climisc.h:89
#define cid_production
Definition climisc.h:71
int cid
Definition climisc.h:31
static struct fc_sockaddr_list * list
Definition clinet.c:102
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Definition cm.c:2172
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
void request_unit_fortify(struct unit *punit)
Definition control.c:2240
struct unit * request_unit_unload_all(struct unit *punit)
Definition control.c:1506
void unit_focus_set(struct unit *punit)
Definition control.c:507
void request_unit_change_homecity(struct unit *punit)
Definition control.c:2021
void request_unit_unload(struct unit *pcargo)
Definition control.c:2119
void request_unit_sentry(struct unit *punit)
Definition control.c:2229
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:40
bool qtg_request_transport(struct unit *pcargo, struct tile *ptile)
Definition dialogs.cpp:4759
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:73
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:73
int int id
Definition editgui_g.h:28
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:789
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:740
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:765
enum extra_cause activity_to_extra_cause(enum unit_activity act)
Definition extras.c:1028
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act)
Definition extras.c:1049
#define extra_index(_e_)
Definition extras.h:177
unsigned char citizens
Definition fc_types.h:358
#define EC_NONE
Definition fc_types.h:967
@ TR_SUCCESS
Definition fc_types.h:1098
#define ERM_NONE
Definition fc_types.h:992
@ O_SHIELD
Definition fc_types.h:91
@ O_FOOD
Definition fc_types.h:91
@ O_TRADE
Definition fc_types.h:91
@ O_SCIENCE
Definition fc_types.h:91
@ O_LUXURY
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
@ O_LAST
Definition fc_types.h:91
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:714
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct city * game_city_by_number(int id)
Definition game.c:102
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:1444
void popup_disband_dialog(struct unit_list *punits)
Definition dialogs.c:1482
static struct tile * pos
Definition finddlg.c:53
const char * tooltip
Definition repodlgs.c:1314
GType type
Definition repodlgs.c:1312
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:3894
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4020
#define CAPTURE_DEFAULT_THIS
Definition gui_main.h:23
QApplication * current_app()
Definition gui_main.cpp:220
char * helptext_unit_upkeep_str(const struct unit_type *utype)
Definition helpdata.c:4834
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1316
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype)
Definition helpdata.c:1763
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)
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:973
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:168
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
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_id16, int city_id32, bv_city_options options)
const char * text_happiness_cities(const struct city *pcity)
Definition text.c:1931
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
struct player * player_slot_get_player(const struct player_slot *pslot)
Definition player.c:430
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
QPixmap map_pixmap
Definition canvas.h:25
void setup_ui(struct city *qcity)
Definition citydlg.cpp:3164
int current_building
Definition citydlg.h:506
void worklist_up()
Definition citydlg.cpp:3591
city_label * citizens_label
Definition citydlg.h:451
QPushButton * lcity_name
Definition citydlg.h:492
void show_happiness()
Definition citydlg.cpp:2129
void closeEvent(QCloseEvent *event)
Definition citydlg.cpp:2277
void update_nation_table()
Definition citydlg.cpp:2966
void hideEvent(QHideEvent *event)
Definition citydlg.cpp:2249
QPushButton * work_next_but
Definition citydlg.h:481
void next_city()
Definition citydlg.cpp:3273
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:2260
QPushButton * happiness_button
Definition citydlg.h:485
void cma_double_clicked(int row, int column)
Definition citydlg.cpp:2453
void display_worklist_menu(const QPoint &p)
Definition citydlg.cpp:2725
void update_disabled()
Definition citydlg.cpp:2158
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:2825
int selected_row_p
Definition citydlg.h:493
QHBoxLayout * leftbot_layout
Definition citydlg.h:446
void update_building()
Definition citydlg.cpp:3343
QPushButton * zoom_in_button
Definition citydlg.h:486
void save_worklist()
Definition citydlg.cpp:3657
void worklist_del()
Definition citydlg.cpp:3616
QGridLayout * info_grid_layout
Definition citydlg.h:453
void clear_worklist()
Definition citydlg.cpp:3576
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:2368
void zoom_in()
Definition citydlg.cpp:2355
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:3043
QPushButton * work_add_but
Definition citydlg.h:483
city_dialog(QWidget *parent=0)
Definition citydlg.cpp:1515
QSplitter * central_left_splitter
Definition citydlg.h:444
void disband_state_changed(bool allow_disband)
Definition citydlg.cpp:2684
void update_citizens()
Definition citydlg.cpp:2850
QRadioButton * r1
Definition citydlg.h:475
void cma_slider(int val)
Definition citydlg.cpp:2659
QCheckBox * cma_celeb_checkbox
Definition citydlg.h:469
QCheckBox * show_units
Definition citydlg.h:472
void worklist_down()
Definition citydlg.cpp:3633
void update_title()
Definition citydlg.cpp:3688
QLabel * cma_info_text
Definition citydlg.h:459
void dbl_click_p(QTableWidgetItem *item)
Definition citydlg.cpp:3180
QPushButton * cma_enable_but
Definition citydlg.h:478
QLabel * cma_result
Definition citydlg.h:460
void cma_remove()
Definition citydlg.cpp:2621
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:2288
QSplitter * prod_unit_splitter
Definition citydlg.h:443
QVBoxLayout * left_layout
Definition citydlg.h:449
void prev_city()
Definition citydlg.cpp:3308
void city_rename()
Definition citydlg.cpp:2325
void refresh()
Definition citydlg.cpp:2934
void update_cma_tab()
Definition citydlg.cpp:2554
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:2648
void show_targets()
Definition citydlg.cpp:3545
QPushButton * buy_button
Definition citydlg.h:477
QWidget * top_widget
Definition citydlg.h:448
void update_happiness_button()
Definition citydlg.cpp:2117
QPushButton * prev_city_but
Definition citydlg.h:480
void cma_enable()
Definition citydlg.cpp:2417
QLabel * cma_result_pix
Definition citydlg.h:461
struct city * dlgcity
Definition citydlg.h:501
void update_sliders()
Definition citydlg.cpp:2502
void update_improvements()
Definition citydlg.cpp:3411
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:2072
void cma_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:2472
QCheckBox * cma_max_growth
Definition citydlg.h:470
void item_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:3255
void show_targets_worklist()
Definition citydlg.cpp:3561
QCheckBox * show_wonders
Definition citydlg.h:474
void cma_context_menu(const QPoint &p)
Definition citydlg.cpp:2705
void cma_changed()
Definition citydlg.cpp:2432
QRadioButton * r4
Definition citydlg.h:475
void update_units()
Definition citydlg.cpp:3197
QRadioButton * r2
Definition citydlg.h:475
QTableWidget * p_table_p
Definition citydlg.h:466
void save_cma()
Definition citydlg.cpp:2381
QPixmap * citizen_pixmap
Definition citydlg.h:488
void production_changed(int index)
Definition citydlg.cpp:3527
void update_prod_buttons()
Definition citydlg.cpp:2196
QWidget * happiness_widget
Definition citydlg.h:456
QGroupBox * happiness_group
Definition citydlg.h:455
QCheckBox * show_buildings
Definition citydlg.h:473
Definition city.h:309
struct worker_task_list * task_reqs
Definition city.h:395
int surplus[O_LAST]
Definition city.h:343
int food_stock
Definition city.h:354
int pollution
Definition city.h:356
int id
Definition city.h:315
int waste[O_LAST]
Definition city.h:344
struct unit_list * info_units_present
Definition city.h:457
struct unit_list * info_units_supported
Definition city.h:456
struct universal production
Definition city.h:382
int steal
Definition city.h:397
citizens size
Definition city.h:320
int culture
Definition city.h:448
int buy_cost
Definition city.h:449
struct tile * tile
Definition city.h:311
int shield_stock
Definition city.h:355
int prod[O_LAST]
Definition city.h:346
struct unit_list * units_supported
Definition city.h:391
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:20
QColor qcolor
Definition colors.h:25
struct player * playing
Definition connection.h:156
Definition mapimg.c:367
struct requirement_vector obsolete_by
Definition improvement.h:76
Definition climisc.h:82
struct universal item
Definition climisc.h:83
enum unit_activity activity
struct city_list * cities
Definition player.h:281
struct player_economic economic
Definition player.h:284
QPixmap * pm
Definition sprite.h:25
struct terrain * cultivate_result
Definition terrain.h:203
struct terrain * plant_result
Definition terrain.h:206
struct terrain * transform_result
Definition terrain.h:217
Definition tile.h:49
int index
Definition tile.h:50
struct unit_list * units
Definition tile.h:57
int defense_strength
Definition unittype.h:496
int firepower
Definition unittype.h:506
const struct unit_type * obsoleted_by
Definition unittype.h:510
int vision_radius_sq
Definition unittype.h:503
int move_rate
Definition unittype.h:497
struct advance * require_advance
Definition unittype.h:500
int attack_strength
Definition unittype.h:495
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:758
universals_u value
Definition fc_types.h:757
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:969
#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:1859
const char * text_happiness_wonders(const struct city *pcity)
Definition text.c:1901
const char * text_happiness_units(const struct city *pcity)
Definition text.c:2065
const char * text_happiness_luxuries(const struct city *pcity)
Definition text.c:2103
const char * text_happiness_buildings(const struct city *pcity)
Definition text.c:1831
const char * unit_description(struct unit *punit)
Definition text.c:508
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_terrain(_tile)
Definition tile.h:109
int tileset_hex_width(const struct tileset *t)
Definition tilespec.c:684
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:6494
int tileset_unit_width(const struct tileset *t)
Definition tilespec.c:760
int tileset_unit_height(const struct tileset *t)
Definition tilespec.c:768
int tileset_small_sprite_width(const struct tileset *t)
Definition tilespec.c:864
struct tileset * get_tileset(void)
Definition tilespec.c:655
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum direction8 facing)
Definition tilespec.c:6516
struct tileset * unscaled_tileset
Definition tilespec.c:545
int tileset_unit_layout_offset_y(const struct tileset *t)
Definition tilespec.c:845
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:675
int tileset_small_sprite_height(const struct tileset *t)
Definition tilespec.c:900
struct sprite * get_icon_sprite(const struct tileset *t, enum icon_type icon)
Definition tilespec.c:6674
int tileset_unit_with_upkeep_height(const struct tileset *t)
Definition tilespec.c:822
int tileset_hex_height(const struct tileset *t)
Definition tilespec.c:693
struct sprite * get_citizen_sprite(const struct tileset *t, enum citizen_category type, int citizen_index, const struct city *pcity)
Definition tilespec.c:6437
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6467
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6485
@ ICON_CITYDLG
Definition tilespec.h:311
const struct unit_type * utype
Definition fc_types.h:604
const struct impr_type * building
Definition fc_types.h:598
struct terrain * terrain
Definition fc_types.h:602
bool can_unit_change_homecity(const struct civ_map *nmap, const struct unit *punit)
Definition unit.c:460
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:328
#define unit_tile(_pu)
Definition unit.h:395
#define unit_owner(_pu)
Definition unit.h:394
bool units_are_occupied(const struct unit_list *punits)
Definition unitlist.c:277
bool units_can_upgrade(const struct civ_map *nmap, const struct unit_list *punits)
Definition unitlist.c:338
bool units_can_unload(const struct unit_list *punits)
Definition unitlist.c:305
bool units_can_load(const struct unit_list *punits)
Definition unitlist.c:291
#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:1520
bool utype_is_consumed_by_action_result(enum action_result result, const struct unit_type *utype)
Definition unittype.c:1281
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:459
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
const char * utype_values_translation(const struct unit_type *punittype)
Definition unittype.c:1669
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:753
#define utype_class(_t_)
Definition unittype.h:736
#define utype_fuel(ptype)
Definition unittype.h:825
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
#define show(id)
Definition widget.h:235
#define hide(id)
Definition widget.h:238
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