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