Freeciv21
Develop your civilization from humble roots to a global empire
fc_client.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can redistribute it
4  and/or modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation, either version 3 of the
6  License, or (at your option) any later version. You should have received
7  a copy of the GNU General Public License along with Freeciv21. If not,
8  see https://www.gnu.org/licenses/.
9  */
10 
11 #include "fc_client.h"
12 // Qt
13 #include <QApplication>
14 #include <QDirIterator>
15 #include <QProcess>
16 #include <QSettings>
17 #include <QStackedLayout>
18 #include <QStandardPaths>
19 #include <QStatusBar>
20 #include <QTcpSocket>
21 #include <QTextBlock>
22 #include <QTextCodec>
23 
24 // utility
25 #include "fcintl.h"
26 // common
27 #include "climisc.h"
28 // client
29 #include "chatline.h"
30 #include "chatline_common.h"
31 #include "client_main.h"
32 #include "clinet.h"
33 #include "connectdlg_common.h"
34 #include "fonts.h"
35 #include "gui_main.h"
36 #include "icons.h"
37 #include "messagewin.h"
38 #include "minimap.h"
39 #include "optiondlg.h"
40 #include "page_game.h"
41 #include "page_load.h"
42 #include "page_main.h"
43 #include "page_network.h"
44 #include "page_pregame.h"
45 #include "page_scenario.h"
46 #include "tileset/sprite.h"
47 #include "top_bar.h"
48 #include "update_queue.h"
49 #include "views/view_map.h"
50 #include "voteinfo_bar.h"
51 
54 
58 fc_client::fc_client() : QMainWindow(), current_file(QLatin1String(""))
59 {
60 #ifdef __EMSCRIPTEN__
61  setWindowFlags(Qt::FramelessWindowHint);
62  setWindowState(Qt::WindowFullScreen);
63 #endif
64  QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
65  status_bar_queue.clear();
66  for (int i = 0; i <= PAGE_GAME; i++) {
67  pages_layout[i] = nullptr;
68  pages[i] = nullptr;
69  }
71  read_settings();
72  QApplication::setFont(fcFont::instance()->getFont(fonts::default_font));
73  QString path;
74 
75  setWindowTitle(_("Freeciv21"));
76 
77  central_wdg = new QWidget;
78  central_layout = new QStackedLayout;
79 
80  menu_bar = new mr_menu();
81  corner_wid = new fc_corner(this);
83  menu_bar->setCornerWidget(corner_wid);
84  }
85  setMenuBar(menu_bar);
86  status_bar = statusBar();
87  status_bar_label = new QLabel;
88  status_bar_label->setAlignment(Qt::AlignCenter);
89  status_bar->addWidget(status_bar_label, 1);
90  set_status_bar(_("Welcome to Freeciv21"));
92  pages[PAGE_MAIN] = new page_main(central_wdg, this);
93  page = PAGE_MAIN;
94  pages[PAGE_START] = new page_pregame(central_wdg, this);
95  pages[PAGE_SCENARIO] = new page_scenario(central_wdg, this);
96  pages[PAGE_LOAD] = new page_load(central_wdg, this);
97  pages[PAGE_NETWORK] = new page_network(central_wdg, this);
98  pages[PAGE_NETWORK]->setVisible(false);
100  path = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
101  if (!path.isEmpty()) {
102  QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, path);
103  }
104 
106  auto page_game = new pageGame(central_wdg);
107  page_game->chat->installEventFilter(this); // To save its location
108  pages[PAGE_GAME] = page_game;
109 
110  pages[PAGE_LOADING] = new QWidget(central_wdg);
112  pages[PAGE_LOADING]->setLayout(pages_layout[PAGE_LOADING]);
113  central_layout->addWidget(pages[PAGE_MAIN]);
114  central_layout->addWidget(pages[PAGE_NETWORK]);
115  central_layout->addWidget(pages[PAGE_LOAD]);
116  central_layout->addWidget(pages[PAGE_SCENARIO]);
117  central_layout->addWidget(pages[PAGE_START]);
118  central_layout->addWidget(pages[PAGE_GAME]);
119  central_layout->addWidget(pages[PAGE_LOADING]);
120  central_wdg->setLayout(central_layout);
121  setCentralWidget(central_wdg);
122  resize(pages[PAGE_MAIN]->minimumSizeHint());
123  setVisible(true);
124  QPixmapCache::setCacheLimit(80000);
125 }
126 
131 {
132  status_bar_queue.clear();
133  if (fc_shortcuts::sc()) {
134  delete fc_shortcuts::sc();
135  }
136  delete_cursors();
137 }
138 
144 void fc_client::fc_main(QApplication *qapp)
145 {
146  qRegisterMetaType<QTextCursor>("QTextCursor");
147  qRegisterMetaType<QTextBlock>("QTextBlock");
149  real_output_window_append(_("This is the client for Freeciv21."), nullptr);
151  chat_welcome_message(true);
152 
154 
155  startTimer(TIMER_INTERVAL);
156  connect(qapp, &QCoreApplication::aboutToQuit, this, &fc_client::closing);
157  qapp->setAttribute(Qt::AA_UseHighDpiPixmaps);
158  qapp->exec();
159 
162 }
163 
167 bool fc_client::is_closing() { return quitting; }
168 
172 void fc_client::closing() { quitting = true; }
173 
180 void fc_client::switch_page(int new_pg)
181 {
182  const auto new_page = static_cast<client_pages>(new_pg);
183 
184  if ((new_page == PAGE_SCENARIO || new_page == PAGE_LOAD)
185  && !is_server_running()) {
186  current_file = QLatin1String("");
188  return;
189  }
190 
191  if (page == PAGE_NETWORK) {
192  qobject_cast<page_network *>(pages[PAGE_NETWORK])
193  ->destroy_server_scans();
194  }
195  menuBar()->setVisible(false);
196  if (status_bar != nullptr) {
197  status_bar->setVisible(true);
198  }
199  QApplication::alert(king()->central_wdg);
200  central_layout->setCurrentWidget(pages[new_pg]);
201  page = new_page;
202  switch (new_page) {
203  case PAGE_MAIN:
204  if (client.conn.used) {
206  }
207  showNormal();
208  show();
209  break;
210  case PAGE_START:
212  showNormal();
213  show();
214  break;
215  case PAGE_LOAD:
216  qobject_cast<page_load *>(pages[PAGE_LOAD])->update_load_page();
217  break;
218  case PAGE_GAME:
219  tileset_changed();
221  setWindowFlags(Qt::Window | Qt::CustomizeWindowHint);
222  }
223  showMaximized();
224  // Uncommenting will fix some resizing errors but will cause some
225  // problems with no focus caused by update_queue or something
226  // QCoreApplication::processEvents();
227  // For MS Windows, it might ingore first
228  showMaximized();
229  queen()->chat->update_widgets();
230  status_bar->setVisible(false);
232  king()->showFullScreen();
233  queen()->game_tab_widget->showFullScreen();
234  }
235  menuBar()->setVisible(true);
237  queen()->mapview_wdg->setFocus();
238  queen()->sw_message->setChecked(qt_settings.show_messages);
239  queen()->sw_message->setIcon(
240  fcIcons::instance()->getIcon(QStringLiteral("messages")));
241  queen()->message->clr();
245  update_minimap();
249  break;
250  case PAGE_SCENARIO:
251  qobject_cast<page_scenario *>(pages[PAGE_SCENARIO])
252  ->update_scenarios_page();
253  break;
254  case PAGE_NETWORK:
255  qobject_cast<page_network *>(pages[PAGE_NETWORK])
256  ->set_connection_state(LOGIN_TYPE);
257  qobject_cast<page_network *>(pages[PAGE_NETWORK])
258  ->update_network_lists();
259  break;
260  case PAGE_LOADING:
261  case PAGE_COUNT:
262  break;
263  }
264 
265  // Maybe popdown the tileset debugger
266  if (page != PAGE_GAME) {
268  }
269 }
270 
274 enum client_pages fc_client::current_page() { return page; }
275 
279 void fc_client::add_server_source(QIODevice *sock)
280 {
281  connect(sock, &QIODevice::readyRead, this, &fc_client::server_input);
282 
283  // By the time we reach this function, the socket may already have received
284  // data. Make sure that it's processed as well.
285  input_from_server(sock);
286 }
287 
291 void fc_client::closeEvent(QCloseEvent *event)
292 {
294  event->ignore();
295 }
296 
301 {
302  if (auto *socket = dynamic_cast<QIODevice *>(sender())) {
303  input_from_server(socket);
304  }
305 }
306 
310 void fc_client::timerEvent(QTimerEvent *event)
311 {
312  // Prevent current timer from repeating with possibly wrong interval
313  killTimer(event->timerId());
314 
315  // Call timer callback in client common code and
316  // start new timer with correct interval
317  startTimer(real_timer_callback() * 1000);
318 }
319 
324 {
325  if (client.conn.used) {
327  switch_page(PAGE_MAIN);
328  }
329 }
330 
335 {
336  int frame;
337  int cursor;
338 
339  for (cursor = 0; cursor < CURSOR_LAST; cursor++) {
340  for (frame = 0; frame < NUM_CURSOR_FRAMES; frame++) {
341  delete fc_cursors[cursor][frame];
342  }
343  }
344 }
345 
349 bool fc_client::eventFilter(QObject *obj, QEvent *event)
350 {
351  const auto page_game = qobject_cast<pageGame *>(pages[PAGE_GAME]);
352  if (page_game && obj == page_game->chat
353  && page_game->chat->is_chat_visible()) {
354  const auto chat = page_game->chat;
355  const auto mapview = page_game->mapview_wdg;
356  if (event->type() == QEvent::Move) {
357  const auto xy = QPointF(chat->pos());
358  qt_settings.chat_fx_pos = xy.x() / mapview->width();
359  qt_settings.chat_fy_pos = xy.y() / mapview->height();
360  } else if (event->type() == QEvent::Resize) {
361  const auto size = QSizeF(chat->size());
362  qt_settings.chat_fwidth = size.width() / mapview->width();
363  qt_settings.chat_fheight = size.height() / mapview->height();
364  }
365  }
366  return false;
367 }
368 
373 {
374  QSettings s(QSettings::IniFormat, QSettings::UserScope,
375  QStringLiteral("freeciv21-client"));
376  if (s.contains(QStringLiteral("Chat-fx-size"))) {
378  s.value(QStringLiteral("Chat-fx-size")).toFloat();
379  } else {
380  qt_settings.chat_fwidth = 0.2;
381  }
382  if (s.contains(QStringLiteral("Chat-fy-size"))) {
384  s.value(QStringLiteral("Chat-fy-size")).toFloat();
385  } else {
387  }
388  if (s.contains(QStringLiteral("Chat-fx-pos"))) {
390  s.value(QStringLiteral("Chat-fx-pos")).toFloat();
391  } else {
392  qt_settings.chat_fx_pos = 0.0;
393  }
394  if (s.contains(QStringLiteral("Chat-fy-pos"))) {
396  s.value(QStringLiteral("Chat-fy-pos")).toFloat();
397  } else {
398  qt_settings.chat_fy_pos = 0.6;
399  }
400  if (s.contains(QStringLiteral("unit_fx"))) {
402  s.value(QStringLiteral("unit_fx")).toFloat();
403  } else {
405  }
406  if (s.contains(QStringLiteral("unit_fy"))) {
408  s.value(QStringLiteral("unit_fy")).toFloat();
409  } else {
411  }
412  if (s.contains(QStringLiteral("minimap_x"))) {
413  qt_settings.minimap_x = s.value(QStringLiteral("minimap_x")).toFloat();
414  } else {
415  qt_settings.minimap_x = 0.84;
416  }
417  if (s.contains(QStringLiteral("minimap_y"))) {
418  qt_settings.minimap_y = s.value(QStringLiteral("minimap_y")).toFloat();
419  } else {
420  qt_settings.minimap_y = 0.79;
421  }
422  if (s.contains(QStringLiteral("minimap_width"))) {
424  s.value(QStringLiteral("minimap_width")).toFloat();
425  } else {
426  qt_settings.minimap_width = 0.15;
427  }
428  if (s.contains(QStringLiteral("minimap_height"))) {
430  s.value(QStringLiteral("minimap_height")).toFloat();
431  } else {
433  }
434  if (s.contains(QStringLiteral("battlelog_scale"))) {
436  s.value(QStringLiteral("battlelog_scale")).toFloat();
437  } else {
439  }
440 
441  if (s.contains(QStringLiteral("help-dialog"))) {
443  s.value(QStringLiteral("help-dialog")).toByteArray();
444  }
445  if (s.contains(QStringLiteral("help_splitter1"))) {
447  s.value(QStringLiteral("help_splitter1")).toByteArray();
448  }
449  if (s.contains(QStringLiteral("new_turn_text"))) {
451  s.value(QStringLiteral("new_turn_text")).toBool();
452  } else {
454  }
455  if (s.contains(QStringLiteral("show_battle_log"))) {
457  s.value(QStringLiteral("show_battle_log")).toBool();
458  } else {
460  }
461 
463  s.value(QStringLiteral("show_chat"), true).toBool();
465  s.value(QStringLiteral("show_messages"), false).toBool();
466 
467  if (s.contains(QStringLiteral("battlelog_x"))) {
469  s.value(QStringLiteral("battlelog_x")).toFloat();
470  } else {
471  qt_settings.battlelog_x = 0.0;
472  }
473  if (s.contains(QStringLiteral("battlelog_y"))) {
475  s.value(QStringLiteral("battlelog_y")).toFloat();
476  } else {
477  qt_settings.battlelog_y = 0.0;
478  }
481 
483  qt_settings.chat_fx_pos = 0.0;
484  }
486  qt_settings.chat_fy_pos = 0.6;
487  }
488  if (qt_settings.chat_fwidth < 0.05 || qt_settings.chat_fwidth > 0.9) {
489  qt_settings.chat_fwidth = 0.2;
490  }
491  if (qt_settings.chat_fheight < 0.05 || qt_settings.chat_fheight > 0.9) {
492  qt_settings.chat_fheight = 0.33;
493  }
494  if (qt_settings.battlelog_x < 0.0) {
495  qt_settings.battlelog_x = 0.33;
496  }
497  if (qt_settings.battlelog_y < 0.0) {
498  qt_settings.battlelog_y = 0.0;
499  }
500  if (qt_settings.battlelog_scale > 5.0) {
501  qt_settings.battlelog_y = 5.0;
502  }
503  if (qt_settings.minimap_x < 0 || qt_settings.minimap_x > 1) {
504  qt_settings.chat_fx_pos = 0.84;
505  }
506  if (qt_settings.minimap_y < 0 || qt_settings.minimap_y > 1) {
507  qt_settings.chat_fx_pos = 0.79;
508  }
509 }
510 
515 {
516  QSettings s(QSettings::IniFormat, QSettings::UserScope,
517  QStringLiteral("freeciv21-client"));
518  s.setValue(QStringLiteral("Fonts-set"), true);
519  s.setValue(QStringLiteral("Chat-fx-size"), qt_settings.chat_fwidth);
520  s.setValue(QStringLiteral("Chat-fy-size"), qt_settings.chat_fheight);
521  s.setValue(QStringLiteral("Chat-fx-pos"), qt_settings.chat_fx_pos);
522  s.setValue(QStringLiteral("Chat-fy-pos"), qt_settings.chat_fy_pos);
523  s.setValue(QStringLiteral("help-dialog"), qt_settings.help_geometry);
524  s.setValue(QStringLiteral("help_splitter1"), qt_settings.help_splitter1);
525  s.setValue(QStringLiteral("unit_fx"), qt_settings.unit_info_pos_fx);
526  s.setValue(QStringLiteral("unit_fy"), qt_settings.unit_info_pos_fy);
527  s.setValue(QStringLiteral("minimap_x"), qt_settings.minimap_x);
528  s.setValue(QStringLiteral("minimap_y"), qt_settings.minimap_y);
529  s.setValue(QStringLiteral("minimap_width"), qt_settings.minimap_width);
530  s.setValue(QStringLiteral("minimap_height"), qt_settings.minimap_height);
531  s.setValue(QStringLiteral("battlelog_scale"), qt_settings.battlelog_scale);
532  s.setValue(QStringLiteral("battlelog_x"), qt_settings.battlelog_x);
533  s.setValue(QStringLiteral("battlelog_y"), qt_settings.battlelog_y);
534  s.setValue(QStringLiteral("new_turn_text"),
536  s.setValue(QStringLiteral("show_battle_log"), qt_settings.show_battle_log);
537  s.setValue(QStringLiteral("show_chat"), queen()->chat->is_chat_visible());
538  s.setValue(QStringLiteral("show_messages"),
539  queen()->sw_message->isChecked());
540  fc_shortcuts::sc()->write();
541 }
542 
547 {
548  option_dialog_popup(_("Interface Options"), client_optset);
549 }
550 
555 {
556  for (int cursor = 0; cursor < CURSOR_LAST; cursor++) {
557  for (int frame = 0; frame < NUM_CURSOR_FRAMES; frame++) {
558  auto curs = static_cast<cursor_type>(cursor);
559  int hot_x, hot_y;
560  auto sprite = get_cursor_sprite(tileset, curs, &hot_x, &hot_y, frame);
561  auto c = new QCursor(*sprite, hot_x, hot_y);
562  fc_cursors[cursor][frame] = c;
563  }
564  }
565 }
566 
570 void real_set_client_page(enum client_pages page)
571 {
572  king()->switch_page(page);
573 }
574 
580 void set_rulesets(int num_rulesets, QStringList rulesets)
581 {
582  qobject_cast<page_pregame *>(king()->pages[PAGE_START])
583  ->set_rulesets(num_rulesets, rulesets);
584 }
585 
589 enum client_pages get_current_client_page()
590 {
591  return king()->current_page();
592 }
593 
598 {
599  qobject_cast<page_pregame *>(king()->pages[PAGE_START])
600  ->update_start_page();
601 }
602 
606 void fc_client::set_status_bar(const QString &message, int timeout)
607 {
608  if (status_bar_label->text().isEmpty()) {
609  status_bar_label->setText(message);
610  QTimer::singleShot(timeout, this, &fc_client::clear_status_bar);
611  } else {
612  status_bar_queue.append(message);
613  while (status_bar_queue.count() > 3) {
614  status_bar_queue.removeFirst();
615  }
616  }
617 }
618 
623 {
624  QString str;
625 
626  if (!status_bar_queue.isEmpty()) {
627  str = status_bar_queue.takeFirst();
628  status_bar_label->setText(str);
629  QTimer::singleShot(2000, this, &fc_client::clear_status_bar);
630  } else {
631  status_bar_label->setText(QLatin1String(""));
632  }
633 }
634 
639 {
640  QLabel *label = new QLabel(_("Loading..."));
641 
642  pages_layout[PAGE_LOADING] = new QGridLayout;
643  pages_layout[PAGE_LOADING]->addWidget(label, 0, 0, 1, 1, Qt::AlignHCenter);
644 }
645 
650 {
651  const auto il = find_files_in_path(get_scenario_dirs(),
652  QStringLiteral("tutorial.sav*"), false);
653  if (il.isEmpty()) {
654  qCritical(_("Could not find the tutorial savegame."));
655  return;
656  }
657 
658  current_file = il.front().absoluteFilePath();
659  if (client_start_server(client_url().userName())) {
661  client.conn.client.last_request_id_used,
662  [](void *) { king()->start_from_file(king()->current_file); }, this);
663  }
664 }
665 
669 void fc_client::start_from_file(const QString &file)
670 {
671  if (!is_server_running()) {
672  if (client_start_server(client_url().userName())) {
673  send_chat("/detach");
674  }
675  }
676  if (is_server_running() && !file.isEmpty()) {
677  send_chat_printf("/load %s", qUtf8Printable(file));
678  switch_page(PAGE_LOADING);
679  }
680 }
681 
686 {
687  if (is_server_running() || client_start_server(client_url().userName())) {
688  /* saved settings are sent in client/options.c load_settable_options() */
689  }
690 }
691 
696 {
697  output_window_append(ftc_client, _("Starting the modpack installer..."));
698 
699  const QString storage = freeciv_storage_dir();
700  if (storage == nullptr) {
702  _("Cannot find Freeciv21 storage directory"));
704  ftc_client,
705  _("You'll have to start the modpack installer manually. Sorry..."));
706  return;
707  }
708 
709  // Look for a modpack installer binary
710  const QString modpack_name = QStringLiteral("freeciv21-modpack-qt");
711 
712  // First next to the client binary
713  // NOTE On Windows findExecutable adds the .exe automatically
714  QString location = QStandardPaths::findExecutable(
715  modpack_name, {QCoreApplication::applicationDirPath()});
716  if (location.isEmpty()) {
717  // Then in PATH
718  location = QStandardPaths::findExecutable(modpack_name);
719  }
720 
721  // Start it
722  qInfo(_("Starting freeciv21-modpack-qt at %s"), qUtf8Printable(location));
723 
724  QProcess *modProcess = new QProcess(this);
725  QStringList arguments;
726  modProcess->start(location, arguments);
727 }
728 
732 fc_corner::fc_corner(QMainWindow *qmw) : QWidget()
733 {
734  QHBoxLayout *hb;
735  QPushButton *qpb;
736  int h;
738 
739  if (f.pointSize() > 0) {
740  h = f.pointSize();
741  } else {
742  h = f.pixelSize();
743  }
744  mw = qmw;
745  hb = new QHBoxLayout();
746  qpb = new QPushButton(fcIcons::instance()->getIcon(QStringLiteral("cmin")),
747  QLatin1String(""));
748  qpb->setFixedSize(h, h);
749  connect(qpb, &QAbstractButton::clicked, this, &fc_corner::minimize);
750  hb->addWidget(qpb);
751  qpb = new QPushButton(fcIcons::instance()->getIcon(QStringLiteral("cmax")),
752  QLatin1String(""));
753  qpb->setFixedSize(h, h);
754  connect(qpb, &QAbstractButton::clicked, this, &fc_corner::maximize);
755  hb->addWidget(qpb);
756  qpb =
757  new QPushButton(fcIcons::instance()->getIcon(QStringLiteral("cclose")),
758  QLatin1String(""));
759  qpb->setFixedSize(h, h);
760  connect(qpb, &QAbstractButton::clicked, this, &fc_corner::close_fc);
761  hb->addWidget(qpb);
762  setLayout(hb);
763 }
764 
768 void fc_corner::close_fc() { mw->close(); }
769 
774 {
775  if (!mw->isMaximized()) {
776  mw->showMaximized();
777  } else {
778  mw->showNormal();
779  }
780 }
781 
785 void fc_corner::minimize() { mw->showMinimized(); }
void real_output_window_append(const QString &astring, const text_tag_list *tags)
Appends the string to the chat output window.
Definition: chatline.cpp:881
int send_chat_printf(const char *format,...)
Send the message as a chat to the server.
void fc_release_ow_mutex()
Release output window mutex.
int send_chat(const char *message)
Send the message as a chat to the server.
void output_window_append(const struct ft_color color, const char *featured_text)
Add a line of text to the output ("chatline") window, like puts() would do it in the console.
void fc_allocate_ow_mutex()
Allocate output window mutex.
void chat_welcome_message(bool gui_has_copying_mitem)
Standard welcome message.
void update_widgets()
Hides allies and links button for local game.
Definition: chatline.cpp:643
void set_chat_visible(bool visible)
Manages toggling minimization.
Definition: chatline.cpp:461
Definition: fonts.h:28
void initFonts()
Initiazlizes fonts from client options.
Definition: fonts.cpp:77
QFont getFont(const QString &name, double zoom=1.0) const
Returns desired font.
Definition: fonts.cpp:57
static fcFont * m_instance
Definition: fonts.h:33
static fcFont * instance()
Returns instance of fc_font.
Definition: fonts.cpp:34
static fcIcons * instance()
Returns instance of fc_icons.
Definition: icons.cpp:36
void load_modpack()
Load the modpack-installer from the start menu.
Definition: fc_client.cpp:695
QStringList status_bar_queue
Definition: fc_client.h:103
fc_settings qt_settings
Definition: fc_client.h:126
mr_menu * menu_bar
Definition: fc_client.h:127
bool quitting
Definition: fc_client.h:104
void closing()
Called when fc_client is going to quit.
Definition: fc_client.cpp:172
void closeEvent(QCloseEvent *event) override
Closes main window.
Definition: fc_client.cpp:291
fc_client()
Constructor.
Definition: fc_client.cpp:58
~fc_client() override
Destructor.
Definition: fc_client.cpp:130
QGridLayout * pages_layout[PAGE_COUNT]
Definition: fc_client.h:97
void timerEvent(QTimerEvent *) override
Timer event handling.
Definition: fc_client.cpp:310
void create_cursors()
Setup cursors.
Definition: fc_client.cpp:554
void read_settings()
Loads qt-specific options.
Definition: fc_client.cpp:372
enum client_pages page
Definition: fc_client.h:96
enum client_pages current_page()
Returns currently open page.
Definition: fc_client.cpp:274
QStatusBar * status_bar
Definition: fc_client.h:101
QCursor * fc_cursors[CURSOR_LAST][NUM_CURSOR_FRAMES]
Definition: fc_client.h:122
bool eventFilter(QObject *obj, QEvent *event) override
Used to keep track of the size and location of the chat widget.
Definition: fc_client.cpp:349
QStackedLayout * central_layout
Definition: fc_client.h:100
void write_settings()
Save qt-specific options.
Definition: fc_client.cpp:514
void slot_disconnect()
Disconnect from server and return to MAIN PAGE.
Definition: fc_client.cpp:323
void clear_status_bar()
Clears status bar or shows next message in queue if exists.
Definition: fc_client.cpp:622
QLabel * status_bar_label
Definition: fc_client.h:98
void add_server_source(QIODevice *socket)
Add notifier for server input.
Definition: fc_client.cpp:279
void switch_page(int i)
Switch from one client page to another.
Definition: fc_client.cpp:180
QWidget * pages[static_cast< int >(PAGE_GAME)+2]
Definition: fc_client.h:111
void create_loading_page()
Creates page LOADING, showing label with Loading text.
Definition: fc_client.cpp:638
QWidget * central_wdg
Definition: fc_client.h:123
void fc_main(QApplication *)
This is not called simply 'fc_client::main()', since SDL includes ould sometimes cause 'main' to be c...
Definition: fc_client.cpp:144
QString current_file
Definition: fc_client.h:102
void set_status_bar(const QString &str, int timeout=20000)
Sets application status bar for given time in miliseconds.
Definition: fc_client.cpp:606
void server_input()
There is input from server.
Definition: fc_client.cpp:300
void start_tutorial()
start tutorial
Definition: fc_client.cpp:649
void start_from_file(const QString &file)
start from save file
Definition: fc_client.cpp:669
void delete_cursors()
Deletes cursors.
Definition: fc_client.cpp:334
fc_corner * corner_wid
Definition: fc_client.h:125
bool is_closing()
Returns status if fc_client is being closed.
Definition: fc_client.cpp:167
void start_new_game()
spawn a server, if there isn't one, using the default settings.
Definition: fc_client.cpp:685
void minimize()
Slot for minimizing freeciv window via corner widget.
Definition: fc_client.cpp:785
QMainWindow * mw
Definition: fc_client.h:83
void maximize()
Slot for maximizing freeciv window via corner widget.
Definition: fc_client.cpp:773
void close_fc()
Slot for closing freeciv via corner widget.
Definition: fc_client.cpp:768
fc_corner(QMainWindow *qmw)
Contructor for corner widget (used for menubar)
Definition: fc_client.cpp:732
static fc_shortcuts * sc()
Returns given instance.
Definition: shortcuts.cpp:354
void write() const
Writes shortcuts to file.
Definition: shortcuts.cpp:746
void hide_debugger()
Closes the tileset debugger if it is open.
Definition: view_map.cpp:301
void clr()
Clears and removes mesg_table all items.
Definition: messagewin.cpp:137
Definition: menu.h:157
map_view * mapview_wdg
Definition: page_game.h:81
chat_widget * chat
Definition: page_game.h:80
void updateSidebarTooltips()
Updates top bar tooltips.
Definition: page_game.cpp:340
message_widget * message
Definition: page_game.h:78
fc_game_tab_widget * game_tab_widget
Definition: page_game.h:72
top_bar_widget * sw_message
Definition: page_game.h:79
static update_queue * uq()
void connect_processing_finished(int request_id, uq_callback_t cb, void *data)
QUrl & client_url()
Returns the URL that this client connects to.
double real_timer_callback()
This function should be called at least once per second.
struct civclient client
void set_client_state(enum client_states newstate)
Change client state.
#define TIMER_INTERVAL
Definition: client_main.h:26
@ C_S_DISCONNECTED
Definition: client_main.h:41
void center_on_something()
Find something sensible to display.
Definition: climisc.cpp:392
void input_from_server(QIODevice *sock)
This function is called when the client received a new input from the server.
Definition: clinet.cpp:297
void disconnect_from_server()
Get rid of server connection.
Definition: clinet.cpp:219
bool is_server_running()
The general chain of events:
bool client_start_server(const QString &user_name)
Forks a server if it can.
enum event_type event
Definition: events.cpp:68
void set_rulesets(int num_rulesets, QStringList rulesets)
Set the list of available rulesets.
Definition: fc_client.cpp:580
enum client_pages get_current_client_page()
Returns current client page.
Definition: fc_client.cpp:589
void popup_client_options()
Popups client options.
Definition: fc_client.cpp:546
void real_set_client_page(enum client_pages page)
Sets the "page" that the client should show.
Definition: fc_client.cpp:570
void real_science_report_dialog_update(void *)
Update the science report.
void update_start_page(void)
Update the start page.
Definition: fc_client.cpp:597
@ LOGIN_TYPE
Definition: fc_client.h:43
class fc_client * king()
Return fc_client instance.
Definition: gui_main.cpp:58
#define _(String)
Definition: fcintl.h:50
const struct ft_color ftc_client
void popup_quit_dialog()
Open dialog to confirm that user wants to quit client.
Definition: gui_main.cpp:293
void show_new_turn_info()
Shows new turn information with big font.
Definition: hudwidget.cpp:1305
void update_info_label(void)
Typically an info box is provided to tell the player about the state of their civilization.
Definition: page_game.cpp:750
void tileset_changed(void)
This function is called when the tileset is changed.
Definition: view_map.cpp:554
void update_minimap(void)
Return a canvas that is the overview window.
Definition: minimap.cpp:256
const char *const default_font
Definition: fonts.h:18
void option_dialog_popup(const char *name, const struct option_set *poptset)
Popup the option dialog for the option set.
Definition: optiondlg.cpp:722
client_options * gui_options
Definition: options.cpp:74
const struct option_set * client_optset
Definition: options.cpp:860
pageGame * queen()
Return game instandce.
Definition: page_game.cpp:557
void client_start_server_and_set_page(enum client_pages page)
QFileInfoList find_files_in_path(const QStringList &path, const QString &pattern, bool nodups)
Search for file names matching the pattern in the provided list of directories.
Definition: shared.cpp:681
QString freeciv_storage_dir()
Returns string which gives freeciv storage dir.
Definition: shared.cpp:419
const QStringList & get_scenario_dirs()
Returns a list of scenario directory paths, in the order in which they should be searched.
Definition: shared.cpp:594
size_t size
Definition: specvec.h:64
struct connection conn
Definition: client_main.h:89
bool gui_qt_fullscreen
Definition: options.h:164
bool gui_qt_allied_chat_only
Definition: options.h:166
bool gui_qt_show_titlebar
Definition: options.h:177
struct connection::@55::@60 client
QByteArray help_geometry
Definition: fc_client.h:65
float unit_info_pos_fx
Definition: fc_client.h:67
float unit_info_pos_fy
Definition: fc_client.h:68
float chat_fwidth
Definition: fc_client.h:53
float chat_fheight
Definition: fc_client.h:54
QByteArray help_splitter1
Definition: fc_client.h:66
float chat_fx_pos
Definition: fc_client.h:55
float battlelog_scale
Definition: fc_client.h:73
float battlelog_x
Definition: fc_client.h:74
float minimap_x
Definition: fc_client.h:69
bool show_messages
Definition: fc_client.h:61
float minimap_height
Definition: fc_client.h:72
bool show_battle_log
Definition: fc_client.h:59
int city_repo_sort_col
Definition: fc_client.h:63
float minimap_width
Definition: fc_client.h:71
float battlelog_y
Definition: fc_client.h:75
bool show_chat
Definition: fc_client.h:60
float chat_fy_pos
Definition: fc_client.h:56
bool show_new_turn_text
Definition: fc_client.h:58
float minimap_y
Definition: fc_client.h:70
int player_repo_sort_col
Definition: fc_client.h:57
int height
int width
void tileset_free_tiles(struct tileset *t)
Free all sprites from tileset.
Definition: tilespec.cpp:3285
const QPixmap * get_cursor_sprite(const struct tileset *t, enum cursor_type cursor, int *hot_x, int *hot_y, int frame)
Returns a sprite for the given cursor.
Definition: tilespec.cpp:3542
#define NUM_CURSOR_FRAMES
Definition: tilespec.h:169
cursor_type
Definition: tilespec.h:154
@ CURSOR_LAST
Definition: tilespec.h:165
void init_mapcanvas_and_overview()
Sets up data for the mapview and overview.
struct view mapview
void free_mapcanvas_and_overview()
Frees resources allocated for mapview and overview.
void voteinfo_gui_update(void)
Refresh all vote related GUI widgets.