Freeciv-3.4
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.4.0, Qt6 client"
163#if defined(FC_QT6X_MODE)
164 fc_snprintf(msgbuf, sizeof(msgbuf), _("%s%s, Qt6x client"),
166#else // FC_QT6X_MODE
167 fc_snprintf(msgbuf, sizeof(msgbuf), _("%s%s, Qt6 client"),
169#endif // FC_QT6X_MODE
170 } else {
171 fc_snprintf(msgbuf, sizeof(msgbuf), "%s%s",
173 painter.drawText(10,
174 main_graphics.height() - fm.descent() - fm.height() * 2,
175 msgbuf);
176
177 // TRANS: "commit: [modified] <git commit id>"
178 fc_snprintf(msgbuf, sizeof(msgbuf), _("commit: %s"), rev_ver);
179 painter.drawText(10,
180 main_graphics.height() - fm.descent() - fm.height(),
181 msgbuf);
182
183#if defined(FC_QT6X_MODE)
184 strncpy(msgbuf, _("Qt6x client"), sizeof(msgbuf) - 1);
185#else // FC_QT6X_MODE
186 strncpy(msgbuf, _("Qt6 client"), sizeof(msgbuf) - 1);
187#endif // FC_QT6X_MODE
188 }
189
190 painter.drawText(main_graphics.width() - fm.horizontalAdvance (msgbuf)
191 -10, main_graphics.height() - fm.descent(), msgbuf);
192 free_main_pic->setPixmap(main_graphics);
194 row++, 0, 1, 2, Qt::AlignCenter);
195
196#if IS_BETA_VERSION || IS_DEVEL_VERSION
197 warn_color.setColor(QPalette::WindowText, Qt::red);
198 unstable_label->setPalette(warn_color);
199 unstable_label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Maximum);
200 unstable_label->setAlignment(Qt::AlignCenter);
202 row++, 0, 1, 2, Qt::AlignHCenter);
203#endif // IS_BETA_VERSION || IS_DEVEL_VERSION
204
205 buttons_names << _("Start new game") << _("Start scenario game")
206 << _("Load saved game") << _("Connect to network game")
207 << _("Options") << _("Quit");
208
209 buttons_nr = buttons_names.count();
210
211 for (int iter = 0; iter < buttons_nr; iter++) {
212 button = new QPushButton(buttons_names[iter]);
213
214 switch (iter) {
215 case 0:
216 pages_layout[PAGE_MAIN]->addWidget(button, row + 1, 0);
217 button->setToolTip(
218 _("Launches local server, and connects to it for a single-player game."));
219 connect(button, &QAbstractButton::clicked, this, &fc_client::start_new_game);
220 break;
221 case 1:
222 pages_layout[PAGE_MAIN]->addWidget(button, row + 2, 0);
223 button->setToolTip(
224 _("Loads one of the scenarios for a single-player game. "
225 "Tutorial is one of the scenarios."));
226 QObject::connect(button, &QPushButton::clicked, [this]() {
228 });
229 break;
230 case 2:
231 pages_layout[PAGE_MAIN]->addWidget(button, row + 3, 0);
232 button->setToolTip(
233 _("Continues previously saved single-player game."));
234 QObject::connect(button, &QPushButton::clicked, [this]() {
236 });
237 break;
238 case 3:
239 pages_layout[PAGE_MAIN]->addWidget(button, row + 1, 1);
240 button->setToolTip(
241 _("Connects to outside server. "
242 "Sometimes you want to launch a separate server even for local games."));
243 QObject::connect(button, &QPushButton::clicked, [this]() {
245 });
246 break;
247 case 4:
248 pages_layout[PAGE_MAIN]->addWidget(button, row + 2, 1);
249 button->setToolTip(_("Adjusting client-side options."));
250 connect(button, &QAbstractButton::clicked, this, &fc_client::popup_client_options);
251 break;
252 case 5:
253 pages_layout[PAGE_MAIN]->addWidget(button, row + 3, 1);
254 button->setToolTip(_("Gives you a break from playing freeciv."));
255 QObject::connect(button, &QAbstractButton::clicked, this, &fc_client::quit);
256 break;
257 default:
258 break;
259 }
260 }
261}
262
263/**********************************************************************/
267{
268 switch (state) {
269 case LOGIN_TYPE:
270 set_status_bar("");
271 connect_password_edit->setText("");
272 connect_password_edit->setDisabled(true);
274 connect_confirm_password_edit->setDisabled(true);
275 break;
277 connect_password_edit->setText("");
279 connect_password_edit->setDisabled(false);
280 connect_confirm_password_edit->setDisabled(false);
281 connect_password_edit->setFocus(Qt::OtherFocusReason);
282 break;
284 connect_password_edit->setText("");
286 connect_password_edit->setDisabled(false);
287 connect_confirm_password_edit->setDisabled(true);
288 connect_password_edit->setFocus(Qt::OtherFocusReason);
289
290
291 break;
292 case WAITING_TYPE:
293 set_status_bar("");
294 break;
295 }
296
297 connection_status = state;
298}
299
300/**********************************************************************/
304{
305 QHeaderView *header;
306 QLabel *connect_msg;
307 QLabel *lan_label;
308 QPushButton *network_button;
309
315
316 connect_host_edit = new QLineEdit;
317 connect_port_edit = new QLineEdit;
318 connect_login_edit = new QLineEdit;
319 connect_password_edit = new QLineEdit;
320 connect_confirm_password_edit = new QLineEdit;
321
322 connect_password_edit->setEchoMode(QLineEdit::Password);
323 connect_confirm_password_edit->setEchoMode(QLineEdit::Password);
324
325 connect_password_edit->setDisabled(true);
326 connect_confirm_password_edit->setDisabled(true);
327 connect_lan = new QWidget;
328 connect_metaserver = new QWidget;
329 lan_widget = new QTableWidget;
330 wan_widget = new QTableWidget;
331 info_widget = new QTableWidget;
332
334 servers_list << _("Server Name") << _("Port") << _("Version")
335 << _("Status") << Q_("?count:Players") << _("Comment");
337 server_info << _("Name") << _("Type") << _("Host") << _("Nation");
338
339 lan_widget->setRowCount(0);
340 lan_widget->setColumnCount(servers_list.count());
341 lan_widget->verticalHeader()->setVisible(false);
342 lan_widget->setAutoScroll(false);
343
344 wan_widget->setRowCount(0);
345 wan_widget->setColumnCount(servers_list.count());
346 wan_widget->verticalHeader()->setVisible(false);
347 wan_widget->setAutoScroll(false);
348
349 info_widget->setRowCount(0);
350 info_widget->setColumnCount(server_info.count());
351 info_widget->verticalHeader()->setVisible(false);
352
353 lan_widget->setHorizontalHeaderLabels(servers_list);
354 lan_widget->setProperty("showGrid", "false");
355 lan_widget->setProperty("selectionBehavior", "SelectRows");
356 lan_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
357 lan_widget->setSelectionMode(QAbstractItemView::SingleSelection);
358
359 wan_widget->setHorizontalHeaderLabels(servers_list);
360 wan_widget->setProperty("showGrid", "false");
361 wan_widget->setProperty("selectionBehavior", "SelectRows");
362 wan_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
363 wan_widget->setSelectionMode(QAbstractItemView::SingleSelection);
364
365 connect(wan_widget->selectionModel(),
366 &QItemSelectionModel::selectionChanged, this,
368
369 connect(lan_widget->selectionModel(),
370 &QItemSelectionModel::selectionChanged, this,
372 connect(wan_widget, &QTableWidget::itemDoubleClicked, this,
374 connect(lan_widget, &QTableWidget::itemDoubleClicked, this,
376
377 info_widget->setHorizontalHeaderLabels(server_info);
378 info_widget->setProperty("selectionBehavior", "SelectRows");
379 info_widget->setEditTriggers(QAbstractItemView::NoEditTriggers);
380 info_widget->setSelectionMode(QAbstractItemView::SingleSelection);
381 info_widget->setProperty("showGrid", "false");
382 info_widget->setAlternatingRowColors(true);
383
384 header = lan_widget->horizontalHeader();
385 header->setSectionResizeMode(0, QHeaderView::Stretch);
386 header->setStretchLastSection(true);
387 header = wan_widget->horizontalHeader();
388 header->setSectionResizeMode(0, QHeaderView::Stretch);
389 header->setStretchLastSection(true);
390 header = info_widget->horizontalHeader();
391 header->setSectionResizeMode(0, QHeaderView::Stretch);
392 header->setStretchLastSection(true);
393
395 label_names << _("Connect") << _("Port") << _("Login")
396 << _("Password") << _("Confirm Password");
397
398 for (int i = 0; i < label_names.count(); i++) {
399 connect_msg = new QLabel;
400 connect_msg->setText(label_names[i]);
401 page_network_grid_layout->addWidget(connect_msg, i, 0, Qt::AlignHCenter);
402 }
403
409 page_network_grid_layout->addWidget(info_widget, 0, 2, 5, 4);
410
411 network_button = new QPushButton(_("Refresh"));
412 QObject::connect(network_button, &QAbstractButton::clicked, this,
415
416 network_button = new QPushButton(_("Cancel"));
417 QObject::connect(network_button, &QPushButton::clicked, [this]() {
419 });
420 page_network_grid_layout->addWidget(network_button, 5, 2, 1, 1);
421
422 network_button = new QPushButton(_("Connect"));
423 page_network_grid_layout->addWidget(network_button, 5, 5, 1, 1);
424 connect(network_button, &QAbstractButton::clicked, this, &fc_client::slot_connect);
425 connect(connect_login_edit, &QLineEdit::returnPressed,
427 connect(connect_password_edit, &QLineEdit::returnPressed,
429 connect(connect_confirm_password_edit, &QLineEdit::returnPressed,
431
434 page_network_lan_layout->addWidget(lan_widget, 0);
435 page_network_wan_layout->addWidget(wan_widget, 1);
436 lan_label = new QLabel(_("Internet servers:"));
437 page_network_layout->addWidget(lan_label, 1);
438 page_network_layout->addWidget(wan_widget, 10);
439 lan_label = new QLabel(_("Local servers:"));
440 page_network_layout->addWidget(lan_label, 1);
441 page_network_layout->addWidget(lan_widget, 1);
442 page_network_grid_layout->setColumnStretch(3, 4);
445
446}
447
448/**********************************************************************/
452{
453 if (status_bar_label->text().isEmpty()) {
454 status_bar_label->setText(message);
455 QTimer::singleShot(timeout, this, SLOT(clear_status_bar()));
456 } else {
458 while (status_bar_queue.count() > 3) {
459 status_bar_queue.removeFirst();
460 }
461 }
462}
463
464/**********************************************************************/
468{
469 QString str;
470
471 if (!status_bar_queue.isEmpty()) {
472 str = status_bar_queue.takeFirst();
473 status_bar_label->setText(str);
474 QTimer::singleShot(2000, this, SLOT(clear_status_bar()));
475 } else {
476 status_bar_label->setText("");
477 }
478}
479
480/**********************************************************************/
484{
485 QLabel *label = new QLabel(_("Loading..."));
486
488 pages_layout[PAGE_GAME + 1]->addWidget(label, 0, 0, 1, 1,
489 Qt::AlignHCenter);
490}
491
492/**********************************************************************/
496{
498 QPushButton *but;
499 QHeaderView *header;
500 QLabel *lbl_show_preview;
501 QWidget *wdg;
503
504 saves_load = new QTableWidget;
505 wdg = new QWidget;
506 hbox = new QHBoxLayout;
508 lbl_show_preview = new QLabel(_("Show preview"));
509 sav << _("Choose Saved Game to Load") << _("Date");
510 load_pix = new QLabel;
511 load_pix->setProperty("themed_border", true);
512 load_pix->setFixedSize(0 ,0);
513 load_save_text = new QLabel;
514 load_save_text->setTextFormat(Qt::RichText);
515 load_save_text->setWordWrap(true);
518 saves_load->setAlternatingRowColors(true);
519 saves_load->setRowCount(0);
520 saves_load->setColumnCount(sav.count());
521 saves_load->setHorizontalHeaderLabels(sav);
522 hbox->addWidget(show_preview);
523 hbox->addWidget(lbl_show_preview, Qt::AlignLeft);
524 wdg->setLayout(hbox);
525
526 saves_load->setProperty("showGrid", "false");
527 saves_load->setProperty("selectionBehavior", "SelectRows");
528 saves_load->setEditTriggers(QAbstractItemView::NoEditTriggers);
529 saves_load->setSelectionMode(QAbstractItemView::SingleSelection);
530 saves_load->verticalHeader()->setVisible(false);
531
532 header = saves_load->horizontalHeader();
533 header->setSectionResizeMode(0, QHeaderView::Stretch);
534 header->setStretchLastSection(true);
535
536 pages_layout[PAGE_LOAD]->addWidget(saves_load, 0, 0, 1, 4);
537 connect(saves_load->selectionModel(),
538 &QItemSelectionModel::selectionChanged, this,
540#ifdef FC_QT6X_MODE
541 // Qt-6.7
542 connect(show_preview, &QCheckBox::checkStateChanged, this,
544#else // FC_QT6X_MODE
545 connect(show_preview, &QCheckBox::stateChanged, this,
547#endif // FC_QT6X_MODE
548 pages_layout[PAGE_LOAD]->addWidget(wdg, 1, 0);
549 pages_layout[PAGE_LOAD]->addWidget(load_save_text, 2, 0, 1, 2);
550 pages_layout[PAGE_LOAD]->addWidget(load_pix, 2, 2, 1, 2);
551
552 but = new QPushButton;
553 but->setText(_("Browse..."));
554 but->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon));
555 connect(but, &QAbstractButton::clicked, this, &fc_client::browse_saves);
556 pages_layout[PAGE_LOAD]->addWidget(but, 3, 0);
557
558 but = new QPushButton;
559 but->setText(_("Cancel"));
560 but->setIcon(QApplication::style()->standardIcon(
561 QStyle::SP_DialogCancelButton));
562 connect(but, &QAbstractButton::clicked, this, &fc_client::slot_disconnect);
563 pages_layout[PAGE_LOAD]->addWidget(but, 3, 2);
564
565 but = new QPushButton;
566 but->setText(_("Load"));
567 but->setIcon(QApplication::style()->standardIcon(
568 QStyle::SP_DialogOkButton));
569 connect(but, &QAbstractButton::clicked, this, &fc_client::start_from_save);
570 pages_layout[PAGE_LOAD]->addWidget(but, 3, 3);
571 pages_layout[PAGE_LOAD]->setColumnStretch(3, 10);
572 pages_layout[PAGE_LOAD]->setColumnStretch(2, 10);
573 pages_layout[PAGE_LOAD]->setColumnStretch(0, 10);
574
575}
576
577/**********************************************************************/
581{
582 QPushButton *but;
583 QHeaderView *header;
585
587 scenarios_load = new QTableWidget;
589 scenarios_text = new QLabel;
590
591 scenarios_view->setObjectName("scenarios_view");
592 scenarios_text->setTextFormat(Qt::RichText);
593 scenarios_text->setWordWrap(true);
594 sav << _("Choose a Scenario");
595 scenarios_load->setRowCount(0);
596 scenarios_load->setColumnCount(sav.count());
597 scenarios_load->setHorizontalHeaderLabels(sav);
598 scenarios_load->setProperty("showGrid", "false");
599 scenarios_load->setProperty("selectionBehavior", "SelectRows");
600 scenarios_load->setEditTriggers(QAbstractItemView::NoEditTriggers);
601 scenarios_load->setSelectionMode(QAbstractItemView::SingleSelection);
602 scenarios_load->verticalHeader()->setVisible(false);
603 pages_layout[PAGE_SCENARIO]->addWidget(scenarios_load, 0, 0, 3, 3,
604 Qt::AlignLeft);
605 pages_layout[PAGE_SCENARIO]->addWidget(scenarios_view, 1, 3, 2, 3);
606 pages_layout[PAGE_SCENARIO]->addWidget(scenarios_text, 0, 3, 1, 2,
607 Qt::AlignTop);
608 scenarios_view->setReadOnly(true);
609 scenarios_view->setWordWrapMode(QTextOption::WordWrap);
610 scenarios_text->setAlignment(Qt::AlignCenter);
611
612 header = scenarios_load->horizontalHeader();
613 header->setSectionResizeMode(0, QHeaderView::Stretch);
614 header->setStretchLastSection(true);
615 connect(scenarios_load->selectionModel(),
616 &QItemSelectionModel::selectionChanged, this,
618
619 but = new QPushButton;
620 but->setText(_("Browse..."));
621 but->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon));
622 connect(but, &QAbstractButton::clicked, this, &fc_client::browse_scenarios);
623 pages_layout[PAGE_SCENARIO]->addWidget(but, 4, 0);
624
625 but = new QPushButton;
626 but->setText(_("Cancel"));
627 but->setIcon(QApplication::style()->standardIcon(
628 QStyle::SP_DialogCancelButton));
629 connect(but, &QAbstractButton::clicked, this, &fc_client::slot_disconnect);
630 pages_layout[PAGE_SCENARIO]->addWidget(but, 4, 3);
631
632 pages_layout[PAGE_SCENARIO]->setColumnStretch(2, 10);
633 pages_layout[PAGE_SCENARIO]->setColumnStretch(4, 20);
634 pages_layout[PAGE_SCENARIO]->setColumnStretch(3, 20);
635 pages_layout[PAGE_SCENARIO]->setRowStretch(1, 5);
636 but = new QPushButton;
637 but->setText(_("Load Scenario"));
638 but->setIcon(QApplication::style()->standardIcon(
639 QStyle::SP_DialogOkButton));
640 connect(but, &QAbstractButton::clicked, this, &fc_client::start_scenario);
641 pages_layout[PAGE_SCENARIO]->addWidget(but, 4, 4);
642}
643
644/**********************************************************************/
648{
649 QPushButton *but;
650 QSplitter *splitter;
653 QWidget *up_widget;
654 QWidget *down_widget;
655 QFont f;
656
662 pr_options = new pregame_options(this);
663 chat_line = new chat_input;
664 chat_line->setProperty("doomchat", true);
666 output_window->setReadOnly(false);
667 f.setBold(true);
668 output_window->setFont(f);
669
670 pr_options->init();
671 player_widget_list << _("Name") << _("Ready") << Q_("?player:Leader")
672 << _("Flag") << _("Border") << _("Nation") << _("Team")
673 << _("Host");
674
675 start_players_tree->setColumnCount(player_widget_list.count());
676 start_players_tree->setHeaderLabels(player_widget_list);
677 start_players_tree->setContextMenuPolicy(Qt::CustomContextMenu);
678 start_players_tree->setProperty("selectionBehavior", "SelectRows");
679 start_players_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
680 start_players_tree->setRootIsDecorated(false);
681
682 connect(start_players_tree,
685
686 up_layout->addWidget(start_players_tree, 0, 0, 3, 6);
687 up_layout->addWidget(pr_options, 0, 6, 3, 2);
688 but = new QPushButton;
689 but->setText(_("Disconnect"));
690 but->setIcon(style()->standardPixmap(QStyle::SP_DialogCancelButton));
691 QObject::connect(but, &QAbstractButton::clicked, this, &fc_client::slot_disconnect);
692 down_layout->addWidget(but, 5, 4);
693 nation_button = new QPushButton;
694 nation_button->setText(_("Pick Nation"));
695 nation_button->setIcon(fc_icons::instance()->get_icon("flag"));
696 down_layout->addWidget(nation_button, 5, 5);
697 QObject::connect(nation_button, &QAbstractButton::clicked, this,
699
700 obs_button = new QPushButton;
701 obs_button->setText(_("Observe"));
702 obs_button->setIcon(fc_icons::instance()->get_icon("meeting-observer"));
703 down_layout->addWidget(obs_button, 5, 6);
704 QObject::connect(obs_button, &QAbstractButton::clicked, this,
706 start_button = new QPushButton;
707 start_button->setText(_("Start"));
708 start_button->setIcon(style()->standardPixmap(QStyle::SP_DialogOkButton));
709 down_layout->addWidget(start_button, 5, 7);
710 QObject::connect(start_button, &QAbstractButton::clicked, this,
712 pre_vote = new pregamevote;
713
714 down_layout->addWidget(pre_vote, 4, 0, 1, 4);
715 down_layout->addWidget(chat_line, 5, 0, 1, 4);
716 down_layout->addWidget(output_window, 3, 0, 1, 8);
717 splitter = new QSplitter;
718 up_widget = new QWidget();
719 down_widget = new QWidget();
720 up_widget->setLayout(up_layout);
721 down_widget->setLayout(down_layout);
722 splitter->addWidget(up_widget);
723 splitter->addWidget(down_widget);
724 splitter->setOrientation(Qt::Vertical);
725 pages_layout[PAGE_START]->addWidget(splitter);
726}
727
728/**********************************************************************/
732{
734
736 game_main_widget = new QWidget;
738 game_layout->setContentsMargins(0, 0, 0, 0);
739 game_layout->setSpacing(0);
740 mapview_wdg = new map_view();
741 mapview_wdg->setFocusPolicy(Qt::WheelFocus);
742 sidebar_wdg = new fc_sidebar();
743
744 sw_map = new fc_sidewidget(fc_icons::instance()->get_pixmap("view"),
745 Q_("?noun:View"), "MAP", side_show_map);
746 sw_tax = new fc_sidewidget(nullptr, nullptr, "", side_rates_wdg, SW_TAX);
747 sw_indicators = new fc_sidewidget(nullptr, nullptr, "", side_show_map,
750 sw_cunit = new fc_sidewidget(fc_icons::instance()->get_pixmap("units"),
751 _("Units"), "",
753 sw_cities = new fc_sidewidget(fc_icons::instance()->get_pixmap("cities"),
754 _("Cities"), "CTS",
758 sw_diplo = new fc_sidewidget(fc_icons::instance()->get_pixmap("nations"),
759 _("Nations"), "PLR", popup_players_dialog);
762 sw_science = new fc_sidewidget(fc_icons::instance()->get_pixmap("research"),
763 _("Research"), "SCI",
765 sw_economy = new fc_sidewidget(fc_icons::instance()->get_pixmap("economy"),
766 _("Economy"), "ECO",
768 sw_endturn = new fc_sidewidget(fc_icons::instance()->get_pixmap("endturn"),
769 _("Turn Done"), "", side_finish_turn);
775
785
787 minimapview_wdg->show();
790 battlelog_wdg->hide();
792 infotab->show();
793 x_vote = new xvote(mapview_wdg);
794 x_vote->hide();
796 gtd->hide();
797
798 game_layout->addWidget(mapview_wdg, 1, 0);
799 game_main_widget->setLayout(game_layout);
801 game_tab_widget->setMinimumSize(600,400);
802 game_tab_widget->setContentsMargins(0, 0, 0, 0);
805 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 0);
806 } else {
807 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 2);
808 }
809 pages_layout[PAGE_GAME]->addWidget(game_tab_widget, 1, 1);
810 pages_layout[PAGE_GAME]->setContentsMargins(0, 0, 0, 0);
811 pages_layout[PAGE_GAME]->setSpacing(0);
812}
813
814/**********************************************************************/
818{
819 int i;
820
821 i = game_tab_widget->addWidget(widget);
822 game_tab_widget->setCurrentWidget(widget);
823 return i;
824}
825
826/**********************************************************************/
830{
831 game_tab_widget->removeWidget(game_tab_widget->widget(index));
832}
833
834/**********************************************************************/
838{
839 QString str;
840 str = QString(_("Save Files"))
841 + QString(" (*.sav *.sav.bz2 *.sav.gz *.sav.xz *.sav.zst)");
842 current_file = QFileDialog::getOpenFileName(gui()->central_wdg,
843 _("Open Save File"),
844 QDir::homePath(), str);
845 if (!current_file.isEmpty()) {
847 }
848}
849
850/**********************************************************************/
853void fc_client::state_preview(Qt::CheckState state)
854{
856
857 if (show_preview->checkState() == Qt::Unchecked) {
859 } else {
861 }
862 slctn = saves_load->selectionModel()->selection();
863 saves_load->selectionModel()->clearSelection();
864 saves_load->selectionModel()->select(slctn, QItemSelectionModel::Rows
865 | QItemSelectionModel::SelectCurrent);
866}
867
868/**********************************************************************/
873{
875
876 if (show_preview->checkState() == Qt::Unchecked) {
878 } else {
880 }
881 slctn = saves_load->selectionModel()->selection();
882 saves_load->selectionModel()->clearSelection();
883 saves_load->selectionModel()->select(slctn, QItemSelectionModel::Rows
884 | QItemSelectionModel::SelectCurrent);
885}
886
887/**********************************************************************/
891{
892 QString str;
893
894 str = QString(_("Scenarios Files"))
895 + QString(" (*.sav *.sav.bz2 *.sav.gz *.sav.xz *.sav.zst)");
896 current_file = QFileDialog::getOpenFileName(gui()->central_wdg,
897 _("Open Scenario File"),
898 QDir::homePath(), str);
899 if (!current_file.isEmpty()) {
901 }
902}
903
904/**********************************************************************/
908 const struct server_list *list)
909{
910 QTableWidget *sel = nullptr;
911 QString host, portstr;
912 int port;
913 int row;
914 int old_row_count;
915
916 switch (sstype) {
918 sel = lan_widget;
919 break;
921 sel = wan_widget;
922 break;
923 default:
924 break;
925 }
926
927 if (!sel) {
928 return;
929 }
930
931 if (!list) {
932 return;
933 }
934
935 host = connect_host_edit->text();
936 portstr = connect_port_edit->text();
937 port = portstr.toInt();
938 old_row_count = sel->rowCount();
939 sel->clearContents();
940 row = 0;
942 char buf[35];
943 int tmp;
945
946 if (old_row_count <= row) {
947 sel->insertRow(row);
948 }
949
950 if (pserver->humans >= 0) {
951 fc_snprintf(buf, sizeof(buf), "%d", pserver->humans);
952 } else {
953 strncpy(buf, _("Unknown"), sizeof(buf) - 1);
954 buf[sizeof(buf) - 1] = '\0';
955 }
956
957 tmp = pserver->port;
958 tstring = QString::number(tmp);
959
960 for (int col = 0; col < 6; col++) {
962
963 item = new QTableWidgetItem();
964
965 switch (col) {
966 case 0:
967 item->setText(pserver->host);
968 break;
969 case 1:
970 item->setText(tstring);
971 break;
972 case 2:
973 item->setText(pserver->version);
974 break;
975 case 3:
976 item->setText(_(pserver->state));
977 break;
978 case 4:
979 item->setText(buf);
980 break;
981 case 5:
982 item->setText(pserver->message);
983 break;
984 default:
985 break;
986 }
987 sel->setItem(row, col, item);
988 }
989
990 if (host == pserver->host && port == pserver->port) {
991 sel->selectRow(row);
992 }
993
994 row++;
996
997 // Remove unneeded rows, if there are any
998 while (old_row_count - row > 0) {
999 sel->removeRow(old_row_count - 1);
1000 old_row_count--;
1001 }
1002
1003}
1004
1005/**********************************************************************/
1008void server_scan_error(struct server_scan *scan, const char *message)
1009{
1011 log_error("%s", message);
1012
1013 /* Main thread will finalize the scan later (or even concurrently) -
1014 * do not do anything here to cause double free or raze condition. */
1015}
1016
1017
1018/**********************************************************************/
1022{
1023 if (meta_scan) {
1025 meta_scan = nullptr;
1026 }
1027
1028 if (meta_scan_timer != nullptr) {
1029 meta_scan_timer->stop();
1030 meta_scan_timer->disconnect();
1031 delete meta_scan_timer;
1032 meta_scan_timer = nullptr;
1033 }
1034
1035 if (lan_scan) {
1037 lan_scan = nullptr;
1038 }
1039
1040 if (lan_scan_timer != nullptr) {
1041 lan_scan_timer->stop();
1042 lan_scan_timer->disconnect();
1043 delete lan_scan_timer;
1044 lan_scan_timer = nullptr;
1045 }
1046}
1047
1048/**********************************************************************/
1052{
1054
1055 lan_scan_timer = new QTimer(this);
1057 connect(lan_scan_timer, &QTimer::timeout, this, &fc_client::slot_lan_scan);
1058 lan_scan_timer->start(500);
1059
1060 meta_scan_timer = new QTimer(this);
1062 connect(meta_scan_timer, &QTimer::timeout, this, &fc_client::slot_meta_scan);
1063 meta_scan_timer->start(800);
1064
1065}
1066
1067/**********************************************************************/
1071{
1072 struct server_scan *scan = scan_data;
1074
1075 if (!scan) {
1076 return false;
1077 }
1078
1079 stat = server_scan_poll(scan);
1080
1081 if (stat >= SCAN_STATUS_PARTIAL) {
1083 struct srv_list *srvrs;
1084
1085 type = server_scan_get_type(scan);
1086 srvrs = server_scan_get_list(scan);
1087 fc_mutex_allocate(&srvrs->mutex);
1090 holding_srv_list_mutex = false;
1091 fc_mutex_release(&srvrs->mutex);
1092 }
1093
1095 return false;
1096 }
1097
1098 return true;
1099}
1100
1101/**********************************************************************/
1105{
1106 if (lan_scan_timer == nullptr) {
1107 return;
1108 }
1110}
1111
1112/**********************************************************************/
1116{
1117 if (meta_scan_timer == nullptr) {
1118 return;
1119 }
1121}
1122
1123/**********************************************************************/
1127{
1128 if (!is_server_running()) {
1130
1131 // Saved settings are sent in client/options.c
1132 // resend_desired_settable_options()
1133 }
1134}
1135
1136/**********************************************************************/
1140{
1141 if (!is_server_running()) {
1143 send_chat("/detach");
1144 }
1145 if (is_server_running() && !current_file.isEmpty()) {
1147
1148 c_bytes = current_file.toUtf8();
1149 send_chat_printf("/load %s", c_bytes.data());
1151 }
1152}
1153
1154/**********************************************************************/
1158{
1159 if (!is_server_running()) {
1161 send_chat("/detach");
1162 }
1163 if (is_server_running() && !current_file.isEmpty()) {
1165
1166 c_bytes = current_file.toUtf8();
1167 send_chat_printf("/load %s", c_bytes.data());
1169 }
1170}
1171
1172/**********************************************************************/
1177{
1178 QModelIndexList indexes = selected.indexes();
1180 QModelIndex index;
1183 QVariant qvar;
1185
1187 const char *terr_name;
1188 const struct server *pserver = nullptr;
1189 int ii = 0;
1190 int k, col, n, nat_y, nat_x;
1191 struct section_file *sf;
1192 struct srv_list *srvrs;
1194
1195 if (indexes.isEmpty()) {
1196 return;
1197 }
1198
1199 switch (cpage) {
1200 case PAGE_NETWORK:
1201 index = indexes.at(0);
1202 connect_host_edit->setText(index.data().toString());
1203 index = indexes.at(1);
1204 connect_port_edit->setText(index.data().toString());
1205
1207
1208 if (tw == lan_widget->selectionModel()) {
1209 wan_widget->clearSelection();
1210 } else {
1211 lan_widget->clearSelection();
1212 }
1213
1216 fc_mutex_allocate(&srvrs->mutex);
1217 }
1218 if (srvrs->servers) {
1219 pserver = server_list_get(srvrs->servers, index.row());
1220 }
1222 fc_mutex_release(&srvrs->mutex);
1223 }
1224 if (!pserver || !pserver->players) {
1225 return;
1226 }
1227 n = pserver->nplayers;
1228 info_widget->clearContents();
1229 info_widget->setRowCount(0);
1230 for (k = 0; k < n; k++) {
1231 info_widget->insertRow(k);
1232 for (col = 0; col < 4; col++) {
1233 item = new QTableWidgetItem();
1234 switch (col) {
1235 case 0:
1236 item->setText(pserver->players[k].name);
1237 break;
1238 case 1:
1239 item->setText(pserver->players[k].type);
1240 break;
1241 case 2:
1242 item->setText(pserver->players[k].host);
1243 break;
1244 case 3:
1245 item->setText(pserver->players[k].nation);
1246 break;
1247 default:
1248 break;
1249 }
1250 info_widget->setItem(k, col, item);
1251 }
1252 }
1253 break;
1254 case PAGE_SCENARIO:
1255 index = indexes.at(0);
1256 qvar = index.data(Qt::UserRole);
1257 sl = qvar.toStringList();
1258 scenarios_text->setText(sl.at(0));
1259 if (sl.count() > 1) {
1260 scenarios_view->setText(sl.at(2));
1261 current_file = sl.at(1);
1262 }
1263 break;
1264 case PAGE_LOAD:
1265 index = indexes.at(0);
1266 qvar = index.data(Qt::UserRole);
1267 current_file = qvar.toString();
1268 if (show_preview->checkState() == Qt::Unchecked) {
1269 load_pix->setPixmap(*(new QPixmap));
1270 load_save_text->setText("");
1271 break;
1272 }
1273 fn_bytes = current_file.toUtf8();
1274 if ((sf = secfile_load_section(fn_bytes.data(),
1275 "game", TRUE))) {
1276 const char *sname;
1277 int integer;
1279 QString pl_str = nullptr;
1280 int num_players = 0;
1281 int curr_player = 0;
1283
1284 integer = secfile_lookup_int_default(sf, -1, "game.turn");
1285 if (integer >= 0) {
1286 final_str = QString("<b>") + _("Turn") + ":</b> "
1287 + QString::number(integer).toHtmlEscaped() + "<br>";
1288 }
1289 if ((sf = secfile_load_section(fn_bytes.data(),
1290 "players", TRUE))) {
1291 integer = secfile_lookup_int_default(sf, -1, "players.nplayers");
1292 if (integer >= 0) {
1293 final_str = final_str + "<b>" + _("Players") + ":</b>" + " "
1294 + QString::number(integer).toHtmlEscaped() + "<br>";
1295 }
1296 num_players = integer;
1297 }
1298 for (int i = 0; i < num_players; i++) {
1299 pl_str = QString("player") + QString::number(i);
1300 pl_bytes = pl_str.toUtf8();
1301 if ((sf = secfile_load_section(fn_bytes.data(),
1302 pl_bytes.data(), true))) {
1303 if (!secfile_lookup_bool_default(sf, true,
1304 "player%d.unassigned_user",
1305 i)) {
1306 curr_player = i;
1307 break;
1308 }
1309 }
1310 }
1311 // Break case (and return) if no human player found
1312 if (pl_str == nullptr) {
1313 load_save_text->setText(final_str);
1314 break;
1315 }
1316
1317 // Information about human player
1318 pl_bytes = pl_str.toUtf8();
1319 if ((sf = secfile_load_section(fn_bytes.data(),
1320 pl_bytes.data(), true))) {
1321 sname = secfile_lookup_str_default(sf, nullptr, "player%d.nation",
1322 curr_player);
1323 if (sname) {
1324 final_str = final_str + "<b>" + _("Nation") + ":</b> "
1325 + QString(sname).toHtmlEscaped() + "<br>";
1326 }
1327 integer = secfile_lookup_int_default(sf, -1, "player%d.ncities",
1328 curr_player);
1329 if (integer >= 0) {
1330 final_str = final_str + "<b>" + _("Cities") + ":</b> "
1331 + QString::number(integer).toHtmlEscaped() + "<br>";
1332 }
1333 integer = secfile_lookup_int_default(sf, -1, "player%d.nunits",
1334 curr_player);
1335 if (integer >= 0) {
1336 final_str = final_str + "<b>" + _("Units") + ":</b> "
1337 + QString::number(integer).toHtmlEscaped() + "<br>";
1338 }
1339 integer = secfile_lookup_int_default(sf, -1, "player%d.gold",
1340 curr_player);
1341 if (integer >= 0) {
1342 final_str = final_str + "<b>" + _("Gold") + ":</b> "
1343 + QString::number(integer).toHtmlEscaped() + "<br>";
1344 }
1345 nat_x = 0;
1346 nat_y = 0;
1347 while (true) { // Until breaks out
1348 const char *line = secfile_lookup_str_default(sf, nullptr,
1349 "player%d.map_t%04d",
1350 curr_player, nat_y);
1351 if (line == nullptr) {
1352 break;
1353 }
1354 nat_y++;
1355 nat_x = strlen(line);
1357 }
1358
1359 // Reset terrain information
1361 pterr->identifier_load = '\0';
1363
1364 // Load possible terrains and their identifiers (chars)
1365 if ((sf = secfile_load_section(fn_bytes.data(),
1366 "savefile", true))) {
1367 while ((terr_name = secfile_lookup_str_default(sf, nullptr,
1368 "savefile.terrident%d.name", ii)) != nullptr) {
1370
1371 if (pterr != nullptr) {
1372 const char *iptr = secfile_lookup_str_default(sf, nullptr,
1373 "savefile.terrident%d.identifier", ii);
1374 pterr->identifier_load = *iptr;
1375 }
1376 ii++;
1377 }
1378 }
1379
1380 // Create image
1381 QImage img(nat_x, nat_y, QImage::Format_ARGB32_Premultiplied);
1382
1383 img.fill(Qt::black);
1384 for (int a = 0 ; a < nat_x; a++) {
1385 for (int b = 0; b < nat_y; b++) {
1386 struct terrain *tr;
1387 struct rgbcolor *rgb;
1388
1389 tr = char2terrain(str_pixmap.at(b * nat_x + a).toLatin1());
1390 if (tr != nullptr) {
1391 rgb = tr->rgb;
1392 QColor color;
1393
1394 color.setRgb(rgb->r, rgb->g, rgb->b);
1395 img.setPixel(a, b, color.rgb());
1396 }
1397 }
1398 }
1399 if (img.width() > 1) {
1400 load_pix->setPixmap(QPixmap::fromImage(img).scaledToHeight(200));
1401 } else {
1402 load_pix->setPixmap(*(new QPixmap));
1403 }
1404
1405 QPixmap pm = load_pix->pixmap();
1406
1407 load_pix->setFixedSize(pm.width(),
1408 pm.height());
1409
1410 if ((sf = secfile_load_section(fn_bytes.data(),
1411 "research", TRUE))) {
1412 sname = secfile_lookup_str_default(sf, nullptr,
1413 "research.r%d.now_name",
1414 curr_player);
1415 if (sname) {
1416 final_str = final_str + "<b>" + _("Researching") + ":</b> "
1417 + QString(sname).toHtmlEscaped();
1418 }
1419 }
1420 }
1421 load_save_text->setText(final_str);
1422 }
1423 break;
1424 default:
1425 break;
1426 }
1427
1428}
1429
1430/**********************************************************************/
1434{
1435 struct fileinfo_list *files;
1436 int row;
1437
1438 row = 0;
1439 files = fileinfolist_infix(get_save_dirs(), ".sav", FALSE);
1440 saves_load->clearContents();
1441 saves_load->setRowCount(0);
1445 QDateTime dt;
1446
1447 item = new QTableWidgetItem();
1448 item->setData(Qt::UserRole, QString(pfile->fullname));
1449 saves_load->insertRow(row);
1450 item->setText(pfile->name);
1451 saves_load->setItem(row, 0, item);
1452 item = new QTableWidgetItem();
1453 dt = QDateTime::fromSecsSinceEpoch(pfile->mtime);
1454 item->setText(dt.toString(Qt::TextDate));
1455 saves_load->setItem(row, 1, item);
1456 row++;
1458 fileinfo_list_destroy(files);
1459}
1460
1461/**********************************************************************/
1465{
1466 struct fileinfo_list *files;
1467 int row = 0;
1468
1469 scenarios_load->clearContents();
1470 scenarios_load->setRowCount(0);
1471 scenarios_text->setText("");
1472 scenarios_view->setText("");
1473
1474 files = fileinfolist_infix(get_scenario_dirs(), ".sav", false);
1476 struct section_file *sf;
1477
1478 if ((sf = secfile_load_section(pfile->fullname, "scenario", TRUE))
1479 && secfile_lookup_bool_default(sf, TRUE, "scenario.is_scenario")) {
1480
1481 const char *sname, *sdescription, *sauthors;
1483 QString format;
1484 QString st;
1485 int fcver;
1486 int fcdev;
1487 int current_ver = MAJOR_VERSION * 1000000 + MINOR_VERSION * 10000;
1489
1490 if (PATCH_VERSION >= 90) {
1491 // Patch level matters on development versions
1492 current_dev += PATCH_VERSION * 100;
1493 }
1494
1495 fcver = secfile_lookup_int_default(sf, 0, "scenario.game_version");
1496 if (fcver < 30000) {
1497 /* Pre-3.0 versions stored version number without emergency version
1498 * part in the end. To get comparable version number stored,
1499 * multiply by 100. */
1500 fcver *= 100;
1501 }
1502 if (fcver % 10000 >= 9000) {
1503 fcdev = fcver - (fcver % 100); // Emergency version does not count.
1504 } else {
1505 fcdev = fcver - (fcver % 10000); // Patch version does not count.
1506 }
1507 sname = secfile_lookup_str_default(sf, nullptr, "scenario.name");
1509 "scenario.description");
1511 "scenario.authors");
1512 // Ignore scenarios for newer freeciv versions than we are.
1513 if (fcdev <= current_dev) {
1514 QString version;
1515 bool add_item = true;
1516 bool found = false;
1518 int rows;
1519 int found_ver;
1520 int i;
1521
1522 if (fcver > 0) {
1523 int maj;
1524 int min;
1525
1526 maj = fcver / 1000000;
1527 fcver %= 1000000;
1528 min = fcver / 10000;
1529 fcver %= 10000;
1530 if (fcver >= 9000) {
1531 // Development version, have '+'
1532 version = QString("%1.%2+").arg(maj).arg(min);
1533 } else {
1534 version = QString("%1.%2").arg(maj).arg(min);
1535 }
1536 } else {
1537 // TRANS: Unknown scenario format
1538 version = QString(_("pre-2.6"));
1539 }
1540
1541 rows = scenarios_load->rowCount();
1542 for (i = 0; i < rows; ++i) {
1543 if (scenarios_load->item(i, 0)
1544 && scenarios_load->item(i, 0)->text() == pfile->name) {
1545 found = true;
1546 item = scenarios_load->takeItem(i, 0);
1547 break;
1548 }
1549 }
1550
1551 if (found) {
1552 sl = item->data(Qt::UserRole).toStringList();
1553 found_ver = sl.at(3).toInt();
1554 if (found_ver < fcver) {
1555 continue;
1556 }
1557 add_item = false;
1558 }
1559 if (add_item) {
1560 item = new QTableWidgetItem();
1561 scenarios_load->insertRow(row);
1562 }
1563 item->setText(QString(pfile->name));
1564 format = QString("<br>") + QString(_("Format:")) + " "
1565 + version.toHtmlEscaped();
1566 if (sauthors) {
1567 st = QString("\n") + QString("<b>") + _("Authors: ")
1568 + QString("</b>") + QString(sauthors).toHtmlEscaped();
1569 } else {
1570 st = "";
1571 }
1572 sl << "<b>"
1573 + QString(sname && strlen(sname) ? Q_(sname) : pfile->name)
1574 .toHtmlEscaped()
1575 + "</b>"
1576 << QString(pfile->fullname).toHtmlEscaped()
1577 << QString(sdescription != nullptr && '\0' != sdescription[0]
1578 ? Q_(sdescription) : "").toHtmlEscaped() + st + format
1579 << QString::number(fcver).toHtmlEscaped();
1580 sl.replaceInStrings("\n", "<br>");
1581 item->setData(Qt::UserRole, sl);
1582 if (add_item) {
1583 scenarios_load->setItem(row, 0, item);
1584 row++;
1585 } else {
1586 scenarios_load->setItem(i, 0, item);
1587 }
1588 }
1589 secfile_destroy(sf);
1590 }
1592 fileinfo_list_destroy(files);
1593 scenarios_load->sortItems(0);
1594 scenarios_load->update();
1595}
1596
1597/**********************************************************************/
1602 const char *message)
1603{
1604 set_status_bar(QString::fromUtf8(message));
1606
1607 switch (type) {
1608 case AUTH_NEWUSER_FIRST:
1609 case AUTH_NEWUSER_RETRY:
1611 return;
1612 case AUTH_LOGIN_FIRST:
1613 /* if we magically have a password already present in 'fc_password'
1614 * then, use that and skip the password entry dialog */
1615 if (fc_password[0] != '\0') {
1617
1618 sz_strlcpy(reply.password, fc_password);
1620 return;
1621 } else {
1623 }
1624
1625 return;
1626 case AUTH_LOGIN_RETRY:
1628 return;
1629 }
1630
1631 log_error("Unsupported authentication type %d: %s.", type, message);
1632}
1633
1634/**********************************************************************/
1640{
1641 char errbuf [512];
1644
1645 switch (connection_status) {
1646 case LOGIN_TYPE:
1647 ba_bytes = connect_login_edit->text().toUtf8();
1648 sz_strlcpy(user_name, ba_bytes.data());
1649 ba_bytes = connect_host_edit->text().toUtf8();
1651 server_port = connect_port_edit->text().toInt();
1652
1654 errbuf, sizeof(errbuf)) != -1) {
1655 } else {
1656 set_status_bar(QString::fromUtf8(errbuf));
1658 }
1659
1660 return;
1661 case NEW_PASSWORD_TYPE:
1662 ba_bytes = connect_password_edit->text().toLatin1();
1664 ba_bytes = connect_confirm_password_edit->text().toLatin1();
1665 sz_strlcpy(reply.password,
1666 ba_bytes.data());
1667
1668 if (!fc_strncmp(reply.password, fc_password, MAX_LEN_NAME)) {
1669 fc_password[0] = '\0';
1672 } else {
1673 set_status_bar(_("Passwords don't match, enter password."));
1675 }
1676
1677 return;
1679 ba_bytes = connect_password_edit->text().toLatin1();
1680 sz_strlcpy(reply.password,
1681 ba_bytes.data());
1684 return;
1685 case WAITING_TYPE:
1686 return;
1687 }
1688
1689 log_error("Unsupported connection status: %d", connection_status);
1690}
1691
1692/**********************************************************************/
1697{
1698 int conn_num, i;
1700 bool is_ready;
1701 QString host, nation, leader, team, str;
1702 QPixmap *pixmap;
1703 QPainter p;
1704 struct sprite *psprite;
1712 int conn_id;
1713 bool svg = is_svg_flag_enabled();
1714
1716
1717 if (conn_num == 0) {
1718 return;
1719 }
1720
1721 start_players_tree->clear();
1722 qvar2 = 0;
1723
1725 player_item->setText(0, Q_("?header:Players"));
1726 player_item->setData(0, Qt::UserRole, qvar2);
1727
1728 i = 0;
1729 players_iterate(pplayer) {
1730 i++;
1733 // Inserts playing players, observing custom players, and AI)
1734
1735 players_iterate(pplayer) {
1736 host = "";
1737 if (!player_has_flag(pplayer, PLRF_SCENARIO_RESERVED)) {
1738 conn_id = -1;
1739 conn_list_iterate(pplayer->connections, pconn) {
1740 if (pconn->playing == pplayer && !pconn->observer) {
1741 conn_id = pconn->id;
1742 host = pconn->addr;
1743 break;
1744 }
1746 if (is_barbarian(pplayer)) {
1747 continue;
1748 }
1749 if (is_ai(pplayer)) {
1750 is_ready = true;
1751 } else {
1752 is_ready = pplayer->is_ready;
1753 }
1754
1755 if (pplayer->nation == NO_NATION_SELECTED) {
1756 nation = _("Random");
1757
1758 if (pplayer->was_created) {
1759 leader = player_name(pplayer);
1760 } else {
1761 leader = "";
1762 }
1763 } else {
1764 nation = nation_adjective_for_player(pplayer);
1765 leader = player_name(pplayer);
1766 }
1767
1768 if (pplayer->team) {
1769 team = team_name_translation(pplayer->team);
1770 } else {
1771 team = "";
1772 }
1773
1774 item = new QTreeWidgetItem();
1775 for (int col = 0; col < 8; col++) {
1776 switch (col) {
1777 case 0:
1778 str = pplayer->username;
1779
1780 if (is_ai(pplayer)) {
1781 str = str + " <" + (ai_level_translated_name(pplayer->ai_common.skill_level))
1782 + ">";
1783 item->setIcon(col, fc_icons::instance()->get_icon("ai"));
1784 } else {
1785 item->setIcon(col, fc_icons::instance()->get_icon("human"));
1786 }
1787
1788 item->setText(col, str);
1789 qvar = QVariant::fromValue((void *) pplayer);
1790 qvar2 = 1;
1791 item->setData(0, Qt::UserRole, qvar2);
1792 item->setData(1, Qt::UserRole, qvar);
1793 break;
1794 case 1:
1795 if (is_ready) {
1796 item->setText(col, _("Yes"));
1797 } else {
1798 item->setText(col, _("No"));
1799 }
1800 break;
1801 case 2:
1802 item->setText(col, leader);
1803 break;
1804 case 3:
1805 if (!pplayer->nation) {
1806 break;
1807 }
1808 psprite = get_nation_flag_sprite(tileset, pplayer->nation);
1809 pixmap = psprite->pm;
1810 if (svg) {
1811 item->setData(col, Qt::DecorationRole, (*pixmap).scaledToHeight(50));
1812 } else {
1813 item->setData(col, Qt::DecorationRole, *pixmap);
1814 }
1815 break;
1816 case 4:
1817 if (!player_has_color(pplayer)) {
1818 break;
1819 }
1820 pixmap = new QPixmap(
1821 start_players_tree->header()->sectionSizeHint(col), 16);
1822 pixmap->fill(Qt::transparent);
1823 p.begin(pixmap);
1824 p.fillRect(pixmap->width() / 2 - 8, 0, 16, 16, Qt::black);
1825 p.fillRect(pixmap->width() / 2 - 7, 1, 14, 14,
1826 get_player_color(tileset, pplayer)->qcolor);
1827 p.end();
1828 item->setData(col, Qt::DecorationRole, *pixmap);
1829 delete pixmap;
1830 break;
1831 case 5:
1832 item->setText(col, nation);
1833 break;
1834 case 6:
1835 item->setText(col, team);
1836 break;
1837 case 7:
1838 item->setText(col, host);
1839 break;
1840 default:
1841 break;
1842 }
1843 }
1844
1845 // Find any custom observers
1846 recursed_items.clear();
1847 conn_list_iterate(pplayer->connections, pconn) {
1848 if (pconn->id == conn_id) {
1849 continue;
1850 }
1851 item_r = new QTreeWidgetItem();
1852 item_r->setText(0, pconn->username);
1853 item_r->setText(5, _("Observer"));
1854 item_r->setText(7, pconn->addr);
1855 recursed_items.append(item_r);
1856 item->addChildren(recursed_items);
1858 items.append(item);
1859 }
1861
1862 player_item->addChildren(items);
1863 start_players_tree->insertTopLevelItem(0, player_item);
1864
1865 // Insert global observers
1866 items.clear();
1868 global_item->setText(0, _("Global observers"));
1869 qvar2 = 0;
1870 global_item->setData(0, Qt::UserRole, qvar2);
1871
1873 if (pconn->playing != nullptr || !pconn->observer) {
1874 continue;
1875 }
1876 item = new QTreeWidgetItem();
1877 for (int col = 0; col < 8; col++) {
1878 switch (col) {
1879 case 0:
1880 item->setText(col, pconn->username);
1881 break;
1882 case 5:
1883 item->setText(col, _("Observer"));
1884 break;
1885 case 7:
1886 item->setText(col, pconn->addr);
1887 break;
1888 default:
1889 break;
1890 }
1891 items.append(item);
1892 }
1894
1895 global_item->addChildren(items);
1896 start_players_tree->insertTopLevelItem(1, global_item);
1897 items.clear();
1898
1899 // Insert detached
1901 detach_item->setText(0, _("Detached"));
1902 qvar2 = 0;
1903 detach_item->setData(0, Qt::UserRole, qvar2);
1904
1906 if (pconn->playing != nullptr || pconn->observer) {
1907 continue;
1908 }
1909 item = new QTreeWidgetItem();
1910 item->setText(0, pconn->username);
1911 item->setText(7, pconn->addr);
1912 items.append(item);
1914
1915 detach_item->addChildren(items);
1916 start_players_tree->insertTopLevelItem(2, detach_item);
1917 start_players_tree->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
1918 start_players_tree->expandAll();
1920}
1921
1922/**********************************************************************/
1926{
1927 bool sensitive;
1928 QString text;
1929
1930 // Observe button
1932 obs_button->setText(_("Don't Observe"));
1933 } else {
1934 obs_button->setText(_("Observe"));
1935 }
1936
1937 // Ready button
1938 if (can_client_control()) {
1939 sensitive = client_player()->is_alive;
1940 if (client_player()->is_ready) {
1941 text = _("Not ready");
1942 } else {
1943 int num_unready = 0;
1944
1945 players_iterate_alive(pplayer) {
1946 if (is_human(pplayer) && !pplayer->is_ready) {
1947 num_unready++;
1948 }
1950
1951 if (num_unready > 1) {
1952 text = _("Ready");
1953 } else {
1954 /* We are the last unready player so clicking here will
1955 * immediately start the game. */
1956 text = _("Start");
1957 }
1958 }
1959 } else {
1960 text = _("Start");
1962 sensitive = true;
1964 if (is_human(plr)) {
1965 /* There's human controlled player(s) in game, so it's their
1966 * job to start the game. */
1967 sensitive = false;
1968 break;
1969 }
1971 } else {
1972 sensitive = false;
1973 }
1974 }
1975 start_button->setEnabled(sensitive);
1976 start_button->setText(text);
1977
1978 // Nation button
1980 nation_button->setEnabled(sensitive);
1981
1983 pr_options->setEnabled(sensitive);
1984
1987}
1988
1989/**********************************************************************/
1993{
1994 QAction *action;
1995 QPoint global_pos = start_players_tree->mapToGlobal(pos);
1996 QString me, splayer, str, sp;
1997 bool need_empty_team;
1998 const char *level_cmd, *level_name;
1999 int level, count;
2001
2004
2005 if (item == nullptr) {
2006 return;
2007 }
2008
2009 qvar = item->data(0, Qt::UserRole);
2010 qvar2 = item->data(1, Qt::UserRole);
2011
2017 if (qvar == 1) {
2018 player *pplayer = (player *) qvar2.value < void *>();
2019
2020 if (pplayer != nullptr) {
2021 QMenu *page_menu = new QMenu(this);
2022
2023 page_submenu_AI = new QMenu(this);
2024 page_submenu_team = new QMenu(this);
2025
2026 splayer = QString(pplayer->name);
2027 sp = "\"" + splayer + "\"";
2028 if (me != splayer) {
2029 str = QString(_("Observe"));
2031 str = "/observe " + sp;
2032 QObject::connect(action, &QAction::triggered, [this,str]() {
2034 });
2035 page_menu->addAction(action);
2036
2038 str = QString(_("Remove player"));
2040 str = "/remove " + sp;
2041 QObject::connect(action, &QAction::triggered, [this,str]() {
2043 });
2044 page_menu->addAction(action);
2045 }
2046 str = QString(_("Take this player"));
2048 str = "/take " + sp;
2049 QObject::connect(action, &QAction::triggered, [this,str]() {
2051 });
2052 page_menu->addAction(action);
2053 }
2054
2055 if (can_conn_edit_players_nation(&client.conn, pplayer)) {
2056 str = QString(_("Pick nation"));
2058 str = "PICK:" + QString(player_name(pplayer)); // PICK is a key
2059 QObject::connect(action, &QAction::triggered, [this,str]() {
2061 });
2062 page_menu->addAction(action);
2063 }
2064
2065 if (is_ai(pplayer)) {
2066 // Set AI difficulty submenu
2068 page_submenu_AI->setTitle(_("Set difficulty"));
2069 page_menu->addMenu(page_submenu_AI);
2070
2071 for (level = 0; level < AI_LEVEL_COUNT; level++) {
2072 if (is_settable_ai_level(static_cast < ai_level > (level))) {
2073 level_name = ai_level_translated_name(static_cast < ai_level > (level));
2074 level_cmd = ai_level_cmd(static_cast < ai_level > (level));
2076 str = "/" + QString(level_cmd) + " " + sp;
2077 QObject::connect(action, &QAction::triggered, [this,str]() {
2079 });
2080 page_submenu_AI->addAction(action);
2081 }
2082 }
2083 }
2084 }
2085
2086 // Put to Team X submenu
2087 if (game.info.is_new_game) {
2088 page_menu->addMenu(page_submenu_team);
2089 page_submenu_team->setTitle(_("Put on team"));
2090 page_menu->addMenu(page_submenu_team);
2091 count = pplayer->team ?
2092 player_list_size(team_members(pplayer->team)) : 0;
2093 need_empty_team = (count != 1);
2095 if (!team_slot_is_used(tslot)) {
2096 if (!need_empty_team) {
2097 continue;
2098 }
2099 need_empty_team = false;
2100 }
2103 str = "/team" + sp + " \"" + QString(team_slot_rule_name(tslot))
2104 + "\"";
2105 QObject::connect(action, &QAction::triggered, [this,str]() {
2107 });
2108 page_submenu_team->addAction(action);
2110 }
2111
2113 str = QString(_("Aitoggle player"));
2115 str = "/aitoggle " + sp;
2116 QObject::connect(action, &QAction::triggered, [this,str]() {
2118 });
2119 page_menu->addAction(action);
2120 }
2121
2122 page_menu->popup(global_pos);
2123 }
2124 }
2125}
2126
2127/**********************************************************************/
2134
2135/**********************************************************************/
2139{
2140 sw_map->set_pixmap(fc_icons::instance()->get_pixmap("view"));
2141 sw_cunit->set_pixmap(fc_icons::instance()->get_pixmap("units"));
2142 sw_cities->set_pixmap(fc_icons::instance()->get_pixmap("cities"));
2143 sw_diplo->set_pixmap(fc_icons::instance()->get_pixmap("nations"));
2144 sw_science->set_pixmap(fc_icons::instance()->get_pixmap("research"));
2145 sw_economy->set_pixmap(fc_icons::instance()->get_pixmap("economy"));
2146 sw_endturn->set_pixmap(fc_icons::instance()->get_pixmap("endturn"));
2147 sidebar_wdg->resize_me(game_tab_widget->height(), true);
2148}
2149
2150/**********************************************************************/
2154{
2155 QString str;
2156 int max;
2158 char buf[256];
2161 struct player *pplayer;
2162
2163 if (current_page() != PAGE_GAME) {
2164 return;
2165 }
2166
2167 pplayer = client_player();
2168 if (pplayer != nullptr) {
2169 max = get_player_bonus(pplayer, EFT_MAX_RATES);
2170 } else {
2171 max = 100;
2172 }
2173
2177 str = str + '\n' + get_info_label_text(false);
2179 str = QString(_("Tax: %1% Science: %2% Luxury: %3%\n"))
2180 .arg(pplayer->economic.tax)
2181 .arg(pplayer->economic.luxury)
2182 .arg(pplayer->economic.science);
2183
2184 str += QString(_("%1 - max rate: %2%")).
2185 arg(government_name_for_player(pplayer),
2186 QString::number(max));
2187
2190 &building_total, &tax);
2191 fc_snprintf(buf, sizeof(buf), _("Income: %d Total Costs: %d"),
2192 tax, building_total + unit_total);
2194 if (player_primary_capital(pplayer)) {
2196 player_primary_capital(pplayer)));
2197 }
2198 } else {
2199 sw_tax->set_tooltip("");
2201 sw_map->set_tooltip("");
2203 }
2204
2206}
2207
2208/**********************************************************************/
2212{
2213 bool center_next = false;
2214 bool first_tile = false;
2215 int first_id;
2216 struct tile *ptile = nullptr;
2217
2218 players_iterate(pplayer) {
2219 if (pplayer != client_player()) {
2220 city_list_iterate(pplayer->cities, pcity) {
2221 if (!first_tile) {
2222 first_tile = true;
2223 ptile = pcity->tile;
2224 first_id = pcity->id;
2225 }
2226 if ((last_center_enemy_city == 0) || center_next) {
2229 return;
2230 }
2232 center_next = true;
2233 }
2235 }
2237
2238 if (ptile != nullptr) {
2239 center_tile_mapcanvas(ptile);
2241 }
2242}
2243
2244/**********************************************************************/
2248{
2249 bool center_next = false;
2250 bool first_tile = false;
2251 int first_id;
2252 struct tile *ptile = nullptr;
2253
2254 players_iterate(pplayer) {
2255 if (pplayer == client_player()) {
2256 city_list_iterate(pplayer->cities, pcity) {
2257 if (!first_tile) {
2258 first_tile = true;
2259 ptile = pcity->tile;
2260 first_id = pcity->id;
2261 }
2262 if ((last_center_player_city == 0) || center_next) {
2265 return;
2266 }
2268 center_next = true;
2269 }
2271 }
2273
2274 if (ptile != nullptr) {
2275 center_tile_mapcanvas(ptile);
2277 }
2278}
2279
2280/**********************************************************************/
2284{
2285 struct city *capital;
2286 bool center_next = false;
2287 bool first_tile = false;
2288 int first_id;
2289 struct tile *ptile = nullptr;
2290
2291 players_iterate(pplayer) {
2292 if (pplayer != client_player()) {
2293 capital = player_primary_capital(pplayer);
2294 if (capital == nullptr) {
2295 continue;
2296 }
2297 if (!first_tile) {
2298 first_tile = true;
2299 ptile = capital->tile;
2300 first_id = capital->id;
2301 }
2302 if ((last_center_player_city == 0) || center_next) {
2303 last_center_player_city = capital->id;
2304 center_tile_mapcanvas(capital->tile);
2305 put_cross_overlay_tile(capital->tile);
2306 return;
2307 }
2308 if (capital->id == last_center_player_city) {
2309 center_next = true;
2310 }
2311 }
2313
2314 if (ptile != nullptr) {
2315 center_tile_mapcanvas(ptile);
2318 }
2319
2320}
2321
2322/**********************************************************************/
2326{
2327 pages_layout[PAGE_GAME]->removeWidget(gui()->sidebar_wdg);
2329 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 0);
2330 } else {
2331 pages_layout[PAGE_GAME]->addWidget(sidebar_wdg, 1, 2);
2332 }
2333}
2334
2335/**********************************************************************/
2339{
2340 bool center_next = false;
2341 bool first_tile = false;
2342 int first_id;
2343 struct tile *ptile = nullptr;
2344
2345 players_iterate(pplayer) {
2346 if (pplayer != client_player()) {
2347 unit_list_iterate(pplayer->units, punit) {
2348 if (!first_tile) {
2349 first_tile = true;
2350 ptile = punit->tile;
2351 first_id = punit->id;
2352 }
2353 if ((last_center_enemy == 0) || center_next) {
2356 return;
2357 }
2358 if (punit->id == last_center_enemy) {
2359 center_next = true;
2360 }
2362 }
2364
2365 if (ptile != nullptr) {
2366 center_tile_mapcanvas(ptile);
2368 }
2369}
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:824
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:508
#define city_list_iterate_end
Definition city.h:510
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:1601
QLineEdit * connect_host_edit
Definition fc_client.h:188
fc_sidewidget * sw_tax
Definition fc_client.h:222
void update_buttons()
Definition pages.cpp:1925
QTextEdit * output_window
Definition fc_client.h:181
void state_preview_depr(int state)
Definition pages.cpp:872
void update_sidebar_tooltips()
Definition pages.cpp:2153
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:1157
QWidget * connect_lan
Definition fc_client.h:174
int add_game_tab(QWidget *widget)
Definition pages.cpp:817
fc_sidewidget * sw_science
Definition fc_client.h:275
QTableWidget * lan_widget
Definition fc_client.h:205
void browse_saves()
Definition pages.cpp:837
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:451
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:1070
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:2138
QTableWidget * wan_widget
Definition fc_client.h:206
void slot_pick_nation()
Definition pages.cpp:2130
map_view * mapview_wdg
Definition fc_client.h:230
void slot_selection_changed(const QItemSelection &, const QItemSelection &)
Definition pages.cpp:1175
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:647
void slot_disconnect()
void clear_status_bar()
Definition pages.cpp:467
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:266
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:1021
void update_sidebar_position()
Definition pages.cpp:2325
QMenu * page_submenu_team
Definition fc_client.h:282
void switch_page(int i)
void create_network_page()
Definition pages.cpp:303
QTreeWidget * start_players_tree
Definition fc_client.h:210
void create_load_page()
Definition pages.cpp:495
QTimer * lan_scan_timer
Definition fc_client.h:213
void update_start_page()
Definition pages.cpp:1696
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:483
void start_page_menu(QPoint)
Definition pages.cpp:1992
void update_server_list(enum server_scan_type sstype, const struct server_list *list)
Definition pages.cpp:907
void update_network_lists()
Definition pages.cpp:1051
QWidget * central_wdg
Definition fc_client.h:256
void slot_meta_scan()
Definition pages.cpp:1115
QString current_file
Definition fc_client.h:353
void slot_lan_scan()
Definition pages.cpp:1104
xvote * x_vote
Definition fc_client.h:264
void browse_scenarios()
Definition pages.cpp:890
void slot_pregame_start()
fc_sidewidget * sw_cities
Definition fc_client.h:221
void popup_client_options()
void slot_connect()
Definition pages.cpp:1639
fc_sidewidget * sw_map
Definition fc_client.h:220
void update_load_page(void)
Definition pages.cpp:1433
void start_scenario()
Definition pages.cpp:1139
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:829
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:853
void create_scenario_page()
Definition pages.cpp:580
void start_new_game()
Definition pages.cpp:1126
void update_scenarios_page(void)
Definition pages.cpp:1464
void create_game_page()
Definition pages.cpp:731
QIcon get_icon(const QString &id)
static fc_icons * instance()
void resize_me(int height, bool force=false)
Definition sidebar.cpp:566
void add_widget(fc_sidewidget *fsw)
Definition sidebar.cpp:533
void set_wheel_down(pfcn func)
Definition sidebar.cpp:283
void set_wheel_up(pfcn func)
Definition sidebar.cpp:291
void set_pixmap(QPixmap *pm)
Definition sidebar.cpp:120
void set_right_click(pfcn func)
Definition sidebar.cpp:275
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:77
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:68
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
void fc_mutex_allocate(fc_mutex *mutex)
Definition fcthread.c:144
void fc_mutex_release(fc_mutex *mutex)
Definition fcthread.c:152
const struct ft_color ftc_client
struct civ_game game
Definition game.c:62
const char * government_name_for_player(const struct player *pplayer)
Definition government.c:156
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
int send_packet_authentication_reply(struct connection *pc, const struct packet_authentication_reply *packet)
#define nat_x
#define nat_y
void center_tile_mapcanvas(const struct tile *ptile)
static mpgui * gui
Definition mpgui_qt.cpp:53
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:1174
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
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:2211
enum client_pages qtg_get_current_client_page()
Definition pages.cpp:122
static void center_next_player_city()
Definition pages.cpp:2247
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:2338
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:1008
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:2283
bool is_settable_ai_level(enum ai_level level)
Definition player.c:1908
const char * player_name(const struct player *pplayer)
Definition player.c:885
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1979
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1325
#define ai_level_cmd(_level_)
Definition player.h:582
#define players_iterate_end
Definition player.h:552
#define players_iterate(_pplayer)
Definition player.h:547
static bool is_barbarian(const struct player *pplayer)
Definition player.h:499
#define is_ai(plr)
Definition player.h:232
#define players_iterate_alive_end
Definition player.h:562
#define is_human(plr)
Definition player.h:231
#define players_iterate_alive(_pplayer)
Definition player.h:557
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:645
void side_show_map(bool nothing)
Definition sidebar.cpp:619
void side_indicators_menu()
Definition sidebar.cpp:697
void side_left_click_science(bool nothing)
Definition sidebar.cpp:805
void side_rates_wdg(bool nothing)
Definition sidebar.cpp:635
void side_finish_turn(bool nothing)
Definition sidebar.cpp:627
void side_right_click_science(void)
Definition sidebar.cpp:756
void side_right_click_diplomacy(void)
Definition sidebar.cpp:711
@ SW_TAX
Definition sidebar.h:26
@ SW_INDICATORS
Definition sidebar.h:26
Definition city.h:318
int id
Definition city.h:324
enum capital_type capital
Definition city.h:326
struct tile * tile
Definition city.h:320
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:421
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:457
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:188
#define terrain_type_iterate(_p)
Definition terrain.h:267
#define T_UNKNOWN
Definition terrain.h:62
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:88
#define terrain_type_iterate_end
Definition terrain.h:273
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:6996
#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
#define MINOR_VERSION
Definition version_gen.h:7
#define VERSION_STRING
Definition version_gen.h:14
#define MAJOR_VERSION
Definition version_gen.h:6
#define PATCH_VERSION
Definition version_gen.h:8