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