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 #ifndef FC__CITYDLG_H
14 #define FC__CITYDLG_H
15 
16 #ifdef HAVE_CONFIG_H
17 #include <fc_config.h>
18 #endif
19 
20 // Qt
21 #include <QElapsedTimer>
22 #include <QItemDelegate>
23 #include <QLabel>
24 #include <QProgressBar>
25 #include <QTableView>
26 #include <QtMath>
27 #include <QVariant>
28 
29 // common
30 #include "unittype.h"
31 
32 // client
33 #include "canvas.h"
34 
35 // gui-qt
36 #include "fonts.h"
37 #include "dialogs.h"
38 
39 class QCheckBox;
40 class QComboBox;
41 class QGridLayout;
42 class QGroupBox;
43 class QHBoxLayout;
44 class QPushButton;
45 class QRadioButton;
46 class QSplitter;
47 class QTableWidget;
48 class QVBoxLayout;
49 
50 #define SPECENUM_NAME city_info
51 
52 #define SPECENUM_VALUE0 INFO_CITIZEN
53 #define SPECENUM_VALUE0NAME N_("Size:")
54 #define SPECENUM_VALUE1 INFO_FOOD
55 #define SPECENUM_VALUE1NAME N_("Food:")
56 #define SPECENUM_VALUE2 INFO_SHIELD
57 #define SPECENUM_VALUE2NAME N_("Prod:")
58 #define SPECENUM_VALUE3 INFO_TRADE
59 #define SPECENUM_VALUE3NAME N_("Trade:")
60 #define SPECENUM_VALUE4 INFO_GOLD
61 #define SPECENUM_VALUE4NAME N_("Gold:")
62 #define SPECENUM_VALUE5 INFO_LUXURY
63 #define SPECENUM_VALUE5NAME N_("Luxury:")
64 #define SPECENUM_VALUE6 INFO_SCIENCE
65 #define SPECENUM_VALUE6NAME N_("Science:")
66 #define SPECENUM_VALUE7 INFO_GRANARY
67 #define SPECENUM_VALUE7NAME N_("Granary:")
68 #define SPECENUM_VALUE8 INFO_GROWTH
69 #define SPECENUM_VALUE8NAME N_("Change in:")
70 #define SPECENUM_VALUE9 INFO_CORRUPTION
71 #define SPECENUM_VALUE9NAME N_("Corruption:")
72 #define SPECENUM_VALUE10 INFO_WASTE
73 #define SPECENUM_VALUE10NAME N_("Waste:")
74 #define SPECENUM_VALUE11 INFO_CULTURE
75 #define SPECENUM_VALUE11NAME N_("Culture:")
76 #define SPECENUM_VALUE12 INFO_POLLUTION
77 #define SPECENUM_VALUE12NAME N_("Pollution:")
78 #define SPECENUM_VALUE13 INFO_ILLNESS
79 #define SPECENUM_VALUE13NAME N_("Plague risk:")
80 #define SPECENUM_VALUE14 INFO_AIRLIFT
81 #define SPECENUM_VALUE14NAME N_("Airlift:")
82 
83 #define SPECENUM_COUNT    NUM_INFO_FIELDS /* number of city_info panel enumerated fields */
84 #include "specenum_gen.h"
85 
86 class QImage;
87 
88 QString get_tooltip(QVariant qvar);
89 QString get_tooltip_improvement(impr_type *building,
90                                 struct city *pcity = nullptr,
91                                 bool ext = false);
92 QString get_tooltip_unit(struct unit_type *unit, bool ext = false);
93 QString bold(QString text);
94 
95 class fc_tooltip : public QObject
96 {
97   Q_OBJECT
98 public:
QObject(parent)99   explicit fc_tooltip(QObject *parent = NULL): QObject(parent) {}
100 
101 protected:
102   bool eventFilter(QObject *obj, QEvent *event);
103 };
104 
105 
106 /****************************************************************************
107   Custom progressbar with animated progress and right click event
108 ****************************************************************************/
109 class progress_bar: public QProgressBar
110 {
111   Q_OBJECT
112   QElapsedTimer m_timer;
113 signals:
114   void clicked();
115 
116 public:
117   progress_bar(QWidget *parent);
118   ~progress_bar();
mousePressEvent(QMouseEvent * event)119   void mousePressEvent(QMouseEvent *event) {
120     emit clicked();
121   }
122   void set_pixmap(struct universal *target);
123   void set_pixmap(int n);
124 
125 protected:
126   void paintEvent(QPaintEvent *event);
127   void timerEvent(QTimerEvent *event);
128   void resizeEvent(QResizeEvent *event);
129 private:
130   void create_region();
131   int m_animate_step;
132   QPixmap *pix;
133   QRegion reg;
134   QFont *sfont;
135 };
136 
137 /****************************************************************************
138   Single item on unit_info in city dialog representing one unit
139 ****************************************************************************/
140 class unit_item: public QLabel
141 {
142   Q_OBJECT
143   QAction *disband_action;
144   QAction *change_home;
145   QAction *activate;
146   QAction *activate_and_close;
147   QAction *sentry;
148   QAction *fortify;
149   QAction *load;
150   QAction *unload;
151   QAction *upgrade;
152   QAction *unload_trans;
153   QMenu *unit_menu;
154 
155 public:
156   unit_item(QWidget *parent ,struct unit *punit, bool supp = false, int happy_cost = 0);
157   ~unit_item();
158   void init_pix();
159 
160 private:
161   struct unit *qunit;
162   QImage unit_img;
163   void contextMenuEvent(QContextMenuEvent *ev);
164   void create_actions();
165   int happy_cost;
166   bool supported;
167 
168 private slots:
169   void disband();
170   void change_homecity();
171   void activate_unit();
172   void activate_and_close_dialog();
173   void sentry_unit();
174   void fortify_unit();
175   void upgrade_unit();
176   void load_unit();
177   void unload_unit();
178   void unload_all();
179 
180 protected:
181   void wheelEvent(QWheelEvent *event);
182   void mousePressEvent(QMouseEvent *event);
183   void leaveEvent(QEvent *event);
184   void enterEvent(QEvent *event);
185 };
186 
187 /****************************************************************************
188   Shows list of units ( as labels - unit_info )
189 ****************************************************************************/
190 class unit_info: public QFrame
191 {
192 
193   Q_OBJECT
194 
195 public:
196   unit_info(bool supp);
197   ~unit_info();
198   void add_item(unit_item *item);
199   void init_layout();
200   void update_units();
201   void clear_layout();
202   QHBoxLayout *layout;
203   QList<unit_item *> unit_list;
204 
205 private:
206   bool supports;
207 protected:
208   void wheelEvent(QWheelEvent *event);
209 };
210 
211 
212 /****************************************************************************
213   Single item on unit_info in city dialog representing one unit
214 ****************************************************************************/
215 class impr_item: public QLabel
216 {
217   Q_OBJECT
218 
219 public:
220   impr_item(QWidget *parent ,struct impr_type *building, struct city *pcity);
221   ~impr_item();
222   void init_pix();
223 
224 private:
225   struct impr_type *impr;
226   struct canvas *impr_pixmap;
227   struct city *pcity;
228 
229 protected:
230   void wheelEvent(QWheelEvent *event);
231   void mouseDoubleClickEvent(QMouseEvent *event);
232   void leaveEvent(QEvent *event);
233   void enterEvent(QEvent *event);
234 };
235 
236 
237 /****************************************************************************
238   Shows list of improvemrnts
239 ****************************************************************************/
240 class impr_info: public QFrame
241 {
242   Q_OBJECT
243 public:
244   impr_info(QWidget *parent);
245   ~impr_info();
246   void add_item(impr_item *item);
247   void init_layout();
248   void update_buildings();
249   void clear_layout();
250   QHBoxLayout *layout;
251   QList<impr_item *> impr_list;
252 protected:
253   void wheelEvent(QWheelEvent *event);
254 };
255 
256 /****************************************************************************
257   Class used for showing tiles and workers view in city dialog
258 ****************************************************************************/
259 class city_map: public QWidget
260 {
261 
262   Q_OBJECT
263   canvas *view;
264   canvas *miniview;
265   QPixmap zoomed_pixmap;
266 
267 public:
268   city_map(QWidget *parent);
269   ~city_map();
270   void set_pixmap(struct city *pcity, float z);
271 private:
272   void mousePressEvent(QMouseEvent *event);
273   void paintEvent(QPaintEvent *event);
274   struct city *mcity;
275   int radius;
276   float zoom;
277   int wdth;
278   int hight;
279   int cutted_width;
280   int cutted_height;
281   int delta_x;
282   int delta_y;
283 protected:
284   QSize sizeHint() const;
285   QSize minimumSizeHint() const;
286 private slots:
287   void context_menu(QPoint point);
288 };
289 
290 /****************************************************************************
291   Item delegate for production popup
292 ****************************************************************************/
293 class city_production_delegate: public QItemDelegate
294 {
295   Q_OBJECT
296 
297 public:
298   city_production_delegate(QPoint sh, QObject *parent, struct city *city);
~city_production_delegate()299   ~city_production_delegate() {}
300   void paint(QPainter *painter, const QStyleOptionViewItem &option,
301              const QModelIndex &index) const;
302   QSize sizeHint(const QStyleOptionViewItem &option,
303                  const QModelIndex &index) const;
304 
305 private:
306   int item_height;
307   QPoint pd;
308   struct city *pcity;
309 
310 protected:
311   void drawFocus(QPainter *painter, const QStyleOptionViewItem &option,
312                  const QRect &rect) const;
313 };
314 
315 /****************************************************************************
316   Single item in production popup
317 ****************************************************************************/
318 class production_item: public QObject
319 {
320   Q_OBJECT
321 
322 public:
323   production_item(struct universal *ptarget, QObject *parent);
324   ~production_item();
columnCount()325   inline int columnCount() const {
326     return 1;
327   }
328   QVariant data() const;
329   bool setData();
330 
331 private:
332   struct universal *target;
333 };
334 
335 /***************************************************************************
336   City production model
337 ***************************************************************************/
338 class city_production_model : public QAbstractListModel
339 {
340   Q_OBJECT
341 
342 public:
343   city_production_model(struct city *pcity, bool f, bool su, bool sw, bool sb,
344                         QObject *parent = 0);
345   ~city_production_model();
346   inline int rowCount(const QModelIndex &index = QModelIndex()) const {
347     Q_UNUSED(index);
348     return (qCeil(static_cast<float>(city_target_list.size()) / 3));
349   }
350   int columnCount(const QModelIndex &parent = QModelIndex()) const {
351     Q_UNUSED(parent);
352     return 3;
353   }
354   QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
355   bool setData(const QModelIndex &index, const QVariant &value,
356                int role = Qt::DisplayRole);
357   QPoint size_hint();
358   void populate();
359   QPoint sh;
360 
361 private:
362   QList<production_item *> city_target_list;
363   struct city *mcity;
364   bool future_t;
365   bool show_units;
366   bool show_buildings;
367   bool show_wonders;
368 };
369 
370 /****************************************************************************
371   Class for popup avaialable production
372 ****************************************************************************/
373 class production_widget: public QTableView
374 {
375   Q_OBJECT
376 
377   city_production_model *list_model;
378   city_production_delegate *c_p_d;
379 
380 public:
381   production_widget(QWidget *parent, struct city *pcity, bool future,
382                     int when, int curr, bool show_units, bool buy = false,
383                     bool show_wonders = true, bool show_buildings = true);
384   ~production_widget();
385 
386 public slots:
387   void prod_selected(const QItemSelection &sl, const QItemSelection &ds);
388 
389 protected:
390   void mousePressEvent(QMouseEvent *event);
391   bool eventFilter(QObject *obj, QEvent *ev);
392 
393 private:
394   struct city *pw_city;
395   int when_change;
396   int curr_selection;
397   bool sh_units;
398   bool buy_it;
399   fc_tooltip *fc_tt;
400 };
401 
402 
403 /****************************************************************************
404   city_label is used only for showing citizens icons
405   and was created to catch mouse events
406 ****************************************************************************/
407 class city_label: public QLabel
408 {
409   Q_OBJECT
410 
411 public:
412   city_label(int type, QWidget *parent = 0);
413   void set_city(struct city *pcity);
414 
415 private:
416   struct city *pcity;
417   int type;
418 
419 protected:
420   void mousePressEvent(QMouseEvent *event);
421 };
422 
423 /****************************************************************************
424   City dialog
425 ****************************************************************************/
426 class city_dialog: public qfc_dialog
427 {
428 
429   Q_OBJECT
430 
431   bool happines_shown;
432   QHBoxLayout *single_page_layout;
433   QHBoxLayout *happiness_layout;
434   QSplitter *prod_unit_splitter;
435   QSplitter *central_left_splitter;
436   QSplitter *central_splitter;
437   QHBoxLayout *leftbot_layout;
438   QWidget *prod_happ_widget;
439   QWidget *top_widget;
440   QVBoxLayout *left_layout;
441   city_map *view;
442   city_label *citizens_label;
443   city_label *lab_table[6];
444   QGridLayout *info_grid_layout;
445   QGroupBox *info_labels_group;
446   QGroupBox *happiness_group;
447   QWidget *happiness_widget;
448   QWidget *info_widget;
449   QLabel *qlt[NUM_INFO_FIELDS];
450   QLabel *cma_info_text;
451   QLabel *cma_result;
452   QLabel *cma_result_pix;
453   QLabel *supp_units;
454   QLabel *curr_units;
455   QLabel *curr_impr;
456   progress_bar *production_combo_p;
457   QTableWidget *p_table_p;
458   QTableWidget *nationality_table;
459   QTableWidget *cma_table;
460   QCheckBox *cma_celeb_checkbox;
461   QCheckBox *future_targets;
462   QCheckBox *show_units;
463   QCheckBox *show_buildings;
464   QCheckBox *show_wonders;
465   QRadioButton *r1, *r2, *r3, *r4;
466   QPushButton *button;
467   QPushButton *buy_button;
468   QPushButton *cma_enable_but;
469   QPushButton *next_city_but;
470   QPushButton *prev_city_but;
471   QPushButton *work_next_but;
472   QPushButton *work_prev_but;
473   QPushButton *work_add_but;
474   QPushButton *work_rem_but;
475   QPushButton *but_menu_worklist;
476   QPushButton *happiness_button;
477   QPushButton *zoom_in_button;
478   QPushButton *zoom_out_button;
479   QPixmap *citizen_pixmap;
480   unit_info *current_units;
481   unit_info *supported_units;
482   impr_info *city_buildings;
483   QPushButton *lcity_name;
484   int selected_row_p;
485   QSlider *slider_tab[2 * O_LAST + 2];
486 
487 public:
488   city_dialog(QWidget *parent = 0);
489   ~city_dialog();
490   void setup_ui(struct city *qcity);
491   void refresh();
492   struct city *pcity;
493   int scroll_height;
494   float zoom;
495 
496 private:
497   int current_building;
498   void update_title();
499   void update_building();
500   void update_info_label();
501   void update_buy_button();
502   void update_citizens();
503   void update_improvements();
504   void update_units();
505   void update_nation_table();
506   void update_cma_tab();
507   void update_disabled();
508   void update_sliders();
509   void update_prod_buttons();
510   void update_happiness_button();
511   void change_production(bool next);
512 
513 private slots:
514   void next_city();
515   void prev_city();
516   void production_changed(int index);
517   void show_targets();
518   void show_targets_worklist();
519   void show_happiness();
520   void buy();
521   void dbl_click_p(QTableWidgetItem *item);
522   void delete_prod();
523   void item_selected(const QItemSelection &sl, const QItemSelection &ds);
524   void clear_worklist();
525   void save_worklist();
526   void worklist_up();
527   void worklist_down();
528   void worklist_del();
529   void display_worklist_menu(const QPoint &p);
530   void disband_state_changed(int state);
531   void cma_slider(int val);
532   void cma_celebrate_changed(int val);
533   void cma_remove();
534   void cma_enable();
535   void cma_changed();
536   void cma_selected(const QItemSelection &sl, const QItemSelection &ds);
537   void cma_double_clicked(int row, int column);
538   void cma_context_menu(const QPoint &p);
539   void save_cma();
540   void city_rename();
541   void zoom_in();
542   void zoom_out();
543 protected:
544   void showEvent(QShowEvent *event);
545   void hideEvent(QHideEvent *event);
546   void closeEvent(QCloseEvent *event);
547   bool eventFilter(QObject *obj, QEvent *event);
548 };
549 
550 void destroy_city_dialog();
551 void city_font_update();
552 
553 #endif                          /* FC__CITYDLG_H */
554