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
2069}
2070
2071/************************************************************************/
2075{
2076
2077 cid cprod;
2078 int i, pos;
2079 int item, targets_used;
2080 QList<cid> prod_list;
2081 QString str;
2082 struct item items[MAX_NUM_PRODUCTION_TARGETS];
2083 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
2084 struct universal univ;
2085
2086 pos = 0;
2087 cprod = cid_encode(dlgcity->production);
2088 targets_used = collect_eventually_buildable_targets(targets, dlgcity, false);
2089 name_and_sort_items(targets, targets_used, items, false, dlgcity);
2090
2091 for (item = 0; item < targets_used; item++) {
2092 if (can_city_build_now(&(wld.map), dlgcity, &items[item].item)) {
2093 prod_list << cid_encode(items[item].item);
2094 }
2095 }
2096
2097 for (i = 0; i < prod_list.size(); i++) {
2098 if (prod_list.at(i) == cprod) {
2099 if (next) {
2100 pos = i + 1;
2101 } else {
2102 pos = i - 1;
2103 }
2104 }
2105 }
2106 if (pos == prod_list.size()) {
2107 pos = 0;
2108 }
2109 if (pos == - 1) {
2110 pos = prod_list.size() - 1;
2111 }
2112 univ = cid_decode(static_cast<cid>(prod_list.at(pos)));
2114}
2115
2116/************************************************************************/
2120{
2121 if (happiness_shown) {
2122 happiness_button->setToolTip(_("Show city production"));
2123 } else {
2124 happiness_button->setToolTip(_("Show happiness information"));
2125 }
2126}
2127
2128/************************************************************************/
2132{
2133 setUpdatesEnabled(false);
2134
2135 if (!happiness_shown) {
2136 leftbot_layout->replaceWidget(prod_unit_splitter,
2138 Qt::FindDirectChildrenOnly);
2139 prod_unit_splitter->hide();
2140 happiness_widget->show();
2141 happiness_widget->updateGeometry();
2142 } else {
2143 leftbot_layout->replaceWidget(happiness_widget,
2145 Qt::FindDirectChildrenOnly);
2146 prod_unit_splitter->show();
2147 prod_unit_splitter->updateGeometry();
2148 happiness_widget->hide();
2149 }
2150
2151 setUpdatesEnabled(true);
2152 update();
2155}
2156
2157/************************************************************************/
2161{
2162 if (NULL == client.conn.playing
2164 prev_city_but->setDisabled(true);
2165 next_city_but->setDisabled(true);
2166 buy_button->setDisabled(true);
2167 cma_enable_but->setDisabled(true);
2168 production_combo_p->setDisabled(true);
2169 current_units->setDisabled(true);
2170 supported_units->setDisabled(true);
2171 view->setDisabled(true);
2172
2173 if (!client_is_observer()) {
2174 }
2175 } else {
2176 prev_city_but->setEnabled(true);
2177 next_city_but->setEnabled(true);
2178 buy_button->setEnabled(true);
2179 cma_enable_but->setEnabled(true);
2180 production_combo_p->setEnabled(true);
2181 current_units->setEnabled(true);
2182 supported_units->setEnabled(true);
2183 view->setEnabled(true);
2184 }
2185
2187 cma_enable_but->setEnabled(true);
2188 } else {
2189 cma_enable_but->setDisabled(true);
2190 }
2191
2193}
2194
2195/************************************************************************/
2199{
2200 work_next_but->setDisabled(true);
2201 work_prev_but->setDisabled(true);
2202 work_add_but->setDisabled(true);
2203 work_rem_but->setDisabled(true);
2204
2206 work_add_but->setEnabled(true);
2207
2208 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount()) {
2209 work_rem_but->setEnabled(true);
2210 }
2211
2212 if (selected_row_p >= 0 && selected_row_p < p_table_p->rowCount() - 1) {
2213 work_next_but->setEnabled(true);
2214 }
2215
2216 if (selected_row_p > 0 && selected_row_p < p_table_p->rowCount()) {
2217 work_prev_but->setEnabled(true);
2218 }
2219 }
2220}
2221
2222/************************************************************************/
2226{
2227 if (citizen_pixmap) {
2228 citizen_pixmap->detach();
2229 delete citizen_pixmap;
2230 }
2231
2232 cma_table->clear();
2233 p_table_p->clear();
2234 nationality_table->clear();
2236 supported_units->clear_layout();
2237 removeEventFilter(this);
2238 ::city_dlg_created = false;
2239
2240 // Delete the one widget that currently does NOT have a parent
2241 if (happiness_shown) {
2242 delete prod_unit_splitter;
2243 } else {
2244 delete happiness_widget;
2245 }
2246}
2247
2248/************************************************************************/
2252{
2253 gui()->qt_settings.city_geometry = saveGeometry();
2254 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2255 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2256 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2257}
2258
2259/************************************************************************/
2263{
2264 if (!gui()->qt_settings.city_geometry.isNull()) {
2265 restoreGeometry(gui()->qt_settings.city_geometry);
2266 prod_unit_splitter->restoreState(gui()->qt_settings.city_splitter1);
2267 central_left_splitter->restoreState(gui()->qt_settings.city_splitter2);
2268 central_splitter->restoreState(gui()->qt_settings.city_splitter3);
2269 } else {
2270 QRect rect = QApplication::primaryScreen()->availableGeometry();
2271
2272 resize((rect.width() * 4) / 5, (rect.height() * 5) / 6);
2273 }
2274}
2275
2276/************************************************************************/
2280{
2281 gui()->qt_settings.city_geometry = saveGeometry();
2282 gui()->qt_settings.city_splitter1 = prod_unit_splitter->saveState();
2283 gui()->qt_settings.city_splitter2 = central_left_splitter->saveState();
2284 gui()->qt_settings.city_splitter3 = central_splitter->saveState();
2285}
2286
2287/************************************************************************/
2290bool city_dialog::eventFilter(QObject *obj, QEvent *event)
2291{
2292
2293 if (obj == this) {
2294 if (event->type() == QEvent::KeyPress) {
2295 }
2296
2297 if (event->type() == QEvent::ShortcutOverride) {
2298 QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
2299 if (key_event->key() == Qt::Key_Right) {
2300 next_city();
2301 event->setAccepted(true);
2302 return true;
2303 }
2304 if (key_event->key() == Qt::Key_Left) {
2305 prev_city();
2306 event->setAccepted(true);
2307 return true;
2308 }
2309 if (key_event->key() == Qt::Key_Up) {
2310 change_production(true);
2311 event->setAccepted(true);
2312 return true;
2313 }
2314 if (key_event->key() == Qt::Key_Down) {
2315 change_production(false);
2316 event->setAccepted(true);
2317 return true;
2318 }
2319 }
2320 }
2321 return QObject::eventFilter(obj, event);
2322}
2323
2324/************************************************************************/
2328{
2329 hud_input_box *ask;
2330 const int city_id = dlgcity->id;
2331
2332 if (!can_client_issue_orders()) {
2333 return;
2334 }
2335
2336 ask = new hud_input_box(gui()->central_wdg);
2337 ask->set_text_title_definput(_("What should we rename the city to?"),
2338 _("Rename City"), city_name_get(dlgcity));
2339 ask->setAttribute(Qt::WA_DeleteOnClose);
2340 connect(ask, &hud_message_box::accepted, this, [=]() {
2341 struct city *pcity = game_city_by_number(city_id);
2342 QByteArray ask_bytes;
2343
2344 if (!pcity) {
2345 return;
2346 }
2347
2348 ask_bytes = ask->input_edit.text().toUtf8();
2349 ::city_rename(pcity, ask_bytes.data());
2350 });
2351 ask->show();
2352}
2353
2354/************************************************************************/
2358{
2359 zoom = zoom * 1.2;
2360 if (dlgcity) {
2361 view->set_pixmap(dlgcity, zoom);
2362 }
2363 updateGeometry();
2364 left_layout->update();
2365}
2366
2367/************************************************************************/
2371{
2372 zoom = zoom / 1.2;
2373 if (dlgcity) {
2374 view->set_pixmap(dlgcity, zoom);
2375 }
2376 updateGeometry();
2377 left_layout->update();
2378}
2379
2380/************************************************************************/
2384{
2385 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
2386
2387 ask->set_text_title_definput(_("What should we name the preset?"),
2388 _("Name new preset"),
2389 _("new preset"));
2390 ask->setAttribute(Qt::WA_DeleteOnClose);
2391 connect(ask, &hud_message_box::accepted, this,
2393 struct cm_parameter param;
2394 QByteArray ask_bytes = ask->input_edit.text().toUtf8();
2395 QString text = ask_bytes.data();
2396 if (!text.isEmpty()) {
2397 param.allow_disorder = false;
2398 param.allow_specialists = true;
2399 param.require_happy = cma_celeb_checkbox->isChecked();
2400 param.max_growth = cma_max_growth->isChecked();
2401 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2402
2403 for (int i = O_FOOD; i < O_LAST; i++) {
2404 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2405 param.factor[i] = slider_tab[2 * i + 1]->value();
2406 }
2407
2408 ask_bytes = text.toUtf8();
2409 cmafec_preset_add(ask_bytes.data(), &param);
2411 }
2412 });
2413 ask->show();
2414}
2415
2416/************************************************************************/
2420{
2421 if (cma_is_city_under_agent(dlgcity, NULL)) {
2423
2424 return;
2425 }
2426
2427 cma_changed();
2429}
2430
2431/************************************************************************/
2435{
2436 struct cm_parameter param;
2437
2438 param.allow_disorder = false;
2439 param.allow_specialists = true;
2440 param.require_happy = cma_celeb_checkbox->isChecked();
2441 param.max_growth = cma_max_growth->isChecked();
2442 param.happy_factor = slider_tab[2 * O_LAST + 1]->value();
2443
2444 for (int i = O_FOOD; i < O_LAST; i++) {
2445 param.minimal_surplus[i] = slider_tab[2 * i]->value();
2446 param.factor[i] = slider_tab[2 * i + 1]->value();
2447 }
2448
2450}
2451
2452/************************************************************************/
2455void city_dialog::cma_double_clicked(int row, int column)
2456{
2457 const struct cm_parameter *param;
2458
2459 if (!can_client_issue_orders()) {
2460 return;
2461 }
2462 param = cmafec_preset_get_parameter(row);
2463 if (cma_is_city_under_agent(dlgcity, NULL)) {
2465 }
2466
2469}
2470
2471/************************************************************************/
2474void city_dialog::cma_selected(const QItemSelection &sl,
2475 const QItemSelection &ds)
2476{
2477 const struct cm_parameter *param;
2478 QModelIndex index;
2479 QModelIndexList indexes = sl.indexes();
2480
2481 if (indexes.isEmpty() || cma_table->signalsBlocked()) {
2482 return;
2483 }
2484
2485 index = indexes.at(0);
2486 int ind = index.row();
2487
2488 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2489 return;
2490 }
2491
2492 param = cmafec_preset_get_parameter(ind);
2494
2495 if (cma_is_city_under_agent(dlgcity, NULL)) {
2498 }
2499}
2500
2501/************************************************************************/
2505{
2506 struct cm_parameter param;
2507 const struct cm_parameter *cparam;
2508 int output;
2509 QVariant qvar;
2510 QLabel *label;
2511
2512 if (!cma_is_city_under_agent(dlgcity, &param)) {
2513 if (cma_table->currentRow() == -1 || cmafec_preset_num() == 0) {
2514 return;
2515 }
2516 cparam = cmafec_preset_get_parameter(cma_table->currentRow());
2517 cm_copy_parameter(&param, cparam);
2518 }
2519
2520 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2521 slider_tab[output]->blockSignals(true);
2522 }
2523
2524 for (output = O_FOOD; output < O_LAST; output++) {
2525 qvar = slider_tab[2 * output + 1]->property("FC");
2526 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2527 label->setText(QString::number(param.factor[output]));
2528 slider_tab[2 * output + 1]->setValue(param.factor[output]);
2529 qvar = slider_tab[2 * output]->property("FC");
2530 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2531 label->setText(QString::number(param.minimal_surplus[output]));
2532 slider_tab[2 * output]->setValue(param.minimal_surplus[output]);
2533 }
2534
2535 slider_tab[2 * O_LAST + 1]->blockSignals(true);
2536 qvar = slider_tab[2 * O_LAST + 1]->property("FC");
2537 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2538 label->setText(QString::number(param.happy_factor));
2539 slider_tab[2 * O_LAST + 1]->setValue(param.happy_factor);
2540 slider_tab[2 * O_LAST + 1]->blockSignals(false);
2541 cma_celeb_checkbox->blockSignals(true);
2542 cma_celeb_checkbox->setChecked(param.require_happy);
2543 cma_celeb_checkbox->blockSignals(false);
2544 cma_max_growth->blockSignals(true);
2545 cma_max_growth->setChecked(param.max_growth);
2546 cma_max_growth->blockSignals(false);
2547
2548 for (output = O_FOOD; output < 2 * O_LAST; output++) {
2549 slider_tab[output]->blockSignals(false);
2550 }
2551}
2552
2553/************************************************************************/
2557{
2558 QString s;
2559 QTableWidgetItem *item;
2560 struct cm_parameter param;
2561 QPixmap pix;
2562 int i;
2563
2564 cma_table->clear();
2565 cma_table->setRowCount(0);
2566
2567 for (i = 0; i < cmafec_preset_num(); i++) {
2568 item = new QTableWidgetItem;
2569 item->setText(cmafec_preset_get_descr(i));
2570 cma_table->insertRow(i);
2571 cma_table->setItem(i, 0, item);
2572 }
2573
2574 if (cmafec_preset_num() == 0) {
2575 cma_table->insertRow(0);
2576 item = new QTableWidgetItem;
2577 item->setText(_("No governor defined"));
2578 cma_table->setItem(0, 0, item);
2579 }
2580
2581 if (cma_is_city_under_agent(dlgcity, NULL)) {
2582 view->update();
2584 pix = style()->standardPixmap(QStyle::SP_DialogApplyButton);
2585 pix = pix.scaled(2 * pix.width(), 2 * pix.height(),
2586 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2587 cma_result_pix->setPixmap(pix);
2588 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2589 /* TRANS: %1 is custom string chosen by player */
2590 cma_result->setText(QString(_("<h3>Governor Enabled<br>(%1)</h3>"))
2591 .arg(s.toHtmlEscaped()));
2592 cma_result->setAlignment(Qt::AlignCenter);
2593 } else {
2594 pix = style()->standardPixmap(QStyle::SP_DialogCancelButton);
2595 pix = pix.scaled(1.6 * pix.width(), 1.6 * pix.height(),
2596 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2597 cma_result_pix->setPixmap(pix);
2598 cma_result_pix->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2599 cma_result->setText(QString(_("<h3>Governor Disabled</h3>")));
2600 cma_result->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
2601 }
2602
2603 if (cma_is_city_under_agent(dlgcity, NULL)) {
2605 i = cmafec_preset_get_index_of_parameter(const_cast <struct
2606 cm_parameter *const >(&param));
2607 if (i >= 0 && i < cma_table->rowCount()) {
2608 cma_table->blockSignals(true);
2609 cma_table->setCurrentCell(i, 0);
2610 cma_table->blockSignals(false);
2611 }
2612
2613 cma_enable_but->setText(_("Disable"));
2614 } else {
2615 cma_enable_but->setText(_("Enable"));
2616 }
2618}
2619
2620/************************************************************************/
2624{
2625 int i;
2626 hud_message_box *ask;
2627
2628 i = cma_table->currentRow();
2629
2630 if (i == -1 || cmafec_preset_num() == 0) {
2631 return;
2632 }
2633
2634 ask = new hud_message_box(city_dlg);
2635 ask->set_text_title(_("Remove this preset?"), cmafec_preset_get_descr(i));
2636 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
2637 ask->setDefaultButton(QMessageBox::Cancel);
2638 ask->setAttribute(Qt::WA_DeleteOnClose);
2639 connect(ask, &hud_message_box::accepted, this,
2643 });
2644 ask->show();
2645}
2646
2647/************************************************************************/
2651{
2652 if (cma_is_city_under_agent(dlgcity, NULL)) {
2653 cma_changed();
2655 }
2656}
2657
2658/************************************************************************/
2662{
2663 QVariant qvar;
2664 QSlider *slider;
2665 QLabel *label;
2666
2667 slider = qobject_cast<QSlider *>(sender());
2668 qvar = slider->property("FC");
2669
2670 if (qvar.isNull() || !qvar.isValid()) {
2671 return;
2672 }
2673
2674 label = reinterpret_cast<QLabel *>(qvar.value<void *>());
2675 label->setText(QString::number(value));
2676
2677 if (cma_is_city_under_agent(dlgcity, NULL)) {
2678 cma_changed();
2680 }
2681}
2682
2683/************************************************************************/
2687{
2688 bv_city_options new_options;
2689
2690 BV_CLR_ALL(new_options);
2691
2692 if (allow_disband) {
2693 BV_SET(new_options, CITYO_DISBAND);
2694 } else {
2695 BV_CLR(new_options, CITYO_DISBAND);
2696 }
2697
2698 if (!client_is_observer()) {
2700 new_options);
2701 }
2702}
2703
2704/************************************************************************/
2708{
2709 QMenu *cma_menu = new QMenu(this);
2710 QAction *cma_del_item;
2711
2712 cma_menu->setAttribute(Qt::WA_DeleteOnClose);
2713 cma_del_item = cma_menu->addAction(_("Remove Governor"));
2714 connect(cma_menu, &QMenu::triggered, this,
2715 CAPTURE_DEFAULT_THIS (QAction *act) {
2716 if (act == cma_del_item) {
2717 cma_remove();
2718 }
2719 });
2720
2721 cma_menu->popup(QCursor::pos());
2722}
2723
2724/************************************************************************/
2728{
2729 QAction *action;
2730 QAction *disband;
2731 QAction *wl_save;
2732 QAction *wl_clear;
2733 QAction *wl_empty;
2734 QMap<QString, cid> list;
2735 QMap<QString, cid>::const_iterator map_iter;
2736 QMenu *change_menu;
2737 QMenu *insert_menu;
2738 QMenu *list_menu;
2739 QMenu *options_menu;
2740 int city_id = dlgcity->id;
2741
2742 if (!can_client_issue_orders()) {
2743 return;
2744 }
2745 list_menu = new QMenu(this);
2746 change_menu = list_menu->addMenu(_("Change worklist"));
2747 insert_menu = list_menu->addMenu(_("Insert worklist"));
2748 wl_clear = list_menu->addAction(_("Clear"));
2749 connect(wl_clear, &QAction::triggered, this, &city_dialog::clear_worklist);
2750 list.clear();
2751
2753 list.insert(global_worklist_name(pgwl), global_worklist_id(pgwl));
2755
2756 if (list.count() == 0) {
2757 wl_empty = change_menu->addAction(_("(no worklists defined)"));
2758 insert_menu->addAction(wl_empty);
2759 }
2760
2761 map_iter = list.constBegin();
2762
2763 while (map_iter != list.constEnd()) {
2764 action = change_menu->addAction(map_iter.key());
2765 action->setData(map_iter.value());
2766
2767 action = insert_menu->addAction(map_iter.key());
2768 action->setData(map_iter.value());
2769
2770 map_iter++;
2771 }
2772
2773 wl_save = list_menu->addAction(_("Save worklist"));
2774 connect(wl_save, &QAction::triggered, this, &city_dialog::save_worklist);
2775 options_menu = list_menu->addMenu(_("Options"));
2776 disband = options_menu->addAction(_("Allow disbanding city"));
2777 disband->setCheckable(true);
2778 disband->setChecked(is_city_option_set(dlgcity, CITYO_DISBAND));
2779 connect(disband, &QAction::triggered, this,
2781
2782 connect(change_menu, &QMenu::triggered, this, [=](QAction *act) {
2783 QVariant id = act->data();
2784 struct city *pcity = game_city_by_number(city_id);
2785 const struct worklist *worklist;
2786
2787 if (!pcity) {
2788 return;
2789 }
2790
2791#ifndef FC_QT5_MODE
2792 fc_assert_ret(id.typeId() == QMetaType::Int);
2793#else // FC_QT5_MODE
2794 fc_assert_ret(id.type() == QVariant::Int);
2795#endif // FC_QT5_MODE
2796
2799 });
2800
2801 connect(insert_menu, &QMenu::triggered, this,
2802 CAPTURE_DEFAULT_THIS (QAction *act) {
2803 QVariant id = act->data();
2804 struct city *pcity = game_city_by_number(city_id);
2805 const struct worklist *worklist;
2806
2807 if (!pcity) {
2808 return;
2809 }
2810
2811#ifndef FC_QT5_MODE
2812 fc_assert_ret(id.typeId() == QMetaType::Int);
2813#else // FC_QT5_MODE
2814 fc_assert_ret(id.type() == QVariant::Int);
2815#endif // FC_QT5_MODE
2816
2819 });
2820
2821 list_menu->popup(QCursor::pos());
2822}
2823
2824/************************************************************************/
2828{
2829 QString str;
2830 int value;
2831
2832 buy_button->setDisabled(true);
2833
2834 if (!client_is_observer() && client.conn.playing != NULL) {
2835 value = dlgcity->client.buy_cost;
2836 str = QString(PL_("Buy (%1 gold)", "Buy (%1 gold)",
2837 value)).arg(QString::number(value));
2838
2839 if (client.conn.playing->economic.gold >= value && value != 0) {
2840 buy_button->setEnabled(true);
2841 }
2842 } else {
2843 str = QString(_("Buy"));
2844 }
2845
2846 buy_button->setText(str);
2847}
2848
2849/************************************************************************/
2853{
2854 enum citizen_category categories[MAX_CITY_SIZE];
2855 int i, j, width, height;
2856 QPainter p;
2857 QPixmap *pix;
2858 int num_citizens = get_city_citizen_types(dlgcity, FEELING_FINAL, categories);
2859 int w = tileset_small_sprite_width(tileset) / gui()->map_scale;
2860 int h = tileset_small_sprite_height(tileset) / gui()->map_scale;
2861
2862 i = 1 + (num_citizens * 5 / 200);
2863 w = w / i;
2864 QRect source_rect(0, 0, w, h);
2865 QRect dest_rect(0, 0, w, h);
2866 width = w * num_citizens;
2867 height = h;
2868
2869 if (citizen_pixmap) {
2870 citizen_pixmap->detach();
2871 delete citizen_pixmap;
2872 }
2873
2874 citizen_pixmap = new QPixmap(width, height);
2875
2876 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2877 dest_rect.moveTo(i * w, 0);
2878 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2879 p.begin(citizen_pixmap);
2880 p.drawPixmap(dest_rect, *pix, source_rect);
2881 p.end();
2882 }
2883
2885 citizens_label->setPixmap(*citizen_pixmap);
2886
2889
2890 for (int k = 0; k < FEELING_LAST - 1; k++) {
2892 num_citizens = get_city_citizen_types(dlgcity,
2893 static_cast<citizen_feeling>(k),
2894 categories);
2895
2896 for (j = 0, i = 0; i < num_citizens; i++, j++) {
2897 dest_rect.moveTo(i * w, 0);
2898 pix = get_citizen_sprite(tileset, categories[j], j, dlgcity)->pm;
2899 p.begin(citizen_pixmap);
2900 p.drawPixmap(dest_rect, *pix, source_rect);
2901 p.end();
2902 }
2903
2904 lab_table[k]->setPixmap(*citizen_pixmap);
2905
2906 switch (k) {
2907 case FEELING_BASE:
2908 lab_table[k]->setToolTip(text_happiness_cities(dlgcity));
2909 break;
2910
2911 case FEELING_LUXURY:
2912 lab_table[k]->setToolTip(text_happiness_luxuries(dlgcity));
2913 break;
2914
2915 case FEELING_EFFECT :
2917 break;
2918
2921 break;
2922
2923 case FEELING_MARTIAL:
2924 lab_table[k]->setToolTip(text_happiness_units(dlgcity));
2925 break;
2926
2927 default:
2928 break;
2929 }
2930 }
2931}
2932
2933/************************************************************************/
2937{
2938 setUpdatesEnabled(false);
2939 production_combo_p->blockSignals(true);
2940
2941 if (dlgcity) {
2942 view->set_pixmap(dlgcity, zoom);
2943 view->update();
2944 update_title();
2950 update_units();
2954 } else {
2956 }
2957
2958 production_combo_p->blockSignals(false);
2959 setUpdatesEnabled(true);
2960 updateGeometry();
2961 update();
2962}
2963
2964
2965/************************************************************************/
2969{
2970 QFont f = QApplication::font();
2971 QFontMetrics fm(f);
2972 QPixmap *pix = NULL;
2973 QPixmap pix_scaled;
2974 QString str;
2975 QStringList info_list;
2976 QTableWidgetItem *item;
2977 char buf[8];
2978 citizens nationality_i;
2979 int h;
2980 int i = 0;
2981 struct sprite *sprite;
2982
2983 h = fm.height() + 6;
2984 nationality_table->clear();
2985 nationality_table->setRowCount(0);
2986 info_list.clear();
2987 info_list << _("#") << _("Flag") << _("Nation");
2988 nationality_table->setHorizontalHeaderLabels(info_list);
2989
2990 citizens_iterate(dlgcity, pslot, nationality) {
2991 nationality_table->insertRow(i);
2992
2993 for (int j = 0; j < nationality_table->columnCount(); j++) {
2994 item = new QTableWidgetItem;
2995
2996 switch (j) {
2997 case 0:
2998 nationality_i = citizens_nation_get(dlgcity, pslot);
2999
3000 if (nationality_i == 0) {
3001 str = "-";
3002 } else {
3003 fc_snprintf(buf, sizeof(buf), "%d", nationality_i);
3004 str = QString(buf);
3005 }
3006
3007 item->setText(str);
3008 break;
3009
3010 case 1:
3013 (player_slot_get_player(pslot)));
3014
3015 if (sprite != NULL) {
3016 pix = sprite->pm;
3017 pix_scaled = pix->scaledToHeight(h);
3018 item->setData(Qt::DecorationRole, pix_scaled);
3019 } else {
3020 item->setText("FLAG MISSING");
3021 }
3022 break;
3023
3024 case 2:
3026 (player_slot_get_player(pslot)));
3027 break;
3028
3029 default:
3030 break;
3031 }
3032 nationality_table->setItem(i, j, item);
3033 }
3034 i++;
3036 nationality_table->horizontalHeader()->setStretchLastSection(false);
3037 nationality_table->resizeColumnsToContents();
3038 nationality_table->resizeRowsToContents();
3039 nationality_table->horizontalHeader()->setStretchLastSection(true);
3040}
3041
3042/************************************************************************/
3046{
3047 int illness = 0;
3048 char buffer[512];
3049 char buf_info[NUM_INFO_FIELDS][512];
3050 char buf_tooltip[NUM_INFO_FIELDS][512];
3051 int granaryturns;
3052 int spec;
3053
3054 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3055 buf_info[i][0] = '\0';
3056 buf_tooltip[i][0] = '\0';
3057 }
3058
3059 /* fill the buffers with the necessary info */
3060 spec = city_specialists(dlgcity);
3061 fc_snprintf(buf_info[INFO_CITIZEN], sizeof(buf_info[INFO_CITIZEN]),
3062 "%3d (%4d)", dlgcity->size, spec);
3063 fc_snprintf(buf_tooltip[INFO_CITIZEN], sizeof(buf_tooltip[INFO_CITIZEN]),
3064 _("Population: %d, Specialists: %d"),
3065 dlgcity->size, spec);
3066 fc_snprintf(buf_info[INFO_FOOD], sizeof(buf_info[INFO_FOOD]), "%3d (%+4d)",
3068 fc_snprintf(buf_info[INFO_SHIELD], sizeof(buf_info[INFO_SHIELD]),
3069 "%3d (%+4d)", dlgcity->prod[O_SHIELD] + dlgcity->waste[O_SHIELD],
3071 fc_snprintf(buf_info[INFO_TRADE], sizeof(buf_info[INFO_TRADE]), "%3d (%+4d)",
3074 fc_snprintf(buf_info[INFO_GOLD], sizeof(buf_info[INFO_GOLD]), "%3d (%+4d)",
3076 fc_snprintf(buf_info[INFO_LUXURY], sizeof(buf_info[INFO_LUXURY]), "%3d",
3078 fc_snprintf(buf_info[INFO_SCIENCE], sizeof(buf_info[INFO_SCIENCE]), "%3d",
3080 fc_snprintf(buf_info[INFO_GRANARY], sizeof(buf_info[INFO_GRANARY]),
3081 "%4d/%-4d", dlgcity->food_stock,
3083
3085 sizeof(buf_tooltip[INFO_FOOD]));
3087 sizeof(buf_tooltip[INFO_SHIELD]));
3089 sizeof(buf_tooltip[INFO_TRADE]));
3091 sizeof(buf_tooltip[INFO_GOLD]));
3093 sizeof(buf_tooltip[INFO_SCIENCE]));
3095 sizeof(buf_tooltip[INFO_LUXURY]));
3097 sizeof(buf_tooltip[INFO_CULTURE]));
3099 sizeof(buf_tooltip[INFO_POLLUTION]));
3101 sizeof(buf_tooltip[INFO_ILLNESS]));
3102
3103 granaryturns = city_turns_to_grow(dlgcity);
3104
3105 if (granaryturns == 0) {
3106 /* TRANS: city growth is blocked. Keep short. */
3107 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("blocked"));
3108 } else if (granaryturns == FC_INFINITY) {
3109 /* TRANS: city is not growing. Keep short. */
3110 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]), _("never"));
3111 } else {
3112 /* A negative value means we'll have famine in that many turns.
3113 But that's handled down below. */
3114 /* TRANS: city growth turns. Keep short. */
3115 fc_snprintf(buf_info[INFO_GROWTH], sizeof(buf_info[INFO_GROWTH]),
3116 PL_("%d turn", "%d turns", abs(granaryturns)),
3117 abs(granaryturns));
3118 }
3119
3120 fc_snprintf(buf_info[INFO_CORRUPTION], sizeof(buf_info[INFO_CORRUPTION]),
3121 "%4d", dlgcity->waste[O_TRADE]);
3122 fc_snprintf(buf_info[INFO_WASTE], sizeof(buf_info[INFO_WASTE]), "%4d",
3124 fc_snprintf(buf_info[INFO_CULTURE], sizeof(buf_info[INFO_CULTURE]), "%4d",
3126 fc_snprintf(buf_info[INFO_POLLUTION], sizeof(buf_info[INFO_POLLUTION]), "%4d",
3128
3129 if (!game.info.illness_on) {
3130 fc_snprintf(buf_info[INFO_ILLNESS], sizeof(buf_info[INFO_ILLNESS]),
3131 " -.-");
3132 } else {
3133 illness = city_illness_calc(dlgcity, NULL, NULL, NULL, NULL);
3134 /* illness is in tenth of percent */
3135 fc_snprintf(buf_info[INFO_ILLNESS], sizeof(buf_info[INFO_ILLNESS]),
3136 "%5.1f%%", (float) illness / 10.0);
3137 }
3138 if (dlgcity->steal) {
3139 fc_snprintf(buf_info[INFO_STEAL], sizeof(buf_info[INFO_STEAL]),
3140 PL_("%d time", "%d times", dlgcity->steal), dlgcity->steal);
3141 } else {
3142 fc_snprintf(buf_info[INFO_STEAL], sizeof(buf_info[INFO_STEAL]),
3143 _("Not stolen"));
3144 }
3145
3147 sizeof(buf_info[INFO_AIRLIFT]));
3149 sizeof(buf_tooltip[INFO_AIRLIFT]));
3150
3151 get_city_dialog_output_text(dlgcity, O_FOOD, buffer, sizeof(buffer));
3152
3153 for (int i = 0; i < NUM_INFO_FIELDS; i++) {
3154 qlt[i]->setText(QString(buf_info[i]));
3155
3156 if (buf_tooltip[i][0]) {
3157 qlt[i]->setToolTip("<pre>" + QString(buf_tooltip[i]).toHtmlEscaped()
3158 + "</pre>");
3159 }
3160 }
3161}
3162
3163/************************************************************************/
3166void city_dialog::setup_ui(struct city *qcity)
3167{
3168 QPixmap q_pix = *get_icon_sprite(tileset, ICON_CITYDLG)->pm;
3169 QIcon q_icon =::QIcon(q_pix);
3170
3171 setContentsMargins(0, 0 ,0 ,0);
3172 setWindowIcon(q_icon);
3173 dlgcity = qcity;
3174 production_combo_p->blockSignals(true);
3175 refresh();
3176 production_combo_p->blockSignals(false);
3177}
3178
3179/************************************************************************/
3182void city_dialog::dbl_click_p(QTableWidgetItem *item)
3183{
3184 struct worklist queue;
3185
3186 city_get_queue(dlgcity, &queue);
3187
3188 if (selected_row_p < 0 || selected_row_p > worklist_length(&queue)) {
3189 return;
3190 }
3191
3193 city_set_queue(dlgcity, &queue);
3194}
3195
3196/************************************************************************/
3200{
3201 unit_item *ui;
3202 struct unit_list *units;
3203 char buf[256];
3204 int n;
3205 int happy_cost;
3206 int free_unhappy = get_city_bonus(dlgcity, EFT_MAKE_CONTENT_MIL);
3207 const struct civ_map *nmap = &(wld.map);
3208
3209 supported_units->setUpdatesEnabled(false);
3210 supported_units->clear_layout();
3211
3212 if (NULL != client.conn.playing
3215 } else {
3216 units = dlgcity->units_supported;
3217 }
3218
3219 unit_list_iterate(units, punit) {
3220 happy_cost = city_unit_unhappiness(nmap, punit, &free_unhappy);
3221 ui = new unit_item(this, punit, true, happy_cost);
3222 ui->init_pix();
3223 supported_units->add_item(ui);
3225 n = unit_list_size(units);
3226 fc_snprintf(buf, sizeof(buf), _("Supported units %d"), n);
3227 supp_units->setText(QString(buf));
3228 supported_units->update_units();
3229 supported_units->setUpdatesEnabled(true);
3230 current_units->setUpdatesEnabled(true);
3232
3233 if (NULL != client.conn.playing
3236 } else {
3237 units = dlgcity->tile->units;
3238 }
3239
3240 unit_list_iterate(units, punit) {
3241 ui = new unit_item(this , punit, false);
3242 ui->init_pix();
3245
3246 n = unit_list_size(units);
3247 fc_snprintf(buf, sizeof(buf), _("Present units %d"), n);
3248 curr_units->setText(QString(buf));
3249
3251 current_units->setUpdatesEnabled(true);
3252}
3253
3254/************************************************************************/
3257void city_dialog::item_selected(const QItemSelection &sl,
3258 const QItemSelection &ds)
3259{
3260 QModelIndex index;
3261 QModelIndexList indexes = sl.indexes();
3262
3263 if (indexes.isEmpty()) {
3264 return;
3265 }
3266
3267 index = indexes.at(0);
3268 selected_row_p = index.row();
3270}
3271
3272/************************************************************************/
3276{
3277 int size, i;
3278 struct city *other_pcity = NULL;
3279
3280 if (NULL == client.conn.playing) {
3281 return;
3282 }
3283
3284 size = city_list_size(client.conn.playing->cities);
3285
3286 if (size <= 1) {
3287 return;
3288 }
3289
3290 for (i = 0; i < size; i++) {
3291 if (dlgcity == city_list_get(client.conn.playing->cities, i)) {
3292 break;
3293 }
3294 }
3295
3296 if (i >= size - 1) {
3297 // Current city last in the list (size - 1) or disappeared (size)
3298 other_pcity = city_list_get(client.conn.playing->cities, 0);
3299 } else {
3300 other_pcity = city_list_get(client.conn.playing->cities, i + 1);
3301 }
3302
3303 center_tile_mapcanvas(other_pcity->tile);
3304 qtg_real_city_dialog_popup(other_pcity);
3305}
3306
3307/************************************************************************/
3311{
3312 int size, i;
3313 struct city *other_pcity = NULL;
3314
3315 if (NULL == client.conn.playing) {
3316 return;
3317 }
3318
3319 size = city_list_size(client.conn.playing->cities);
3320
3321 if (size <= 1) {
3322 return;
3323 }
3324
3325 for (i = 0; i < size; i++) {
3326 if (dlgcity == city_list_get(client.conn.playing->cities, i)) {
3327 break;
3328 }
3329 }
3330
3331 if (i == 0 || i == size) {
3332 // Current city in the beginning of the list or disappeared
3333 other_pcity = city_list_get(client.conn.playing->cities, size - 1);
3334 } else {
3335 other_pcity = city_list_get(client.conn.playing->cities, i - 1);
3336 }
3337
3338 center_tile_mapcanvas(other_pcity->tile);
3339 qtg_real_city_dialog_popup(other_pcity);
3340}
3341
3342/************************************************************************/
3346{
3347 char buf[32];
3348 QString str;
3350
3351 get_city_dialog_production(dlgcity, buf, sizeof(buf));
3352 production_combo_p->setRange(0, cost);
3354 if (dlgcity->shield_stock >= cost) {
3355 production_combo_p->setValue(cost);
3356 } else {
3358 }
3359 production_combo_p->setAlignment(Qt::AlignCenter);
3360 str = QString(buf);
3361 str = str.simplified();
3362
3363 production_combo_p->setFormat(QString("(%p%) %2\n%1")
3365 str));
3366
3367 production_combo_p->updateGeometry();
3368
3369}
3370
3371/************************************************************************/
3375{
3376 char buf[1024], buf2[1024];
3378 int value = dlgcity->client.buy_cost;
3379 hud_message_box *ask;
3380 int city_id = dlgcity->id;
3381
3382 if (!can_client_issue_orders()) {
3383 return;
3384 }
3385
3386 ask = new hud_message_box(city_dlg);
3387 fc_snprintf(buf2, ARRAY_SIZE(buf2), PL_("Treasury contains %d gold.",
3388 "Treasury contains %d gold.",
3389 client_player()->economic.gold),
3390 client_player()->economic.gold);
3391 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("Buy %s for %d gold?",
3392 "Buy %s for %d gold?", value),
3393 name, value);
3394 ask->set_text_title(buf, buf2);
3395 ask->setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
3396 ask->setDefaultButton(QMessageBox::Cancel);
3397 ask->setAttribute(Qt::WA_DeleteOnClose);
3398 connect(ask, &hud_message_box::accepted, this, [=]() {
3399 struct city *pcity = game_city_by_number(city_id);
3400
3401 if (!pcity) {
3402 return;
3403 }
3404
3406 });
3407 ask->show();
3408}
3409
3410/************************************************************************/
3414{
3415 QFont f = QApplication::font();
3416 QFontMetrics fm(f);
3417 QPixmap *pix = NULL;
3418 QPixmap pix_scaled;
3419 QString str, tooltip;
3420 QTableWidgetItem *qitem;
3421 struct sprite *sprite;
3422 int h, cost, item, targets_used, col, upkeep;
3423 struct item items[MAX_NUM_PRODUCTION_TARGETS];
3424 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
3425 struct worklist queue;
3426 impr_item *ui;
3427
3428 upkeep = 0;
3429 city_buildings->setUpdatesEnabled(false);
3431
3432 h = fm.height() + 6;
3433 targets_used = collect_already_built_targets(targets, dlgcity);
3434 name_and_sort_items(targets, targets_used, items, false, dlgcity);
3435
3436 for (item = 0; item < targets_used; item++) {
3437 struct universal target = items[item].item;
3438
3439 ui = new impr_item(this, target.value.building, dlgcity);
3440 ui->init_pix();
3442
3443 fc_assert_action(VUT_IMPROVEMENT == target.kind, continue);
3445 upkeep = upkeep + city_improvement_upkeep(dlgcity, target.value.building);
3446 if (sprite != nullptr) {
3447 pix = sprite->pm;
3448 pix_scaled = pix->scaledToHeight(h);
3449 }
3450 }
3451
3452 city_get_queue(dlgcity, &queue);
3453 p_table_p->setRowCount(worklist_length(&queue));
3454
3455 for (int i = 0; i < worklist_length(&queue); i++) {
3456 struct universal target = queue.entries[i];
3457
3458 tooltip = "";
3459
3460 if (VUT_UTYPE == target.kind) {
3463 tooltip = get_tooltip_unit(target.value.utype, true).trimmed();
3465 direction8_invalid());
3466 } else {
3470 dlgcity, true).trimmed();
3471
3472 if (improvement_has_flag(target.value.building, IF_GOLD)) {
3473 cost = -1;
3474 } else {
3476 }
3477 }
3478
3479 for (col = 0; col < 3; col++) {
3480 qitem = new QTableWidgetItem();
3481 qitem->setToolTip(tooltip);
3482
3483 switch (col) {
3484 case 0:
3485 if (sprite) {
3486 pix = sprite->pm;
3487 pix_scaled = pix->scaledToHeight(h);
3488 qitem->setData(Qt::DecorationRole, pix_scaled);
3489 }
3490 break;
3491
3492 case 1:
3493 if (str.contains('[') && str.contains(']')) {
3494 int ii, ij;
3495
3496 ii = str.lastIndexOf('[');
3497 ij = str.lastIndexOf(']');
3498 if (ij > ii) {
3499 str = str.remove(ii, ij - ii + 1);
3500 }
3501 }
3502 qitem->setText(str);
3503 break;
3504
3505 case 2:
3506 qitem->setTextAlignment(Qt::AlignRight);
3507 qitem->setText(QString::number(cost));
3508 break;
3509 }
3510 p_table_p->setItem(i, col, qitem);
3511 }
3512 }
3513
3514 p_table_p->horizontalHeader()->setStretchLastSection(false);
3515 p_table_p->resizeColumnsToContents();
3516 p_table_p->resizeRowsToContents();
3517 p_table_p->horizontalHeader()->setStretchLastSection(true);
3518
3520 city_buildings->setUpdatesEnabled(true);
3521 city_buildings->setUpdatesEnabled(true);
3522
3523 curr_impr->setText(QString(_("Improvements - upkeep %1")).arg(upkeep));
3524}
3525
3526/************************************************************************/
3530{
3531 cid id;
3532 QVariant qvar;
3533
3535 struct universal univ;
3536
3537 id = qvar.toInt();
3538 univ = cid_production(id);
3540 }
3541}
3542
3543/************************************************************************/
3548{
3550 int when = 1;
3551
3552 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3553 when, selected_row_p, show_units->isChecked(),
3554 false, show_wonders->isChecked(),
3555 show_buildings->isChecked());
3556 pw->show();
3557}
3558
3559/************************************************************************/
3564{
3566 int when = 4;
3567
3568 pw = new production_widget(this, dlgcity, future_targets->isChecked(),
3569 when, selected_row_p, show_units->isChecked(),
3570 false, show_wonders->isChecked(),
3571 show_buildings->isChecked());
3572 pw->show();
3573}
3574
3575/************************************************************************/
3579{
3580 struct worklist empty;
3581
3582 if (!can_client_issue_orders()) {
3583 return;
3584 }
3585
3586 worklist_init(&empty);
3587 city_set_worklist(dlgcity, &empty);
3588}
3589
3590/************************************************************************/
3594{
3595 QModelIndex index;
3596 struct worklist queue;
3597 struct universal *target;
3598
3599 if (selected_row_p < 1 || selected_row_p >= p_table_p->rowCount()) {
3600 return;
3601 }
3602
3603 target = new universal;
3604 city_get_queue(dlgcity, &queue);
3605 worklist_peek_ith(&queue, target, selected_row_p);
3607 worklist_insert(&queue, target, selected_row_p - 1);
3608 city_set_queue(dlgcity, &queue);
3609 index = p_table_p->model()->index(selected_row_p - 1, 0);
3610 p_table_p->setCurrentIndex(index);
3611 delete target;
3612
3613}
3614
3615/************************************************************************/
3619{
3620 QTableWidgetItem *item;
3621
3622 if (selected_row_p < 0
3623 || selected_row_p >= p_table_p->rowCount()) {
3624 return;
3625 }
3626
3630}
3631
3632/************************************************************************/
3636{
3637 QModelIndex index;
3638 struct worklist queue;
3639 struct universal *target;
3640
3641 if (selected_row_p < 0 || selected_row_p >= p_table_p->rowCount() - 1) {
3642 return;
3643 }
3644
3645 target = new universal;
3646 city_get_queue(dlgcity, &queue);
3647 worklist_peek_ith(&queue, target, selected_row_p);
3649 worklist_insert(&queue, target, selected_row_p + 1);
3650 city_set_queue(dlgcity, &queue);
3651 index = p_table_p->model()->index(selected_row_p + 1, 0);
3652 p_table_p->setCurrentIndex(index);
3653 delete target;
3654}
3655
3656/************************************************************************/
3660{
3661 hud_input_box *ask = new hud_input_box(gui()->central_wdg);
3662 int city_id = dlgcity->id;
3663
3664 ask->set_text_title_definput(_("What should we name new worklist?"),
3665 _("Save current worklist"),
3666 _("New worklist"));
3667 ask->setAttribute(Qt::WA_DeleteOnClose);
3668 connect(ask, &hud_message_box::accepted, [=]() {
3669 struct global_worklist *gw;
3670 struct worklist queue;
3671 QByteArray ask_bytes;
3672 QString text;
3673 struct city *pcity = game_city_by_number(city_id);
3674
3675 ask_bytes = ask->input_edit.text().toUtf8();
3676 text = ask_bytes.data();
3677 if (!text.isEmpty()) {
3678 ask_bytes = text.toUtf8();
3679 gw = global_worklist_new(ask_bytes.data());
3680 city_get_queue(pcity, &queue);
3681 global_worklist_set(gw, &queue);
3682 }
3683 });
3684 ask->show();
3685}
3686
3687/************************************************************************/
3691{
3692 QString buf;
3693
3694 // Defeat keyboard shortcut mnemonics
3695 lcity_name->setText(QString(city_name_get(dlgcity))
3696 .replace("&", "&&"));
3697
3698 if (city_unhappy(dlgcity)) {
3699 /* TRANS: city dialog title */
3700 buf = QString(_("%1 - %2 citizens - DISORDER")).arg(city_name_get(dlgcity),
3702 } else if (city_celebrating(dlgcity)) {
3703 /* TRANS: city dialog title */
3704 buf = QString(_("%1 - %2 citizens - celebrating")).arg(city_name_get(dlgcity),
3706 } else if (city_happy(dlgcity)) {
3707 /* TRANS: city dialog title */
3708 buf = QString(_("%1 - %2 citizens - happy")).arg(city_name_get(dlgcity),
3710 } else {
3711 /* TRANS: city dialog title */
3712 buf = QString(_("%1 - %2 citizens")).arg(city_name_get(dlgcity),
3714 }
3715
3716 setWindowTitle(buf);
3717}
3718
3719/************************************************************************/
3724{
3725 if (!::city_dlg_created) {
3726 ::city_dlg = new city_dialog(gui()->mapview_wdg);
3727 }
3728
3729 city_dlg->setup_ui(pcity);
3730 city_dlg->show();
3731 city_dlg->activateWindow();
3732 city_dlg->raise();
3733}
3734
3735/************************************************************************/
3739{
3740 if (!::city_dlg_created) {
3741 return;
3742 }
3743
3744 city_dlg->close();
3745 ::city_dlg_created = false;
3746}
3747
3748/************************************************************************/
3752{
3753 if (!::city_dlg_created) {
3754 return;
3755 }
3756
3758}
3759
3760/************************************************************************/
3767
3768/************************************************************************/
3772{
3773 if (!::city_dlg_created) {
3774 return;
3775 }
3776
3777 if (qtg_city_dialog_is_open(pcity)) {
3778 city_dlg->refresh();
3779 }
3780}
3781
3782/************************************************************************/
3786{
3787 QList<QLabel *> l;
3788 QFont *f;
3789
3790 if (!::city_dlg_created) {
3791 return;
3792 }
3793
3794 l = city_dlg->findChildren<QLabel *>();
3795
3797
3798 for (int i = 0; i < l.size(); ++i) {
3799 if (l.at(i)->property(fonts::notify_label).isValid()) {
3800 l.at(i)->setFont(*f);
3801 }
3802 }
3803}
3804
3805/************************************************************************/
3811{
3812
3813 struct city *pcity_sup, *pcity_pre;
3814
3815 pcity_sup = game_city_by_number(punit->homecity);
3816 pcity_pre = tile_city(punit->tile);
3817
3820
3821}
3822
3823/************************************************************************/
3827{
3828 if (!::city_dlg_created) {
3829 return false;
3830 }
3831
3832 if (city_dlg->dlgcity == pcity && city_dlg->isVisible()) {
3833 return true;
3834 }
3835
3836 return false;
3837}
3838
3839/************************************************************************/
3842bool fc_tooltip::eventFilter(QObject *obj, QEvent *ev)
3843{
3844 QHelpEvent *help_event;
3845 QString item_tooltip;
3846 QRect rect;
3847
3848 if (ev->type() == QEvent::ToolTip) {
3849 QAbstractItemView *view = qobject_cast<QAbstractItemView *>(obj->parent());
3850
3851 if (!view) {
3852 return false;
3853 }
3854
3855 help_event = static_cast<QHelpEvent *>(ev);
3856 QPoint pos = help_event->pos();
3857 QModelIndex index = view->indexAt(pos);
3858 QPoint hpos;
3859
3860 if (!index.isValid()) {
3861 return false;
3862 }
3863
3864 item_tooltip = view->model()->data(index, Qt::ToolTipRole).toString();
3865 rect = view->visualRect(index);
3866
3867 hpos = help_event->globalPos();
3868
3869 rect.setX(rect.x() + hpos.x());
3870 rect.setY(rect.y() + hpos.y());
3871
3872 if (!item_tooltip.isEmpty()) {
3873 QToolTip::showText(help_event->globalPos(), item_tooltip, view, rect);
3874 } else {
3875 QToolTip::hideText();
3876 }
3877
3878 return true;
3879 }
3880
3881 return false;
3882}
3883
3884/************************************************************************/
3887static QString bold(QString text)
3888{
3889 return QString("<b>" + text + "</b>");
3890}
3891
3892/************************************************************************/
3896QString get_tooltip_improvement(const impr_type *building, struct city *pcity,
3897 bool ext)
3898{
3899 QString def_str;
3900 QString upkeep;
3901 QString s1, s2, str;
3902 const char *req = skip_intl_qualifier_prefix(_("?tech:None"));
3903
3904 if (pcity != nullptr) {
3905 upkeep = QString::number(city_improvement_upkeep(pcity, building));
3906 } else {
3907 upkeep = QString::number(building->upkeep);
3908 }
3909 requirement_vector_iterate(&building->obsolete_by, pobs) {
3910 if (pobs->source.kind == VUT_ADVANCE) {
3911 req = advance_name_translation(pobs->source.value.advance);
3912 break;
3913 }
3915 s2 = QString(req);
3916 str = _("Obsolete by:");
3917 str = str + " " + s2;
3918 def_str = "<p style='white-space:pre'><b>"
3919 + QString(improvement_name_translation(building)).toHtmlEscaped()
3920 + "</b>\n";
3921 if (pcity != nullptr) {
3922 def_str += QString(_("Cost: %1, Upkeep: %2\n"))
3923 .arg(impr_build_shield_cost(pcity, building))
3924 .arg(upkeep).toHtmlEscaped();
3925 } else {
3926 int cost_est = impr_estimate_build_shield_cost(client.conn.playing, NULL, building);
3927
3928 def_str += QString(_("Cost Estimate: %1, Upkeep: %2\n"))
3929 .arg(cost_est)
3930 .arg(upkeep).toHtmlEscaped();
3931 }
3932 if (s1.compare(s2) != 0) {
3933 def_str = def_str + str.toHtmlEscaped() + "\n";
3934 }
3935 def_str = def_str + "\n";
3936 if (ext) {
3937 char buffer[8192];
3938
3939 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
3940 NULL, building);
3941 str = cut_helptext(str);
3942 str = split_text(str, true);
3943 str = str.trimmed();
3944 def_str = def_str + str.toHtmlEscaped();
3945 }
3946 return def_str;
3947}
3948
3949/************************************************************************/
3953QString get_tooltip_unit(const struct unit_type *utype, bool ext)
3954{
3955 QString def_str;
3956 QString obsolete_str;
3957 QString str;
3958 const struct unit_type *obsolete;
3959 struct advance *tech;
3960
3961 def_str = "<b>"
3962 + QString(utype_name_translation(utype)).toHtmlEscaped()
3963 + "</b>\n";
3964 obsolete = utype->obsoleted_by;
3965 if (obsolete) {
3966 tech = obsolete->require_advance;
3967 obsolete_str = QString("</td></tr><tr><td colspan=\"3\">");
3968 if (tech && tech != advance_by_number(A_NONE)) {
3969 /* TRANS: this and nearby literal strings are interpreted
3970 * as (Qt) HTML */
3971 obsolete_str = obsolete_str + QString(_("Obsoleted by %1 (%2)."))
3972 .arg(utype_name_translation(obsolete))
3973 .arg(advance_name_translation(tech)).toHtmlEscaped();
3974 } else {
3975 obsolete_str = obsolete_str + QString(_("Obsoleted by %1."))
3976 .arg(utype_name_translation(obsolete)).toHtmlEscaped();
3977 }
3978 }
3979 def_str += "<table width=\"100\%\"><tr><td>"
3980 + bold(QString(_("Attack:"))) + " "
3981 + QString::number(utype->attack_strength).toHtmlEscaped()
3982 + QString("</td><td>") + bold(QString(_("Defense:"))) + " "
3983 + QString::number(utype->defense_strength).toHtmlEscaped()
3984 + QString("</td><td>") + bold(QString(_("Move:"))) + " "
3985 + QString(move_points_text(utype->move_rate, TRUE)).toHtmlEscaped()
3986 + QString("</td></tr><tr><td>")
3987 + bold(QString(_("Cost:"))) + " "
3988 + QString::number(utype_build_shield_cost_base(utype))
3989 .toHtmlEscaped()
3990 + QString("</td><td colspan=\"2\">")
3991 + bold(QString(_("Basic Upkeep:")))
3992 + " " + QString(helptext_unit_upkeep_str(utype)).toHtmlEscaped()
3993 + QString("</td></tr><tr><td>")
3994 + bold(QString(_("Hitpoints:"))) + " "
3995 + QString::number(utype->hp).toHtmlEscaped()
3996 + QString("</td><td>") + bold(QString(_("Firepower:"))) + " "
3997 + QString::number(utype->firepower).toHtmlEscaped()
3998 + QString("</td><td>") + bold(QString(_("Vision:"))) + " "
3999 + QString::number((int) sqrt((double) utype->vision_radius_sq))
4000 .toHtmlEscaped()
4001 + obsolete_str
4002 + QString("</td></tr></table><p style='white-space:pre'>");
4003 if (ext) {
4004 char buffer[8192];
4005 char buf2[1];
4006
4007 buf2[0] = '\0';
4008 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
4009 buf2, utype);
4010 str = cut_helptext(str);
4011 str = split_text(str, true);
4012 str = str.trimmed().toHtmlEscaped();
4013 def_str = def_str + str;
4014 }
4015
4016 return def_str;
4017};
4018
4019/************************************************************************/
4022QString get_tooltip(QVariant qvar)
4023{
4024 QString str, def_str, ret_str;
4025 QStringList sl;
4026 char buffer[8192];
4027 char buf2[1];
4028 struct universal *target;
4029
4030 buf2[0] = '\0';
4031 target = reinterpret_cast<universal *>(qvar.value<void *>());
4032
4033 if (target == NULL) {
4034 } else if (VUT_UTYPE == target->kind) {
4035 def_str = get_tooltip_unit(target->value.utype);
4036 str = helptext_unit(buffer, sizeof(buffer), client.conn.playing,
4037 buf2, target->value.utype);
4038 } else {
4039 if (!improvement_has_flag(target->value.building, IF_GOLD)) {
4040 def_str = get_tooltip_improvement(target->value.building);
4041 }
4042
4043 str = helptext_building(buffer, sizeof(buffer), client.conn.playing,
4044 NULL, target->value.building);
4045 }
4046
4047 /* Remove all lines from help which has '*' in first 3 chars */
4048 ret_str = cut_helptext(str);
4049 ret_str = split_text(ret_str, true);
4050 ret_str = ret_str.trimmed();
4051 ret_str = def_str + ret_str.toHtmlEscaped();
4052
4053 return ret_str;
4054}
4055
4056/************************************************************************/
4060 QObject *parent,
4061 struct city *city)
4062 : QItemDelegate(parent)
4063{
4064 pd = sh;
4065 item_height = sh.y();
4066 pcity = city;
4067}
4068
4069/************************************************************************/
4072void city_production_delegate::paint(QPainter *painter,
4073 const QStyleOptionViewItem &option,
4074 const QModelIndex &index) const
4075{
4076 struct universal *target;
4077 QString name;
4078 QVariant qvar;
4079 QPixmap *pix;
4080 QPixmap pix_scaled;
4081 QRect rect1;
4082 QRect rect2;
4083 struct sprite *sprite;
4084 bool useless = false;
4085 bool is_coinage = false;
4086 bool is_neutral = false;
4087 bool is_sea = false;
4088 bool is_flying = false;
4089 bool is_unit = true;
4090 QPixmap pix_dec(option.rect.width(), option.rect.height());
4091 QStyleOptionViewItem opt;
4092 color col;
4093 QIcon icon = current_app()->style()->standardIcon(QStyle::SP_DialogCancelButton);
4094 bool free_sprite = false;
4095 struct unit_class *pclass;
4096
4097 if (!option.rect.isValid()) {
4098 return;
4099 }
4100
4101 qvar = index.data();
4102
4103 if (!qvar.isValid()) {
4104 return;
4105 }
4106
4107 target = reinterpret_cast<universal *>(qvar.value<void *>());
4108
4109 if (target == NULL) {
4110 col.qcolor = Qt::white;
4111 sprite = qtg_create_sprite(100, 100, &col);
4112 free_sprite = true;
4113 *sprite->pm = icon.pixmap(100, 100);
4114 name = _("Cancel");
4115 is_unit = false;
4116 } else if (VUT_UTYPE == target->kind) {
4118 is_neutral = utype_has_flag(target->value.utype, UTYF_CIVILIAN);
4119 pclass = utype_class(target->value.utype);
4120 if (!uclass_has_flag(pclass, UCF_TERRAIN_DEFENSE)
4121 && !utype_can_do_action_result(target->value.utype, ACTRES_FORTIFY)
4122 && !uclass_has_flag(pclass, UCF_ZOC)) {
4123 is_sea = true;
4124 }
4125
4126 if ((utype_fuel(target->value.utype)
4127 && !uclass_has_flag(pclass, UCF_TERRAIN_DEFENSE)
4128 && !utype_can_do_action_result(target->value.utype, ACTRES_PILLAGE)
4129 && !utype_can_do_action_result(target->value.utype, ACTRES_FORTIFY)
4130 && !uclass_has_flag(pclass, UCF_ZOC))
4131 /* FIXME: Assumed to be flying since only missiles can do suicide
4132 * attacks in classic-like rulesets. This isn't true for all
4133 * rulesets. Not a high priority to fix since all is_flying and
4134 * is_sea is used for is to set a color. */
4135 || utype_is_consumed_by_action_result(ACTRES_ATTACK,
4136 target->value.utype)) {
4137 if (is_sea) {
4138 is_sea = false;
4139 }
4140 is_flying = true;
4141 }
4142
4144 direction8_invalid());
4145 } else {
4146 is_unit = false;
4149 useless = is_improvement_redundant(pcity, target->value.building);
4150 is_coinage = improvement_has_flag(target->value.building, IF_GOLD);
4151 }
4152
4153 if (sprite != NULL) {
4154 pix = sprite->pm;
4155 pix_scaled = pix->scaledToHeight(item_height - 2, Qt::SmoothTransformation);
4156
4157 if (useless) {
4158 pixmap_put_x(&pix_scaled);
4159 }
4160 }
4161
4162 opt = QItemDelegate::setOptions(index, option);
4163 painter->save();
4164 opt.displayAlignment = Qt::AlignLeft;
4165 opt.textElideMode = Qt::ElideMiddle;
4166 QItemDelegate::drawBackground(painter, opt, index);
4167 rect1 = option.rect;
4168 rect1.setWidth(pix_scaled.width() + 4);
4169 rect2 = option.rect;
4170 rect2.setLeft(option.rect.left() + rect1.width());
4171 rect2.setTop(rect2.top() + (rect2.height()
4172 - painter->fontMetrics().height()) / 2);
4173 QItemDelegate::drawDisplay(painter, opt, rect2, name);
4174
4175 if (is_unit) {
4176 if (is_sea) {
4177 pix_dec.fill(QColor(0, 0, 255, 80));
4178 } else if (is_flying) {
4179 pix_dec.fill(QColor(220, 0, 0, 80));
4180 } else if (is_neutral) {
4181 pix_dec.fill(QColor(0, 120, 0, 40));
4182 } else {
4183 pix_dec.fill(QColor(0, 0, 150, 40));
4184 }
4185
4186 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4187 }
4188
4189 if (is_coinage) {
4190 pix_dec.fill(QColor(255, 255, 0, 70));
4191 QItemDelegate::drawDecoration(painter, option, option.rect, pix_dec);
4192 }
4193
4194 if (!pix_scaled.isNull()) {
4195 QItemDelegate::drawDecoration(painter, opt, rect1, pix_scaled);
4196 }
4197
4198 drawFocus(painter, opt, option.rect);
4199
4200 painter->restore();
4201
4202 if (free_sprite) {
4204 }
4205}
4206
4207/************************************************************************/
4211 const QStyleOptionViewItem &option,
4212 const QRect &rect) const
4213{
4214 QPixmap pix(option.rect.width(), option.rect.height());
4215
4216 if ((option.state & QStyle::State_MouseOver) == 0 || !rect.isValid()) {
4217 return;
4218 }
4219
4220 pix.fill(QColor(50, 50, 50, 50));
4221 QItemDelegate::drawDecoration(painter, option, option.rect, pix);
4222}
4223
4224/************************************************************************/
4227QSize city_production_delegate::sizeHint(const QStyleOptionViewItem &option,
4228 const QModelIndex &index) const
4229{
4230 QSize s;
4231
4232 s.setWidth(pd.x());
4233 s.setHeight(pd.y());
4234 return s;
4235}
4236
4237/************************************************************************/
4241 QObject *parent): QObject()
4242{
4243 setParent(parent);
4244 target = ptarget;
4245}
4246
4247/************************************************************************/
4251{
4252 /* allocated as renegade in model */
4253 if (target != NULL) {
4254 delete target;
4255 }
4256}
4257
4258/************************************************************************/
4262{
4263 return QVariant::fromValue((void *)target);
4264}
4265
4266/************************************************************************/
4270{
4271 return false;
4272}
4273
4274/************************************************************************/
4278 bool su, bool sw, bool sb,
4279 QObject *parent)
4280 : QAbstractListModel(parent)
4281{
4282 show_units = su;
4283 show_wonders = sw;
4284 show_buildings = sb;
4285 mcity = pcity;
4286 future_t = f;
4287 populate();
4288}
4289
4290/************************************************************************/
4298
4299/************************************************************************/
4302QVariant city_production_model::data(const QModelIndex &index, int role) const
4303{
4304 if (!index.isValid()) {
4305 return QVariant();
4306 }
4307
4308 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4309 && index.column() < columnCount()
4310 && (index.column() + index.row() * 3 < city_target_list.count())) {
4311 int r, c, t ,new_index;
4312 r = index.row();
4313 c = index.column();
4314 t = r * 3 + c;
4315 new_index = t / 3 + rowCount() * c;
4316 /* Exception, shift whole column */
4317 if ((c == 2) && city_target_list.count() % 3 == 1) {
4318 new_index = t / 3 + rowCount() * c - 1;
4319 }
4320 if (role == Qt::ToolTipRole) {
4321 return get_tooltip(city_target_list[new_index]->data());
4322 }
4323
4324 return city_target_list[new_index]->data();
4325 }
4326
4327 return QVariant();
4328}
4329
4330/************************************************************************/
4334{
4335 production_item *pi;
4336 struct universal targets[MAX_NUM_PRODUCTION_TARGETS];
4337 struct item items[MAX_NUM_PRODUCTION_TARGETS];
4338 struct universal *renegade;
4339 int item, targets_used;
4340 QString str;
4342 QFontMetrics fm(f);
4343
4344 sh.setY(fm.height() * 2);
4345 sh.setX(0);
4346
4347 qDeleteAll(city_target_list);
4348 city_target_list.clear();
4349
4350 targets_used = collect_eventually_buildable_targets(targets, mcity,
4351 future_t);
4352 name_and_sort_items(targets, targets_used, items, false, mcity);
4353
4354 for (item = 0; item < targets_used; item++) {
4355 if (future_t || can_city_build_now(&(wld.map), mcity, &items[item].item)) {
4356 renegade = new universal(items[item].item);
4357
4358 // Renegade deleted in production_item destructor
4359 if (VUT_UTYPE == renegade->kind) {
4361 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4362
4363 if (show_units) {
4364 pi = new production_item(renegade, this);
4365 city_target_list << pi;
4366 } else {
4367 delete renegade;
4368 }
4369 } else {
4371 sh.setX(qMax(sh.x(), fm.horizontalAdvance(str)));
4372
4373 if ((is_wonder(renegade->value.building) && show_wonders)
4374 || (is_improvement(renegade->value.building) && show_buildings)
4375 || (improvement_has_flag(renegade->value.building, IF_GOLD))
4377 && show_buildings)) {
4378 pi = new production_item(renegade, this);
4379 city_target_list << pi;
4380 } else {
4381 delete renegade;
4382 }
4383 }
4384 }
4385 }
4386
4387 pi = new production_item(nullptr, this);
4388 city_target_list << pi;
4389 sh.setX(2 * sh.y() + sh.x());
4390 sh.setX(qMin(sh.x(), 250));
4391}
4392
4393/************************************************************************/
4396bool city_production_model::setData(const QModelIndex &index,
4397 const QVariant &value, int role)
4398{
4399 if (!index.isValid() || role != Qt::DisplayRole || role != Qt::ToolTipRole)
4400 return false;
4401
4402 if (index.row() >= 0 && index.row() < rowCount() && index.column() >= 0
4403 && index.column() < columnCount()) {
4404 bool change = city_target_list[index.row()]->setData();
4405 return change;
4406 }
4407
4408 return false;
4409}
4410
4411/************************************************************************/
4419production_widget::production_widget(QWidget *parent, struct city *pcity,
4420 bool future, int when, int curr,
4421 bool show_units, bool buy,
4422 bool show_wonders,
4423 bool show_buildings): QTableView()
4424{
4425 QPoint pos, sh;
4426 QRect rect = QApplication::primaryScreen()->availableGeometry();
4427 int desk_width = rect.width();
4428 int desk_height = rect.height();
4429 fc_tt = new fc_tooltip(this);
4430 setAttribute(Qt::WA_DeleteOnClose);
4431 setWindowFlags(Qt::Popup);
4432 verticalHeader()->setVisible(false);
4433 horizontalHeader()->setVisible(false);
4434 setProperty("showGrid", false);
4435 curr_selection = curr;
4436 sh_units = show_units;
4437 pw_city = pcity;
4438 buy_it = buy;
4439 when_change = when;
4440 list_model = new city_production_model(pw_city, future, show_units,
4441 show_wonders, show_buildings, this);
4442 sh = list_model->sh;
4443 c_p_d = new city_production_delegate(sh, this, pw_city);
4444 setItemDelegate(c_p_d);
4445 setModel(list_model);
4446 viewport()->installEventFilter(fc_tt);
4447 installEventFilter(this);
4448 connect(selectionModel(), SIGNAL(selectionChanged(const QItemSelection &,
4449 const QItemSelection &)),
4450 SLOT(prod_selected(const QItemSelection &,
4451 const QItemSelection &)));
4452 resizeRowsToContents();
4453 resizeColumnsToContents();
4454 setFixedWidth(3 * sh.x() + 6);
4455 setFixedHeight(list_model->rowCount()*sh.y() + 6);
4456
4457 if (width() > desk_width) {
4458 setFixedWidth(desk_width);
4459 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4460 } else {
4461 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4462 }
4463
4464 if (height() > desk_height) {
4465 setFixedHeight(desk_height);
4466 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
4467 } else {
4468 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
4469 }
4470
4471 pos = QCursor::pos();
4472
4473 if (pos.x() + width() > desk_width) {
4474 pos.setX(desk_width - width());
4475 } else if (pos.x() - width() < 0) {
4476 pos.setX(0);
4477 }
4478
4479 if (pos.y() + height() > desk_height) {
4480 pos.setY(desk_height - height());
4481 } else if (pos.y() - height() < 0) {
4482 pos.setY(0);
4483 }
4484
4485 move(pos);
4486 setMouseTracking(true);
4487 setFocus();
4488}
4489
4490/************************************************************************/
4494{
4495 if (event->button() == Qt::RightButton) {
4496 close();
4497 return;
4498 }
4499
4500 QAbstractItemView::mousePressEvent(event);
4501}
4502
4503/************************************************************************/
4506bool production_widget::eventFilter(QObject *obj, QEvent *ev)
4507{
4508 QRect pw_rect;
4509 QPoint br;
4510
4511 if (obj != this)
4512 return false;
4513
4514 if (ev->type() == QEvent::MouseButtonPress) {
4515 pw_rect.setTopLeft(pos());
4516 br.setX(pos().x() + width());
4517 br.setY(pos().y() + height());
4518 pw_rect.setBottomRight(br);
4519
4520 if (!pw_rect.contains(QCursor::pos())) {
4521 close();
4522 }
4523 }
4524
4525 return false;
4526}
4527
4528/************************************************************************/
4531void production_widget::prod_selected(const QItemSelection &sl,
4532 const QItemSelection &ds)
4533{
4534 QModelIndexList indexes = selectionModel()->selectedIndexes();
4535 QModelIndex index;
4536 QVariant qvar;
4537 struct worklist queue;
4538 struct universal *target;
4539
4540 if (indexes.isEmpty() || client_is_observer()) {
4541 return;
4542 }
4543 index = indexes.at(0);
4544 qvar = index.data(Qt::UserRole);
4545 if (!qvar.isValid()) {
4546 return;
4547 }
4548 target = reinterpret_cast<universal *>(qvar.value<void *>());
4549 if (target != NULL) {
4550 city_get_queue(pw_city, &queue);
4551 switch (when_change) {
4552 case 0: /* Change current target */
4554 if (city_can_buy(pw_city) && buy_it) {
4556 }
4557 break;
4558
4559 case 1: /* Change current (selected on list)*/
4560 if (curr_selection < 0 || curr_selection > worklist_length(&queue)) {
4562 } else {
4564 worklist_insert(&queue, target, curr_selection);
4565 city_set_queue(pw_city, &queue);
4566 }
4567 break;
4568
4569 case 2: /* Insert before */
4570 if (curr_selection < 0 || curr_selection > worklist_length(&queue)) {
4571 curr_selection = 0;
4572 }
4574 curr_selection = qMax(0, curr_selection);
4575 worklist_insert(&queue, target, curr_selection);
4576 city_set_queue(pw_city, &queue);
4577 break;
4578
4579 case 3: /* Insert after */
4580 if (curr_selection < 0 || curr_selection > worklist_length(&queue)) {
4581 city_queue_insert(pw_city, -1, target);
4582 break;
4583 }
4585 worklist_insert(&queue, target, curr_selection);
4586 city_set_queue(pw_city, &queue);
4587 break;
4588
4589 case 4: /* Add last */
4590 city_queue_insert(pw_city, -1, target);
4591 break;
4592
4593 default:
4594 break;
4595 }
4596 }
4597 close();
4598 destroy();
4599}
4600
4601/************************************************************************/
4605{
4606 delete c_p_d;
4607 delete list_model;
4608 viewport()->removeEventFilter(fc_tt);
4609 removeEventFilter(this);
4610}
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:964
#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:3751
void qtg_real_city_dialog_refresh(struct city *pcity)
Definition citydlg.cpp:3771
QString split_text(QString text, bool cut)
Definition optiondlg.cpp:62
void city_font_update()
Definition citydlg.cpp:3785
bool qtg_city_dialog_is_open(struct city *pcity)
Definition citydlg.cpp:3826
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4022
void qtg_popdown_all_city_dialogs()
Definition citydlg.cpp:3763
static city_dialog * city_dlg
Definition citydlg.cpp:74
void qtg_refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.cpp:3810
static QString bold(QString text)
Definition citydlg.cpp:3887
void qtg_real_city_dialog_popup(struct city *pcity)
Definition citydlg.cpp:3723
QString get_tooltip_improvement(const impr_type *building, struct city *pcity, bool ext)
Definition citydlg.cpp:3896
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:3953
void destroy_city_dialog()
Definition citydlg.cpp:3738
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:4059
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4072
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition citydlg.cpp:4227
struct city * pcity
Definition citydlg.h:318
void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
Definition citydlg.cpp:4210
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:4277
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:4396
int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition citydlg.h:360
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition citydlg.cpp:4302
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:3842
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:4261
production_item(struct universal *ptarget, QObject *parent)
Definition citydlg.cpp:4240
bool eventFilter(QObject *obj, QEvent *ev)
Definition citydlg.cpp:4506
void prod_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:4531
void mousePressEvent(QMouseEvent *event)
Definition citydlg.cpp:4493
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:4419
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:3896
QString get_tooltip(QVariant qvar)
Definition citydlg.cpp:4022
void set_theme_style()
Definition themes.cpp:107
#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:4894
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1374
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype)
Definition helpdata.c:1823
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:1005
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:3166
int current_building
Definition citydlg.h:506
void worklist_up()
Definition citydlg.cpp:3593
city_label * citizens_label
Definition citydlg.h:451
QPushButton * lcity_name
Definition citydlg.h:492
void show_happiness()
Definition citydlg.cpp:2131
void closeEvent(QCloseEvent *event)
Definition citydlg.cpp:2279
void update_nation_table()
Definition citydlg.cpp:2968
void hideEvent(QHideEvent *event)
Definition citydlg.cpp:2251
QPushButton * work_next_but
Definition citydlg.h:481
void next_city()
Definition citydlg.cpp:3275
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:2262
QPushButton * happiness_button
Definition citydlg.h:485
void cma_double_clicked(int row, int column)
Definition citydlg.cpp:2455
void display_worklist_menu(const QPoint &p)
Definition citydlg.cpp:2727
void update_disabled()
Definition citydlg.cpp:2160
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:2827
int selected_row_p
Definition citydlg.h:493
QHBoxLayout * leftbot_layout
Definition citydlg.h:446
void update_building()
Definition citydlg.cpp:3345
QPushButton * zoom_in_button
Definition citydlg.h:486
void save_worklist()
Definition citydlg.cpp:3659
void worklist_del()
Definition citydlg.cpp:3618
QGridLayout * info_grid_layout
Definition citydlg.h:453
void clear_worklist()
Definition citydlg.cpp:3578
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:2370
void zoom_in()
Definition citydlg.cpp:2357
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:3045
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:2686
void update_citizens()
Definition citydlg.cpp:2852
QRadioButton * r1
Definition citydlg.h:475
void cma_slider(int val)
Definition citydlg.cpp:2661
QCheckBox * cma_celeb_checkbox
Definition citydlg.h:469
QCheckBox * show_units
Definition citydlg.h:472
void worklist_down()
Definition citydlg.cpp:3635
void update_title()
Definition citydlg.cpp:3690
QLabel * cma_info_text
Definition citydlg.h:459
void dbl_click_p(QTableWidgetItem *item)
Definition citydlg.cpp:3182
QPushButton * cma_enable_but
Definition citydlg.h:478
QLabel * cma_result
Definition citydlg.h:460
void cma_remove()
Definition citydlg.cpp:2623
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:2290
QSplitter * prod_unit_splitter
Definition citydlg.h:443
QVBoxLayout * left_layout
Definition citydlg.h:449
void prev_city()
Definition citydlg.cpp:3310
void city_rename()
Definition citydlg.cpp:2327
void refresh()
Definition citydlg.cpp:2936
void update_cma_tab()
Definition citydlg.cpp:2556
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:2650
void show_targets()
Definition citydlg.cpp:3547
QPushButton * buy_button
Definition citydlg.h:477
QWidget * top_widget
Definition citydlg.h:448
void update_happiness_button()
Definition citydlg.cpp:2119
QPushButton * prev_city_but
Definition citydlg.h:480
void cma_enable()
Definition citydlg.cpp:2419
QLabel * cma_result_pix
Definition citydlg.h:461
struct city * dlgcity
Definition citydlg.h:501
void update_sliders()
Definition citydlg.cpp:2504
void update_improvements()
Definition citydlg.cpp:3413
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:2074
void cma_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:2474
QCheckBox * cma_max_growth
Definition citydlg.h:470
void item_selected(const QItemSelection &sl, const QItemSelection &ds)
Definition citydlg.cpp:3257
void show_targets_worklist()
Definition citydlg.cpp:3563
QCheckBox * show_wonders
Definition citydlg.h:474
void cma_context_menu(const QPoint &p)
Definition citydlg.cpp:2707
void cma_changed()
Definition citydlg.cpp:2434
QRadioButton * r4
Definition citydlg.h:475
void update_units()
Definition citydlg.cpp:3199
QRadioButton * r2
Definition citydlg.h:475
QTableWidget * p_table_p
Definition citydlg.h:466
void save_cma()
Definition citydlg.cpp:2383
QPixmap * citizen_pixmap
Definition citydlg.h:488
void production_changed(int index)
Definition citydlg.cpp:3529
void update_prod_buttons()
Definition citydlg.cpp:2198
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:113
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:6495
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:6517
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:6675
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:6438
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6468
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6486
@ 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:468
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:336
#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