Freeciv-3.2: /fast/freeciv/nightly/S3_2/client/gui-qt/pages.cpp Source File

Freeciv-3.2

Loading...
Searching...
No Matches
pages.cpp
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996-2004 - The Freeciv Team
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 <QAction>
20#include <QApplication>
21#include <QCheckBox>
22#include <QDateTime>
23#include <QFileDialog>
24#include <QGridLayout>
25#include <QHeaderView>
26#include <QLineEdit>
27#include <QPainter>
28#include <QSplitter>
29#include <QStackedWidget>
30#include <QTableWidget>
31#include <QTextEdit>
32#include <QTreeWidget>
33
34// common
35#include "game.h"
36#include "rgbcolor.h"
37#include "version.h"
38
39// client
40#include "client_main.h"
41#include "connectdlg_common.h"
42
43// gui-qt
44#include "colors.h"
45#include "dialogs.h"
46#include "fc_client.h"
47#include "pages.h"
48#include "plrdlg.h"
49#include "qtg_cxxside.h"
50#include "sidebar.h"
51#include "sprite.h"
52#include "voteinfo_bar.h"
53
54extern "C" {
55#include "repodlgs_g.h"
56#include "cityrep_g.h"
57const char *science_dialog_text(void);
58const char *get_bulb_tooltip(void);
59const char *get_global_warming_tooltip(void);
60const char *get_nuclear_winter_tooltip(void);
61const char *get_government_tooltip(void);
62const char *get_info_label_text_popup(void);
63const char *get_info_label_text(bool);
64const char *text_happiness_cities(const struct city *pcity);
65}
66
67 int last_center_capital = 0;
68 int last_center_player_city = 0;
69 int last_center_enemy_city = 0;
70extern void toggle_units_report(bool);
71extern void popup_shortcuts_dialog();
72static void center_next_enemy_city();
73static void center_next_player_city();
74static void center_next_player_capital();
75 static struct server_scan *meta_scan, *lan_scan;
76 static bool holding_srv_list_mutex = false;
77 static enum connection_state connection_status;
78static struct terrain *char2terrain(char ch);
79static void cycle_enemy_units();
80 int last_center_enemy = 0;
81
82/**********************************************************************/
86 static struct terrain *char2terrain(char ch)
87{
88 if (ch == TERRAIN_UNKNOWN_IDENTIFIER) {
89 return T_UNKNOWN;
90 }
91 terrain_type_iterate(pterrain) {
92 if (pterrain->identifier_load == ch) {
93 return pterrain;
94 }
95 } terrain_type_iterate_end;
96 return nullptr;
97}
98
99
100/**********************************************************************/
103 void qtg_real_set_client_page(enum client_pages page)
104{
105 gui()->switch_page(page);
106}
107
108/**********************************************************************/
113 void qtg_set_rulesets(int num_rulesets, char **rulesets)
114{
115 gui()->pr_options->set_rulesets(num_rulesets, rulesets);
116}
117
118/**********************************************************************/
121 enum client_pages qtg_get_current_client_page()
122{
123 return gui()->current_page();
124}
125
126/**********************************************************************/
129 void update_start_page(void)
130{
131 gui()->update_start_page();
132}
133
134/**********************************************************************/
137 void fc_client::create_main_page(void)
138{
139 QPixmap main_graphics(tileset_main_intro_filename(tileset));
140 QLabel* free_main_pic = new QLabel;
141 QPainter painter(&main_graphics);
142 QStringList buttons_names;
143 int buttons_nr;
144 char msgbuf[128];
145 const char *rev_ver;
146 QFont f = QApplication::font();
147 QFontMetrics fm(f);
148 int row = 0;
149#if IS_BETA_VERSION || IS_DEVEL_VERSION
150 QPalette warn_color;
151 QLabel *unstable_label = new QLabel(unstable_message());
152#endif // IS_BETA_VERSION || IS_DEVEL_VERSION
153
154 pages_layout[PAGE_MAIN] = new QGridLayout;
155
156 painter.setPen(Qt::white);
157
158 rev_ver = fc_git_revision();
159
160 if (rev_ver == NULL) {
161 // TRANS: "version 3.1.0, Qt5 client"
162#ifdef FC_QT5_MODE
163 fc_snprintf(msgbuf, sizeof(msgbuf), _("%s%s, Qt5 client"),
164 word_version(), VERSION_STRING);
165#else // FC_QT5_MODE
166 fc_snprintf(msgbuf, sizeof(msgbuf), _("%s%s, Qt6 client"),
167 word_version(), VERSION_STRING);
168#endif // FC_QT5_MODE
169 } else {
170 fc_snprintf(msgbuf, sizeof(msgbuf), "%s%s",
171 word_version(), VERSION_STRING);
172 painter.drawText(10,
173 main_graphics.height() - fm.descent() - fm.height() * 2,
174 msgbuf);
175
176 // TRANS: "commit: [modified] <git commit id>"
177 fc_snprintf(msgbuf, sizeof(msgbuf), _("commit: %s"), rev_ver);
178 painter.drawText(10,
179 main_graphics.height() - fm.descent() - fm.height(),
180 msgbuf);
181
182#ifdef FC_QT5_MODE
183 strncpy(msgbuf, _("Qt5 client"), sizeof(msgbuf) - 1);
184#else // FC_QT5_MODE
185 strncpy(msgbuf, _("Qt6 client"), sizeof(msgbuf) - 1);
186#endif // FC_QT5_MODE
187 }
188
189 painter.drawText(main_graphics.width() - fm.horizontalAdvance (msgbuf)
190 -10, main_graphics.height() - fm.descent(), msgbuf);
191 free_main_pic->setPixmap(main_graphics);
192 pages_layout[PAGE_MAIN]->addWidget(free_main_pic,
193 row++, 0, 1, 2, Qt::AlignCenter);
194
195#if IS_BETA_VERSION || IS_DEVEL_VERSION
196 warn_color.setColor(QPalette::WindowText, Qt::red);
197 unstable_label->setPalette(warn_color);
198 unstable_label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum);
199 unstable_label->setAlignment(Qt::AlignCenter);
200 pages_layout[PAGE_MAIN]->addWidget(unstable_label,
201 row++, 0, 1, 2, Qt::AlignHCenter);
202#endif // IS_BETA_VERSION || IS_DEVEL_VERSION
203
204 buttons_names << _("Start new game") << _("Start scenario game")
205 << _("Load saved game") << _("Connect to network game")
206 << _("Options") << _("Quit");
207
208 buttons_nr = buttons_names.count();
209
210 for (int iter = 0; iter < buttons_nr; iter++) {
211 button = new QPushButton(buttons_names[iter]);
212
213 switch (iter) {
214 case 0:
215 pages_layout[PAGE_MAIN]->addWidget(button, row + 1, 0);
216 connect(button, &QAbstractButton::clicked, this, &fc_client::start_new_game);
217 break;
218 case 1:
219 pages_layout[PAGE_MAIN]->addWidget(button, row + 2, 0);
220 QObject::connect(button, &QPushButton::clicked, [this]() {
221 switch_page(PAGE_SCENARIO);
222 });
223 break;
224 case 2:
225 pages_layout[PAGE_MAIN]->addWidget(button, row + 3, 0);
226 QObject::connect(button, &QPushButton::clicked, [this]() {
227 switch_page(PAGE_LOAD);
228 });
229 break;
230 case 3:
231 pages_layout[PAGE_MAIN]->addWidget(button, row + 1, 1);
232 QObject::connect(button, &QPushButton::clicked, [this]() {
233 switch_page(PAGE_NETWORK);
234 });
235 break;
236 case 4:
237 pages_layout[PAGE_MAIN]->addWidget(button, row + 2, 1);
238 connect(button, &QAbstractButton::clicked, this, &fc_client::popup_client_options);
239 break;
240 case 5:
241 pages_layout[PAGE_MAIN]->addWidget(button, row + 3, 1);
242 QObject::connect(button, &QAbstractButton::clicked, this, &fc_client::quit);
243 break;
244 default:
245 break;
246 }
247 }
248}
249
250/**********************************************************************/
253 void fc_client::set_connection_state(enum connection_state state)
254{
255 switch (state) {
256 case LOGIN_TYPE:
257 set_status_bar("");
258 connect_password_edit->setText("");
259 connect_password_edit->setDisabled(true);
260 connect_confirm_password_edit->setText("");
261 connect_confirm_password_edit->setDisabled(true);
262 break;
263 case NEW_PASSWORD_TYPE:
264 connect_password_edit->setText("");
265 connect_confirm_password_edit->setText("");
266 connect_password_edit->setDisabled(false);
267 connect_confirm_password_edit->setDisabled(false);
268 connect_password_edit->setFocus(Qt::OtherFocusReason);
269 break;
270 case ENTER_PASSWORD_TYPE:
271 connect_password_edit->setText("");
272 connect_confirm_password_edit->setText("");
273 connect_password_edit->setDisabled(false);
274 connect_confirm_password_edit->setDisabled(true);
275 connect_password_edit->setFocus(Qt::OtherFocusReason);
276
277
278 break;
279 case WAITING_TYPE:
280 set_status_bar("");
281 break;
282 }
283
284 connection_status = state;
285}
286
287/**********************************************************************/
290 void fc_client::create_network_page(void)
291{
292 QHeaderView *header;
293 QLabel *connect_msg;
294 QLabel *lan_label;
295 QPushButton *network_button;
296
297 pages_layout[PAGE_NETWORK] = new QGridLayout;
298 QVBoxLayout *page_network_layout = new QVBoxLayout;
299 QGridLayout *page_network_grid_layout = new QGridLayout;
300 QHBoxLayout *page_network_lan_layout = new QHBoxLayout;
301 QHBoxLayout *page_network_wan_layout = new QHBoxLayout;
302
303 connect_host_edit = new QLineEdit;
304 connect_port_edit = new QLineEdit;
305 connect_login_edit = new QLineEdit;
306 connect_password_edit = new QLineEdit;
307 connect_confirm_password_edit = new QLineEdit;
308
309 connect_password_edit->setEchoMode(QLineEdit::Password);
310 connect_confirm_password_edit->setEchoMode(QLineEdit::Password);
311
312 connect_password_edit->setDisabled(true);
313 connect_confirm_password_edit->setDisabled(true);
314 connect_lan = new QWidget;
315 connect_metaserver = new QWidget;
316 lan_widget = new QTableWidget;
317 wan_widget = new QTableWidget;
318 info_widget = new QTableWidget;
319
320 QStringList servers_list;
321 servers_list << _("Server Name") << _("Port") << _("Version")
322 << _("Status") << Q_("?count:Players") << _("Comment");
323 QStringList server_info;
324 server_info << _("Name") << _("Type") << _("Host") << _("Nation");
325
326 lan_widget->setRowCount(0);
327 lan_widget->setColumnCount(servers_list.count());
328 lan_widget->verticalHeader()->setVisible(false);
329 lan_widget->setAutoScroll(false);
330
331 wan_widget->setRowCount(0);
332 wan_widget->setColumnCount(servers_list.count());
333 wan_widget->verticalHeader()->setVisible(false);
334 wan_widget->setAutoScroll(false);
335
336 info_widget->setRowCount(0);
337 info_widget->setColumnCount(server_info.count());
338 info_widget->verticalHeader()->setVisible(false);
339
340 lan_widget->setHorizontalHeaderLabels(servers_list);
341 lan_widget->setProperty("showGrid", "false");
342 lan_widget->setProperty("selectionBehavior", "SelectRows");
343 lan_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
344 lan_widget->setSelectionMode(QAbstractItemView::SingleSelection);
345
346 wan_widget->setHorizontalHeaderLabels(servers_list);
347 wan_widget->setProperty("showGrid", "false");
348 wan_widget->setProperty("selectionBehavior", "SelectRows");
349 wan_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
350 wan_widget->setSelectionMode(QAbstractItemView::SingleSelection);
351
352 connect(wan_widget->selectionModel(),
353 &QItemSelectionModel::selectionChanged, this,
354 &fc_client::slot_selection_changed);
355
356 connect(lan_widget->selectionModel(),
357 &QItemSelectionModel::selectionChanged, this,
358 &fc_client::slot_selection_changed);
359 connect(wan_widget, &QTableWidget::itemDoubleClicked, this,
360 &fc_client::slot_connect);
361 connect(lan_widget, &QTableWidget::itemDoubleClicked, this,
362 &fc_client::slot_connect);
363
364 info_widget->setHorizontalHeaderLabels(server_info);
365 info_widget->setProperty("selectionBehavior", "SelectRows");
366 info_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
367 info_widget->setSelectionMode(QAbstractItemView::SingleSelection);
368 info_widget->setProperty("showGrid", "false");
369 info_widget->setAlternatingRowColors(true);
370
371 header = lan_widget->horizontalHeader();
372 header->setSectionResizeMode(0, QHeaderView::Stretch);
373 header->setStretchLastSection(true);
374 header = wan_widget->horizontalHeader();
375 header->setSectionResizeMode(0, QHeaderView::Stretch);
376 header->setStretchLastSection(true);
377 header = info_widget->horizontalHeader();
378 header->setSectionResizeMode(0, QHeaderView::Stretch);
379 header->setStretchLastSection(true);
380
381 QStringList label_names;
382 label_names << _("Connect") << _("Port") << _("Login")
383 << _("Password") << _("Confirm Password");
384
385 for (int i = 0; i < label_names.count(); i++) {
386 connect_msg = new QLabel;
387 connect_msg->setText(label_names[i]);
388 page_network_grid_layout->addWidget(connect_msg, i, 0, Qt::AlignHCenter);
389 }
390
391 page_network_grid_layout->addWidget(connect_host_edit, 0, 1);
392 page_network_grid_layout->addWidget(connect_port_edit, 1, 1);
393 page_network_grid_layout->addWidget(connect_login_edit, 2, 1);
394 page_network_grid_layout->addWidget(connect_password_edit, 3, 1);
395 page_network_grid_layout->addWidget(connect_confirm_password_edit, 4, 1);
396 page_network_grid_layout->addWidget(info_widget, 0, 2, 5, 4);
397
398 network_button = new QPushButton(_("Refresh"));
399 QObject::connect(network_button, &QAbstractButton::clicked, this,
400 &fc_client::update_network_lists);
401 page_network_grid_layout->addWidget(network_button, 5, 0);
402
403 network_button = new QPushButton(_("Cancel"));
404 QObject::connect(network_button, &QPushButton::clicked, [this]() {
405 switch_page(PAGE_MAIN);
406 });
407 page_network_grid_layout->addWidget(network_button, 5, 2, 1, 1);
408
409 network_button = new QPushButton(_("Connect"));
410 page_network_grid_layout->addWidget(network_button, 5, 5, 1, 1);
411 connect(network_button, &QAbstractButton::clicked, this, &fc_client::slot_connect);
412 connect(connect_login_edit, &QLineEdit::returnPressed,
413 this, &fc_client::slot_connect);
414 connect(connect_password_edit, &QLineEdit::returnPressed,
415 this, &fc_client::slot_connect);
416 connect(connect_confirm_password_edit, &QLineEdit::returnPressed,
417 this, &fc_client::slot_connect);
418
419 connect_lan->setLayout(page_network_lan_layout);
420 connect_metaserver->setLayout(page_network_wan_layout);
421 page_network_lan_layout->addWidget(lan_widget, 0);
422 page_network_wan_layout->addWidget(wan_widget, 1);
423 lan_label = new QLabel(_("Internet servers:"));
424 page_network_layout->addWidget(lan_label, 1);
425 page_network_layout->addWidget(wan_widget, 10);
426 lan_label = new QLabel(_("Local servers:"));
427 page_network_layout->addWidget(lan_label, 1);
428 page_network_layout->addWidget(lan_widget, 1);
429 page_network_grid_layout->setColumnStretch(3, 4);
430 pages_layout[PAGE_NETWORK]->addLayout(page_network_layout, 1, 1);
431 pages_layout[PAGE_NETWORK]->addLayout(page_network_grid_layout, 2, 1);
432
433}
434
435/**********************************************************************/
438 void fc_client::set_status_bar(QString message, int timeout)
439{
440 if (status_bar_label->text().isEmpty()) {
441 status_bar_label->setText(message);
442 QTimer::singleShot(timeout, this, SLOT(clear_status_bar()));
443 } else {
444 status_bar_queue.append(message);
445 while (status_bar_queue.count() > 3) {
446 status_bar_queue.removeFirst();
447 }
448 }
449}
450
451/**********************************************************************/
454 void fc_client::clear_status_bar()
455{
456 QString str;
457
458 if (!status_bar_queue.isEmpty()) {
459 str = status_bar_queue.takeFirst();
460 status_bar_label->setText(str);
461 QTimer::singleShot(2000, this, SLOT(clear_status_bar()));
462 } else {
463 status_bar_label->setText("");
464 }
465}
466
467/**********************************************************************/
470 void fc_client::create_loading_page()
471{
472 QLabel *label = new QLabel(_("Loading..."));
473
474 pages_layout[PAGE_GAME + 1] = new QGridLayout;
475 pages_layout[PAGE_GAME + 1]->addWidget(label, 0, 0, 1, 1,
476 Qt::AlignHCenter);
477}
478
479/**********************************************************************/
482 void fc_client::create_load_page()
483{
484 pages_layout[PAGE_LOAD] = new QGridLayout;
485 QPushButton *but;
486 QHeaderView *header;
487 QLabel *lbl_show_preview;
488 QWidget *wdg;
489 QHBoxLayout *hbox;
490
491 saves_load = new QTableWidget;
492 wdg = new QWidget;
493 hbox = new QHBoxLayout;
494 QStringList sav;
495 lbl_show_preview = new QLabel(_("Show preview"));
496 sav << _("Choose Saved Game to Load") << _("Date");
497 load_pix = new QLabel;
498 load_pix->setProperty("themed_border", true);
499 load_pix->setFixedSize(0 ,0);
500 load_save_text = new QLabel;
501 load_save_text->setTextFormat(Qt::RichText);
502 load_save_text->setWordWrap(true);
503 show_preview = new QCheckBox;
504 show_preview->setChecked(gui_options.gui_qt_show_preview);
505 saves_load->setAlternatingRowColors(true);
506 saves_load->setRowCount(0);
507 saves_load->setColumnCount(sav.count());
508 saves_load->setHorizontalHeaderLabels(sav);
509 hbox->addWidget(show_preview);
510 hbox->addWidget(lbl_show_preview, Qt::AlignLeft);
511 wdg->setLayout(hbox);
512
513 saves_load->setProperty("showGrid", "false");
514 saves_load->setProperty("selectionBehavior", "SelectRows");
515 saves_load->setEditTriggers(QAbstractItemView::NoEditTriggers);
516 saves_load->setSelectionMode(QAbstractItemView::SingleSelection);
517 saves_load->verticalHeader()->setVisible(false);
518
519 header = saves_load->horizontalHeader();
520 header->setSectionResizeMode(0, QHeaderView::Stretch);
521 header->setStretchLastSection(true);
522
523 pages_layout[PAGE_LOAD]->addWidget(saves_load, 0, 0, 1, 4);
524 connect(saves_load->selectionModel(),
525 &QItemSelectionModel::selectionChanged, this,
526 &fc_client::slot_selection_changed);
527 connect(show_preview, &QCheckBox::stateChanged, this,
528 &fc_client::state_preview);
529 pages_layout[PAGE_LOAD]->addWidget(wdg, 1, 0);
530 pages_layout[PAGE_LOAD]->addWidget(load_save_text, 2, 0, 1, 2);
531 pages_layout[PAGE_LOAD]->addWidget(load_pix, 2, 2, 1, 2);
532
533 but = new QPushButton;
534 but->setText(_("Browse..."));
535 but->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon));
536 connect(but, &QAbstractButton::clicked, this, &fc_client::browse_saves);
537 pages_layout[PAGE_LOAD]->addWidget(but, 3, 0);
538
539 but = new QPushButton;
540 but->setText(_("Cancel"));
541 but->setIcon(QApplication::style()->standardIcon(
542 QStyle::SP_DialogCancelButton));
543 connect(but, &QAbstractButton::clicked, this, &fc_client::slot_disconnect);
544 pages_layout[PAGE_LOAD]->addWidget(but, 3, 2);
545
546 but = new QPushButton;
547 but->setText(_("Load"));
548 but->setIcon(QApplication::style()->standardIcon(
549 QStyle::SP_DialogOkButton));
550 connect(but, &QAbstractButton::clicked, this, &fc_client::start_from_save);
551 pages_layout[PAGE_LOAD]->addWidget(but, 3, 3);
552 pages_layout[PAGE_LOAD]->setColumnStretch(3, 10);
553 pages_layout[PAGE_LOAD]->setColumnStretch(2, 10);
554 pages_layout[PAGE_LOAD]->setColumnStretch(0, 10);
555
556}
557
558/**********************************************************************/
561 void fc_client::create_scenario_page()
562{
563 QPushButton *but;
564 QHeaderView *header;
565 QStringList sav;
566
567 pages_layout[PAGE_SCENARIO] = new QGridLayout;
568 scenarios_load = new QTableWidget;
569 scenarios_view = new QTextEdit;
570 scenarios_text = new QLabel;
571
572 scenarios_view->setObjectName("scenarios_view");
573 scenarios_text->setTextFormat(Qt::RichText);
574 scenarios_text->setWordWrap(true);
575 sav << _("Choose a Scenario");
576 scenarios_load->setRowCount(0);
577 scenarios_load->setColumnCount(sav.count());
578 scenarios_load->setHorizontalHeaderLabels(sav);
579 scenarios_load->setProperty("showGrid", "false");
580 scenarios_load->setProperty("selectionBehavior", "SelectRows");
581 scenarios_load->setEditTriggers(QAbstractItemView::NoEditTriggers);
582 scenarios_load->setSelectionMode(QAbstractItemView::SingleSelection);
583 scenarios_load->verticalHeader()->setVisible(false);
584 pages_layout[PAGE_SCENARIO]->addWidget(scenarios_load, 0, 0, 3, 3,
585 Qt::AlignLeft);
586 pages_layout[PAGE_SCENARIO]->addWidget(scenarios_view, 1, 3, 2, 3);
587 pages_layout[PAGE_SCENARIO]->addWidget(scenarios_text, 0, 3, 1, 2,
588 Qt::AlignTop);
589 scenarios_view->setReadOnly(true);
590 scenarios_view->setWordWrapMode(QTextOption::WordWrap);
591 scenarios_text->setAlignment(Qt::AlignCenter);
592
593 header = scenarios_load->horizontalHeader();
594 header->setSectionResizeMode(0, QHeaderView::Stretch);
595 header->setStretchLastSection(true);
596 connect(scenarios_load->selectionModel(),
597 &QItemSelectionModel::selectionChanged, this,
598 &fc_client::slot_selection_changed);
599
600 but = new QPushButton;
601 but->setText(_("Browse..."));
602 but->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon));
603 connect(but, &QAbstractButton::clicked, this, &fc_client::browse_scenarios);
604 pages_layout[PAGE_SCENARIO]->addWidget(but, 4, 0);
605
606 but = new QPushButton;
607 but->setText(_("Cancel"));
608 but->setIcon(QApplication::style()->standardIcon(
609 QStyle::SP_DialogCancelButton));
610 connect(but, &QAbstractButton::clicked, this, &fc_client::slot_disconnect);
611 pages_layout[PAGE_SCENARIO]->addWidget(but, 4, 3);
612
613 pages_layout[PAGE_SCENARIO]->setColumnStretch(2, 10);
614 pages_layout[PAGE_SCENARIO]->setColumnStretch(4, 20);
615 pages_layout[PAGE_SCENARIO]->setColumnStretch(3, 20);
616 pages_layout[PAGE_SCENARIO]->setRowStretch(1, 5);
617 but = new QPushButton;
618 but->setText(_("Load Scenario"));
619 but->setIcon(QApplication::style()->standardIcon(
620 QStyle::SP_DialogOkButton));
621 connect(but, &QAbstractButton::clicked, this, &fc_client::start_scenario);
622 pages_layout[PAGE_SCENARIO]->addWidget(but, 4, 4);
623}
624
625/**********************************************************************/
628 void fc_client::create_start_page()
629{
630 QPushButton *but;
631 QSplitter *splitter;
632 QGridLayout *up_layout;
633 QGridLayout *down_layout;
634 QWidget *up_widget;
635 QWidget *down_widget;
636 QFont f;
637
638 QStringList player_widget_list;
639 pages_layout[PAGE_START] = new QGridLayout;
640 up_layout = new QGridLayout;
641 down_layout = new QGridLayout;
642 start_players_tree = new QTreeWidget;
643 pr_options = new pregame_options(this);
644 chat_line = new chat_input;
645 chat_line->setProperty("doomchat", true);
646 output_window = new QTextEdit;
647 output_window->setReadOnly(false);
648 f.setBold(true);
649 output_window->setFont(f);
650
651 pr_options->init();
652 player_widget_list << _("Name") << _("Ready") << Q_("?player:Leader")
653 << _("Flag") << _("Border") << _("Nation") << _("Team")
654 << _("Host");
655
656 start_players_tree->setColumnCount(player_widget_list.count());
657 start_players_tree->setHeaderLabels(player_widget_list);
658 start_players_tree->setContextMenuPolicy(Qt::CustomContextMenu);
659 start_players_tree->setProperty("selectionBehavior", "SelectRows");
660 start_players_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
661 start_players_tree->setRootIsDecorated(false);
662
663 connect(start_players_tree,
664 SIGNAL(customContextMenuRequested(const QPoint&)),
665 SLOT(start_page_menu(QPoint)));
666
667 up_layout->addWidget(start_players_tree, 0, 0, 3, 6);
668 up_layout->addWidget(pr_options, 0, 6, 3, 2);
669 but = new QPushButton;
670 but->setText(_("Disconnect"));
671 but->setIcon(style()->standardPixmap(QStyle::SP_DialogCancelButton));
672 QObject::connect(but, &QAbstractButton::clicked, this, &fc_client::slot_disconnect);
673 down_layout->addWidget(but, 5, 4);
674 nation_button = new QPushButton;
675 nation_button->setText(_("Pick Nation"));
676 nation_button->setIcon(fc_icons::instance()->get_icon("flag"));
677 down_layout->addWidget(nation_button, 5, 5);
678 QObject::connect(nation_button, &QAbstractButton::clicked, this,
679 &fc_client::slot_pick_nation);
680
681 obs_button = new QPushButton;
682 obs_button->setText(_("Observe"));
683 obs_button->setIcon(fc_icons::instance()->get_icon("meeting-observer"));
684 down_layout->addWidget(obs_button, 5, 6);
685 QObject::connect(obs_button, &QAbstractButton::clicked, this,
686 &fc_client::slot_pregame_observe);
687 start_button = new QPushButton;
688 start_button->setText(_("Start"));
689 start_button->setIcon(style()->standardPixmap(QStyle::SP_DialogOkButton));
690 down_layout->addWidget(start_button, 5, 7);
691 QObject::connect(start_button, &QAbstractButton::clicked, this,
692 &fc_client::slot_pregame_start);
693 pre_vote = new pregamevote;
694
695 down_layout->addWidget(pre_vote, 4, 0, 1, 4);
696 down_layout->addWidget(chat_line, 5, 0, 1, 4);
697 down_layout->addWidget(output_window, 3, 0, 1, 8);
698 splitter = new QSplitter;
699 up_widget = new QWidget();
700 down_widget = new QWidget();
701 up_widget->setLayout(up_layout);
702 down_widget->setLayout(down_layout);
703 splitter->addWidget(up_widget);
704 splitter->addWidget(down_widget);
705 splitter->setOrientation(Qt::Vertical);
706 pages_layout[PAGE_START]->addWidget(splitter);
707}
708
709/**********************************************************************/
712 void fc_client::create_game_page()
713{
714 QGridLayout *game_layout;
715
716 pages_layout[PAGE_GAME] = new QGridLayout;
717 game_main_widget = new QWidget;
718 game_layout = new QGridLayout;
719 game_layout->setContentsMargins(0, 0, 0, 0);
720 game_layout->setSpacing(0);
721 mapview_wdg = new map_view();
722 mapview_wdg->setFocusPolicy(Qt::WheelFocus);
723 sidebar_wdg = new fc_sidebar();
724
725 sw_map = new fc_sidewidget(fc_icons::instance()->get_pixmap("view"),
726 Q_("?noun:View"), "MAP", side_show_map);
727 sw_tax = new fc_sidewidget(nullptr, nullptr, "", side_rates_wdg, SW_TAX);
728 sw_indicators = new fc_sidewidget(nullptr, nullptr, "", side_show_map,
729 SW_INDICATORS);
730 sw_indicators->set_right_click(side_indicators_menu);
731 sw_cunit = new fc_sidewidget(fc_icons::instance()->get_pixmap("units"),
732 _("Units"), "",
733 toggle_units_report);
734 sw_cities = new fc_sidewidget(fc_icons::instance()->get_pixmap("cities"),
735 _("Cities"), "CTS",
736 city_report_dialog_popup);
737 sw_cities->set_wheel_up(center_next_enemy_city);
738 sw_cities->set_wheel_down(center_next_player_city);
739 sw_diplo = new fc_sidewidget(fc_icons::instance()->get_pixmap("nations"),
740 _("Nations"), "PLR", popup_players_dialog);
741 sw_diplo->set_wheel_up(center_next_player_capital);
742 sw_diplo->set_wheel_down(key_center_capital);
743 sw_science = new fc_sidewidget(fc_icons::instance()->get_pixmap("research"),
744 _("Research"), "SCI",
745 side_left_click_science);
746 sw_economy = new fc_sidewidget(fc_icons::instance()->get_pixmap("economy"),
747 _("Economy"), "ECO",
748 economy_report_dialog_popup);
749 sw_endturn = new fc_sidewidget(fc_icons::instance()->get_pixmap("endturn"),
750 _("Turn Done"), "", side_finish_turn);
751 sw_cunit->set_right_click(side_center_unit);
752 sw_cunit->set_wheel_up(cycle_enemy_units);
753 sw_cunit->set_wheel_down(key_unit_wait);
754 sw_diplo->set_right_click(side_right_click_diplomacy);
755 sw_science->set_right_click(side_right_click_science);
756
757 sidebar_wdg->add_widget(sw_map);
758 sidebar_wdg->add_widget(sw_cunit);
759 sidebar_wdg->add_widget(sw_cities);
760 sidebar_wdg->add_widget(sw_diplo);
761 sidebar_wdg->add_widget(sw_science);
762 sidebar_wdg->add_widget(sw_economy);
763 sidebar_wdg->add_widget(sw_tax);
764 sidebar_wdg->add_widget(sw_indicators);
765 sidebar_wdg->add_widget(sw_endturn);
766
767 minimapview_wdg = new minimap_view(mapview_wdg);
768 minimapview_wdg->show();
769 unitinfo_wdg = new hud_units(mapview_wdg);
770 battlelog_wdg = new hud_battle_log(mapview_wdg);
771 battlelog_wdg->hide();
772 infotab = new info_tab(mapview_wdg);
773 infotab->show();
774 x_vote = new xvote(mapview_wdg);
775 x_vote->hide();
776 gtd = new goto_dialog(mapview_wdg);
777 gtd->hide();
778
779 game_layout->addWidget(mapview_wdg, 1, 0);
780 game_main_widget->setLayout(game_layout);
781 game_tab_widget = new fc_game_tab_widget;
782 game_tab_widget->setMinimumSize(600,400);
783 game_tab_widget->setContentsMargins(0, 0, 0, 0);
784 add_game_tab(game_main_widget);
785 if (gui_options.gui_qt_sidebar_left) {
786 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 0);
787 } else {
788 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 2);
789 }
790 pages_layout[PAGE_GAME]->addWidget(game_tab_widget, 1, 1);
791 pages_layout[PAGE_GAME]->setContentsMargins(0, 0, 0, 0);
792 pages_layout[PAGE_GAME]->setSpacing(0);
793}
794
795/**********************************************************************/
798 int fc_client::add_game_tab(QWidget *widget)
799{
800 int i;
801
802 i = game_tab_widget->addWidget(widget);
803 game_tab_widget->setCurrentWidget(widget);
804 return i;
805}
806
807/**********************************************************************/
810 void fc_client::rm_game_tab(int index)
811{
812 game_tab_widget->removeWidget(game_tab_widget->widget(index));
813}
814
815/**********************************************************************/
818 void fc_client::browse_saves(void)
819{
820 QString str;
821 str = QString(_("Save Files"))
822 + QString(" (*.sav *.sav.bz2 *.sav.gz *.sav.xz *.sav.zst)");
823 current_file = QFileDialog::getOpenFileName(gui()->central_wdg,
824 _("Open Save File"),
825 QDir::homePath(), str);
826 if (!current_file.isEmpty()) {
827 start_from_save();
828 }
829}
830
831/**********************************************************************/
834 void fc_client::state_preview(int new_state)
835{
836 QItemSelection slctn;
837
838 if (show_preview->checkState() == Qt::Unchecked) {
839 gui_options.gui_qt_show_preview = false;
840 } else {
841 gui_options.gui_qt_show_preview = true;
842 }
843 slctn = saves_load->selectionModel()->selection();
844 saves_load->selectionModel()->clearSelection();
845 saves_load->selectionModel()->select(slctn, QItemSelectionModel::Rows
846 | QItemSelectionModel::SelectCurrent);
847}
848
849/**********************************************************************/
852 void fc_client::browse_scenarios(void)
853{
854 QString str;
855
856 str = QString(_("Scenarios Files"))
857 + QString(" (*.sav *.sav.bz2 *.sav.gz *.sav.xz *.sav.zst)");
858 current_file = QFileDialog::getOpenFileName(gui()->central_wdg,
859 _("Open Scenario File"),
860 QDir::homePath(), str);
861 if (!current_file.isEmpty()) {
862 start_scenario();
863 }
864}
865
866/**********************************************************************/
869 void fc_client::update_server_list(enum server_scan_type sstype,
870 const struct server_list *list)
871{
872 QTableWidget* sel = NULL;
873 QString host, portstr;
874 int port;
875 int row;
876 int old_row_count;
877
878 switch (sstype) {
879 case SERVER_SCAN_LOCAL:
880 sel = lan_widget;
881 break;
882 case SERVER_SCAN_GLOBAL:
883 sel = wan_widget;
884 break;
885 default:
886 break;
887 }
888
889 if (!sel) {
890 return;
891 }
892
893 if (!list) {
894 return;
895 }
896
897 host = connect_host_edit->text();
898 portstr = connect_port_edit->text();
899 port = portstr.toInt();
900 old_row_count = sel->rowCount();
901 sel->clearContents();
902 row = 0;
903 server_list_iterate(list, pserver) {
904 char buf[35];
905 int tmp;
906 QString tstring;
907
908 if (old_row_count <= row) {
909 sel->insertRow(row);
910 }
911
912 if (pserver->humans >= 0) {
913 fc_snprintf(buf, sizeof(buf), "%d", pserver->humans);
914 } else {
915 strncpy(buf, _("Unknown"), sizeof(buf) - 1);
916 buf[sizeof(buf) - 1] = '\0';
917 }
918
919 tmp = pserver->port;
920 tstring = QString::number(tmp);
921
922 for (int col = 0; col < 6; col++) {
923 QTableWidgetItem *item;
924
925 item = new QTableWidgetItem();
926
927 switch (col) {
928 case 0:
929 item->setText(pserver->host);
930 break;
931 case 1:
932 item->setText(tstring);
933 break;
934 case 2:
935 item->setText(pserver->version);
936 break;
937 case 3:
938 item->setText(_(pserver->state));
939 break;
940 case 4:
941 item->setText(buf);
942 break;
943 case 5:
944 item->setText(pserver->message);
945 break;
946 default:
947 break;
948 }
949 sel->setItem(row, col, item);
950 }
951
952 if (host == pserver->host && port == pserver->port) {
953 sel->selectRow(row);
954 }
955
956 row++;
957 } server_list_iterate_end;
958
959 // Remove unneeded rows, if there are any
960 while (old_row_count - row > 0) {
961 sel->removeRow(old_row_count - 1);
962 old_row_count--;
963 }
964
965}
966
967/**********************************************************************/
970 void server_scan_error(struct server_scan *scan, const char *message)
971{
972 qtg_version_message(message);
973 log_error("%s", message);
974
975 /* Main thread will finalize the scan later (or even concurrently) -
976 * do not do anything here to cause double free or raze condition. */
977}
978
979
980/**********************************************************************/
983 void fc_client::destroy_server_scans(void)
984{
985 if (meta_scan) {
986 server_scan_finish(meta_scan);
987 meta_scan = NULL;
988 }
989
990 if (meta_scan_timer != NULL) {
991 meta_scan_timer->stop();
992 meta_scan_timer->disconnect();
993 delete meta_scan_timer;
994 meta_scan_timer = NULL;
995 }
996
997 if (lan_scan) {
998 server_scan_finish(lan_scan);
999 lan_scan = NULL;
1000 }
1001
1002 if (lan_scan_timer != NULL) {
1003 lan_scan_timer->stop();
1004 lan_scan_timer->disconnect();
1005 delete lan_scan_timer;
1006 lan_scan_timer = NULL;
1007 }
1008}
1009
1010/**********************************************************************/
1013 void fc_client::update_network_lists(void)
1014{
1015 destroy_server_scans();
1016
1017 lan_scan_timer = new QTimer(this);
1018 lan_scan = server_scan_begin(SERVER_SCAN_LOCAL, server_scan_error);
1019 connect(lan_scan_timer, &QTimer::timeout, this, &fc_client::slot_lan_scan);
1020 lan_scan_timer->start(500);
1021
1022 meta_scan_timer = new QTimer(this);
1023 meta_scan = server_scan_begin(SERVER_SCAN_GLOBAL, server_scan_error);
1024 connect(meta_scan_timer, &QTimer::timeout, this, &fc_client::slot_meta_scan);
1025 meta_scan_timer->start(800);
1026
1027}
1028
1029/**********************************************************************/
1032 bool fc_client::check_server_scan(server_scan *scan_data)
1033{
1034 struct server_scan *scan = scan_data;
1035 enum server_scan_status stat;
1036
1037 if (!scan) {
1038 return false;
1039 }
1040
1041 stat = server_scan_poll(scan);
1042
1043 if (stat >= SCAN_STATUS_PARTIAL) {
1044 enum server_scan_type type;
1045 struct srv_list *srvrs;
1046
1047 type = server_scan_get_type(scan);
1048 srvrs = server_scan_get_list(scan);
1049 fc_mutex_allocate(&srvrs->mutex);
1050 holding_srv_list_mutex = true;
1051 update_server_list(type, srvrs->servers);
1052 holding_srv_list_mutex = false;
1053 fc_mutex_release(&srvrs->mutex);
1054 }
1055
1056 if (stat == SCAN_STATUS_ERROR || stat == SCAN_STATUS_DONE) {
1057 return false;
1058 }
1059
1060 return true;
1061}
1062
1063/**********************************************************************/
1066 void fc_client::slot_lan_scan()
1067{
1068 if (lan_scan_timer == NULL) {
1069 return;
1070 }
1071 check_server_scan(lan_scan);
1072}
1073
1074/**********************************************************************/
1077 void fc_client::slot_meta_scan()
1078{
1079 if (meta_scan_timer == NULL) {
1080 return;
1081 }
1082 check_server_scan(meta_scan);
1083}
1084
1085/**********************************************************************/
1088 void fc_client::start_new_game()
1089{
1090 if (!is_server_running()) {
1091 client_start_server();
1092
1093 // Saved settings are sent in client/options.c
1094 // resend_desired_settable_options()
1095 }
1096}
1097
1098/**********************************************************************/
1101 void fc_client::start_scenario()
1102{
1103 if (!is_server_running()) {
1104 client_start_server();
1105 send_chat("/detach");
1106 }
1107 if (is_server_running() && !current_file.isEmpty()) {
1108 QByteArray c_bytes;
1109
1110 c_bytes = current_file.toUtf8();
1111 send_chat_printf("/load %s", c_bytes.data());
1112 switch_page(PAGE_GAME + 1);
1113 }
1114}
1115
1116/**********************************************************************/
1119 void fc_client::start_from_save()
1120{
1121 if (!is_server_running()) {
1122 client_start_server();
1123 send_chat("/detach");
1124 }
1125 if (is_server_running() && !current_file.isEmpty()) {
1126 QByteArray c_bytes;
1127
1128 c_bytes = current_file.toUtf8();
1129 send_chat_printf("/load %s", c_bytes.data());
1130 switch_page(PAGE_GAME + 1);
1131 }
1132}
1133
1134/**********************************************************************/
1137 void fc_client::slot_selection_changed(const QItemSelection &selected,
1138 const QItemSelection &deselected)
1139{
1140 QModelIndexList indexes = selected.indexes();
1141 QStringList sl;
1142 QModelIndex index;
1143 QTableWidgetItem *item;
1144 QItemSelectionModel *tw;
1145 QVariant qvar;
1146 QString str_pixmap;
1147
1148 client_pages cpage = current_page();
1149 const char *terr_name;
1150 const struct server *pserver = NULL;
1151 int ii = 0;
1152 int k, col, n, nat_y, nat_x;
1153 struct section_file *sf;
1154 struct srv_list *srvrs;
1155 QByteArray fn_bytes;
1156
1157 if (indexes.isEmpty()) {
1158 return;
1159 }
1160
1161 switch (cpage) {
1162 case PAGE_NETWORK:
1163 index = indexes.at(0);
1164 connect_host_edit->setText(index.data().toString());
1165 index = indexes.at(1);
1166 connect_port_edit->setText(index.data().toString());
1167
1168 tw = qobject_cast<QItemSelectionModel *>(sender());
1169
1170 if (tw == lan_widget->selectionModel()) {
1171 wan_widget->clearSelection();
1172 } else {
1173 lan_widget->clearSelection();
1174 }
1175
1176 srvrs = server_scan_get_list(meta_scan);
1177 if (!holding_srv_list_mutex) {
1178 fc_mutex_allocate(&srvrs->mutex);
1179 }
1180 if (srvrs->servers) {
1181 pserver = server_list_get(srvrs->servers, index.row());
1182 }
1183 if (!holding_srv_list_mutex) {
1184 fc_mutex_release(&srvrs->mutex);
1185 }
1186 if (!pserver || !pserver->players) {
1187 return;
1188 }
1189 n = pserver->nplayers;
1190 info_widget->clearContents();
1191 info_widget->setRowCount(0);
1192 for (k = 0; k < n; k++) {
1193 info_widget->insertRow(k);
1194 for (col = 0; col < 4; col++) {
1195 item = new QTableWidgetItem();
1196 switch (col) {
1197 case 0:
1198 item->setText(pserver->players[k].name);
1199 break;
1200 case 1:
1201 item->setText(pserver->players[k].type);
1202 break;
1203 case 2:
1204 item->setText(pserver->players[k].host);
1205 break;
1206 case 3:
1207 item->setText(pserver->players[k].nation);
1208 break;
1209 default:
1210 break;
1211 }
1212 info_widget->setItem(k, col, item);
1213 }
1214 }
1215 break;
1216 case PAGE_SCENARIO:
1217 index = indexes.at(0);
1218 qvar = index.data(Qt::UserRole);
1219 sl = qvar.toStringList();
1220 scenarios_text->setText(sl.at(0));
1221 if (sl.count() > 1) {
1222 scenarios_view->setText(sl.at(2));
1223 current_file = sl.at(1);
1224 }
1225 break;
1226 case PAGE_LOAD:
1227 index = indexes.at(0);
1228 qvar = index.data(Qt::UserRole);
1229 current_file = qvar.toString();
1230 if (show_preview->checkState() == Qt::Unchecked) {
1231 load_pix->setPixmap(*(new QPixmap));
1232 load_save_text->setText("");
1233 break;
1234 }
1235 fn_bytes = current_file.toUtf8();
1236 if ((sf = secfile_load_section(fn_bytes.data(),
1237 "game", TRUE))) {
1238 const char *sname;
1239 int integer;
1240 QString final_str;
1241 QString pl_str = nullptr;
1242 int num_players = 0;
1243 int curr_player = 0;
1244 QByteArray pl_bytes;
1245
1246 integer = secfile_lookup_int_default(sf, -1, "game.turn");
1247 if (integer >= 0) {
1248 final_str = QString("<b>") + _("Turn") + ":</b> "
1249 + QString::number(integer).toHtmlEscaped() + "<br>";
1250 }
1251 if ((sf = secfile_load_section(fn_bytes.data(),
1252 "players", TRUE))) {
1253 integer = secfile_lookup_int_default(sf, -1, "players.nplayers");
1254 if (integer >= 0) {
1255 final_str = final_str + "<b>" + _("Players") + ":</b>" + " "
1256 + QString::number(integer).toHtmlEscaped() + "<br>";
1257 }
1258 num_players = integer;
1259 }
1260 for (int i = 0; i < num_players; i++) {
1261 pl_str = QString("player") + QString::number(i);
1262 pl_bytes = pl_str.toUtf8();
1263 if ((sf = secfile_load_section(fn_bytes.data(),
1264 pl_bytes.data(), true))) {
1265 if (!secfile_lookup_bool_default(sf, true,
1266 "player%d.unassigned_user",
1267 i)) {
1268 curr_player = i;
1269 break;
1270 }
1271 }
1272 }
1273 // Break case (and return) if no human player found
1274 if (pl_str == nullptr) {
1275 load_save_text->setText(final_str);
1276 break;
1277 }
1278
1279 // Information about human player
1280 pl_bytes = pl_str.toUtf8();
1281 if ((sf = secfile_load_section(fn_bytes.data(),
1282 pl_bytes.data(), true))) {
1283 sname = secfile_lookup_str_default(sf, nullptr, "player%d.nation",
1284 curr_player);
1285 if (sname) {
1286 final_str = final_str + "<b>" + _("Nation") + ":</b> "
1287 + QString(sname).toHtmlEscaped() + "<br>";
1288 }
1289 integer = secfile_lookup_int_default(sf, -1, "player%d.ncities",
1290 curr_player);
1291 if (integer >= 0) {
1292 final_str = final_str + "<b>" + _("Cities") + ":</b> "
1293 + QString::number(integer).toHtmlEscaped() + "<br>";
1294 }
1295 integer = secfile_lookup_int_default(sf, -1, "player%d.nunits",
1296 curr_player);
1297 if (integer >= 0) {
1298 final_str = final_str + "<b>" + _("Units") + ":</b> "
1299 + QString::number(integer).toHtmlEscaped() + "<br>";
1300 }
1301 integer = secfile_lookup_int_default(sf, -1, "player%d.gold",
1302 curr_player);
1303 if (integer >= 0) {
1304 final_str = final_str + "<b>" + _("Gold") + ":</b> "
1305 + QString::number(integer).toHtmlEscaped() + "<br>";
1306 }
1307 nat_x = 0;
1308 nat_y = 0;
1309 while (true) { // Until breaks out
1310 const char *line = secfile_lookup_str_default(sf, nullptr,
1311 "player%d.map_t%04d",
1312 curr_player, nat_y++);
1313 if (line == nullptr) {
1314 break;
1315 }
1316 nat_x = strlen(line);
1317 str_pixmap = str_pixmap + line;
1318 }
1319
1320 // Reset terrain information
1321 terrain_type_iterate(pterr) {
1322 pterr->identifier_load = '\0';
1323 } terrain_type_iterate_end;
1324
1325 // Load possible terrains and their identifiers (chars)
1326 if ((sf = secfile_load_section(fn_bytes.data(),
1327 "savefile", true))) {
1328 while ((terr_name = secfile_lookup_str_default(sf, NULL,
1329 "savefile.terrident%d.name", ii)) != NULL) {
1330 struct terrain *pterr = terrain_by_rule_name(terr_name);
1331
1332 if (pterr != NULL) {
1333 const char *iptr = secfile_lookup_str_default(sf, NULL,
1334 "savefile.terrident%d.identifier", ii);
1335 pterr->identifier_load = *iptr;
1336 }
1337 ii++;
1338 }
1339 }
1340
1341 // Create image
1342 QImage img(nat_x, nat_y, QImage::Format_ARGB32_Premultiplied);
1343
1344 img.fill(Qt::black);
1345 for (int a = 0 ; a < nat_x; a++) {
1346 for (int b = 0; b < nat_y; b++) {
1347 struct terrain *tr;
1348 struct rgbcolor *rgb;
1349
1350 tr = char2terrain(str_pixmap.at(b * nat_x + a).toLatin1());
1351 if (tr != nullptr) {
1352 rgb = tr->rgb;
1353 QColor color;
1354
1355 color.setRgb(rgb->r, rgb->g, rgb->b);
1356 img.setPixel(a, b, color.rgb());
1357 }
1358 }
1359 }
1360 if (img.width() > 1) {
1361 load_pix->setPixmap(QPixmap::fromImage(img).scaledToHeight(200));
1362 } else {
1363 load_pix->setPixmap(*(new QPixmap));
1364 }
1365
1366#ifndef FC_QT5_MODE
1367 // This is Qt6 implementation
1368 // Qt-5.15 could use load_pix->pixmap(Qt::ReturnByValue)
1369 QPixmap pm = load_pix->pixmap();
1370
1371 load_pix->setFixedSize(pm.width(),
1372 pm.height());
1373#else // FC_QT5_MODE
1374 load_pix->setFixedSize(load_pix->pixmap()->width(),
1375 load_pix->pixmap()->height());
1376#endif // FC_QT5_MODE
1377
1378 if ((sf = secfile_load_section(fn_bytes.data(),
1379 "research", TRUE))) {
1380 sname = secfile_lookup_str_default(sf, nullptr,
1381 "research.r%d.now_name",
1382 curr_player);
1383 if (sname) {
1384 final_str = final_str + "<b>" + _("Researching") + ":</b> "
1385 + QString(sname).toHtmlEscaped();
1386 }
1387 }
1388 }
1389 load_save_text->setText(final_str);
1390 }
1391 break;
1392 default:
1393 break;
1394 }
1395
1396}
1397
1398/**********************************************************************/
1401 void fc_client::update_load_page(void)
1402{
1403 struct fileinfo_list *files;
1404 int row;
1405
1406 row = 0;
1407 files = fileinfolist_infix(get_save_dirs(), ".sav", FALSE);
1408 saves_load->clearContents();
1409 saves_load->setRowCount(0);
1410 show_preview->setChecked(gui_options.gui_qt_show_preview);
1411 fileinfo_list_iterate(files, pfile) {
1412 QTableWidgetItem *item;
1413 QDateTime dt;
1414
1415 item = new QTableWidgetItem();
1416 item->setData(Qt::UserRole, QString(pfile->fullname));
1417 saves_load->insertRow(row);
1418 item->setText(pfile->name);
1419 saves_load->setItem(row, 0, item);
1420 item = new QTableWidgetItem();
1421 dt = QDateTime::fromSecsSinceEpoch(pfile->mtime);
1422 item->setText(dt.toString(Qt::TextDate));
1423 saves_load->setItem(row, 1, item);
1424 row++;
1425 } fileinfo_list_iterate_end;
1426 fileinfo_list_destroy(files);
1427}
1428
1429/**********************************************************************/
1432 void fc_client::update_scenarios_page(void)
1433{
1434 struct fileinfo_list *files;
1435 int row = 0;
1436
1437 scenarios_load->clearContents();
1438 scenarios_load->setRowCount(0);
1439 scenarios_text->setText("");
1440 scenarios_view->setText("");
1441
1442 files = fileinfolist_infix(get_scenario_dirs(), ".sav", false);
1443 fileinfo_list_iterate(files, pfile) {
1444 struct section_file *sf;
1445
1446 if ((sf = secfile_load_section(pfile->fullname, "scenario", TRUE))
1447 && secfile_lookup_bool_default(sf, TRUE, "scenario.is_scenario")) {
1448
1449 const char *sname, *sdescription, *sauthors;
1450 QTableWidgetItem *item;
1451 QString format;
1452 QString st;
1453 int fcver;
1454 int fcdev;
1455 int current_ver = MAJOR_VERSION * 1000000 + MINOR_VERSION * 10000;
1456 int current_dev = current_ver;
1457
1458 if (PATCH_VERSION >= 90) {
1459 // Patch level matters on development versions
1460 current_dev += PATCH_VERSION * 100;
1461 }
1462
1463 fcver = secfile_lookup_int_default(sf, 0, "scenario.game_version");
1464 if (fcver < 30000) {
1465 /* Pre-3.0 versions stored version number without emergency version
1466 * part in the end. To get comparable version number stored,
1467 * multiply by 100. */
1468 fcver *= 100;
1469 }
1470 if (fcver % 10000 >= 9000) {
1471 fcdev = fcver - (fcver % 100); // Emergency version does not count.
1472 } else {
1473 fcdev = fcver - (fcver % 10000); // Patch version does not count.
1474 }
1475 sname = secfile_lookup_str_default(sf, NULL, "scenario.name");
1476 sdescription = secfile_lookup_str_default(sf, NULL,
1477 "scenario.description");
1478 sauthors = secfile_lookup_str_default(sf, NULL,
1479 "scenario.authors");
1480 // Ignore scenarios for newer freeciv versions than we are.
1481 if (fcdev <= current_dev) {
1482 QString version;
1483 bool add_item = true;
1484 bool found = false;
1485 QStringList sl;
1486 int rows;
1487 int found_ver;
1488 int i;
1489
1490 if (fcver > 0) {
1491 int maj;
1492 int min;
1493
1494 maj = fcver / 1000000;
1495 fcver %= 1000000;
1496 min = fcver / 10000;
1497 fcver %= 10000;
1498 if (fcver >= 9000) {
1499 // Development version, have '+'
1500 version = QString("%1.%2+").arg(maj).arg(min);
1501 } else {
1502 version = QString("%1.%2").arg(maj).arg(min);
1503 }
1504 } else {
1505 // TRANS: Unknown scenario format
1506 version = QString(_("pre-2.6"));
1507 }
1508
1509 rows = scenarios_load->rowCount();
1510 for (i = 0; i < rows; ++i) {
1511 if (scenarios_load->item(i, 0)
1512 && scenarios_load->item(i, 0)->text() == pfile->name) {
1513 found = true;
1514 item = scenarios_load->takeItem(i, 0);
1515 break;
1516 }
1517 }
1518
1519 if (found) {
1520 sl = item->data(Qt::UserRole).toStringList();
1521 found_ver = sl.at(3).toInt();
1522 if (found_ver < fcver) {
1523 continue;
1524 }
1525 add_item = false;
1526 }
1527 if (add_item) {
1528 item = new QTableWidgetItem();
1529 scenarios_load->insertRow(row);
1530 }
1531 item->setText(QString(pfile->name));
1532 format = QString("<br>") + QString(_("Format:")) + " "
1533 + version.toHtmlEscaped();
1534 if (sauthors) {
1535 st = QString("\n") + QString("<b>") + _("Authors: ")
1536 + QString("</b>") + QString(sauthors).toHtmlEscaped();
1537 } else {
1538 st = "";
1539 }
1540 sl << "<b>"
1541 + QString(sname && strlen(sname) ? Q_(sname) : pfile->name)
1542 .toHtmlEscaped()
1543 + "</b>"
1544 << QString(pfile->fullname).toHtmlEscaped()
1545 << QString(NULL != sdescription && '\0' != sdescription[0]
1546 ? Q_(sdescription) : "").toHtmlEscaped() + st + format
1547 << QString::number(fcver).toHtmlEscaped();
1548 sl.replaceInStrings("\n", "<br>");
1549 item->setData(Qt::UserRole, sl);
1550 if (add_item) {
1551 scenarios_load->setItem(row, 0, item);
1552 row++;
1553 } else {
1554 scenarios_load->setItem(i, 0, item);
1555 }
1556 }
1557 secfile_destroy(sf);
1558 }
1559 } fileinfo_list_iterate_end;
1560 fileinfo_list_destroy(files);
1561 scenarios_load->sortItems(0);
1562 scenarios_load->update();
1563}
1564
1565/**********************************************************************/
1569 void fc_client::handle_authentication_req(enum authentication_type type,
1570 const char *message)
1571{
1572 set_status_bar(QString::fromUtf8(message));
1573 destroy_server_scans();
1574
1575 switch (type) {
1576 case AUTH_NEWUSER_FIRST:
1577 case AUTH_NEWUSER_RETRY:
1578 set_connection_state(NEW_PASSWORD_TYPE);
1579 return;
1580 case AUTH_LOGIN_FIRST:
1581 /* if we magically have a password already present in 'fc_password'
1582 * then, use that and skip the password entry dialog */
1583 if (fc_password[0] != '\0') {
1584 struct packet_authentication_reply reply;
1585
1586 sz_strlcpy(reply.password, fc_password);
1587 send_packet_authentication_reply(&client.conn, &reply);
1588 return;
1589 } else {
1590 set_connection_state(ENTER_PASSWORD_TYPE);
1591 }
1592
1593 return;
1594 case AUTH_LOGIN_RETRY:
1595 set_connection_state(ENTER_PASSWORD_TYPE);
1596 return;
1597 }
1598
1599 log_error("Unsupported authentication type %d: %s.", type, message);
1600}
1601
1602/**********************************************************************/
1607 void fc_client::slot_connect()
1608{
1609 char errbuf [512];
1610 struct packet_authentication_reply reply;
1611 QByteArray ba_bytes;
1612
1613 switch (connection_status) {
1614 case LOGIN_TYPE:
1615 ba_bytes = connect_login_edit->text().toUtf8();
1616 sz_strlcpy(user_name, ba_bytes.data());
1617 ba_bytes = connect_host_edit->text().toUtf8();
1618 sz_strlcpy(server_host, ba_bytes.data());
1619 server_port = connect_port_edit->text().toInt();
1620
1621 if (connect_to_server(user_name, server_host, server_port,
1622 errbuf, sizeof(errbuf)) != -1) {
1623 } else {
1624 set_status_bar(QString::fromUtf8(errbuf));
1625 output_window_append(ftc_client, errbuf);
1626 }
1627
1628 return;
1629 case NEW_PASSWORD_TYPE:
1630 ba_bytes = connect_password_edit->text().toLatin1();
1631 sz_strlcpy(fc_password, ba_bytes.data());
1632 ba_bytes = connect_confirm_password_edit->text().toLatin1();
1633 sz_strlcpy(reply.password,
1634 ba_bytes.data());
1635
1636 if (!fc_strncmp(reply.password, fc_password, MAX_LEN_NAME)) {
1637 fc_password[0] = '\0';
1638 send_packet_authentication_reply(&client.conn, &reply);
1639 set_connection_state(WAITING_TYPE);
1640 } else {
1641 set_status_bar(_("Passwords don't match, enter password."));
1642 set_connection_state(NEW_PASSWORD_TYPE);
1643 }
1644
1645 return;
1646 case ENTER_PASSWORD_TYPE:
1647 ba_bytes = connect_password_edit->text().toLatin1();
1648 sz_strlcpy(reply.password,
1649 ba_bytes.data());
1650 send_packet_authentication_reply(&client.conn, &reply);
1651 set_connection_state(WAITING_TYPE);
1652 return;
1653 case WAITING_TYPE:
1654 return;
1655 }
1656
1657 log_error("Unsupported connection status: %d", connection_status);
1658}
1659
1660/**********************************************************************/
1664 void fc_client::update_start_page()
1665{
1666 int conn_num, i;
1667 QVariant qvar, qvar2;
1668 bool is_ready;
1669 QString host, nation, leader, team, str;
1670 QPixmap *pixmap;
1671 QPainter p;
1672 struct sprite *psprite;
1673 QTreeWidgetItem *item;
1674 QTreeWidgetItem *item_r;
1675 QList <QTreeWidgetItem*> items;
1676 QList <QTreeWidgetItem*> recursed_items;
1677 QTreeWidgetItem *player_item;
1678 QTreeWidgetItem *global_item;
1679 QTreeWidgetItem *detach_item;
1680 int conn_id;
1681 conn_num = conn_list_size(game.est_connections);
1682
1683 if (conn_num == 0) {
1684 return;
1685 }
1686
1687 start_players_tree->clear();
1688 qvar2 = 0;
1689
1690 player_item = new QTreeWidgetItem();
1691 player_item->setText(0, Q_("?header:Players"));
1692 player_item->setData(0, Qt::UserRole, qvar2);
1693
1694 i = 0;
1695 players_iterate(pplayer) {
1696 i++;
1697 } players_iterate_end;
1698 gui()->pr_options->set_aifill(i);
1699 // Inserts playing players, observing custom players, and AI)
1700
1701 players_iterate(pplayer) {
1702 host = "";
1703 if (!player_has_flag(pplayer, PLRF_SCENARIO_RESERVED)) {
1704 conn_id = -1;
1705 conn_list_iterate(pplayer->connections, pconn) {
1706 if (pconn->playing == pplayer && !pconn->observer) {
1707 conn_id = pconn->id;
1708 host = pconn->addr;
1709 break;
1710 }
1711 } conn_list_iterate_end;
1712 if (is_barbarian(pplayer)) {
1713 continue;
1714 }
1715 if (is_ai(pplayer)) {
1716 is_ready = true;
1717 } else {
1718 is_ready = pplayer->is_ready;
1719 }
1720
1721 if (pplayer->nation == NO_NATION_SELECTED) {
1722 nation = _("Random");
1723
1724 if (pplayer->was_created) {
1725 leader = player_name(pplayer);
1726 } else {
1727 leader = "";
1728 }
1729 } else {
1730 nation = nation_adjective_for_player(pplayer);
1731 leader = player_name(pplayer);
1732 }
1733
1734 if (pplayer->team) {
1735 team = team_name_translation(pplayer->team);
1736 } else {
1737 team = "";
1738 }
1739
1740 item = new QTreeWidgetItem();
1741 for (int col = 0; col < 8; col++) {
1742 switch (col) {
1743 case 0:
1744 str = pplayer->username;
1745
1746 if (is_ai(pplayer)) {
1747 str = str + " <" + (ai_level_translated_name(pplayer->ai_common.skill_level))
1748 + ">";
1749 item->setIcon(col, fc_icons::instance()->get_icon("ai"));
1750 } else {
1751 item->setIcon(col, fc_icons::instance()->get_icon("human"));
1752 }
1753
1754 item->setText(col, str);
1755 qvar = QVariant::fromValue((void *) pplayer);
1756 qvar2 = 1;
1757 item->setData(0, Qt::UserRole, qvar2);
1758 item->setData(1, Qt::UserRole, qvar);
1759 break;
1760 case 1:
1761 if (is_ready) {
1762 item->setText(col, _("Yes"));
1763 } else {
1764 item->setText(col, _("No"));
1765 }
1766 break;
1767 case 2:
1768 item->setText(col, leader);
1769 break;
1770 case 3:
1771 if (!pplayer->nation) {
1772 break;
1773 }
1774 psprite = get_nation_flag_sprite(tileset, pplayer->nation);
1775 pixmap = psprite->pm;
1776 item->setData(col, Qt::DecorationRole, *pixmap);
1777 break;
1778 case 4:
1779 if (!player_has_color(pplayer)) {
1780 break;
1781 }
1782 pixmap = new QPixmap(
1783 start_players_tree->header()->sectionSizeHint(col), 16);
1784 pixmap->fill(Qt::transparent);
1785 p.begin(pixmap);
1786 p.fillRect(pixmap->width() / 2 - 8, 0, 16, 16, Qt::black);
1787 p.fillRect(pixmap->width() / 2 - 7, 1, 14, 14,
1788 get_player_color(tileset, pplayer)->qcolor);
1789 p.end();
1790 item->setData(col, Qt::DecorationRole, *pixmap);
1791 delete pixmap;
1792 break;
1793 case 5:
1794 item->setText(col, nation);
1795 break;
1796 case 6:
1797 item->setText(col, team);
1798 break;
1799 case 7:
1800 item->setText(col, host);
1801 break;
1802 default:
1803 break;
1804 }
1805 }
1806
1807 // Find any custom observers
1808 recursed_items.clear();
1809 conn_list_iterate(pplayer->connections, pconn) {
1810 if (pconn->id == conn_id) {
1811 continue;
1812 }
1813 item_r = new QTreeWidgetItem();
1814 item_r->setText(0, pconn->username);
1815 item_r->setText(5, _("Observer"));
1816 item_r->setText(7, pconn->addr);
1817 recursed_items.append(item_r);
1818 item->addChildren(recursed_items);
1819 } conn_list_iterate_end;
1820 items.append(item);
1821 }
1822 } players_iterate_end;
1823
1824 player_item->addChildren(items);
1825 start_players_tree->insertTopLevelItem(0, player_item);
1826
1827 // Insert global observers
1828 items.clear();
1829 global_item = new QTreeWidgetItem();
1830 global_item->setText(0, _("Global observers"));
1831 qvar2 = 0;
1832 global_item->setData(0, Qt::UserRole, qvar2);
1833
1834 conn_list_iterate(game.est_connections, pconn) {
1835 if (NULL != pconn->playing || !pconn->observer) {
1836 continue;
1837 }
1838 item = new QTreeWidgetItem();
1839 for (int col = 0; col < 8; col++) {
1840 switch (col) {
1841 case 0:
1842 item->setText(col, pconn->username);
1843 break;
1844 case 5:
1845 item->setText(col, _("Observer"));
1846 break;
1847 case 7:
1848 item->setText(col, pconn->addr);
1849 break;
1850 default:
1851 break;
1852 }
1853 items.append(item);
1854 }
1855 } conn_list_iterate_end;
1856
1857 global_item->addChildren(items);
1858 start_players_tree->insertTopLevelItem(1, global_item);
1859 items.clear();
1860
1861 // Insert detached
1862 detach_item = new QTreeWidgetItem();
1863 detach_item->setText(0, _("Detached"));
1864 qvar2 = 0;
1865 detach_item->setData(0, Qt::UserRole, qvar2);
1866
1867 conn_list_iterate(game.all_connections, pconn) {
1868 if (NULL != pconn->playing || pconn->observer) {
1869 continue;
1870 }
1871 item = new QTreeWidgetItem();
1872 item->setText(0, pconn->username);
1873 item->setText(7, pconn->addr);
1874 items.append(item);
1875 } conn_list_iterate_end;
1876
1877 detach_item->addChildren(items);
1878 start_players_tree->insertTopLevelItem(2, detach_item);
1879 start_players_tree->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1880 start_players_tree->expandAll();
1881 update_buttons();
1882}
1883
1884/**********************************************************************/
1887 void fc_client::update_buttons()
1888{
1889 bool sensitive;
1890 QString text;
1891
1892 // Observe button
1893 if (client_is_observer() || client_is_global_observer()) {
1894 obs_button->setText(_("Don't Observe"));
1895 } else {
1896 obs_button->setText(_("Observe"));
1897 }
1898
1899 // Ready button
1900 if (can_client_control()) {
1901 sensitive = client_player()->is_alive;
1902 if (client_player()->is_ready) {
1903 text = _("Not ready");
1904 } else {
1905 int num_unready = 0;
1906
1907 players_iterate_alive(pplayer) {
1908 if (is_human(pplayer) && !pplayer->is_ready) {
1909 num_unready++;
1910 }
1911 } players_iterate_alive_end;
1912
1913 if (num_unready > 1) {
1914 text = _("Ready");
1915 } else {
1916 /* We are the last unready player so clicking here will
1917 * immediately start the game. */
1918 text = _("Start");
1919 }
1920 }
1921 } else {
1922 text = _("Start");
1923 if (can_client_access_hack() && client.conn.observer) {
1924 sensitive = true;
1925 players_iterate_alive(plr) {
1926 if (is_human(plr)) {
1927 /* There's human controlled player(s) in game, so it's their
1928 * job to start the game. */
1929 sensitive = false;
1930 break;
1931 }
1932 } players_iterate_alive_end;
1933 } else {
1934 sensitive = false;
1935 }
1936 }
1937 start_button->setEnabled(sensitive);
1938 start_button->setText(text);
1939
1940 // Nation button
1941 sensitive = game.info.is_new_game && can_client_control();
1942 nation_button->setEnabled(sensitive);
1943
1944 sensitive = game.info.is_new_game;
1945 pr_options->setEnabled(sensitive);
1946
1947 gui()->pr_options->update_buttons();
1948 gui()->pr_options->update_ai_level();
1949}
1950
1951/**********************************************************************/
1954 void fc_client::start_page_menu(QPoint pos)
1955{
1956 QAction *action;
1957 QPoint global_pos = start_players_tree->mapToGlobal(pos);
1958 QString me, splayer, str, sp;
1959 bool need_empty_team;
1960 const char *level_cmd, *level_name;
1961 int level, count;
1962 QVariant qvar, qvar2;
1963
1964 me = client.conn.username;
1965 QTreeWidgetItem *item = start_players_tree->itemAt(pos);
1966
1967 if (item == nullptr) {
1968 return;
1969 }
1970
1971 qvar = item->data(0, Qt::UserRole);
1972 qvar2 = item->data(1, Qt::UserRole);
1973
1979 if (qvar == 1) {
1980 player *pplayer = (player *) qvar2.value < void *>();
1981
1982 if (pplayer != nullptr) {
1983 QMenu *page_menu = new QMenu(this);
1984
1985 page_submenu_AI = new QMenu(this);
1986 page_submenu_team = new QMenu(this);
1987
1988 splayer = QString(pplayer->name);
1989 sp = "\"" + splayer + "\"";
1990 if (me != splayer) {
1991 str = QString(_("Observe"));
1992 action = new QAction(str, start_players_tree);
1993 str = "/observe " + sp;
1994 QObject::connect(action, &QAction::triggered, [this,str]() {
1995 send_fake_chat_message(str);
1996 });
1997 page_menu->addAction(action);
1998
1999 if (ALLOW_CTRL <= client.conn.access_level) {
2000 str = QString(_("Remove player"));
2001 action = new QAction(str, start_players_tree);
2002 str = "/remove " + sp;
2003 QObject::connect(action, &QAction::triggered, [this,str]() {
2004 send_fake_chat_message(str);
2005 });
2006 page_menu->addAction(action);
2007 }
2008 str = QString(_("Take this player"));
2009 action = new QAction(str, start_players_tree);
2010 str = "/take " + sp;
2011 QObject::connect(action, &QAction::triggered, [this,str]() {
2012 send_fake_chat_message(str);
2013 });
2014 page_menu->addAction(action);
2015 }
2016
2017 if (can_conn_edit_players_nation(&client.conn, pplayer)) {
2018 str = QString(_("Pick nation"));
2019 action = new QAction(str, start_players_tree);
2020 str = "PICK:" + QString(player_name(pplayer)); // PICK is a key
2021 QObject::connect(action, &QAction::triggered, [this,str]() {
2022 send_fake_chat_message(str);
2023 });
2024 page_menu->addAction(action);
2025 }
2026
2027 if (is_ai(pplayer)) {
2028 // Set AI difficulty submenu
2029 if (ALLOW_CTRL <= client.conn.access_level) {
2030 page_submenu_AI->setTitle(_("Set difficulty"));
2031 page_menu->addMenu(page_submenu_AI);
2032
2033 for (level = 0; level < AI_LEVEL_COUNT; level++) {
2034 if (is_settable_ai_level(static_cast < ai_level > (level))) {
2035 level_name = ai_level_translated_name(static_cast < ai_level > (level));
2036 level_cmd = ai_level_cmd(static_cast < ai_level > (level));
2037 action = new QAction(QString(level_name), start_players_tree);
2038 str = "/" + QString(level_cmd) + " " + sp;
2039 QObject::connect(action, &QAction::triggered, [this,str]() {
2040 send_fake_chat_message(str);
2041 });
2042 page_submenu_AI->addAction(action);
2043 }
2044 }
2045 }
2046 }
2047
2048 // Put to Team X submenu
2049 if (game.info.is_new_game) {
2050 page_menu->addMenu(page_submenu_team);
2051 page_submenu_team->setTitle(_("Put on team"));
2052 page_menu->addMenu(page_submenu_team);
2053 count = pplayer->team ?
2054 player_list_size(team_members(pplayer->team)) : 0;
2055 need_empty_team = (count != 1);
2056 team_slots_iterate(tslot) {
2057 if (!team_slot_is_used(tslot)) {
2058 if (!need_empty_team) {
2059 continue;
2060 }
2061 need_empty_team = false;
2062 }
2063 str = team_slot_name_translation(tslot);
2064 action = new QAction(str, start_players_tree);
2065 str = "/team" + sp + " \"" + QString(team_slot_rule_name(tslot))
2066 + "\"";
2067 QObject::connect(action, &QAction::triggered, [this,str]() {
2068 send_fake_chat_message(str);
2069 });
2070 page_submenu_team->addAction(action);
2071 } team_slots_iterate_end;
2072 }
2073
2074 if (ALLOW_CTRL <= client.conn.access_level) {
2075 str = QString(_("Aitoggle player"));
2076 action = new QAction(str, start_players_tree);
2077 str = "/aitoggle " + sp;
2078 QObject::connect(action, &QAction::triggered, [this,str]() {
2079 send_fake_chat_message(str);
2080 });
2081 page_menu->addAction(action);
2082 }
2083
2084 page_menu->popup(global_pos);
2085 }
2086 }
2087}
2088
2089/**********************************************************************/
2092 void fc_client::slot_pick_nation()
2093{
2094 popup_races_dialog(client_player());
2095}
2096
2097/**********************************************************************/
2100 void fc_client::reload_sidebar_icons()
2101{
2102 sw_map->set_pixmap(fc_icons::instance()->get_pixmap("view"));
2103 sw_cunit->set_pixmap(fc_icons::instance()->get_pixmap("units"));
2104 sw_cities->set_pixmap(fc_icons::instance()->get_pixmap("cities"));
2105 sw_diplo->set_pixmap(fc_icons::instance()->get_pixmap("nations"));
2106 sw_science->set_pixmap(fc_icons::instance()->get_pixmap("research"));
2107 sw_economy->set_pixmap(fc_icons::instance()->get_pixmap("economy"));
2108 sw_endturn->set_pixmap(fc_icons::instance()->get_pixmap("endturn"));
2109 sidebar_wdg->resize_me(game_tab_widget->height(), true);
2110}
2111
2112/**********************************************************************/
2115 void fc_client::update_sidebar_tooltips()
2116{
2117 QString str;
2118 int max;
2119 int entries_used, building_total, unit_total, tax;
2120 char buf[256];
2121
2122 struct improvement_entry building_entries[B_LAST];
2123 struct unit_entry unit_entries[U_LAST];
2124
2125 if (current_page() != PAGE_GAME) {
2126 return;
2127 }
2128
2129 if (NULL != client.conn.playing) {
2130 max = get_player_bonus(client.conn.playing, EFT_MAX_RATES);
2131 } else {
2132 max = 100;
2133 }
2134
2135 if (!client_is_global_observer()) {
2136 sw_science->set_tooltip(science_dialog_text());
2137 str = QString(nation_plural_for_player(client_player()));
2138 str = str + '\n' + get_info_label_text(false);
2139 sw_map->set_tooltip(str);
2140 str = QString(_("Tax: %1% Science: %2% Luxury: %3%\n"))
2141 .arg(client.conn.playing->economic.tax)
2142 .arg(client.conn.playing->economic.luxury)
2143 .arg(client.conn.playing->economic.science);
2144
2145 str += QString(_("%1 - max rate: %2%")).
2146 arg(government_name_for_player(client.conn.playing),
2147 QString::number(max));
2148
2149 get_economy_report_units_data(unit_entries, &entries_used, &unit_total);
2150 get_economy_report_data(building_entries, &entries_used,
2151 &building_total, &tax);
2152 fc_snprintf(buf, sizeof(buf), _("Income: %d Total Costs: %d"),
2153 tax, building_total + unit_total);
2154 sw_economy->set_tooltip(buf);
2155 if (player_primary_capital(client_player())) {
2156 sw_cities->set_tooltip(text_happiness_cities(
2157 player_primary_capital(client_player())));
2158 }
2159 } else {
2160 sw_tax->set_tooltip("");
2161 sw_science->set_tooltip("");
2162 sw_map->set_tooltip("");
2163 sw_economy->set_tooltip("");
2164 }
2165 sw_indicators->set_tooltip(QString(get_info_label_text_popup()));
2166}
2167
2168/**********************************************************************/
2171 void center_next_enemy_city()
2172{
2173 bool center_next = false;
2174 bool first_tile = false;
2175 int first_id;
2176 struct tile *ptile = nullptr;
2177
2178 players_iterate(pplayer) {
2179 if (pplayer != client_player()) {
2180 city_list_iterate(pplayer->cities, pcity) {
2181 if (!first_tile) {
2182 first_tile = true;
2183 ptile = pcity->tile;
2184 first_id = pcity->id;
2185 }
2186 if ((last_center_enemy_city == 0) || center_next) {
2187 last_center_enemy_city = pcity->id;
2188 center_tile_mapcanvas(pcity->tile);
2189 return;
2190 }
2191 if (pcity->id == last_center_enemy_city) {
2192 center_next = true;
2193 }
2194 } city_list_iterate_end;
2195 }
2196 } players_iterate_end;
2197
2198 if (ptile != nullptr) {
2199 center_tile_mapcanvas(ptile);
2200 last_center_enemy_city = first_id;
2201 }
2202}
2203
2204/**********************************************************************/
2207 void center_next_player_city()
2208{
2209 bool center_next = false;
2210 bool first_tile = false;
2211 int first_id;
2212 struct tile *ptile = nullptr;
2213
2214 players_iterate(pplayer) {
2215 if (pplayer == client_player()) {
2216 city_list_iterate(pplayer->cities, pcity) {
2217 if (!first_tile) {
2218 first_tile = true;
2219 ptile = pcity->tile;
2220 first_id = pcity->id;
2221 }
2222 if ((last_center_player_city == 0) || center_next) {
2223 last_center_player_city = pcity->id;
2224 center_tile_mapcanvas(pcity->tile);
2225 return;
2226 }
2227 if (pcity->id == last_center_player_city) {
2228 center_next = true;
2229 }
2230 } city_list_iterate_end;
2231 }
2232 } players_iterate_end;
2233
2234 if (ptile != nullptr) {
2235 center_tile_mapcanvas(ptile);
2236 last_center_player_city = first_id;
2237 }
2238}
2239
2240/**********************************************************************/
2243 void center_next_player_capital()
2244{
2245 struct city *capital;
2246 bool center_next = false;
2247 bool first_tile = false;
2248 int first_id;
2249 struct tile *ptile = nullptr;
2250
2251 players_iterate(pplayer) {
2252 if (pplayer != client_player()) {
2253 capital = player_primary_capital(pplayer);
2254 if (capital == nullptr) {
2255 continue;
2256 }
2257 if (!first_tile) {
2258 first_tile = true;
2259 ptile = capital->tile;
2260 first_id = capital->id;
2261 }
2262 if ((last_center_player_city == 0) || center_next) {
2263 last_center_player_city = capital->id;
2264 center_tile_mapcanvas(capital->tile);
2265 put_cross_overlay_tile(capital->tile);
2266 return;
2267 }
2268 if (capital->id == last_center_player_city) {
2269 center_next = true;
2270 }
2271 }
2272 } players_iterate_end;
2273
2274 if (ptile != nullptr) {
2275 center_tile_mapcanvas(ptile);
2276 put_cross_overlay_tile(ptile);
2277 last_center_player_city = first_id;
2278 }
2279
2280}
2281
2282/**********************************************************************/
2285 void fc_client::update_sidebar_position()
2286{
2287 pages_layout[PAGE_GAME]->removeWidget(gui()->sidebar_wdg);
2288 if (gui_options.gui_qt_sidebar_left) {
2289 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 0);
2290 } else {
2291 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 2);
2292 }
2293}
2294
2295/**********************************************************************/
2298 void cycle_enemy_units()
2299{
2300 bool center_next = false;
2301 bool first_tile = false;
2302 int first_id;
2303 struct tile *ptile = nullptr;
2304
2305 players_iterate(pplayer) {
2306 if (pplayer != client_player()) {
2307 unit_list_iterate(pplayer->units, punit) {
2308 if (!first_tile) {
2309 first_tile = true;
2310 ptile = punit->tile;
2311 first_id = punit->id;
2312 }
2313 if ((last_center_enemy == 0) || center_next) {
2314 last_center_enemy = punit->id;
2315 center_tile_mapcanvas(punit->tile);
2316 return;
2317 }
2318 if (punit->id == last_center_enemy) {
2319 center_next = true;
2320 }
2321 } unit_list_iterate_end;
2322 }
2323 } players_iterate_end;
2324
2325 if (ptile != nullptr) {
2326 center_tile_mapcanvas(ptile);
2327 last_center_enemy = first_id;
2328 }
2329}
entries_used
int entries_used
Definition agents.c:77
str
#define str
Definition astring.c:76
n
#define n
Definition astring.c:77
qtg_version_message
void qtg_version_message(const char *vertext)
Definition chatline.cpp:806
send_chat_printf
int send_chat_printf(const char *format,...)
Definition chatline_common.c:55
send_chat
int send_chat(const char *message)
Definition chatline_common.c:46
output_window_append
void output_window_append(const struct ft_color color, const char *featured_text)
Definition chatline_common.c:104
city_list_iterate
#define city_list_iterate(citylist, pcity)
Definition city.h:508
city_list_iterate_end
#define city_list_iterate_end
Definition city.h:510
cityrep_g.h
chat_input
Definition chatline.h:82
fc_client::game_tab_widget
fc_game_tab_widget * game_tab_widget
Definition fc_client.h:259
fc_client::status_bar_queue
QStringList status_bar_queue
Definition fc_client.h:351
fc_client::handle_authentication_req
void handle_authentication_req(enum authentication_type type, const char *message)
Definition pages.cpp:1569
fc_client::connect_host_edit
QLineEdit * connect_host_edit
Definition fc_client.h:188
fc_client::sw_tax
fc_sidewidget * sw_tax
Definition fc_client.h:222
fc_client::update_buttons
void update_buttons()
Definition pages.cpp:1887
fc_client::output_window
QTextEdit * output_window
Definition fc_client.h:181
fc_client::update_sidebar_tooltips
void update_sidebar_tooltips()
Definition pages.cpp:2115
fc_client::gtd
goto_dialog * gtd
Definition fc_client.h:265
fc_client::sw_economy
fc_sidewidget * sw_economy
Definition fc_client.h:223
fc_client::meta_scan_timer
QTimer * meta_scan_timer
Definition fc_client.h:212
fc_client::battlelog_wdg
hud_battle_log * battlelog_wdg
Definition fc_client.h:272
fc_client::start_button
QPushButton * start_button
Definition fc_client.h:196
fc_client::start_from_save
void start_from_save()
Definition pages.cpp:1119
fc_client::connect_lan
QWidget * connect_lan
Definition fc_client.h:174
fc_client::add_game_tab
int add_game_tab(QWidget *widget)
Definition pages.cpp:798
fc_client::sw_science
fc_sidewidget * sw_science
Definition fc_client.h:275
fc_client::lan_widget
QTableWidget * lan_widget
Definition fc_client.h:205
fc_client::browse_saves
void browse_saves()
Definition pages.cpp:818
fc_client::connect_metaserver
QWidget * connect_metaserver
Definition fc_client.h:175
fc_client::game_main_widget
QWidget * game_main_widget
Definition fc_client.h:176
fc_client::connect_confirm_password_edit
QLineEdit * connect_confirm_password_edit
Definition fc_client.h:192
fc_client::chat_line
chat_input * chat_line
Definition fc_client.h:203
fc_client::unitinfo_wdg
hud_units * unitinfo_wdg
Definition fc_client.h:271
fc_client::pre_vote
pregamevote * pre_vote
Definition fc_client.h:262
fc_client::nation_button
QPushButton * nation_button
Definition fc_client.h:197
fc_client::saves_load
QTableWidget * saves_load
Definition fc_client.h:208
fc_client::set_status_bar
void set_status_bar(QString str, int timeout=2000)
Definition pages.cpp:438
fc_client::button
QPushButton * button
Definition fc_client.h:194
fc_client::show_preview
QCheckBox * show_preview
Definition fc_client.h:186
fc_client::sw_cunit
fc_sidewidget * sw_cunit
Definition fc_client.h:274
fc_client::current_page
enum client_pages current_page()
Definition fc_client.cpp:441
fc_client::check_server_scan
bool check_server_scan(server_scan *scan_data)
Definition pages.cpp:1032
fc_client::connect_password_edit
QLineEdit * connect_password_edit
Definition fc_client.h:191
fc_client::quit
void quit()
Definition fc_client.cpp:525
fc_client::minimapview_wdg
minimap_view * minimapview_wdg
Definition fc_client.h:232
fc_client::reload_sidebar_icons
void reload_sidebar_icons()
Definition pages.cpp:2100
fc_client::wan_widget
QTableWidget * wan_widget
Definition fc_client.h:206
fc_client::slot_pick_nation
void slot_pick_nation()
Definition pages.cpp:2092
fc_client::mapview_wdg
map_view * mapview_wdg
Definition fc_client.h:230
fc_client::slot_selection_changed
void slot_selection_changed(const QItemSelection &, const QItemSelection &)
Definition pages.cpp:1137
fc_client::sw_indicators
fc_sidewidget * sw_indicators
Definition fc_client.h:277
fc_client::page_submenu_AI
QMenu * page_submenu_AI
Definition fc_client.h:281
fc_client::infotab
info_tab * infotab
Definition fc_client.h:261
fc_client::scenarios_text
QLabel * scenarios_text
Definition fc_client.h:183
fc_client::load_save_text
QLabel * load_save_text
Definition fc_client.h:184
fc_client::create_start_page
void create_start_page()
Definition pages.cpp:628
fc_client::slot_disconnect
void slot_disconnect()
Definition fc_client.cpp:537
fc_client::clear_status_bar
void clear_status_bar()
Definition pages.cpp:454
fc_client::sw_endturn
fc_sidewidget * sw_endturn
Definition fc_client.h:276
fc_client::slot_pregame_observe
void slot_pregame_observe()
Definition fc_client.cpp:549
fc_client::state_preview
void state_preview(int)
Definition pages.cpp:834
fc_client::info_widget
QTableWidget * info_widget
Definition fc_client.h:207
fc_client::set_connection_state
void set_connection_state(enum connection_state state)
Definition pages.cpp:253
fc_client::obs_button
QPushButton * obs_button
Definition fc_client.h:195
fc_client::load_pix
QLabel * load_pix
Definition fc_client.h:185
fc_client::status_bar_label
QLabel * status_bar_label
Definition fc_client.h:217
fc_client::pages_layout
QGridLayout * pages_layout[PAGE_GAME+2]
Definition fc_client.h:178
fc_client::connect_login_edit
QLineEdit * connect_login_edit
Definition fc_client.h:190
fc_client::scenarios_view
QTextEdit * scenarios_view
Definition fc_client.h:182
fc_client::destroy_server_scans
void destroy_server_scans(void)
Definition pages.cpp:983
fc_client::update_sidebar_position
void update_sidebar_position()
Definition pages.cpp:2285
fc_client::page_submenu_team
QMenu * page_submenu_team
Definition fc_client.h:282
fc_client::switch_page
void switch_page(int i)
Definition fc_client.cpp:338
fc_client::create_network_page
void create_network_page()
Definition pages.cpp:290
fc_client::start_players_tree
QTreeWidget * start_players_tree
Definition fc_client.h:210
fc_client::create_load_page
void create_load_page()
Definition pages.cpp:482
fc_client::lan_scan_timer
QTimer * lan_scan_timer
Definition fc_client.h:213
fc_client::update_start_page
void update_start_page()
Definition pages.cpp:1664
fc_client::connect_port_edit
QLineEdit * connect_port_edit
Definition fc_client.h:189
fc_client::sidebar_wdg
fc_sidebar * sidebar_wdg
Definition fc_client.h:231
fc_client::create_main_page
void create_main_page()
Definition pages.cpp:137
fc_client::create_loading_page
void create_loading_page()
Definition pages.cpp:470
fc_client::start_page_menu
void start_page_menu(QPoint)
Definition pages.cpp:1954
fc_client::update_server_list
void update_server_list(enum server_scan_type sstype, const struct server_list *list)
Definition pages.cpp:869
fc_client::update_network_lists
void update_network_lists()
Definition pages.cpp:1013
fc_client::central_wdg
QWidget * central_wdg
Definition fc_client.h:256
fc_client::slot_meta_scan
void slot_meta_scan()
Definition pages.cpp:1077
fc_client::current_file
QString current_file
Definition fc_client.h:352
fc_client::slot_lan_scan
void slot_lan_scan()
Definition pages.cpp:1066
fc_client::x_vote
xvote * x_vote
Definition fc_client.h:264
fc_client::browse_scenarios
void browse_scenarios()
Definition pages.cpp:852
fc_client::slot_pregame_start
void slot_pregame_start()
Definition fc_client.cpp:567
fc_client::sw_cities
fc_sidewidget * sw_cities
Definition fc_client.h:221
fc_client::popup_client_options
void popup_client_options()
Definition fc_client.cpp:882
fc_client::slot_connect
void slot_connect()
Definition pages.cpp:1607
fc_client::sw_map
fc_sidewidget * sw_map
Definition fc_client.h:220
fc_client::update_load_page
void update_load_page(void)
Definition pages.cpp:1401
fc_client::start_scenario
void start_scenario()
Definition pages.cpp:1101
fc_client::pr_options
pregame_options * pr_options
Definition fc_client.h:267
fc_client::scenarios_load
QTableWidget * scenarios_load
Definition fc_client.h:209
fc_client::rm_game_tab
void rm_game_tab(int index)
Definition pages.cpp:810
fc_client::send_fake_chat_message
void send_fake_chat_message(const QString &message)
Definition fc_client.cpp:298
fc_client::sw_diplo
fc_sidewidget * sw_diplo
Definition fc_client.h:278
fc_client::create_scenario_page
void create_scenario_page()
Definition pages.cpp:561
fc_client::start_new_game
void start_new_game()
Definition pages.cpp:1088
fc_client::update_scenarios_page
void update_scenarios_page(void)
Definition pages.cpp:1432
fc_client::create_game_page
void create_game_page()
Definition pages.cpp:712
fc_game_tab_widget
Definition fc_client.h:107
fc_icons::get_icon
QIcon get_icon(const QString &id)
Definition fc_client.cpp:1017
fc_icons::instance
static fc_icons * instance()
Definition fc_client.cpp:995
fc_sidewidget
Definition sidebar.h:50
fc_sidewidget::set_wheel_down
void set_wheel_down(pfcn func)
Definition sidebar.cpp:287
fc_sidewidget::set_wheel_up
void set_wheel_up(pfcn func)
Definition sidebar.cpp:295
fc_sidewidget::set_pixmap
void set_pixmap(QPixmap *pm)
Definition sidebar.cpp:120
fc_sidewidget::set_right_click
void set_right_click(pfcn func)
Definition sidebar.cpp:279
fc_sidewidget::set_tooltip
void set_tooltip(QString tooltip)
Definition sidebar.cpp:160
goto_dialog
Definition gotodlg.h:43
hud_battle_log
Definition hudwidget.h:357
hud_units
Definition hudwidget.h:206
info_tab
Definition messagewin.h:72
map_view
Definition mapview.h:80
minimap_view
Definition mapview.h:219
pregame_options
Definition fc_client.h:370
pregame_options::update_ai_level
void update_ai_level()
Definition fc_client.cpp:1288
pregame_options::set_aifill
void set_aifill(int aifill)
Definition fc_client.cpp:1252
pregame_options::init
void init()
Definition fc_client.cpp:1168
pregame_options::update_buttons
void update_buttons()
Definition fc_client.cpp:1262
pregamevote
Definition voteinfo_bar.h:31
xvote
Definition voteinfo_bar.h:57
can_client_control
bool can_client_control(void)
Definition client_main.c:1253
client_is_global_observer
bool client_is_global_observer(void)
Definition client_main.c:1345
client_is_observer
bool client_is_observer(void)
Definition client_main.c:1083
user_name
char user_name[512]
Definition client_main.c:142
server_host
char server_host[512]
Definition client_main.c:141
client
struct civclient client
Definition client_main.c:150
fc_password
char fc_password[MAX_LEN_PASSWORD]
Definition client_main.c:143
server_port
int server_port
Definition client_main.c:145
client_main.h
client_player
#define client_player()
Definition client_main.h:106
list
static struct fc_sockaddr_list * list
Definition clinet.c:102
connect_to_server
int connect_to_server(const char *username, const char *hostname, int port, char *errbuf, int errbufsize)
Definition clinet.c:249
get_player_color
struct color * get_player_color(const struct tileset *t, const struct player *pplayer)
Definition colors_common.c:125
player_has_color
bool player_has_color(const struct player *pplayer)
Definition colors_common.c:113
incite_cost
char * incite_cost
Definition comments.c:74
authentication_type
authentication_type
Definition conn_types.h:41
AUTH_NEWUSER_RETRY
@ AUTH_NEWUSER_RETRY
Definition conn_types.h:45
AUTH_NEWUSER_FIRST
@ AUTH_NEWUSER_FIRST
Definition conn_types.h:43
AUTH_LOGIN_RETRY
@ AUTH_LOGIN_RETRY
Definition conn_types.h:44
AUTH_LOGIN_FIRST
@ AUTH_LOGIN_FIRST
Definition conn_types.h:42
is_server_running
bool is_server_running(void)
Definition connectdlg_common.c:124
client_start_server
bool client_start_server(void)
Definition connectdlg_common.c:224
can_client_access_hack
bool can_client_access_hack(void)
Definition connectdlg_common.c:141
connectdlg_common.h
conn_list_iterate
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
conn_list_iterate_end
#define conn_list_iterate_end
Definition connection.h:110
key_unit_wait
void key_unit_wait(void)
Definition control.c:3513
key_center_capital
void key_center_capital(void)
Definition control.c:3266
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
fc_client.h
connection_state
connection_state
Definition fc_client.h:55
LOGIN_TYPE
@ LOGIN_TYPE
Definition fc_client.h:56
NEW_PASSWORD_TYPE
@ NEW_PASSWORD_TYPE
Definition fc_client.h:57
WAITING_TYPE
@ WAITING_TYPE
Definition fc_client.h:59
ENTER_PASSWORD_TYPE
@ ENTER_PASSWORD_TYPE
Definition fc_client.h:58
gui
class fc_client * gui()
Definition gui_main.cpp:84
MAX_LEN_NAME
#define MAX_LEN_NAME
Definition fc_types.h:66
Q_
#define Q_(String)
Definition fcintl.h:70
_
#define _(String)
Definition fcintl.h:67
fc_mutex_allocate
void fc_mutex_allocate(fc_mutex *mutex)
fc_mutex_release
void fc_mutex_release(fc_mutex *mutex)
ftc_client
const struct ft_color ftc_client
Definition featured_text.c:78
game
struct civ_game game
Definition game.c:62
game.h
government_name_for_player
const char * government_name_for_player(const struct player *pplayer)
Definition government.c:154
city_report_dialog_popup
void city_report_dialog_popup(bool raise)
Definition cityrep.c:292
popup_races_dialog
void popup_races_dialog(struct player *pplayer)
Definition dialogs.c:1215
pos
static struct tile * pos
Definition finddlg.c:53
put_cross_overlay_tile
void put_cross_overlay_tile(struct tile *ptile)
Definition mapview.c:643
meta_scan
static struct server_scan_timer_data meta_scan
Definition pages.c:86
connection_status
static enum connection_state connection_status
Definition pages.c:843
lan_scan
static struct server_scan_timer_data lan_scan
Definition pages.c:87
connection_state
connection_state
Definition pages.c:836
server_scan_error
static void server_scan_error(struct server_scan *scan, const char *message)
Definition pages.c:809
holding_srv_list_mutex
static bool holding_srv_list_mutex
Definition pages.c:95
popup_players_dialog
void popup_players_dialog(bool raise)
Definition plrdlg.c:91
economy_report_dialog_popup
void economy_report_dialog_popup(bool raise)
Definition repodlgs.c:1243
type
GType type
Definition repodlgs.c:1313
server_list
static struct server_list * server_list
Definition connectdlg.c:61
colors.h
dialogs.h
pages.h
plrdlg.h
sprite.h
voteinfo_bar.h
B_LAST
#define B_LAST
Definition improvement.h:42
log_error
#define log_error(message,...)
Definition log.h:103
nat_x
#define nat_x
nat_y
#define nat_y
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1237
gui
static mpgui * gui
Definition mpgui_qt.cpp:52
nation_adjective_for_player
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
can_conn_edit_players_nation
bool can_conn_edit_players_nation(const struct connection *pconn, const struct player *pplayer)
Definition nation.c:1187
nation_plural_for_player
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
NO_NATION_SELECTED
#define NO_NATION_SELECTED
Definition nation.h:30
gui_options
struct client_options gui_options
Definition options.c:71
send_packet_authentication_reply
int send_packet_authentication_reply(struct connection *pc, const struct packet_authentication_reply *packet)
Definition packets_gen.c:2267
get_government_tooltip
const char * get_government_tooltip(void)
Definition text.c:1478
text_happiness_cities
const char * text_happiness_cities(const struct city *pcity)
Definition text.c:1900
qtg_real_set_client_page
void qtg_real_set_client_page(enum client_pages page)
Definition pages.cpp:103
last_center_capital
int last_center_capital
Definition pages.cpp:67
last_center_enemy
int last_center_enemy
Definition pages.cpp:80
center_next_enemy_city
static void center_next_enemy_city()
Definition pages.cpp:2171
qtg_get_current_client_page
enum client_pages qtg_get_current_client_page()
Definition pages.cpp:121
center_next_player_city
static void center_next_player_city()
Definition pages.cpp:2207
popup_shortcuts_dialog
void popup_shortcuts_dialog()
Definition shortcuts.cpp:756
connection_status
static enum connection_state connection_status
Definition pages.cpp:77
meta_scan
static struct server_scan * meta_scan
Definition pages.cpp:75
qtg_set_rulesets
void qtg_set_rulesets(int num_rulesets, char **rulesets)
Definition pages.cpp:113
last_center_player_city
int last_center_player_city
Definition pages.cpp:68
get_info_label_text_popup
const char * get_info_label_text_popup(void)
Definition text.c:969
toggle_units_report
void toggle_units_report(bool)
Definition repodlgs.cpp:1870
holding_srv_list_mutex
static bool holding_srv_list_mutex
Definition pages.cpp:76
science_dialog_text
const char * science_dialog_text(void)
Definition text.c:741
cycle_enemy_units
static void cycle_enemy_units()
Definition pages.cpp:2298
char2terrain
static struct terrain * char2terrain(char ch)
Definition pages.cpp:86
last_center_enemy_city
int last_center_enemy_city
Definition pages.cpp:69
get_nuclear_winter_tooltip
const char * get_nuclear_winter_tooltip(void)
Definition text.c:1451
server_scan_error
void server_scan_error(struct server_scan *scan, const char *message)
Definition pages.cpp:970
get_bulb_tooltip
const char * get_bulb_tooltip(void)
Definition text.c:1367
get_info_label_text
const char * get_info_label_text(bool)
Definition text.c:917
get_global_warming_tooltip
const char * get_global_warming_tooltip(void)
Definition text.c:1424
update_start_page
void update_start_page(void)
Definition pages.cpp:129
lan_scan
static struct server_scan * lan_scan
Definition pages.cpp:75
center_next_player_capital
static void center_next_player_capital()
Definition pages.cpp:2243
is_settable_ai_level
bool is_settable_ai_level(enum ai_level level)
Definition player.c:1919
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:895
player_has_flag
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1990
player_primary_capital
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1337
ai_level_cmd
#define ai_level_cmd(_level_)
Definition player.h:567
players_iterate_end
#define players_iterate_end
Definition player.h:537
players_iterate
#define players_iterate(_pplayer)
Definition player.h:532
is_barbarian
static bool is_barbarian(const struct player *pplayer)
Definition player.h:489
is_ai
#define is_ai(plr)
Definition player.h:230
players_iterate_alive_end
#define players_iterate_alive_end
Definition player.h:547
is_human
#define is_human(plr)
Definition player.h:229
players_iterate_alive
#define players_iterate_alive(_pplayer)
Definition player.h:542
qtg_cxxside.h
secfile_destroy
void secfile_destroy(struct section_file *secfile)
Definition section_file.c:95
secfile_load_section
struct section_file * secfile_load_section(const char *filename, const char *section, bool allow_duplicates)
Definition registry_ini.c:596
secfile_lookup_bool_default
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
Definition registry_ini.c:1900
secfile_lookup_int_default
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Definition registry_ini.c:2000
secfile_lookup_str_default
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Definition registry_ini.c:2205
get_economy_report_units_data
void get_economy_report_units_data(struct unit_entry *entries, int *num_entries_used, int *total_cost)
Definition repodlgs_common.c:105
get_economy_report_data
void get_economy_report_data(struct improvement_entry *entries, int *num_entries_used, int *total_cost, int *total_income)
Definition repodlgs_common.c:46
repodlgs_g.h
rgbcolor.h
char2terrain
static struct terrain * char2terrain(char ch)
Definition savegame2.c:1331
server_scan_get_list
struct srv_list * server_scan_get_list(struct server_scan *scan)
Definition servers.c:866
server_scan_finish
void server_scan_finish(struct server_scan *scan)
Definition servers.c:879
server_scan_begin
struct server_scan * server_scan_begin(enum server_scan_type type, ServerScanErrorFunc error_func)
Definition servers.c:755
server_scan_get_type
enum server_scan_type server_scan_get_type(const struct server_scan *scan)
Definition servers.c:809
server_scan_poll
enum server_scan_status server_scan_poll(struct server_scan *scan)
Definition servers.c:832
server_list_iterate_end
#define server_list_iterate_end
Definition servers.h:57
server_scan_status
server_scan_status
Definition servers.h:79
SCAN_STATUS_PARTIAL
@ SCAN_STATUS_PARTIAL
Definition servers.h:82
SCAN_STATUS_ERROR
@ SCAN_STATUS_ERROR
Definition servers.h:80
SCAN_STATUS_DONE
@ SCAN_STATUS_DONE
Definition servers.h:83
server_list_iterate
#define server_list_iterate(serverlist, pserver)
Definition servers.h:55
server_scan_type
server_scan_type
Definition servers.h:67
SERVER_SCAN_LOCAL
@ SERVER_SCAN_LOCAL
Definition servers.h:68
SERVER_SCAN_GLOBAL
@ SERVER_SCAN_GLOBAL
Definition servers.h:69
level
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
get_scenario_dirs
const struct strvec * get_scenario_dirs(void)
Definition shared.c:978
get_save_dirs
const struct strvec * get_save_dirs(void)
Definition shared.c:941
fileinfolist_infix
struct fileinfo_list * fileinfolist_infix(const struct strvec *dirs, const char *infix, bool nodups)
Definition shared.c:1211
fileinfo_list_iterate
#define fileinfo_list_iterate(list, pnode)
Definition shared.h:176
fileinfo_list_iterate_end
#define fileinfo_list_iterate_end
Definition shared.h:178
side_center_unit
void side_center_unit()
Definition sidebar.cpp:649
side_show_map
void side_show_map(bool nothing)
Definition sidebar.cpp:623
side_indicators_menu
void side_indicators_menu()
Definition sidebar.cpp:701
side_left_click_science
void side_left_click_science(bool nothing)
Definition sidebar.cpp:808
side_rates_wdg
void side_rates_wdg(bool nothing)
Definition sidebar.cpp:639
side_finish_turn
void side_finish_turn(bool nothing)
Definition sidebar.cpp:631
side_right_click_science
void side_right_click_science(void)
Definition sidebar.cpp:759
side_right_click_diplomacy
void side_right_click_diplomacy(void)
Definition sidebar.cpp:715
sidebar.h
SW_TAX
@ SW_TAX
Definition sidebar.h:26
SW_INDICATORS
@ SW_INDICATORS
Definition sidebar.h:26
action
Definition actions.h:360
city
Definition city.h:320
city::id
int id
Definition city.h:326
city::capital
enum capital_type capital
Definition city.h:328
city::tile
struct tile * tile
Definition city.h:322
civ_game::est_connections
struct conn_list * est_connections
Definition game.h:97
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::all_connections
struct conn_list * all_connections
Definition game.h:96
civclient::conn
struct connection conn
Definition client_main.h:96
client_options::gui_qt_show_preview
bool gui_qt_show_preview
Definition options.h:407
client_options::gui_qt_sidebar_left
bool gui_qt_sidebar_left
Definition options.h:409
color
Definition colors.h:21
connection::playing
struct player * playing
Definition connection.h:151
connection::access_level
enum cmdlevel access_level
Definition connection.h:177
connection::observer
bool observer
Definition connection.h:147
connection::username
char username[MAX_LEN_NAME]
Definition connection.h:164
img
Definition mapimg.c:367
improvement_entry
Definition repodlgs_common.h:28
item
Definition climisc.h:80
message
Definition messagewin_common.h:29
packet_authentication_reply
Definition packets_gen.h:64
packet_game_info::is_new_game
bool is_new_game
Definition packets_gen.h:186
player_economic::luxury
int luxury
Definition player.h:64
player_economic::science
int science
Definition player.h:63
player_economic::tax
int tax
Definition player.h:62
player
Definition player.h:247
player::team
struct team * team
Definition player.h:259
player::economic
struct player_economic economic
Definition player.h:282
player::name
char name[MAX_LEN_NAME]
Definition player.h:249
rgbcolor
Definition rgbcolor.h:33
rgbcolor::g
int g
Definition rgbcolor.h:34
rgbcolor::b
int b
Definition rgbcolor.h:34
rgbcolor::r
int r
Definition rgbcolor.h:34
section_file
Definition section_file.h:36
server_scan
Definition servers.c:84
server
Definition servers.h:29
sprite
Definition sprite.h:22
srv_list
Definition servers.h:62
srv_list::mutex
fc_mutex mutex
Definition servers.h:64
srv_list::servers
struct server_list * servers
Definition servers.h:63
team
Definition team.c:40
terrain
Definition terrain.h:182
tile
Definition tile.h:50
tileset
Definition tilespec.c:481
unit_entry
Definition repodlgs_common.h:34
unit::id
int id
Definition unit.h:145
unit::tile
struct tile * tile
Definition unit.h:140
widget
Definition widget.h:112
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
sz_strlcpy
#define sz_strlcpy(dest, src)
Definition support.h:189
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
fc_strncmp
#define fc_strncmp(_s1_, _s2_, _len_)
Definition support.h:154
team_name_translation
const char * team_name_translation(const struct team *pteam)
Definition team.c:420
team_slot_name_translation
const char * team_slot_name_translation(const struct team_slot *tslot)
Definition team.c:253
team_members
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
team_slot_is_used
bool team_slot_is_used(const struct team_slot *tslot)
Definition team.c:162
team_slot_rule_name
const char * team_slot_rule_name(const struct team_slot *tslot)
Definition team.c:233
team_slots_iterate_end
#define team_slots_iterate_end
Definition team.h:77
team_slots_iterate
#define team_slots_iterate(_tslot)
Definition team.h:72
terrain_by_rule_name
struct terrain * terrain_by_rule_name(const char *name)
Definition terrain.c:186
terrain_type_iterate
#define terrain_type_iterate(_p)
Definition terrain.h:373
T_UNKNOWN
#define T_UNKNOWN
Definition terrain.h:57
TERRAIN_UNKNOWN_IDENTIFIER
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:195
terrain_type_iterate_end
#define terrain_type_iterate_end
Definition terrain.h:379
tileset_main_intro_filename
const char * tileset_main_intro_filename(const struct tileset *t)
Definition tilespec.c:947
get_nation_flag_sprite
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6760
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
U_LAST
#define U_LAST
Definition unittype.h:40
fc_git_revision
const char * fc_git_revision(void)
Definition version.c:75
unstable_message
const char * unstable_message(void)
Definition version.c:160
word_version
const char * word_version(void)
Definition version.c:62
version.h