Freeciv21
Develop your civilization from humble roots to a global empire
gotodlg.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can redistribute it
4  and/or modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation, either version 3 of the
6  License, or (at your option) any later version. You should have received
7  a copy of the GNU General Public License along with Freeciv21. If not,
8  see https://www.gnu.org/licenses/.
9  */
10 
11 #include "gotodlg.h"
12 // Qt
13 #include <QApplication>
14 #include <QCheckBox>
15 #include <QHBoxLayout>
16 #include <QHeaderView>
17 #include <QLabel>
18 #include <QPainter>
19 #include <QPushButton>
20 #include <QTableWidget>
21 // common
22 #include "game.h"
23 #include "nation.h"
24 // client
25 #include "client_main.h"
26 #include "control.h"
27 #include "fc_client.h"
28 #include "goto.h"
29 #include "page_game.h"
30 #include "text.h"
31 #include "tileset/sprite.h"
32 #include "views/view_map.h"
33 #include "views/view_map_common.h"
34 
38 goto_dialog::goto_dialog(QWidget *parent)
39 {
40  QStringList headers_lst;
41  QHBoxLayout *hb;
42 
43  setParent(parent);
44  headers_lst << QString(_("City")) << QString(_("Nation"))
45  << QString(_("Airlift"));
46  goto_tab = new QTableWidget;
47  goto_city = new QPushButton(_("&Goto"));
48  airlift_city = new QPushButton(_("&Airlift"));
49  close_but = new QPushButton(_("&Close"));
50  layout = new QGridLayout;
51 
52  show_all = new QCheckBox;
53  show_all->setChecked(false);
54  show_all_label = new QLabel(_("Show All Cities"));
55  show_all_label->setAlignment(Qt::AlignLeft);
56  hb = new QHBoxLayout;
57  hb->addWidget(show_all);
58  hb->addWidget(show_all_label, Qt::AlignLeft);
59 
60  goto_tab->setProperty("showGrid", "false");
61  goto_tab->setSelectionBehavior(QAbstractItemView::SelectRows);
62  goto_tab->setEditTriggers(QAbstractItemView::NoEditTriggers);
63  goto_tab->verticalHeader()->setVisible(false);
64  goto_tab->horizontalHeader()->setVisible(true);
65  goto_tab->setSelectionMode(QAbstractItemView::SingleSelection);
66  goto_tab->setColumnCount(3);
67  goto_tab->setHorizontalHeaderLabels(headers_lst);
68  goto_tab->setSortingEnabled(true);
69  goto_tab->horizontalHeader()->setSectionResizeMode(
70  QHeaderView::ResizeToContents);
71 
72  layout->addWidget(goto_tab, 0, 0, 4, 4);
73  layout->addItem(hb, 4, 0, 1, 2);
74  layout->addWidget(goto_city, 5, 0, 1, 1);
75  layout->addWidget(airlift_city, 5, 1, 1, 1);
76  layout->addWidget(close_but, 5, 3, 1, 1);
77 
78  setFixedWidth(goto_tab->horizontalHeader()->width());
79  connect(close_but, &QAbstractButton::clicked, this,
81  connect(goto_city, &QAbstractButton::clicked, this,
83  connect(airlift_city, &QAbstractButton::clicked, this,
85  connect(show_all, &QCheckBox::stateChanged, this,
87  connect(goto_tab->selectionModel(), &QItemSelectionModel::selectionChanged,
89 
90  setLayout(layout);
91  original_tile = nullptr;
92  setFocus();
93 }
94 
99 {
100  if (original_tile) {
102  }
104 }
105 
110 {
111  if (original_tile) {
113  }
114 }
115 
120 {
121  Q_UNUSED(state);
122  update_dlg();
123 }
124 
128 void goto_dialog::item_selected(const QItemSelection &sl,
129  const QItemSelection &ds)
130 {
131  Q_UNUSED(ds)
132  int i;
133  int city_id;
134  QModelIndex index;
135  QModelIndexList indexes = sl.indexes();
136  QTableWidgetItem *item;
137  struct city *dest;
138  bool can_airlift;
139 
140  if (indexes.isEmpty()) {
141  return;
142  }
143  index = indexes.at(0);
144  i = index.row();
145  item = goto_tab->item(i, 0);
146  city_id = item->data(Qt::UserRole).toInt();
147  dest = game_city_by_number(city_id);
149  can_airlift = false;
150  for (const auto punit : get_units_in_focus()) {
151  if (unit_can_airlift_to(punit, dest)) {
152  can_airlift = true;
153  break;
154  }
155  }
156 
157  if (can_airlift) {
158  airlift_city->setEnabled(true);
159  } else {
160  airlift_city->setDisabled(true);
161  }
162 }
163 
168 {
169  goto_tab->sortByColumn(0, Qt::AscendingOrder);
170 }
171 
176 {
177  QPoint p, final_p;
178  p = QCursor::pos();
179  p = parentWidget()->mapFromGlobal(p);
180  final_p.setX(p.x());
181  final_p.setY(p.y());
182  if (p.x() + width() > parentWidget()->width()) {
183  final_p.setX(parentWidget()->width() - width());
184  }
185  if (p.y() - height() < 0) {
186  final_p.setY(height());
187  }
188  move(final_p.x(), final_p.y() - height());
189  show();
190 }
191 
196 {
197  goto_tab->clearContents();
198  goto_tab->setRowCount(0);
199  goto_tab->setSortingEnabled(false);
200  if (show_all->isChecked()) {
201  players_iterate(pplayer) { fill_tab(pplayer); }
203  } else {
205  }
206  goto_tab->setSortingEnabled(true);
207  goto_tab->horizontalHeader()->setStretchLastSection(false);
208  goto_tab->resizeRowsToContents();
209  goto_tab->horizontalHeader()->setStretchLastSection(true);
210 }
211 
216 {
217  int i;
218 
219  QString str;
220  QFont f = QApplication::font();
221  QFontMetrics fm(f);
222  int h;
223  QTableWidgetItem *item;
224 
225  h = fm.height() + 6;
226  i = goto_tab->rowCount();
227  city_list_iterate(pplayer->cities, pcity)
228  {
229  goto_tab->insertRow(i);
230  for (int j = 0; j < 3; j++) {
231  item = new QTableWidgetItem;
232  switch (j) {
233  case 0:
234  str = city_name_get(pcity);
235  break;
236  case 1: {
237  auto sprite =
239  if (sprite != nullptr) {
240  item->setData(Qt::DecorationRole, sprite->scaledToHeight(h));
241  }
243  } break;
244  case 2:
245  str = get_airlift_text(get_units_in_focus(), pcity);
246  if (str.isEmpty()) {
247  str = QStringLiteral("-");
248  }
249  item->setTextAlignment(Qt::AlignHCenter);
250  break;
251  }
252  item->setText(str);
253  item->setData(Qt::UserRole, pcity->id);
254  goto_tab->setItem(i, j, item);
255  }
256  i++;
257  }
259 }
260 
265 {
266  struct city *pdest;
267 
268  if (goto_tab->currentRow() == -1) {
269  return;
270  }
271  pdest = game_city_by_number(
272  goto_tab->item(goto_tab->currentRow(), 0)->data(Qt::UserRole).toInt());
273  if (pdest) {
274  for (const auto punit : get_units_in_focus()) {
275  if (unit_can_airlift_to(punit, pdest)) {
276  request_unit_airlift(punit, pdest);
277  }
278  }
279  }
280 }
281 
286 {
287  struct city *pdest;
288 
289  if (goto_tab->currentRow() == -1) {
290  return;
291  }
292 
293  pdest = game_city_by_number(
294  goto_tab->item(goto_tab->currentRow(), 0)->data(Qt::UserRole).toInt());
295  if (pdest) {
296  for (const auto punit : get_units_in_focus()) {
297  send_goto_tile(punit, pdest->tile);
298  }
299  }
300 }
301 
306 {
308  hide();
309 }
310 
314 void goto_dialog::paint(QPainter *painter, QPaintEvent *event)
315 {
316  Q_UNUSED(event)
317  painter->setBrush(QColor(0, 0, 30, 85));
318  painter->drawRect(0, 0, width(), height());
319  painter->setBrush(QColor(0, 0, 0, 85));
320  painter->drawRect(5, 5, width() - 10, height() - 10);
321 }
322 
326 void goto_dialog::paintEvent(QPaintEvent *event)
327 {
328  QPainter painter;
329 
330  painter.begin(this);
331  paint(&painter, event);
332  painter.end();
333 }
334 
335 /*
336  Popup a dialog to have the focus unit goto to a city.
337  */
339 {
340  if (C_S_RUNNING != client_state()) {
341  return;
342  }
343  if (get_num_units_in_focus() == 0) {
344  return;
345  }
346  if (!client_has_player()) {
347  return;
348  }
349 
350  if (queen()->gtd != nullptr) {
351  queen()->gtd->init();
352  queen()->gtd->update_dlg();
353  queen()->gtd->sort_def();
354  queen()->gtd->show_me();
355  }
356 }
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_list_iterate_end
Definition: city.h:484
void sort_def()
Sorts dialog by default column (0)
Definition: gotodlg.cpp:167
QPushButton * close_but
Definition: gotodlg.h:32
void go_to_city()
Slot for goto for city.
Definition: gotodlg.cpp:285
QPushButton * goto_city
Definition: gotodlg.h:30
void update_dlg()
Updates table in widget.
Definition: gotodlg.cpp:195
void init()
Sets variables which must be destroyed later.
Definition: gotodlg.cpp:98
void close_dlg()
Slot for hiding dialog.
Definition: gotodlg.cpp:305
struct tile * original_tile
Definition: gotodlg.h:58
QCheckBox * show_all
Definition: gotodlg.h:33
~goto_dialog() override
Destructor for goto dialog.
Definition: gotodlg.cpp:109
goto_dialog(QWidget *parent=0)
Constructor for goto_dialog.
Definition: gotodlg.cpp:38
void checkbox_changed(int state)
Slot for checkbox 'all nations'.
Definition: gotodlg.cpp:119
QLabel * show_all_label
Definition: gotodlg.h:35
QTableWidget * goto_tab
Definition: gotodlg.h:29
void paint(QPainter *painter, QPaintEvent *event)
Paints rectangles for goto_dialog.
Definition: gotodlg.cpp:314
QPushButton * airlift_city
Definition: gotodlg.h:31
void airlift_to()
Slot for airlifting unit.
Definition: gotodlg.cpp:264
void show_me()
Shows and moves widget.
Definition: gotodlg.cpp:175
void paintEvent(QPaintEvent *event) override
Paint event for goto_dialog.
Definition: gotodlg.cpp:326
void item_selected(const QItemSelection &sl, const QItemSelection &ds)
User has chosen some city on table.
Definition: gotodlg.cpp:128
QGridLayout * layout
Definition: gotodlg.h:34
void fill_tab(struct player *pplayer)
Helper for function for filling table.
Definition: gotodlg.cpp:215
void center_on_tile(tile *tile, bool animate=true)
Centers the view on a tile.
Definition: view_map.cpp:197
map_view * mapview_wdg
Definition: page_game.h:81
goto_dialog * gtd
Definition: page_game.h:74
enum client_states client_state()
Return current client state.
bool client_has_player()
Either controlling or observing.
struct player * client_player()
Either controlling or observing.
@ C_S_RUNNING
Definition: client_main.h:43
void request_unit_airlift(struct unit *punit, struct city *pcity)
Send unit airlift request to server.
Definition: control.cpp:1397
std::vector< unit * > & get_units_in_focus()
Returns list of units currently in focus.
Definition: control.cpp:169
int get_num_units_in_focus()
Return the number of units currently in focus (0 or more).
Definition: control.cpp:174
enum event_type event
Definition: events.cpp:68
#define _(String)
Definition: fcintl.h:50
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
bool send_goto_tile(struct unit *punit, struct tile *ptile)
Send orders for the unit to move it to the arbitrary tile.
Definition: goto.cpp:630
void popup_goto_dialog(void)
Definition: gotodlg.cpp:338
const char * nation_adjective_translation(const struct nation_type *pnation)
Return the (translated) adjective for the given nation.
Definition: nation.cpp:126
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
Definition: nation.cpp:419
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
Definition: city.h:291
struct tile * tile
Definition: city.h:293
Definition: climisc.h:66
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
const QString get_airlift_text(const std::vector< unit * > &units, const struct city *pdest)
Describe the airlift capacity of a city for the given units (from their current positions).
Definition: text.cpp:612
void tile_virtual_destroy(struct tile *vtile)
Frees all memory used by the virtual tile, including freeing virtual units in the tile's unit list an...
Definition: tile.cpp:1051
struct tile * tile_virtual_new(const struct tile *ptile)
Returns a virtual tile.
Definition: tile.cpp:997
const QPixmap * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Return the sprite for the nation.
Definition: tilespec.cpp:3367
bool unit_can_airlift_to(const struct unit *punit, const struct city *pdest_city)
Determines if punit can be airlifted to dest_city now! So punit needs to be in a city now.
Definition: unit.cpp:179
struct tile * get_center_tile_mapcanvas()
Finds the current center tile of the mapcanvas.